Add read-only web dashboard MVP
Adds a disabled-by-default loopback web dashboard MVP with read-only control-plane views, prompt preview redaction, Vite React UI, and validation coverage.
This commit is contained in:
100
apps/dashboard/src/api.ts
Normal file
100
apps/dashboard/src/api.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
export interface DashboardOverview {
|
||||
generatedAt: string;
|
||||
services: Array<{
|
||||
serviceId: string;
|
||||
assistantName: string;
|
||||
agentType: string;
|
||||
updatedAt: string;
|
||||
totalRooms: number;
|
||||
activeRooms: number;
|
||||
}>;
|
||||
rooms: {
|
||||
total: number;
|
||||
active: number;
|
||||
waiting: number;
|
||||
inactive: number;
|
||||
};
|
||||
tasks: {
|
||||
total: number;
|
||||
active: number;
|
||||
paused: number;
|
||||
completed: number;
|
||||
watchers: {
|
||||
active: number;
|
||||
paused: number;
|
||||
completed: number;
|
||||
};
|
||||
};
|
||||
usage: {
|
||||
rows: Array<{
|
||||
name: string;
|
||||
h5pct: number;
|
||||
h5reset: string;
|
||||
d7pct: number;
|
||||
d7reset: string;
|
||||
}>;
|
||||
fetchedAt: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
export interface StatusSnapshot {
|
||||
serviceId: string;
|
||||
agentType: string;
|
||||
assistantName: string;
|
||||
updatedAt: string;
|
||||
entries: Array<{
|
||||
jid: string;
|
||||
name: string;
|
||||
folder: string;
|
||||
agentType: string;
|
||||
status: 'processing' | 'waiting' | 'inactive';
|
||||
elapsedMs: number | null;
|
||||
pendingMessages: boolean;
|
||||
pendingTasks: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface DashboardTask {
|
||||
id: string;
|
||||
groupFolder: string;
|
||||
chatJid: string;
|
||||
agentType: string | null;
|
||||
ciProvider: string | null;
|
||||
ciMetadata: string | null;
|
||||
scheduleType: string;
|
||||
scheduleValue: string;
|
||||
contextMode: string;
|
||||
nextRun: string | null;
|
||||
lastRun: string | null;
|
||||
lastResult: string | null;
|
||||
status: 'active' | 'paused' | 'completed';
|
||||
suspendedUntil: string | null;
|
||||
createdAt: string;
|
||||
promptPreview: string;
|
||||
promptLength: number;
|
||||
isWatcher: boolean;
|
||||
}
|
||||
|
||||
async function fetchJson<T>(path: string): Promise<T> {
|
||||
const response = await fetch(path, {
|
||||
headers: { accept: 'application/json' },
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`${path} failed: ${response.status}`);
|
||||
}
|
||||
return (await response.json()) as T;
|
||||
}
|
||||
|
||||
export async function fetchDashboardData(): Promise<{
|
||||
overview: DashboardOverview;
|
||||
snapshots: StatusSnapshot[];
|
||||
tasks: DashboardTask[];
|
||||
}> {
|
||||
const [overview, snapshots, tasks] = await Promise.all([
|
||||
fetchJson<DashboardOverview>('/api/overview'),
|
||||
fetchJson<StatusSnapshot[]>('/api/status-snapshots'),
|
||||
fetchJson<DashboardTask[]>('/api/tasks'),
|
||||
]);
|
||||
|
||||
return { overview, snapshots, tasks };
|
||||
}
|
||||
Reference in New Issue
Block a user