Working dashboard!
Some checks are pending
/ setup (push) Waiting to run

This commit is contained in:
soaxelbrooke 2025-07-12 10:13:38 -07:00
parent 5af7e751ae
commit b314ee6abd
4 changed files with 43 additions and 24 deletions

View file

@ -13,6 +13,7 @@ export const RecentActivity = {
console.log('RecentActivity: Starting loadData, loading=', this.loading); console.log('RecentActivity: Starting loadData, loading=', this.loading);
this.loading = true; this.loading = true;
this.error = null; this.error = null;
m.redraw(); // Redraw to show loading state
const service = DashboardService.getInstance(); const service = DashboardService.getInstance();
console.log('RecentActivity: Got service instance, calling getRecentActivity'); console.log('RecentActivity: Got service instance, calling getRecentActivity');
@ -23,11 +24,13 @@ export const RecentActivity = {
this.data = data; this.data = data;
this.loading = false; this.loading = false;
console.log('RecentActivity: Data loaded, loading=', this.loading, 'data=', !!this.data); console.log('RecentActivity: Data loaded, loading=', this.loading, 'data=', !!this.data);
m.redraw(); // Explicitly redraw after data loads
}) })
.catch(error => { .catch(error => {
console.error('RecentActivity: Error in loadData:', error); console.error('RecentActivity: Error in loadData:', error);
this.error = error instanceof Error ? error.message : 'Failed to load data'; this.error = error instanceof Error ? error.message : 'Failed to load data';
this.loading = false; this.loading = false;
m.redraw(); // Redraw after error
}); });
}, },

View file

