diff --git a/ui/web/src/index.css b/ui/web/src/index.css index bb7d5a49..762678f5 100644 --- a/ui/web/src/index.css +++ b/ui/web/src/index.css @@ -128,6 +128,8 @@ @layer base { * { @apply border-border; + scrollbar-width: thin; + scrollbar-color: var(--border) transparent; } body { @apply bg-background text-foreground; diff --git a/ui/web/src/pages/teams/task-sections/task-detail-dialog.tsx b/ui/web/src/pages/teams/task-sections/task-detail-dialog.tsx index 86d52d9d..b9c3bd5d 100644 --- a/ui/web/src/pages/teams/task-sections/task-detail-dialog.tsx +++ b/ui/web/src/pages/teams/task-sections/task-detail-dialog.tsx @@ -17,7 +17,7 @@ interface TaskDetailDialogProps { export function TaskDetailDialog({ task, onClose }: TaskDetailDialogProps) { return ( onClose()}> - + Task Detail diff --git a/ui/web/src/pages/teams/team-delegations-tab.tsx b/ui/web/src/pages/teams/team-delegations-tab.tsx index 047f020e..87235254 100644 --- a/ui/web/src/pages/teams/team-delegations-tab.tsx +++ b/ui/web/src/pages/teams/team-delegations-tab.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; -import { ArrowRightLeft } from "lucide-react"; +import { ArrowRightLeft, RefreshCw } from "lucide-react"; import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; import { EmptyState } from "@/components/shared/empty-state"; import { DeferredSpinner } from "@/components/shared/loading-skeleton"; import { formatDate, formatDuration } from "@/lib/format"; @@ -14,12 +15,12 @@ interface TeamDelegationsTabProps { } export function TeamDelegationsTab({ teamId }: TeamDelegationsTabProps) { - const { records, loading } = useTeamDelegations(teamId); + const { records, loading, refresh } = useTeamDelegations(teamId); const { getDelegation } = useDelegations(); const { getTrace } = useTraces(); const [selectedId, setSelectedId] = useState(null); - if (loading) return ; + if (loading && records.length === 0) return ; if (records.length === 0) { return ( @@ -33,6 +34,12 @@ export function TeamDelegationsTab({ teamId }: TeamDelegationsTabProps) { return ( <> +
+ +
diff --git a/ui/web/src/pages/teams/team-detail-page.tsx b/ui/web/src/pages/teams/team-detail-page.tsx index f600d72d..8487a338 100644 --- a/ui/web/src/pages/teams/team-detail-page.tsx +++ b/ui/web/src/pages/teams/team-detail-page.tsx @@ -105,9 +105,9 @@ export function TeamDetailPage({ teamId, onBack }: TeamDetailPageProps) { {/* Tabs */} -
+
- + Members Tasks Delegations diff --git a/ui/web/src/pages/teams/team-tasks-tab.tsx b/ui/web/src/pages/teams/team-tasks-tab.tsx index bfd362b2..319c2073 100644 --- a/ui/web/src/pages/teams/team-tasks-tab.tsx +++ b/ui/web/src/pages/teams/team-tasks-tab.tsx @@ -1,4 +1,6 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useCallback } from "react"; +import { Button } from "@/components/ui/button"; +import { RefreshCw } from "lucide-react"; import type { TeamTaskData } from "@/types/team"; import { TaskList } from "./task-sections"; @@ -11,24 +13,30 @@ export function TeamTasksTab({ teamId, getTeamTasks }: TeamTasksTabProps) { const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(true); - useEffect(() => { - let cancelled = false; - (async () => { - setLoading(true); - try { - const res = await getTeamTasks(teamId); - if (!cancelled) setTasks(res.tasks ?? []); - } catch { - // ignore - } finally { - if (!cancelled) setLoading(false); - } - })(); - return () => { cancelled = true; }; + const load = useCallback(async () => { + setLoading(true); + try { + const res = await getTeamTasks(teamId); + setTasks(res.tasks ?? []); + } catch { + // ignore + } finally { + setLoading(false); + } }, [teamId, getTeamTasks]); + useEffect(() => { + load(); + }, [load]); + return ( -
+
+
+ +
);