feat(issues): S4b frontend — open-issues lists + issue plumbing
CI & Build / Python lint (push) Successful in 5s
CI & Build / TypeScript typecheck (push) Successful in 40s
CI & Build / Python tests (push) Successful in 1m36s
CI & Build / Build & push image (push) Successful in 59s

- types/note.ts: Note gains systems? + arose_from_id?; TaskKind includes 'issue'.
- stores/tasks.ts: create/update accept IssueFields (kind/system_ids/arose_from_id).
- api/systems.ts: getProjectIssues + TaskLike.
- DashboardView.vue: 'Open issues' rail section from dashboard.open_issues
  (links to /tasks/<id>, project + status).
- SystemsSection.vue (project Systems tab): 'Open issues' list via getProjectIssues,
  with system chips, links to /tasks/<id>. Both reuse existing CSS tokens.

Issue-editor controls (kind selector / system multi-select / arose-from picker
in WorkspaceTaskPanel) are the remaining S4b piece. NEEDS operator browser
verification (CI typechecks only).

Refs plan 825 (S4b frontend — lists).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 10:50:41 -04:00
parent 79040fe5db
commit 94d32c524a
5 changed files with 101 additions and 5 deletions
+20
View File
@@ -42,3 +42,23 @@ export async function updateSystem(
export async function deleteSystem(projectId: number, systemId: number): Promise<void> {
return apiDelete(`/api/projects/${projectId}/systems/${systemId}`);
}
// Lightweight issue shape returned by the project-issues list endpoint.
export interface TaskLike {
id: number;
title: string;
status: string;
priority: string;
systems?: System[];
updated_at?: string | null;
}
export async function getProjectIssues(
projectId: number,
openOnly = true,
): Promise<TaskLike[]> {
const data = await apiGet<{ issues: TaskLike[] }>(
`/api/projects/${projectId}/issues?open_only=${openOnly}`,
);
return data.issues;
}