Files
FabledScribe/frontend/src/api/systems.ts
T
bvandeusen 94d32c524a
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
feat(issues): S4b frontend — open-issues lists + issue plumbing
- 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>
2026-06-14 10:50:41 -04:00

65 lines
1.7 KiB
TypeScript

import { apiGet, apiPost, apiPatch, apiDelete } from "@/api/client";
export interface System {
id: number;
project_id: number;
name: string;
description: string;
color: string | null;
status: "active" | "archived";
order_index: number;
open_issue_count: number;
created_at: string | null;
updated_at: string | null;
}
export async function listSystems(projectId: number): Promise<System[]> {
const data = await apiGet<{ systems: System[] }>(`/api/projects/${projectId}/systems`);
return data.systems;
}
export async function createSystem(
projectId: number,
data: { name: string; description?: string; color?: string },
): Promise<System> {
return apiPost(`/api/projects/${projectId}/systems`, data);
}
export async function updateSystem(
projectId: number,
systemId: number,
data: Partial<{
name: string;
description: string;
color: string | null;
status: "active" | "archived";
order_index: number;
}>,
): Promise<System> {
return apiPatch(`/api/projects/${projectId}/systems/${systemId}`, data);
}
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;
}