feat(lanes): show proof gallery panel in the Workspace page (C)

This commit is contained in:
2026-08-04 16:25:09 +07:00
parent a545230746
commit fccfa5ad17
6 changed files with 178 additions and 0 deletions
+31
View File
@@ -2032,6 +2032,37 @@ export const api = {
`/lanes/${id}/features/${encodeURIComponent(slug)}`
),
},
/**
* GET /api/lanes/:id/proof — list all proof gallery entries for a lane.
* @param id The lane id.
* @returns `{ features }` — all {@link ProofFeature} records.
*/
proof: {
list: (id: number) =>
request<{ features: import("./types").ProofFeature[] }>(`/lanes/${id}/proof`),
/**
* URL for a proof image, ready to use in an <img src>.
* @param id The lane id.
* @param slug The feature slug.
* @param group The screenshot group name.
* @param file The image filename.
* @returns A URL string pointing to the image.
*/
imageUrl: (id: number, slug: string, group: string, file: string): string =>
`/api/lanes/${id}/proof/${encodeURIComponent(slug)}/${encodeURIComponent(group)}/${encodeURIComponent(file)}`,
/**
* DELETE /api/lanes/:id/proof/:slug — delete proof entries for a feature.
* @param id The lane id.
* @param slug The feature slug.
* @param body Optional filters: { group?, images? }.
* @returns `{ deleted }` — count of deleted images.
*/
delete: (id: number, slug: string, body: { group?: string; images?: string[] }) =>
request<{ deleted: number }>(`/lanes/${id}/proof/${encodeURIComponent(slug)}`, {
method: "DELETE",
body: JSON.stringify(body),
}),
},
},
// ──────────────────────────────── Locks API ────────────────────────────────
/** Named locks across all lanes: used for serialization and gating.
+11
View File
@@ -2304,6 +2304,15 @@ export interface LaneFeature {
pipeline_nodes: LaneNode[];
progress: number;
}
/** QC proof gallery: screenshots and artifact report for a feature. */
export interface ProofFeature {
slug: string;
groups: Record<string, string[]>;
ticket_report: string;
mtime: number;
}
export interface Lane {
id: number;
title: string;
@@ -2340,6 +2349,8 @@ export interface Lane {
/** Ports the lane ACTUALLY bound, by declared name. Empty until first boot.
* May differ from `base + slot` when the preferred number was taken. */
ports: Record<string, number>;
/** ID of the currently-active feature, or null if no feature is active. */
active_feature_id: number | null;
}
/** One line a lane's profile hook wrote, pushed while the hook is still running