@ -57,14 +57,14 @@ export class DashboardService {
const recentBuilds: BuildRequest[] = activityResponse.recentBuilds.map((build: BuildSummary) => ({ const recentBuilds: BuildRequest[] = activityResponse.recentBuilds.map((build: BuildSummary) => ({
id: build.buildRequestId, id: build.buildRequestId,
status: build.status, status: build.status,
createdAt: new Date(build.createdAt * 1000).toISOString(), // Convert from Unix timestamp createdAt: new Date(build.createdAt / 1000000).toISOString(), // Convert from nanoseconds to milliseconds
updatedAt: new Date(build.updatedAt * 1000).toISOString() updatedAt: new Date(build.updatedAt / 1000000).toISOString()
})); }));
const recentPartitions: PartitionBuild[] = activityResponse.recentPartitions.map((partition: PartitionSummary) => ({ const recentPartitions: PartitionBuild[] = activityResponse.recentPartitions.map((partition: PartitionSummary) => ({
ref: partition.partitionRef, ref: partition.partitionRef,
status: partition.status, status: partition.status,
updatedAt: new Date(partition.updatedAt * 1000).toISOString(), updatedAt: new Date(partition.updatedAt / 1000000).toISOString(),
buildRequestId: partition.buildRequestId || undefined buildRequestId: partition.buildRequestId || undefined
})); }));

View file

@ -4,27 +4,29 @@ use rusqlite::{params, Connection, Row};
use serde_json; use serde_json;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
// Helper functions to convert strings back to enum values // Helper functions to convert integer values back to enum values
fn string_to_build_request_status(s: &str) -> BuildRequestStatus { fn int_to_build_request_status(i: i32) -> BuildRequestStatus {
match s { match i {
"BuildRequestReceived" => BuildRequestStatus::BuildRequestReceived, 0 => BuildRequestStatus::BuildRequestUnknown,
"BuildRequestPlanning" => BuildRequestStatus::BuildRequestPlanning, 1 => BuildRequestStatus::BuildRequestReceived,
"BuildRequestExecuting" => BuildRequestStatus::BuildRequestExecuting, 2 => BuildRequestStatus::BuildRequestPlanning,
"BuildRequestCompleted" => BuildRequestStatus::BuildRequestCompleted, 3 => BuildRequestStatus::BuildRequestExecuting,
"BuildRequestFailed" => BuildRequestStatus::BuildRequestFailed, 4 => BuildRequestStatus::BuildRequestCompleted,
"BuildRequestCancelled" => BuildRequestStatus::BuildRequestCancelled, 5 => BuildRequestStatus::BuildRequestFailed,
6 => BuildRequestStatus::BuildRequestCancelled,
_ => BuildRequestStatus::BuildRequestUnknown, _ => BuildRequestStatus::BuildRequestUnknown,
} }
} }
fn string_to_partition_status(s: &str) -> PartitionStatus { fn int_to_partition_status(i: i32) -> PartitionStatus {
match s { match i {
"PartitionRequested" => PartitionStatus::PartitionRequested, 0 => PartitionStatus::PartitionUnknown,
"PartitionScheduled" => PartitionStatus::PartitionScheduled, 1 => PartitionStatus::PartitionRequested,
"PartitionBuilding" => PartitionStatus::PartitionBuilding, 2 => PartitionStatus::PartitionScheduled,
"PartitionAvailable" => PartitionStatus::PartitionAvailable, 3 => PartitionStatus::PartitionBuilding,
"PartitionFailed" => PartitionStatus::PartitionFailed, 4 => PartitionStatus::PartitionAvailable,
"PartitionDelegated" => PartitionStatus::PartitionDelegated, 5 => PartitionStatus::PartitionFailed,
6 => PartitionStatus::PartitionDelegated,
_ => PartitionStatus::PartitionUnknown, _ => PartitionStatus::PartitionUnknown,
} }
} }
@ -465,9 +467,14 @@ impl BuildEventLog for SqliteBuildEventLog {
.map_err(|e| BuildEventLogError::QueryError(e.to_string()))?; .map_err(|e| BuildEventLogError::QueryError(e.to_string()))?;
let build_row_mapper = |row: &Row| -> rusqlite::Result<BuildRequestSummary> { let build_row_mapper = |row: &Row| -> rusqlite::Result<BuildRequestSummary> {
let status_str: String = row.get(1)?;
let status = status_str.parse::<i32>()
.map(int_to_build_request_status)
.unwrap_or(BuildRequestStatus::BuildRequestUnknown);
Ok(BuildRequestSummary { Ok(BuildRequestSummary {
build_request_id: row.get(0)?, build_request_id: row.get(0)?,
status: string_to_build_request_status(&row.get::<_, String>(1)?), status,
requested_partitions: serde_json::from_str(&row.get::<_, String>(2)?).unwrap_or_default(), requested_partitions: serde_json::from_str(&row.get::<_, String>(2)?).unwrap_or_default(),
created_at: row.get(3)?, created_at: row.get(3)?,
updated_at: row.get(4)?, updated_at: row.get(4)?,
@ -535,9 +542,14 @@ impl BuildEventLog for SqliteBuildEventLog {
.map_err(|e| BuildEventLogError::QueryError(e.to_string()))?; .map_err(|e| BuildEventLogError::QueryError(e.to_string()))?;
let row_mapper = |row: &Row| -> rusqlite::Result<PartitionSummary> { let row_mapper = |row: &Row| -> rusqlite::Result<PartitionSummary> {
let status_str: String = row.get(1)?;
let status = status_str.parse::<i32>()
.map(int_to_partition_status)
.unwrap_or(PartitionStatus::PartitionUnknown);
Ok(PartitionSummary { Ok(PartitionSummary {
partition_ref: row.get(0)?, partition_ref: row.get(0)?,
status: string_to_partition_status(&row.get::<_, String>(1)?), status,
updated_at: row.get(2)?, updated_at: row.get(2)?,
build_request_id: Some(row.get(3)?), build_request_id: Some(row.get(3)?),
}) })

View file

@ -60,7 +60,11 @@ async fn main() {
let port: u16 = matches.get_one::<String>("port").unwrap() let port: u16 = matches.get_one::<String>("port").unwrap()
.parse().expect("Invalid port number"); .parse().expect("Invalid port number");
let host = matches.get_one::<String>("host").unwrap(); let host = matches.get_one::<String>("host").unwrap();
let event_log_uri = matches.get_one::<String>("event-log").unwrap();
// Check environment variable first, fall back to command line argument
let event_log_uri = env::var("DATABUILD_BUILD_EVENT_LOG")
.unwrap_or_else(|_| matches.get_one::<String>("event-log").unwrap().to_string());
let graph_label = matches.get_one::<String>("graph-label").unwrap().to_string(); let graph_label = matches.get_one::<String>("graph-label").unwrap().to_string();
let job_lookup_path = matches.get_one::<String>("job-lookup-path").unwrap().to_string(); let job_lookup_path = matches.get_one::<String>("job-lookup-path").unwrap().to_string();
@ -110,7 +114,7 @@ async fn main() {
// Create service // Create service
let service = match BuildGraphService::new( let service = match BuildGraphService::new(
event_log_uri, &event_log_uri,
graph_label, graph_label,
job_lookup_path, job_lookup_path,
candidate_jobs, candidate_jobs,