mirror of
https://github.com/BradGroux/veritas-kanban.git
synced 2026-10-08 20:57:51 +00:00
feat(dashboard): add refresh indicator during data fetch
- Show spinning RefreshCw icon and 'Refreshing...' text during fetch - Expose isFetching state from useMetrics hook - Dashboard already has all required metrics features: - Run count from real telemetry data - Success rate with color coding (green/yellow/red) - Token usage with input/output/cache breakdown - Duration with avg/p50/p95 percentiles - Trend indicators (↑/↓) comparing to previous period - Auto-refresh every 30 seconds - Graceful empty state when no data Closes US-1405
This commit is contained in:
parent
fdf5ff187d
commit
b53ef09dcd
5 changed files with 128 additions and 4 deletions
|
|
@ -1044,3 +1044,66 @@
|
|||
{"type":"task.archived","taskId":"task_20260128_o0FPtg","project":"veritas-kanban","status":"done","id":"evt_0gdktmGAqnRA","timestamp":"2026-01-28T14:12:01.970Z"}
|
||||
{"type":"task.archived","taskId":"task_20260128_q38wnR","project":"veritas-kanban","status":"done","id":"evt_B3rKqlEaywqP","timestamp":"2026-01-28T14:12:01.971Z"}
|
||||
{"type":"task.archived","taskId":"task_20260128_tD7fef","project":"veritas-kanban","status":"done","id":"evt_b2Kt6rRrap0P","timestamp":"2026-01-28T14:12:01.972Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260128_V0MVwS","project":"veritas-kanban","status":"done","previousStatus":"in-progress","id":"evt_EIdDEc4fzlA9","timestamp":"2026-01-28T14:12:56.406Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260126_legacy1","status":"blocked","previousStatus":"review","id":"evt_aJKeQEJzFVlh","timestamp":"2026-01-28T14:13:49.706Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_qeDVe7","status":"todo","id":"evt_qF3rAJT_JkA-","timestamp":"2026-01-28T14:13:49.711Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_JuSpOm","status":"todo","id":"evt_y_URQGQeqFd7","timestamp":"2026-01-28T14:13:49.716Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260128_JuSpOm","status":"in-progress","previousStatus":"todo","id":"evt_0GdekA5NSe9b","timestamp":"2026-01-28T14:13:49.719Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_664iza","status":"todo","id":"evt_yCUA_i9DTyFb","timestamp":"2026-01-28T14:13:49.720Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260128_664iza","status":"blocked","previousStatus":"todo","id":"evt_yGUFtpfZDadq","timestamp":"2026-01-28T14:13:49.723Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_wLa9-l","status":"todo","id":"evt_BUzHobjagh0M","timestamp":"2026-01-28T14:13:49.724Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260128_wLa9-l","status":"done","previousStatus":"todo","id":"evt_yc0d-aT8hYPF","timestamp":"2026-01-28T14:13:49.727Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260126_idem1","status":"blocked","previousStatus":"review","id":"evt_-RHZi0G2MeXn","timestamp":"2026-01-28T14:13:49.740Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_56EzyF","project":"my-project","status":"todo","id":"evt_Y3SKILqPxO2O","timestamp":"2026-01-28T14:13:49.741Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_EW5A0c","status":"todo","id":"evt_EajwoH4VXoqt","timestamp":"2026-01-28T14:13:49.744Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_t5JkOe","status":"todo","id":"evt_WCfjJrq-Injc","timestamp":"2026-01-28T14:13:49.746Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_i00QLj","status":"todo","id":"evt_y1G8ehDhh3Wm","timestamp":"2026-01-28T14:13:49.749Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260126_multi1","status":"blocked","previousStatus":"review","id":"evt_2T2SN1fHJHEH","timestamp":"2026-01-28T14:13:49.751Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260126_multi2","status":"blocked","previousStatus":"review","id":"evt_pwMXj_ggyr2m","timestamp":"2026-01-28T14:13:49.753Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260128_i00QLj","status":"in-progress","previousStatus":"todo","id":"evt_lhxwY8L0vV1R","timestamp":"2026-01-28T14:13:49.761Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_aeg-ro","status":"todo","id":"evt_PMIUKN5xoS0h","timestamp":"2026-01-28T14:13:49.767Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_guLYDE","status":"todo","id":"evt_pJh1_QEZXIoZ","timestamp":"2026-01-28T14:13:49.775Z"}
|
||||
{"type":"task.restored","taskId":"task_20260126_arch1","status":"done","id":"evt_NJPC4BbV5KQt","timestamp":"2026-01-28T14:13:49.783Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260126_arch1","status":"blocked","previousStatus":"done","id":"evt_njisU91EW8L9","timestamp":"2026-01-28T14:13:49.784Z"}
|
||||
{"type":"task.archived","taskId":"task_20260126_arch1","status":"blocked","id":"evt_NRcgw6pR_dhS","timestamp":"2026-01-28T14:13:49.789Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_DHmiw3","status":"todo","id":"evt_WUAkr3Uao_jq","timestamp":"2026-01-28T14:13:49.795Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_8ZiG0y","status":"todo","id":"evt_3WUhEVT9pFke","timestamp":"2026-01-28T14:13:49.803Z"}
|
||||
{"type":"task.archived","taskId":"task_20260128_8ZiG0y","status":"todo","id":"evt_sbqAjp377WEw","timestamp":"2026-01-28T14:13:49.806Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_Dxfb66","status":"todo","id":"evt_YbnRJ-Oah-C1","timestamp":"2026-01-28T14:13:49.807Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_j4v-ml","status":"todo","id":"evt_EwxCDT_8Epgc","timestamp":"2026-01-28T14:13:49.810Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_FyeeJm","status":"todo","id":"evt_xgehu5XzNRZ4","timestamp":"2026-01-28T14:13:49.832Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_feXRCT","status":"todo","id":"evt_ZsnxO4ZlBVZU","timestamp":"2026-01-28T14:13:49.833Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_O8LwAG","status":"todo","id":"evt_BBALxBLr05JU","timestamp":"2026-01-28T14:13:49.843Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_DhgY5l","status":"todo","id":"evt_EWNd5I4cKS6Z","timestamp":"2026-01-28T14:13:49.843Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_PVtzVP","project":"test-project","status":"todo","id":"evt_d4aHuProMU3Y","timestamp":"2026-01-28T14:13:49.850Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_QXbYX7","status":"todo","id":"evt_ajLMYiNp5WUn","timestamp":"2026-01-28T14:13:49.856Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_6TzEJP","status":"todo","id":"evt_7-HJz_BBigJp","timestamp":"2026-01-28T14:13:49.859Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_pVir6P","status":"todo","id":"evt_jomFWF36skWJ","timestamp":"2026-01-28T14:13:49.869Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_BhxcoA","status":"todo","id":"evt_Ws3O_bsSi9jo","timestamp":"2026-01-28T14:13:49.870Z"}
|
||||
{"type":"task.status_changed","taskId":"task_20260128_pVir6P","status":"in-progress","previousStatus":"todo","id":"evt_eQ-I8ghnB6NB","timestamp":"2026-01-28T14:13:49.872Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_7Hlf3i","status":"todo","id":"evt_VUEzjHZKI9dn","timestamp":"2026-01-28T14:13:49.875Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_vEuwon","status":"todo","id":"evt_9WQ8ClfOQjsS","timestamp":"2026-01-28T14:13:49.877Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_TlJaN9","status":"todo","id":"evt_iHDk5pd8-vAs","timestamp":"2026-01-28T14:13:49.880Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_OVULhb","status":"todo","id":"evt_0wopJ2nDMHgl","timestamp":"2026-01-28T14:13:49.880Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_LNFgfG","status":"todo","id":"evt_4SPvlaIc5oNQ","timestamp":"2026-01-28T14:13:49.886Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_oxhHCK","status":"todo","id":"evt_ZL_aKJeDzk36","timestamp":"2026-01-28T14:13:49.888Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_JGKvCV","status":"todo","id":"evt_uYecKQyBVX15","timestamp":"2026-01-28T14:13:49.889Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_b38X4p","status":"todo","id":"evt_pNUDid_I7Q-G","timestamp":"2026-01-28T14:13:49.890Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_1Nh91U","status":"todo","id":"evt_71eeAPanN2ZK","timestamp":"2026-01-28T14:13:49.894Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_qowqT9","status":"todo","id":"evt_0qHMP5wYHu4O","timestamp":"2026-01-28T14:13:49.898Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_FxN6To","status":"todo","id":"evt_1v8_5Vnb6gez","timestamp":"2026-01-28T14:13:49.902Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_oMsuBK","status":"todo","id":"evt_1ujGfMgnI63A","timestamp":"2026-01-28T14:13:49.904Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_GCHHR-","status":"todo","id":"evt_IYIOhiVcviqd","timestamp":"2026-01-28T14:13:49.904Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_WsJPVK","status":"todo","id":"evt_libonFSyzB2L","timestamp":"2026-01-28T14:13:49.905Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_D_pyB9","status":"todo","id":"evt_p01Mmh9rYjLf","timestamp":"2026-01-28T14:13:49.906Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_R0kUOu","status":"todo","id":"evt_Jj8QuYrZJxs0","timestamp":"2026-01-28T14:13:49.909Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_GRZ3Ky","status":"todo","id":"evt_zxeZSRY_NoBq","timestamp":"2026-01-28T14:13:49.910Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_cxwVaV","status":"todo","id":"evt_ubDlTAHwaUhB","timestamp":"2026-01-28T14:13:49.916Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_dSHkGk","status":"todo","id":"evt_REPqQbIgsU5s","timestamp":"2026-01-28T14:13:49.921Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_Jt3pVG","status":"todo","id":"evt_FJCpmdXPSyZ2","timestamp":"2026-01-28T14:13:49.927Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_g7oMUz","status":"todo","id":"evt_-tgPW_4eIqeK","timestamp":"2026-01-28T14:13:49.931Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_1AL-Ps","status":"todo","id":"evt_N9R0LVDJLtC1","timestamp":"2026-01-28T14:13:49.936Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_WehfEe","project":"project-a","status":"todo","id":"evt_BCp5yYwOXlU9","timestamp":"2026-01-28T14:13:49.936Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_b2CW4g","project":"project-a","status":"todo","id":"evt_-g7kMhjBnCYG","timestamp":"2026-01-28T14:13:49.936Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_NEm1K_","project":"project-b","status":"todo","id":"evt_aCXwbrsfHVkW","timestamp":"2026-01-28T14:13:49.937Z"}
|
||||
{"type":"task.created","taskId":"task_20260128_eCyXeF","status":"todo","id":"evt_qx8JflCKJ_1V","timestamp":"2026-01-28T14:13:49.944Z"}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,44 @@
|
|||
[
|
||||
{
|
||||
"id": "activity_1769609585007_vp6ouz8mc",
|
||||
"type": "comment_added",
|
||||
"taskId": "task_20260128_efQBVi",
|
||||
"taskTitle": "US-1011: Cost budget tracking",
|
||||
"details": {
|
||||
"author": "Veritas",
|
||||
"preview": "Verified complete implementation: Budget settings ..."
|
||||
},
|
||||
"timestamp": "2026-01-28T14:13:05.007Z"
|
||||
},
|
||||
{
|
||||
"id": "activity_1769609584757_n6s7jq73m",
|
||||
"type": "task_updated",
|
||||
"taskId": "task_20260128_efQBVi",
|
||||
"taskTitle": "US-1011: Cost budget tracking",
|
||||
"timestamp": "2026-01-28T14:13:04.757Z"
|
||||
},
|
||||
{
|
||||
"id": "activity_1769609584571_l6zlkl6ou",
|
||||
"type": "comment_added",
|
||||
"taskId": "task_20260128_V0MVwS",
|
||||
"taskTitle": "US-1405: Dashboard metrics cards refresh",
|
||||
"details": {
|
||||
"author": "Veritas",
|
||||
"preview": "Dashboard metrics cards now display real telemetry..."
|
||||
},
|
||||
"timestamp": "2026-01-28T14:13:04.571Z"
|
||||
},
|
||||
{
|
||||
"id": "activity_1769609576406_awrw3g8pe",
|
||||
"type": "status_changed",
|
||||
"taskId": "task_20260128_V0MVwS",
|
||||
"taskTitle": "US-1405: Dashboard metrics cards refresh",
|
||||
"details": {
|
||||
"from": "in-progress",
|
||||
"status": "done"
|
||||
},
|
||||
"timestamp": "2026-01-28T14:12:56.406Z"
|
||||
},
|
||||
{
|
||||
"id": "activity_1769609521972_4we6i0l5b",
|
||||
"type": "sprint_archived",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,12 @@
|
|||
[
|
||||
{
|
||||
"id": "status_1769609601418_kzwyjd0u0",
|
||||
"timestamp": "2026-01-28T14:13:21.418Z",
|
||||
"previousStatus": "sub-agent",
|
||||
"newStatus": "idle",
|
||||
"subAgentCount": 1,
|
||||
"durationMs": 98854
|
||||
},
|
||||
{
|
||||
"id": "status_1769609502564_sefpbuxpw",
|
||||
"timestamp": "2026-01-28T14:11:42.564Z",
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ export function Dashboard() {
|
|||
const [project, setProject] = useState<string | undefined>(undefined);
|
||||
const [drillDown, setDrillDown] = useState<DrillDownType>(null);
|
||||
|
||||
const { data: metrics, isLoading, error, dataUpdatedAt } = useMetrics(period, project);
|
||||
const { data: metrics, isLoading, isFetching, error, dataUpdatedAt } = useMetrics(period, project);
|
||||
const { data: tasks } = useTasks();
|
||||
|
||||
// Get unique projects from tasks
|
||||
|
|
@ -257,8 +257,8 @@ export function Dashboard() {
|
|||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
||||
<RefreshCw className="h-3 w-3" />
|
||||
Updated {new Date(dataUpdatedAt).toLocaleTimeString()}
|
||||
<RefreshCw className={cn('h-3 w-3', isFetching && 'animate-spin')} />
|
||||
{isFetching ? 'Refreshing...' : `Updated ${new Date(dataUpdatedAt).toLocaleTimeString()}`}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState } from 'react';
|
||||
import { Activity, Trash2, RefreshCw } from 'lucide-react';
|
||||
import { Activity, Trash2, RefreshCw, Clock, Coffee, ArrowRight, Zap } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import {
|
||||
|
|
@ -15,7 +15,20 @@ import {
|
|||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from '@/components/ui/tabs';
|
||||
import { useActivities, useClearActivities, type Activity as ActivityItem, type ActivityType } from '@/hooks/useActivity';
|
||||
import {
|
||||
useDailySummary,
|
||||
useStatusHistory,
|
||||
formatDurationMs,
|
||||
getStatusColor,
|
||||
type StatusHistoryEntry,
|
||||
} from '@/hooks/useStatusHistory';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface ActivitySidebarProps {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue