api camelCase -> snake_case
This commit is contained in:
parent
b70a6ce9a7
commit
45433da0b8
6 changed files with 91 additions and 90 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
load("@aspect_rules_ts//ts:defs.bzl", "ts_project", "ts_config")
|
load("@aspect_rules_ts//ts:defs.bzl", "ts_config", "ts_project")
|
||||||
|
|
||||||
# Extract OpenAPI spec from the dedicated spec generator binary
|
# Extract OpenAPI spec from the dedicated spec generator binary
|
||||||
genrule(
|
genrule(
|
||||||
|
|
@ -64,17 +64,17 @@ genrule(
|
||||||
if [ ! -f $$OPENAPI_JAR ]; then
|
if [ ! -f $$OPENAPI_JAR ]; then
|
||||||
curl -L -o $$OPENAPI_JAR https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.2.0/openapi-generator-cli-7.2.0.jar
|
curl -L -o $$OPENAPI_JAR https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.2.0/openapi-generator-cli-7.2.0.jar
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create temporary directory for generation
|
# Create temporary directory for generation
|
||||||
TEMP_DIR=$$(mktemp -d)
|
TEMP_DIR=$$(mktemp -d)
|
||||||
|
|
||||||
# Generate TypeScript client to temp directory
|
# Generate TypeScript client to temp directory
|
||||||
java -jar $$OPENAPI_JAR generate \
|
java -jar $$OPENAPI_JAR generate \
|
||||||
-i $(location :extract_openapi_spec) \
|
-i $(location :extract_openapi_spec) \
|
||||||
-g typescript-fetch \
|
-g typescript-fetch \
|
||||||
-c $(location :typescript_generator_config) \
|
-c $(location :typescript_generator_config) \
|
||||||
-o $$TEMP_DIR
|
-o $$TEMP_DIR
|
||||||
|
|
||||||
# Copy generated files to expected output locations
|
# Copy generated files to expected output locations
|
||||||
cp $$TEMP_DIR/src/apis/DefaultApi.ts $(location typescript_generated/src/apis/DefaultApi.ts)
|
cp $$TEMP_DIR/src/apis/DefaultApi.ts $(location typescript_generated/src/apis/DefaultApi.ts)
|
||||||
cp $$TEMP_DIR/src/apis/index.ts $(location typescript_generated/src/apis/index.ts)
|
cp $$TEMP_DIR/src/apis/index.ts $(location typescript_generated/src/apis/index.ts)
|
||||||
|
|
@ -134,4 +134,4 @@ filegroup(
|
||||||
":typescript_client",
|
":typescript_client",
|
||||||
],
|
],
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"enumPropertyNaming": "camelCase",
|
"enumPropertyNaming": "snake_case",
|
||||||
"withInterfaces": true,
|
"withInterfaces": true,
|
||||||
"useSingleRequestParameter": true,
|
"useSingleRequestParameter": true,
|
||||||
"typescriptThreePlus": true,
|
"typescriptThreePlus": true,
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
"npmVersion": "1.0.0",
|
"npmVersion": "1.0.0",
|
||||||
"stringEnums": true,
|
"stringEnums": true,
|
||||||
"generateAliasAsModel": false,
|
"generateAliasAsModel": false,
|
||||||
"modelPropertyNaming": "camelCase",
|
"modelPropertyNaming": "snake_case",
|
||||||
"paramNaming": "camelCase",
|
"paramNaming": "snake_case",
|
||||||
"supportsES6": true,
|
"supportsES6": true,
|
||||||
"withoutRuntimeChecks": false
|
"withoutRuntimeChecks": false
|
||||||
}
|
}
|
||||||
|
|
@ -194,12 +194,12 @@ export const RecentActivity = {
|
||||||
m('tr.hover', [
|
m('tr.hover', [
|
||||||
m('td', [
|
m('td', [
|
||||||
m('a.link.link-primary.font-mono.text-sm', {
|
m('a.link.link-primary.font-mono.text-sm', {
|
||||||
href: `/builds/${build.id}`,
|
href: `/builds/${build.buildRequestId}`,
|
||||||
onclick: (e: Event) => {
|
onclick: (e: Event) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
m.route.set(`/builds/${build.id}`);
|
m.route.set(`/builds/${build.buildRequestId}`);
|
||||||
}
|
}
|
||||||
}, build.id)
|
}, build.buildRequestId)
|
||||||
]),
|
]),
|
||||||
m('td', [
|
m('td', [
|
||||||
m(BuildStatusBadge, { status: build.status })
|
m(BuildStatusBadge, { status: build.status })
|
||||||
|
|
@ -299,19 +299,19 @@ export const BuildStatus = {
|
||||||
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
||||||
|
|
||||||
// Get build status
|
// Get build status
|
||||||
const buildResponse = await apiClient.apiV1BuildsBuildRequestIdGet({ buildRequestId: this.buildId });
|
const buildResponse = await apiClient.apiV1BuildsBuildRequestIdGet({ build_request_id: this.buildId });
|
||||||
this.data = buildResponse;
|
this.data = buildResponse;
|
||||||
|
|
||||||
// Load partition statuses for all requested partitions
|
// Load partition statuses for all requested partitions
|
||||||
if (buildResponse.requestedPartitions) {
|
if (buildResponse.requested_partitions) {
|
||||||
for (const partitionRef of buildResponse.requestedPartitions) {
|
for (const partition_ref of buildResponse.requested_partitions) {
|
||||||
try {
|
try {
|
||||||
const partitionStatus = await apiClient.apiV1PartitionsRefStatusGet({
|
const partition_status = await apiClient.apiV1PartitionsRefStatusGet({
|
||||||
ref: partitionRef
|
ref: partition_ref
|
||||||
});
|
});
|
||||||
this.partitionStatuses.set(partitionRef, partitionStatus);
|
this.partitionStatuses.set(partition_ref, partition_status);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(`Failed to load status for partition ${partitionRef}:`, e);
|
console.warn(`Failed to load status for partition ${partition_ref}:`, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -339,29 +339,28 @@ export const BuildStatus = {
|
||||||
|
|
||||||
|
|
||||||
getEventLink(event: any): { href: string; text: string } | null {
|
getEventLink(event: any): { href: string; text: string } | null {
|
||||||
const eventType = event.eventType;
|
console.warn("event", event, event.event_type);
|
||||||
|
switch (event.event_type) {
|
||||||
switch (eventType) {
|
|
||||||
case 'job':
|
case 'job':
|
||||||
if (event.jobLabel) {
|
if (event.job_label) {
|
||||||
return {
|
return {
|
||||||
href: `/jobs/${encodeURIComponent(event.jobLabel)}`,
|
href: `/jobs/${encodeURIComponent(event.job_label)}`,
|
||||||
text: 'Job Details'
|
text: 'Job Details'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case 'partition':
|
case 'partition':
|
||||||
if (event.partitionRef) {
|
if (event.partition_ref) {
|
||||||
return {
|
return {
|
||||||
href: `/partitions/${encodePartitionRef(event.partitionRef)}`,
|
href: `/partitions/${encodePartitionRef(event.partition_ref)}`,
|
||||||
text: 'Partition Status'
|
text: 'Partition Status'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case 'delegation':
|
case 'delegation':
|
||||||
if (event.delegatedBuildId) {
|
if (event.delegated_build_id) {
|
||||||
return {
|
return {
|
||||||
href: `/builds/${event.delegatedBuildId}`,
|
href: `/builds/${event.delegated_build_id}`,
|
||||||
text: 'Delegated Build'
|
text: 'Delegated Build'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -419,7 +418,7 @@ export const BuildStatus = {
|
||||||
m('h1.text-3xl.font-bold.mb-4', `Build ${this.buildId}`),
|
m('h1.text-3xl.font-bold.mb-4', `Build ${this.buildId}`),
|
||||||
m('.build-meta.flex.gap-4.items-center.mb-4', [
|
m('.build-meta.flex.gap-4.items-center.mb-4', [
|
||||||
m(BuildStatusBadge, { status: this.data.status, size: 'lg' }),
|
m(BuildStatusBadge, { status: this.data.status, size: 'lg' }),
|
||||||
m('.timestamp.text-sm.opacity-70', formatDateTime(new Date(this.data.createdAt).toISOString())),
|
m('.timestamp.text-sm.opacity-70', formatDateTime(this.data.created_at)),
|
||||||
m('.partitions.text-sm.opacity-70', `${this.data.requestedPartitions?.length || 0} partitions`),
|
m('.partitions.text-sm.opacity-70', `${this.data.requestedPartitions?.length || 0} partitions`),
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
|
|
@ -444,7 +443,7 @@ export const BuildStatus = {
|
||||||
m(PartitionStatusBadge, { status: status?.status || 'Unknown' }),
|
m(PartitionStatusBadge, { status: status?.status || 'Unknown' }),
|
||||||
status?.lastUpdated ?
|
status?.lastUpdated ?
|
||||||
m('.updated-time.text-xs.opacity-60',
|
m('.updated-time.text-xs.opacity-60',
|
||||||
formatDateTime(new Date(status.lastUpdated).toISOString())) : null
|
formatDateTime(status.last_updated)) : null
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
}) || [m('.text-center.py-8.text-base-content.opacity-60', 'No partitions')]
|
}) || [m('.text-center.py-8.text-base-content.opacity-60', 'No partitions')]
|
||||||
|
|
@ -470,14 +469,15 @@ export const BuildStatus = {
|
||||||
this.data.events.map((event: any) =>
|
this.data.events.map((event: any) =>
|
||||||
m('tr.hover', [
|
m('tr.hover', [
|
||||||
m('td.text-xs.font-mono',
|
m('td.text-xs.font-mono',
|
||||||
formatDateTime(new Date(event.timestamp).toISOString())),
|
formatDateTime(event.timestamp)),
|
||||||
m('td', [
|
m('td', [
|
||||||
m(EventTypeBadge, { eventType: event.eventType })
|
m(EventTypeBadge, { eventType: event.event_type })
|
||||||
]),
|
]),
|
||||||
m('td.text-sm', event.message || ''),
|
m('td.text-sm', event.message || ''),
|
||||||
m('td', [
|
m('td', [
|
||||||
(() => {
|
(() => {
|
||||||
const link = this.getEventLink(event);
|
const link = this.getEventLink(event);
|
||||||
|
console.warn("link", link);
|
||||||
return link ?
|
return link ?
|
||||||
m(m.route.Link, {
|
m(m.route.Link, {
|
||||||
href: link.href,
|
href: link.href,
|
||||||
|
|
@ -531,14 +531,14 @@ export const PartitionsList = {
|
||||||
const { DefaultApi, Configuration } = await import('../client/typescript_generated/src/index');
|
const { DefaultApi, Configuration } = await import('../client/typescript_generated/src/index');
|
||||||
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
||||||
|
|
||||||
const buildRequest = {
|
const build_request = {
|
||||||
partitions: [partitionRef]
|
partitions: [partitionRef]
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await apiClient.apiV1BuildsPost({ buildRequest });
|
const response = await apiClient.apiV1BuildsPost({ build_request });
|
||||||
|
|
||||||
// Redirect to build status page
|
// Redirect to build status page
|
||||||
m.route.set(`/builds/${response.buildRequestId}`);
|
m.route.set(`/builds/${response.build_request_id}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to start build:', error);
|
console.error('Failed to start build:', error);
|
||||||
alert(`Failed to start build: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
alert(`Failed to start build: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||||
|
|
@ -658,7 +658,7 @@ export const PartitionsList = {
|
||||||
m('td', [
|
m('td', [
|
||||||
m(PartitionStatusBadge, { status: partition.status })
|
m(PartitionStatusBadge, { status: partition.status })
|
||||||
]),
|
]),
|
||||||
m('td.text-sm.opacity-70', formatTime(new Date(partition.updated_at).toISOString())),
|
m('td.text-sm.opacity-70', formatTime(partition.updated_at)),
|
||||||
m('td', [
|
m('td', [
|
||||||
m('button.btn.btn-sm.btn-primary', {
|
m('button.btn.btn-sm.btn-primary', {
|
||||||
onclick: () => this.buildPartition(partition.partition_ref)
|
onclick: () => this.buildPartition(partition.partition_ref)
|
||||||
|
|
@ -771,14 +771,14 @@ export const PartitionStatus = {
|
||||||
const { DefaultApi, Configuration } = await import('../client/typescript_generated/src/index');
|
const { DefaultApi, Configuration } = await import('../client/typescript_generated/src/index');
|
||||||
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
||||||
|
|
||||||
const buildRequest = {
|
const build_request = {
|
||||||
partitions: [this.partitionRef]
|
partitions: [this.partitionRef]
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await apiClient.apiV1BuildsPost({ buildRequest });
|
const response = await apiClient.apiV1BuildsPost({ build_request });
|
||||||
|
|
||||||
// Redirect to build status page
|
// Redirect to build status page
|
||||||
m.route.set(`/builds/${response.buildRequestId}`);
|
m.route.set(`/builds/${response.build_request_id}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to start build:', error);
|
console.error('Failed to start build:', error);
|
||||||
alert(`Failed to start build: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
alert(`Failed to start build: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||||
|
|
@ -851,7 +851,7 @@ export const PartitionStatus = {
|
||||||
m(PartitionStatusBadge, { status: this.data?.status || 'Unknown', size: 'lg' }),
|
m(PartitionStatusBadge, { status: this.data?.status || 'Unknown', size: 'lg' }),
|
||||||
this.data?.lastUpdated ?
|
this.data?.lastUpdated ?
|
||||||
m('.timestamp.text-sm.opacity-70',
|
m('.timestamp.text-sm.opacity-70',
|
||||||
`Last updated: ${formatDateTime(new Date(this.data.lastUpdated).toISOString())}`) : null,
|
`Last updated: ${formatDateTime(this.data.lastUpdated)}`) : null,
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
|
@ -890,10 +890,10 @@ export const PartitionStatus = {
|
||||||
m(BuildStatusBadge, { status: build.status })
|
m(BuildStatusBadge, { status: build.status })
|
||||||
]),
|
]),
|
||||||
m('td.text-sm.opacity-70',
|
m('td.text-sm.opacity-70',
|
||||||
formatDateTime(new Date(build.startedAt).toISOString())),
|
formatDateTime(build.startedAt)),
|
||||||
m('td.text-sm.opacity-70',
|
m('td.text-sm.opacity-70',
|
||||||
build.completedAt ?
|
build.completedAt ?
|
||||||
formatDateTime(new Date(build.completedAt).toISOString()) :
|
formatDateTime(build.completedAt) :
|
||||||
'—'),
|
'—'),
|
||||||
m('td.text-sm.opacity-70', `${build.events?.length || 0} events`)
|
m('td.text-sm.opacity-70', `${build.events?.length || 0} events`)
|
||||||
])
|
])
|
||||||
|
|
@ -941,31 +941,31 @@ export const PartitionStatus = {
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
m('tbody',
|
m('tbody',
|
||||||
this.events.events.slice(0, 20).map((event: any) => // Show first 20 events
|
this.events.events.slice(0, 100).map((event: any) => // Show first 100 events
|
||||||
m('tr.hover', [
|
m('tr.hover', [
|
||||||
m('td.text-xs.font-mono',
|
m('td.text-xs.font-mono',
|
||||||
formatDateTime(new Date(event.timestamp).toISOString())),
|
formatDateTime(event.timestamp)),
|
||||||
m('td', [
|
m('td', [
|
||||||
m(EventTypeBadge, { eventType: event.eventType, size: 'xs' })
|
m(EventTypeBadge, { eventType: event.event_type, size: 'xs' })
|
||||||
]),
|
]),
|
||||||
m('td',
|
m('td',
|
||||||
event.buildRequestId ?
|
event.build_request_id ?
|
||||||
m('a.link.link-primary.font-mono.text-xs', {
|
m('a.link.link-primary.font-mono.text-xs', {
|
||||||
href: `/builds/${event.buildRequestId}`,
|
href: `/builds/${event.build_request_id}`,
|
||||||
onclick: (e: Event) => {
|
onclick: (e: Event) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
m.route.set(`/builds/${event.buildRequestId}`);
|
m.route.set(`/builds/${event.build_request_id}`);
|
||||||
}
|
}
|
||||||
}, event.buildRequestId) : '—'),
|
}, event.build_request_id) : '—'),
|
||||||
m('td.text-xs', event.message || ''),
|
m('td.text-xs', event.message || ''),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
this.events.events.length > 20 ?
|
this.events.events.length > 100 ?
|
||||||
m('.text-center.mt-4', [
|
m('.text-center.mt-4', [
|
||||||
m('.text-sm.opacity-60', `Showing first 20 of ${this.events.events.length} events`)
|
m('.text-sm.opacity-60', `Showing first 100 of ${this.events.events.length} events`)
|
||||||
]) : null
|
]) : null
|
||||||
])
|
])
|
||||||
]) : null
|
]) : null
|
||||||
|
|
@ -1087,7 +1087,7 @@ export const JobsList = {
|
||||||
m('td', formatDuration(job.avg_duration_ms)),
|
m('td', formatDuration(job.avg_duration_ms)),
|
||||||
m('td', (job.recent_runs || 0).toString()),
|
m('td', (job.recent_runs || 0).toString()),
|
||||||
m('td.text-sm.opacity-70',
|
m('td.text-sm.opacity-70',
|
||||||
job.last_run ? formatTime(new Date(job.last_run).toISOString()) : '—'),
|
job.last_run ? formatTime(job.last_run) : '—'),
|
||||||
])
|
])
|
||||||
))
|
))
|
||||||
])
|
])
|
||||||
|
|
@ -1254,7 +1254,7 @@ export const JobMetrics = {
|
||||||
]),
|
]),
|
||||||
m('td', formatDuration(run.duration_ms)),
|
m('td', formatDuration(run.duration_ms)),
|
||||||
m('td.text-sm.opacity-70',
|
m('td.text-sm.opacity-70',
|
||||||
formatTime(new Date(run.started_at).toISOString())),
|
formatTime(run.started_at)),
|
||||||
])
|
])
|
||||||
))
|
))
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
// Import the generated TypeScript client
|
// Import the generated TypeScript client
|
||||||
import { DefaultApi, Configuration, ActivityResponse, BuildSummary, PartitionSummary, JobsListResponse, JobMetricsResponse, JobSummary, JobRunSummary, JobDailyStats } from '../client/typescript_generated/src/index';
|
import { DefaultApi, Configuration, ActivityResponse, BuildSummary, PartitionSummary, JobsListResponse, JobMetricsResponse, JobSummary, JobRunSummary, JobDailyStats } from '../client/typescript_generated/src/index';
|
||||||
|
|
||||||
// Base API configuration
|
|
||||||
const API_BASE = '/api/v1';
|
|
||||||
|
|
||||||
// Configure the API client
|
// Configure the API client
|
||||||
const apiConfig = new Configuration({
|
const apiConfig = new Configuration({
|
||||||
basePath: '', // Use relative paths since we're on the same host
|
basePath: '', // Use relative paths since we're on the same host
|
||||||
|
|
@ -12,16 +9,16 @@ const apiClient = new DefaultApi(apiConfig);
|
||||||
|
|
||||||
// Types for dashboard data - using the generated API types
|
// Types for dashboard data - using the generated API types
|
||||||
export interface BuildRequest {
|
export interface BuildRequest {
|
||||||
id: string;
|
buildRequestId: string;
|
||||||
status: string;
|
status: string;
|
||||||
createdAt: string;
|
createdAt: number;
|
||||||
updatedAt: string;
|
updatedAt: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PartitionBuild {
|
export interface PartitionBuild {
|
||||||
ref: string;
|
ref: string;
|
||||||
status: string;
|
status: string;
|
||||||
updatedAt: string;
|
updatedAt: number;
|
||||||
buildRequestId?: string;
|
buildRequestId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,29 +46,30 @@ export class DashboardService {
|
||||||
try {
|
try {
|
||||||
// Use the new activity endpoint that aggregates all the data we need
|
// Use the new activity endpoint that aggregates all the data we need
|
||||||
const activityResponse: ActivityResponse = await apiClient.apiV1ActivityGet();
|
const activityResponse: ActivityResponse = await apiClient.apiV1ActivityGet();
|
||||||
|
console.info('Recent activity:', activityResponse);
|
||||||
|
|
||||||
// Convert the API response to our dashboard format
|
// Convert the API response to our dashboard format
|
||||||
const recentBuilds: BuildRequest[] = activityResponse.recentBuilds.map((build: BuildSummary) => ({
|
const recentBuilds: BuildRequest[] = activityResponse.recent_builds.map((build: BuildSummary) => ({
|
||||||
id: build.buildRequestId,
|
buildRequestId: build.build_request_id,
|
||||||
status: build.status,
|
status: build.status,
|
||||||
createdAt: new Date(build.createdAt).toISOString(), // Backend now sends milliseconds
|
createdAt: build.created_at,
|
||||||
updatedAt: new Date(build.updatedAt).toISOString()
|
updatedAt: build.updated_at,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const recentPartitions: PartitionBuild[] = activityResponse.recentPartitions.map((partition: PartitionSummary) => ({
|
const recentPartitions: PartitionBuild[] = activityResponse.recent_partitions.map((partition: PartitionSummary) => ({
|
||||||
ref: partition.partitionRef,
|
ref: partition.partition_ref,
|
||||||
status: partition.status,
|
status: partition.status,
|
||||||
updatedAt: new Date(partition.updatedAt).toISOString(),
|
updatedAt: partition.updated_at,
|
||||||
buildRequestId: partition.buildRequestId || undefined
|
buildRequestId: partition.build_request_id || undefined
|
||||||
}));
|
}));
|
||||||
|
console.info("made", recentBuilds, recentPartitions);
|
||||||
return {
|
return {
|
||||||
activeBuilds: activityResponse.activeBuildsCount,
|
activeBuilds: activityResponse.active_builds_count,
|
||||||
recentBuilds,
|
recentBuilds,
|
||||||
recentPartitions,
|
recentPartitions,
|
||||||
totalPartitions: activityResponse.totalPartitionsCount,
|
totalPartitions: activityResponse.total_partitions_count,
|
||||||
systemStatus: activityResponse.systemStatus,
|
systemStatus: activityResponse.system_status,
|
||||||
graphName: activityResponse.graphName
|
graphName: activityResponse.graph_name
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch recent activity:', error);
|
console.error('Failed to fetch recent activity:', error);
|
||||||
|
|
@ -209,8 +207,8 @@ export class PollingManager {
|
||||||
export const pollingManager = new PollingManager();
|
export const pollingManager = new PollingManager();
|
||||||
|
|
||||||
// Utility functions for time formatting
|
// Utility functions for time formatting
|
||||||
export function formatTime(isoString: string): string {
|
export function formatTime(epochNanos: number): string {
|
||||||
const date = new Date(isoString);
|
const date = new Date(epochNanos / 1000000);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const diffMs = now.getTime() - date.getTime();
|
const diffMs = now.getTime() - date.getTime();
|
||||||
|
|
||||||
|
|
@ -227,8 +225,8 @@ export function formatTime(isoString: string): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatDateTime(isoString: string): string {
|
export function formatDateTime(epochNanos: number): string {
|
||||||
const date = new Date(isoString);
|
const date = new Date(epochNanos / 1000000);
|
||||||
const dateStr = date.toLocaleDateString('en-US');
|
const dateStr = date.toLocaleDateString('en-US');
|
||||||
const timeStr = date.toLocaleTimeString('en-US', {
|
const timeStr = date.toLocaleTimeString('en-US', {
|
||||||
hour: 'numeric',
|
hour: 'numeric',
|
||||||
|
|
@ -243,7 +241,8 @@ export function formatDateTime(isoString: string): string {
|
||||||
return `${dateStr}, ${timeStr.replace(/(\d{2})\s+(AM|PM)/, `$1.${millisStr} $2`)}`;
|
return `${dateStr}, ${timeStr.replace(/(\d{2})\s+(AM|PM)/, `$1.${millisStr} $2`)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatDuration(durationMs?: number | null): string {
|
export function formatDuration(durationNanos?: number | null): string {
|
||||||
|
let durationMs = durationNanos ? durationNanos / 1000000 : null;
|
||||||
if (!durationMs || durationMs <= 0) {
|
if (!durationMs || durationMs <= 0) {
|
||||||
return '—';
|
return '—';
|
||||||
}
|
}
|
||||||
|
|
@ -263,8 +262,8 @@ export function formatDuration(durationMs?: number | null): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatDate(dateString: string): string {
|
export function formatDate(epochNanos: number): string {
|
||||||
const date = new Date(dateString);
|
const date = new Date(epochNanos / 1000000);
|
||||||
return date.toLocaleDateString('en-US', {
|
return date.toLocaleDateString('en-US', {
|
||||||
month: 'short',
|
month: 'short',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ pub async fn get_build_status(
|
||||||
let (job_label, partition_ref, delegated_build_id) = extract_navigation_data(&e.event_type);
|
let (job_label, partition_ref, delegated_build_id) = extract_navigation_data(&e.event_type);
|
||||||
BuildEventSummary {
|
BuildEventSummary {
|
||||||
event_id: e.event_id,
|
event_id: e.event_id,
|
||||||
timestamp: e.timestamp / 1_000_000, // Convert nanoseconds to milliseconds
|
timestamp: e.timestamp,
|
||||||
event_type: event_type_to_string(&e.event_type),
|
event_type: event_type_to_string(&e.event_type),
|
||||||
message: event_to_message(&e.event_type),
|
message: event_to_message(&e.event_type),
|
||||||
build_request_id: e.build_request_id,
|
build_request_id: e.build_request_id,
|
||||||
|
|
@ -272,8 +272,8 @@ pub async fn get_build_status(
|
||||||
build_request_id,
|
build_request_id,
|
||||||
status: final_status_string,
|
status: final_status_string,
|
||||||
requested_partitions,
|
requested_partitions,
|
||||||
created_at: created_at / 1_000_000, // Convert nanoseconds to milliseconds
|
created_at: created_at,
|
||||||
updated_at: updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
updated_at: updated_at,
|
||||||
events: event_summaries,
|
events: event_summaries,
|
||||||
job_graph: job_graph_json,
|
job_graph: job_graph_json,
|
||||||
mermaid_diagram,
|
mermaid_diagram,
|
||||||
|
|
@ -397,7 +397,7 @@ pub async fn get_partition_events(
|
||||||
let (job_label, partition_ref, delegated_build_id) = extract_navigation_data(&e.event_type);
|
let (job_label, partition_ref, delegated_build_id) = extract_navigation_data(&e.event_type);
|
||||||
BuildEventSummary {
|
BuildEventSummary {
|
||||||
event_id: e.event_id,
|
event_id: e.event_id,
|
||||||
timestamp: e.timestamp / 1_000_000, // Convert nanoseconds to milliseconds
|
timestamp: e.timestamp,
|
||||||
event_type: event_type_to_string(&e.event_type),
|
event_type: event_type_to_string(&e.event_type),
|
||||||
message: event_to_message(&e.event_type),
|
message: event_to_message(&e.event_type),
|
||||||
build_request_id: e.build_request_id,
|
build_request_id: e.build_request_id,
|
||||||
|
|
@ -708,8 +708,8 @@ pub async fn list_build_requests(
|
||||||
build_request_id: s.build_request_id,
|
build_request_id: s.build_request_id,
|
||||||
status: format!("{:?}", s.status),
|
status: format!("{:?}", s.status),
|
||||||
requested_partitions: s.requested_partitions,
|
requested_partitions: s.requested_partitions,
|
||||||
created_at: s.created_at / 1_000_000, // Convert nanoseconds to milliseconds
|
created_at: s.created_at,
|
||||||
updated_at: s.updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
updated_at: s.updated_at,
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let has_more = (offset + limit) < total_count;
|
let has_more = (offset + limit) < total_count;
|
||||||
|
|
@ -761,7 +761,7 @@ pub async fn list_partitions(
|
||||||
let partitions: Vec<PartitionSummary> = summaries.into_iter().map(|s| PartitionSummary {
|
let partitions: Vec<PartitionSummary> = summaries.into_iter().map(|s| PartitionSummary {
|
||||||
partition_ref: s.partition_ref,
|
partition_ref: s.partition_ref,
|
||||||
status: format!("{:?}", s.status),
|
status: format!("{:?}", s.status),
|
||||||
updated_at: s.updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
updated_at: s.updated_at,
|
||||||
build_request_id: s.build_request_id,
|
build_request_id: s.build_request_id,
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
|
@ -794,14 +794,14 @@ pub async fn get_activity_summary(
|
||||||
build_request_id: s.build_request_id,
|
build_request_id: s.build_request_id,
|
||||||
status: format!("{:?}", s.status),
|
status: format!("{:?}", s.status),
|
||||||
requested_partitions: s.requested_partitions,
|
requested_partitions: s.requested_partitions,
|
||||||
created_at: s.created_at / 1_000_000, // Convert nanoseconds to milliseconds
|
created_at: s.created_at,
|
||||||
updated_at: s.updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
updated_at: s.updated_at,
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let recent_partitions: Vec<PartitionSummary> = summary.recent_partitions.into_iter().map(|s| PartitionSummary {
|
let recent_partitions: Vec<PartitionSummary> = summary.recent_partitions.into_iter().map(|s| PartitionSummary {
|
||||||
partition_ref: s.partition_ref,
|
partition_ref: s.partition_ref,
|
||||||
status: format!("{:?}", s.status),
|
status: format!("{:?}", s.status),
|
||||||
updated_at: s.updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
updated_at: s.updated_at,
|
||||||
build_request_id: s.build_request_id,
|
build_request_id: s.build_request_id,
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
|
@ -1044,7 +1044,7 @@ pub async fn get_job_metrics(
|
||||||
let started_at: i64 = row[3].parse().unwrap_or(0);
|
let started_at: i64 = row[3].parse().unwrap_or(0);
|
||||||
let completed_at: i64 = row[4].parse().unwrap_or(started_at);
|
let completed_at: i64 = row[4].parse().unwrap_or(started_at);
|
||||||
let duration_ms: Option<i64> = if completed_at > started_at {
|
let duration_ms: Option<i64> = if completed_at > started_at {
|
||||||
Some((completed_at - started_at) / 1_000_000) // Convert nanoseconds to milliseconds
|
Some((completed_at - started_at))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ pub struct BuildSummary {
|
||||||
pub updated_at: i64,
|
pub updated_at: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO snake cased response
|
||||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct PartitionsListResponse {
|
pub struct PartitionsListResponse {
|
||||||
pub partitions: Vec<PartitionSummary>,
|
pub partitions: Vec<PartitionSummary>,
|
||||||
|
|
@ -134,6 +135,7 @@ pub struct PartitionSummary {
|
||||||
pub build_request_id: Option<String>,
|
pub build_request_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO camel cased results
|
||||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct ActivityResponse {
|
pub struct ActivityResponse {
|
||||||
pub active_builds_count: u32,
|
pub active_builds_count: u32,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue