feat(dashboard): task system with DB persistence, CRUD endpoints, frontend API integration
CI - Build & Test / Backend (.NET) (push) Successful in 27s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 15s
CI - Build & Test / Security Check (push) Successful in 3s

This commit is contained in:
2026-06-11 15:51:47 +02:00
parent 2877035c5c
commit 81af81fb6f
8 changed files with 599 additions and 8 deletions
+56 -6
View File
@@ -103,6 +103,18 @@ interface DashboardQueueItem {
status: string
}
interface DashboardTaskResponse {
id: string
title: string
detail: string | null
source: string
state: string
priority: string
assignedTo: string | null
createdAt: string
updatedAt: string
}
// ── Agent Catalog (static enrichment) ──
const AGENT_CATALOG: Record<string, Partial<AgentNodeData>> = {
@@ -244,12 +256,8 @@ const busySince = ref(0)
// Operations Feed
const feedEntries = ref<FeedEntry[]>([])
// Open Tasks (mock only no API endpoint)
const openTasks = ref<OpenTask[]>([
{ id: 't1', title: 'Agent Thinking Panel visualisieren', detail: 'Live-Animation der Denkprozesse im AgentModal', source: 'iris', createdAt: '22:30' },
{ id: 't2', title: 'CI/CD Pipeline Monitoring Dashboard', detail: 'Echtzeit-Status der Gitea Actions im Dashboard', source: 'iris', createdAt: '21:15' },
{ id: 't3', title: 'Dungeon System Dokumentation', detail: 'API-Doku für Room-Generation-Endpunkte schreiben', source: 'bao', createdAt: '20:00' },
])
// Open Tasks (fetched from API)
const openTasks = ref<OpenTask[]>([])
// Queue
const queue = ref<QueueItem[]>([])
@@ -342,6 +350,45 @@ async function fetchQueue(): Promise<void> {
}
}
async function fetchTasks(): Promise<void> {
try {
const res = await apiFetch('/api/dashboard/tasks')
if (!res.ok) return
const data: DashboardTaskResponse[] = await res.json()
openTasks.value = data.map(mapTaskResponse)
} catch {
// API unreachable keep current values
}
}
function mapTaskResponse(t: DashboardTaskResponse): OpenTask {
const source: OpenTask['source'] = t.source === 'iris' ? 'iris' : 'bao'
// Format createdAt as relative time string (like "22:30")
const created = new Date(t.createdAt)
const now = new Date()
const diffMs = now.getTime() - created.getTime()
const diffMins = Math.floor(diffMs / 60000)
let createdAt: string
if (diffMins < 1) {
createdAt = 'just now'
} else if (diffMins < 60) {
createdAt = `${diffMins}m`
} else if (diffMins < 1440) {
createdAt = `${Math.floor(diffMins / 60)}h`
} else {
createdAt = created.toLocaleDateString('de-DE', { month: 'short', day: 'numeric' })
}
return {
id: t.id,
title: t.title,
detail: t.detail ?? '',
source,
createdAt,
}
}
// ── Chat Send ──
async function sendChatMessage(text: string): Promise<void> {
@@ -454,6 +501,7 @@ function startPolling(): void {
fetchOperations()
fetchChatMessages()
fetchQueue()
fetchTasks()
// Polling intervals
intervals.push(setInterval(fetchStatus, 5000))
@@ -461,6 +509,7 @@ function startPolling(): void {
intervals.push(setInterval(fetchOperations, 10000))
intervals.push(setInterval(fetchChatMessages, 3000))
intervals.push(setInterval(fetchQueue, 10000))
intervals.push(setInterval(fetchTasks, 15000))
}
function stopPolling(): void {
@@ -512,5 +561,6 @@ export function useDashboardData() {
fetchOperations,
fetchChatMessages,
fetchQueue,
fetchTasks,
}
}