feat(nav): hide unfinished Reports section platform-wide
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled

Route and nav link removed (not the page/component files, kept as a
base to resume later) — navigating to /reports now falls through to
the catch-all redirect to /dashboard for every role, including admin.

fix(campaigns): show all non-campaign tests when adding to a campaign

The 'Existing Test' picker only ever queried state=draft, but the
backend places no restriction on a test's own state when adding it to
a campaign (only the campaign's own status matters) — tests already
in progress or completed were invisible here for no real reason.
This commit is contained in:
kitos
2026-07-16 08:32:31 +02:00
parent 8d9e25703d
commit 8493a6a764
3 changed files with 11 additions and 7 deletions
+4 -3
View File
@@ -20,7 +20,9 @@ const TestCatalogPage = React.lazy(() => import("./pages/TestCatalogPage"));
const ValidatedTestsPage = React.lazy(() => import("./pages/ValidatedTestsPage")); const ValidatedTestsPage = React.lazy(() => import("./pages/ValidatedTestsPage"));
const ReviewQueuePage = React.lazy(() => import("./pages/ReviewQueuePage")); const ReviewQueuePage = React.lazy(() => import("./pages/ReviewQueuePage"));
const ImportRTPage = React.lazy(() => import("./pages/ImportRTPage")); const ImportRTPage = React.lazy(() => import("./pages/ImportRTPage"));
const ReportsPage = React.lazy(() => import("./pages/ReportsPage")); // Reports is unfinished — hidden platform-wide (route + nav link removed
// below) until it's ready. Left unimported/unrouted rather than deleted.
// const ReportsPage = React.lazy(() => import("./pages/ReportsPage"));
const SystemPage = React.lazy(() => import("./pages/SystemPage")); const SystemPage = React.lazy(() => import("./pages/SystemPage"));
const UsersPage = React.lazy(() => import("./pages/UsersPage")); const UsersPage = React.lazy(() => import("./pages/UsersPage"));
const AuditLogPage = React.lazy(() => import("./pages/AuditLogPage")); const AuditLogPage = React.lazy(() => import("./pages/AuditLogPage"));
@@ -110,8 +112,7 @@ export default function App() {
} }
/> />
{/* ── Reports ──────────────────────────────────────────── */} {/* ── Reports (hidden — unfinished, see import comment above) ── */}
<Route path="/reports" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><ReportsPage /></Suspense>} />
{/* ── Settings (all authenticated users) ───────────────── */} {/* ── Settings (all authenticated users) ───────────────── */}
<Route path="/settings" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><SettingsPage /></Suspense>} /> <Route path="/settings" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><SettingsPage /></Suspense>} />
@@ -110,7 +110,11 @@ export default function AddTestToCampaignModal({
const { data: allTests, isLoading: testsLoading } = useQuery({ const { data: allTests, isLoading: testsLoading } = useQuery({
queryKey: ["tests", "for-campaign-picker"], queryKey: ["tests", "for-campaign-picker"],
queryFn: () => getTests({ state: "draft", not_in_any_campaign: true, limit: 200 }), // No state filter — the backend places no restriction on a test's own
// state when adding it to a campaign (only the campaign's own status
// matters), so limiting this picker to "draft" only was hiding tests
// that could legitimately be added.
queryFn: () => getTests({ not_in_any_campaign: true, limit: 200 }),
enabled: open && tab === "existing", enabled: open && tab === "existing",
}); });
@@ -511,7 +515,7 @@ export default function AddTestToCampaignModal({
<p className="text-sm"> <p className="text-sm">
{existingSearch {existingSearch
? "No tests match your search." ? "No tests match your search."
: "No draft tests available. All existing tests are already in a campaign."} : "No tests available. All existing tests are already in a campaign."}
</p> </p>
</div> </div>
) : ( ) : (
+1 -2
View File
@@ -5,7 +5,6 @@ import {
LayoutDashboard, LayoutDashboard,
FlaskConical, FlaskConical,
BookOpen, BookOpen,
BarChart3,
Settings, Settings,
Users, Users,
FileText, FileText,
@@ -62,7 +61,7 @@ const mainLinks: NavItem[] = [
{ to: "/threat-actors", label: "Threat Actors", icon: Crosshair }, { to: "/threat-actors", label: "Threat Actors", icon: Crosshair },
{ to: "/compliance", label: "Compliance", icon: ShieldCheck }, { to: "/compliance", label: "Compliance", icon: ShieldCheck },
{ to: "/comparison", label: "Comparison", icon: GitCompareArrows, roles: ["admin", "red_lead", "blue_lead", "viewer"] }, { to: "/comparison", label: "Comparison", icon: GitCompareArrows, roles: ["admin", "red_lead", "blue_lead", "viewer"] },
{ to: "/reports", label: "Reports", icon: BarChart3 }, // Reports is unfinished — hidden platform-wide until it's ready (see App.tsx).
{ to: "/settings", label: "Settings", icon: Settings }, { to: "/settings", label: "Settings", icon: Settings },
]; ];