After #34 the workspace store only holds the root-level scripts plus whatever subfolders the user has expanded. DashboardRoute's "全部脚本"/"工作副本" counts derived from scripts.length therefore underreport the workspace total until the user navigates to /scripts and expands every folder. Fix: separate count endpoint + dedicated store field, mounted independently. Backend — backend/src/backend/scripts.py - New endpoint GET /api/v1/scripts/count. - Route declared BEFORE /api/v1/scripts/{script_id}/... so FastAPI's declaration-order matching does not interpret "count" as a script_id. - Returns { data: { total: number }, meta: {} }; SQL is a single COUNT(*) on scripts filtered by workspace_id + status='active'. Frontend — services/api.ts + context/AuthContext.tsx - countScripts(workspaceId) client; WorkspaceBoundApi gains the field; AuthContext binding forwards workspaceId. Frontend — state/scriptWorkspaceStore.ts - scriptCount: number | null, scriptCountLoading: boolean. - loadScriptCount() action: idempotent (no-op while in-flight), silent on failure (dashboard tolerates a stale count). - Initial state and reset() clear both fields. Frontend — features/platform/DashboardRoute.tsx - Subscribes to scriptCount; calls loadScriptCount() on mount. - Falls back to scripts.length until the count resolves so the dashboard never blanks. Tests — backend/tests/test_count_scripts.py (new) - 3 unit tests: scalar result handling, NULL coercion, route callable. Verified: pytest 55 passed (52 + 3 new); pnpm typecheck clean.
32 lines
1.1 KiB
TypeScript
32 lines
1.1 KiB
TypeScript
import { useEffect } from "react";
|
|
import { useNavigate } from "react-router";
|
|
|
|
import { DashboardPage } from "../../components/admin/DashboardPage";
|
|
import { useScriptWorkspaceStore } from "./state/scriptWorkspaceStore";
|
|
|
|
export default function DashboardRoute() {
|
|
const scripts = useScriptWorkspaceStore((s) => s.scripts);
|
|
const scriptCount = useScriptWorkspaceStore((s) => s.scriptCount);
|
|
const loadScriptCount = useScriptWorkspaceStore((s) => s.loadScriptCount);
|
|
const apiOnline = useScriptWorkspaceStore((s) => s.apiOnline);
|
|
const navigate = useNavigate();
|
|
|
|
// Independent of the lazy-loaded `scripts` array — the count endpoint
|
|
// returns the workspace-wide total even when no folders have been
|
|
// expanded yet (see #34 + #37).
|
|
useEffect(() => {
|
|
void loadScriptCount();
|
|
}, [loadScriptCount]);
|
|
|
|
return (
|
|
<DashboardPage
|
|
scriptCount={scriptCount ?? scripts.length}
|
|
online={apiOnline}
|
|
onNavigate={(page) => {
|
|
if (page === "scripts") navigate("/scripts");
|
|
else if (page === "schedules") navigate("/schedules");
|
|
else navigate("/system");
|
|
}}
|
|
/>
|
|
);
|
|
} |