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
|
||||
genrule(
|
||||
|
|
@ -64,17 +64,17 @@ genrule(
|
|||
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
|
||||
fi
|
||||
|
||||
|
||||
# Create temporary directory for generation
|
||||
TEMP_DIR=$$(mktemp -d)
|
||||
|
||||
|
||||
# Generate TypeScript client to temp directory
|
||||
java -jar $$OPENAPI_JAR generate \
|
||||
-i $(location :extract_openapi_spec) \
|
||||
-g typescript-fetch \
|
||||
-c $(location :typescript_generator_config) \
|
||||
-o $$TEMP_DIR
|
||||
|
||||
|
||||
# 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/index.ts $(location typescript_generated/src/apis/index.ts)
|
||||
|
|
@ -134,4 +134,4 @@ filegroup(
|
|||
":typescript_client",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"enumPropertyNaming": "camelCase",
|
||||
"enumPropertyNaming": "snake_case",
|
||||
"withInterfaces": true,
|
||||
"useSingleRequestParameter": true,
|
||||
"typescriptThreePlus": true,
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
"npmVersion": "1.0.0",
|
||||
"stringEnums": true,
|
||||
"generateAliasAsModel": false,
|
||||
"modelPropertyNaming": "camelCase",
|
||||
"paramNaming": "camelCase",
|
||||
"modelPropertyNaming": "snake_case",
|
||||
"paramNaming": "snake_case",
|
||||
"supportsES6": true,
|
||||
"withoutRuntimeChecks": false
|
||||
}
|
||||
|
|
@ -194,12 +194,12 @@ export const RecentActivity = {
|
|||
m('tr.hover', [
|
||||
m('td', [
|
||||
m('a.link.link-primary.font-mono.text-sm', {
|
||||
href: `/builds/${build.id}`,
|
||||
href: `/builds/${build.buildRequestId}`,
|
||||
onclick: (e: Event) => {
|
||||
e.preventDefault();
|
||||
m.route.set(`/builds/${build.id}`);
|
||||
m.route.set(`/builds/${build.buildRequestId}`);
|
||||
}
|
||||
}, build.id)
|
||||
}, build.buildRequestId)
|
||||
]),
|
||||
m('td', [
|
||||
m(BuildStatusBadge, { status: build.status })
|
||||
|
|
@ -299,19 +299,19 @@ export const BuildStatus = {
|
|||
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
||||
|
||||
// Get build status
|
||||
const buildResponse = await apiClient.apiV1BuildsBuildRequestIdGet({ buildRequestId: this.buildId });
|
||||
const buildResponse = await apiClient.apiV1BuildsBuildRequestIdGet({ build_request_id: this.buildId });
|
||||
this.data = buildResponse;
|
||||
|
||||
// Load partition statuses for all requested partitions
|
||||
if (buildResponse.requestedPartitions) {
|
||||
for (const partitionRef of buildResponse.requestedPartitions) {
|
||||
if (buildResponse.requested_partitions) {
|
||||
for (const partition_ref of buildResponse.requested_partitions) {
|
||||
try {
|
||||
const partitionStatus = await apiClient.apiV1PartitionsRefStatusGet({
|
||||
ref: partitionRef
|
||||
const partition_status = await apiClient.apiV1PartitionsRefStatusGet({
|
||||
ref: partition_ref
|
||||
});
|
||||
this.partitionStatuses.set(partitionRef, partitionStatus);
|
||||
this.partitionStatuses.set(partition_ref, partition_status);
|
||||
} 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 {
|
||||
const eventType = event.eventType;
|
||||
|
||||
switch (eventType) {
|
||||
console.warn("event", event, event.event_type);
|
||||
switch (event.event_type) {
|
||||
case 'job':
|
||||
if (event.jobLabel) {
|
||||
if (event.job_label) {
|
||||
return {
|
||||
href: `/jobs/${encodeURIComponent(event.jobLabel)}`,
|
||||
href: `/jobs/${encodeURIComponent(event.job_label)}`,
|
||||
text: 'Job Details'
|
||||
};
|
||||
}
|
||||
return null;
|
||||
case 'partition':
|
||||
if (event.partitionRef) {
|
||||
if (event.partition_ref) {
|
||||
return {
|
||||
href: `/partitions/${encodePartitionRef(event.partitionRef)}`,
|
||||
href: `/partitions/${encodePartitionRef(event.partition_ref)}`,
|
||||
text: 'Partition Status'
|
||||
};
|
||||
}
|
||||
return null;
|
||||
case 'delegation':
|
||||
if (event.delegatedBuildId) {
|
||||
if (event.delegated_build_id) {
|
||||
return {
|
||||
href: `/builds/${event.delegatedBuildId}`,
|
||||
href: `/builds/${event.delegated_build_id}`,
|
||||
text: 'Delegated Build'
|
||||
};
|
||||
}
|
||||
|
|
@ -419,7 +418,7 @@ export const BuildStatus = {
|
|||
m('h1.text-3xl.font-bold.mb-4', `Build ${this.buildId}`),
|
||||
m('.build-meta.flex.gap-4.items-center.mb-4', [
|
||||
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`),
|
||||
])
|
||||
]),
|
||||
|
|
@ -444,7 +443,7 @@ export const BuildStatus = {
|
|||
m(PartitionStatusBadge, { status: status?.status || 'Unknown' }),
|
||||
status?.lastUpdated ?
|
||||
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')]
|
||||
|
|
@ -470,14 +469,15 @@ export const BuildStatus = {
|
|||
this.data.events.map((event: any) =>
|
||||
m('tr.hover', [
|
||||
m('td.text-xs.font-mono',
|
||||
formatDateTime(new Date(event.timestamp).toISOString())),
|
||||
formatDateTime(event.timestamp)),
|
||||
m('td', [
|
||||
m(EventTypeBadge, { eventType: event.eventType })
|
||||
m(EventTypeBadge, { eventType: event.event_type })
|
||||
]),
|
||||
m('td.text-sm', event.message || ''),
|
||||
m('td', [
|
||||
(() => {
|
||||
const link = this.getEventLink(event);
|
||||
console.warn("link", link);
|
||||
return link ?
|
||||
m(m.route.Link, {
|
||||
href: link.href,
|
||||
|
|
@ -531,14 +531,14 @@ export const PartitionsList = {
|
|||
const { DefaultApi, Configuration } = await import('../client/typescript_generated/src/index');
|
||||
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
||||
|
||||
const buildRequest = {
|
||||
const build_request = {
|
||||
partitions: [partitionRef]
|
||||
};
|
||||
|
||||
const response = await apiClient.apiV1BuildsPost({ buildRequest });
|
||||
const response = await apiClient.apiV1BuildsPost({ build_request });
|
||||
|
||||
// Redirect to build status page
|
||||
m.route.set(`/builds/${response.buildRequestId}`);
|
||||
m.route.set(`/builds/${response.build_request_id}`);
|
||||
} catch (error) {
|
||||
console.error('Failed to start build:', error);
|
||||
alert(`Failed to start build: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
|
|
@ -658,7 +658,7 @@ export const PartitionsList = {
|
|||
m('td', [
|
||||
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('button.btn.btn-sm.btn-primary', {
|
||||
onclick: () => this.buildPartition(partition.partition_ref)
|
||||
|
|
@ -771,14 +771,14 @@ export const PartitionStatus = {
|
|||
const { DefaultApi, Configuration } = await import('../client/typescript_generated/src/index');
|
||||
const apiClient = new DefaultApi(new Configuration({ basePath: '' }));
|
||||
|
||||
const buildRequest = {
|
||||
const build_request = {
|
||||
partitions: [this.partitionRef]
|
||||
};
|
||||
|
||||
const response = await apiClient.apiV1BuildsPost({ buildRequest });
|
||||
const response = await apiClient.apiV1BuildsPost({ build_request });
|
||||
|
||||
// Redirect to build status page
|
||||
m.route.set(`/builds/${response.buildRequestId}`);
|
||||
m.route.set(`/builds/${response.build_request_id}`);
|
||||
} catch (error) {
|
||||
console.error('Failed to start build:', 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' }),
|
||||
this.data?.lastUpdated ?
|
||||
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('td.text-sm.opacity-70',
|
||||
formatDateTime(new Date(build.startedAt).toISOString())),
|
||||
formatDateTime(build.startedAt)),
|
||||
m('td.text-sm.opacity-70',
|
||||
build.completedAt ?
|
||||
formatDateTime(new Date(build.completedAt).toISOString()) :
|
||||
formatDateTime(build.completedAt) :
|
||||
'—'),
|
||||
m('td.text-sm.opacity-70', `${build.events?.length || 0} events`)
|
||||
])
|
||||
|
|
@ -941,31 +941,31 @@ export const PartitionStatus = {
|
|||
])
|
||||
]),
|
||||
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('td.text-xs.font-mono',
|
||||
formatDateTime(new Date(event.timestamp).toISOString())),
|
||||
formatDateTime(event.timestamp)),
|
||||
m('td', [
|
||||
m(EventTypeBadge, { eventType: event.eventType, size: 'xs' })
|
||||
m(EventTypeBadge, { eventType: event.event_type, size: 'xs' })
|
||||
]),
|
||||
m('td',
|
||||
event.buildRequestId ?
|
||||
event.build_request_id ?
|
||||
m('a.link.link-primary.font-mono.text-xs', {
|
||||
href: `/builds/${event.buildRequestId}`,
|
||||
href: `/builds/${event.build_request_id}`,
|
||||
onclick: (e: Event) => {
|
||||
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 || ''),
|
||||
])
|
||||
)
|
||||
)
|
||||
])
|
||||
]),
|
||||
this.events.events.length > 20 ?
|
||||
this.events.events.length > 100 ?
|
||||
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
|
||||
|
|
@ -1087,7 +1087,7 @@ export const JobsList = {
|
|||
m('td', formatDuration(job.avg_duration_ms)),
|
||||
m('td', (job.recent_runs || 0).toString()),
|
||||
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.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 { 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
|
||||
const apiConfig = new Configuration({
|
||||
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
|
||||
export interface BuildRequest {
|
||||
id: string;
|
||||
buildRequestId: string;
|
||||
status: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
}
|
||||
|
||||
export interface PartitionBuild {
|
||||
ref: string;
|
||||
status: string;
|
||||
updatedAt: string;
|
||||
updatedAt: number;
|
||||
buildRequestId?: string;
|
||||
}
|
||||
|
||||
|
|
@ -49,29 +46,30 @@ export class DashboardService {
|
|||
try {
|
||||
// Use the new activity endpoint that aggregates all the data we need
|
||||
const activityResponse: ActivityResponse = await apiClient.apiV1ActivityGet();
|
||||
console.info('Recent activity:', activityResponse);
|
||||
|
||||
// Convert the API response to our dashboard format
|
||||
const recentBuilds: BuildRequest[] = activityResponse.recentBuilds.map((build: BuildSummary) => ({
|
||||
id: build.buildRequestId,
|
||||
const recentBuilds: BuildRequest[] = activityResponse.recent_builds.map((build: BuildSummary) => ({
|
||||
buildRequestId: build.build_request_id,
|
||||
status: build.status,
|
||||
createdAt: new Date(build.createdAt).toISOString(), // Backend now sends milliseconds
|
||||
updatedAt: new Date(build.updatedAt).toISOString()
|
||||
createdAt: build.created_at,
|
||||
updatedAt: build.updated_at,
|
||||
}));
|
||||
|
||||
const recentPartitions: PartitionBuild[] = activityResponse.recentPartitions.map((partition: PartitionSummary) => ({
|
||||
ref: partition.partitionRef,
|
||||
const recentPartitions: PartitionBuild[] = activityResponse.recent_partitions.map((partition: PartitionSummary) => ({
|
||||
ref: partition.partition_ref,
|
||||
status: partition.status,
|
||||
updatedAt: new Date(partition.updatedAt).toISOString(),
|
||||
buildRequestId: partition.buildRequestId || undefined
|
||||
updatedAt: partition.updated_at,
|
||||
buildRequestId: partition.build_request_id || undefined
|
||||
}));
|
||||
|
||||
console.info("made", recentBuilds, recentPartitions);
|
||||
return {
|
||||
activeBuilds: activityResponse.activeBuildsCount,
|
||||
activeBuilds: activityResponse.active_builds_count,
|
||||
recentBuilds,
|
||||
recentPartitions,
|
||||
totalPartitions: activityResponse.totalPartitionsCount,
|
||||
systemStatus: activityResponse.systemStatus,
|
||||
graphName: activityResponse.graphName
|
||||
totalPartitions: activityResponse.total_partitions_count,
|
||||
systemStatus: activityResponse.system_status,
|
||||
graphName: activityResponse.graph_name
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch recent activity:', error);
|
||||
|
|
@ -209,8 +207,8 @@ export class PollingManager {
|
|||
export const pollingManager = new PollingManager();
|
||||
|
||||
// Utility functions for time formatting
|
||||
export function formatTime(isoString: string): string {
|
||||
const date = new Date(isoString);
|
||||
export function formatTime(epochNanos: number): string {
|
||||
const date = new Date(epochNanos / 1000000);
|
||||
const now = new Date();
|
||||
const diffMs = now.getTime() - date.getTime();
|
||||
|
||||
|
|
@ -227,8 +225,8 @@ export function formatTime(isoString: string): string {
|
|||
}
|
||||
}
|
||||
|
||||
export function formatDateTime(isoString: string): string {
|
||||
const date = new Date(isoString);
|
||||
export function formatDateTime(epochNanos: number): string {
|
||||
const date = new Date(epochNanos / 1000000);
|
||||
const dateStr = date.toLocaleDateString('en-US');
|
||||
const timeStr = date.toLocaleTimeString('en-US', {
|
||||
hour: 'numeric',
|
||||
|
|
@ -243,7 +241,8 @@ export function formatDateTime(isoString: string): string {
|
|||
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) {
|
||||
return '—';
|
||||
}
|
||||
|
|
@ -263,8 +262,8 @@ export function formatDuration(durationMs?: number | null): string {
|
|||
}
|
||||
}
|
||||
|
||||
export function formatDate(dateString: string): string {
|
||||
const date = new Date(dateString);
|
||||
export function formatDate(epochNanos: number): string {
|
||||
const date = new Date(epochNanos / 1000000);
|
||||
return date.toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
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);
|
||||
BuildEventSummary {
|
||||
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),
|
||||
message: event_to_message(&e.event_type),
|
||||
build_request_id: e.build_request_id,
|
||||
|
|
@ -272,8 +272,8 @@ pub async fn get_build_status(
|
|||
build_request_id,
|
||||
status: final_status_string,
|
||||
requested_partitions,
|
||||
created_at: created_at / 1_000_000, // Convert nanoseconds to milliseconds
|
||||
updated_at: updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
||||
created_at: created_at,
|
||||
updated_at: updated_at,
|
||||
events: event_summaries,
|
||||
job_graph: job_graph_json,
|
||||
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);
|
||||
BuildEventSummary {
|
||||
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),
|
||||
message: event_to_message(&e.event_type),
|
||||
build_request_id: e.build_request_id,
|
||||
|
|
@ -708,8 +708,8 @@ pub async fn list_build_requests(
|
|||
build_request_id: s.build_request_id,
|
||||
status: format!("{:?}", s.status),
|
||||
requested_partitions: s.requested_partitions,
|
||||
created_at: s.created_at / 1_000_000, // Convert nanoseconds to milliseconds
|
||||
updated_at: s.updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
||||
created_at: s.created_at,
|
||||
updated_at: s.updated_at,
|
||||
}).collect();
|
||||
|
||||
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 {
|
||||
partition_ref: s.partition_ref,
|
||||
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,
|
||||
}).collect();
|
||||
|
||||
|
|
@ -794,14 +794,14 @@ pub async fn get_activity_summary(
|
|||
build_request_id: s.build_request_id,
|
||||
status: format!("{:?}", s.status),
|
||||
requested_partitions: s.requested_partitions,
|
||||
created_at: s.created_at / 1_000_000, // Convert nanoseconds to milliseconds
|
||||
updated_at: s.updated_at / 1_000_000, // Convert nanoseconds to milliseconds
|
||||
created_at: s.created_at,
|
||||
updated_at: s.updated_at,
|
||||
}).collect();
|
||||
|
||||
let recent_partitions: Vec<PartitionSummary> = summary.recent_partitions.into_iter().map(|s| PartitionSummary {
|
||||
partition_ref: s.partition_ref,
|
||||
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,
|
||||
}).collect();
|
||||
|
||||
|
|
@ -1044,7 +1044,7 @@ pub async fn get_job_metrics(
|
|||
let started_at: i64 = row[3].parse().unwrap_or(0);
|
||||
let completed_at: i64 = row[4].parse().unwrap_or(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 {
|
||||
None
|
||||
};
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ pub struct BuildSummary {
|
|||
pub updated_at: i64,
|
||||
}
|
||||
|
||||
// TODO snake cased response
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PartitionsListResponse {
|
||||
pub partitions: Vec<PartitionSummary>,
|
||||
|
|
@ -134,6 +135,7 @@ pub struct PartitionSummary {
|
|||
pub build_request_id: Option<String>,
|
||||
}
|
||||
|
||||
// TODO camel cased results
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct ActivityResponse {
|
||||
pub active_builds_count: u32,
|
||||
|
|
|
|||
Loading…
Reference in a new issue