feat(phase-33): final polish V3 - navigation, performance, and documentation (T-238 to T-240)
This commit is contained in:
@@ -1,28 +1,34 @@
|
||||
import React, { Suspense } from "react";
|
||||
import { Routes, Route, Navigate } from "react-router-dom";
|
||||
import LoginPage from "./pages/LoginPage";
|
||||
import DashboardPage from "./pages/DashboardPage";
|
||||
import TechniquesPage from "./pages/TechniquesPage";
|
||||
import MatrixPage from "./pages/MatrixPage";
|
||||
import ExecutiveDashboardPage from "./pages/ExecutiveDashboardPage";
|
||||
import CompliancePage from "./pages/CompliancePage";
|
||||
import TechniqueDetailPage from "./pages/TechniqueDetailPage";
|
||||
import TestsPage from "./pages/TestsPage";
|
||||
import TestCreatePage from "./pages/TestCreatePage";
|
||||
import TestDetailPage from "./pages/TestDetailPage";
|
||||
import TestCatalogPage from "./pages/TestCatalogPage";
|
||||
import ReportsPage from "./pages/ReportsPage";
|
||||
import SystemPage from "./pages/SystemPage";
|
||||
import UsersPage from "./pages/UsersPage";
|
||||
import AuditLogPage from "./pages/AuditLogPage";
|
||||
import DataSourcesPage from "./pages/DataSourcesPage";
|
||||
import ThreatActorsPage from "./pages/ThreatActorsPage";
|
||||
import ThreatActorDetailPage from "./pages/ThreatActorDetailPage";
|
||||
import CampaignsPage from "./pages/CampaignsPage";
|
||||
import CampaignDetailPage from "./pages/CampaignDetailPage";
|
||||
import ComparisonPage from "./pages/ComparisonPage";
|
||||
import LoadingSpinner from "./components/LoadingSpinner";
|
||||
import Layout from "./components/Layout";
|
||||
import ProtectedRoute from "./components/ProtectedRoute";
|
||||
|
||||
/* ── Eagerly loaded (core pages) ──────────────────────────────────── */
|
||||
import LoginPage from "./pages/LoginPage";
|
||||
import DashboardPage from "./pages/DashboardPage";
|
||||
|
||||
/* ── Lazy loaded (V1-V3 pages) ────────────────────────────────────── */
|
||||
const TechniquesPage = React.lazy(() => import("./pages/TechniquesPage"));
|
||||
const MatrixPage = React.lazy(() => import("./pages/MatrixPage"));
|
||||
const ExecutiveDashboardPage = React.lazy(() => import("./pages/ExecutiveDashboardPage"));
|
||||
const CompliancePage = React.lazy(() => import("./pages/CompliancePage"));
|
||||
const TechniqueDetailPage = React.lazy(() => import("./pages/TechniqueDetailPage"));
|
||||
const TestsPage = React.lazy(() => import("./pages/TestsPage"));
|
||||
const TestCreatePage = React.lazy(() => import("./pages/TestCreatePage"));
|
||||
const TestDetailPage = React.lazy(() => import("./pages/TestDetailPage"));
|
||||
const TestCatalogPage = React.lazy(() => import("./pages/TestCatalogPage"));
|
||||
const ReportsPage = React.lazy(() => import("./pages/ReportsPage"));
|
||||
const SystemPage = React.lazy(() => import("./pages/SystemPage"));
|
||||
const UsersPage = React.lazy(() => import("./pages/UsersPage"));
|
||||
const AuditLogPage = React.lazy(() => import("./pages/AuditLogPage"));
|
||||
const DataSourcesPage = React.lazy(() => import("./pages/DataSourcesPage"));
|
||||
const ThreatActorsPage = React.lazy(() => import("./pages/ThreatActorsPage"));
|
||||
const ThreatActorDetailPage = React.lazy(() => import("./pages/ThreatActorDetailPage"));
|
||||
const CampaignsPage = React.lazy(() => import("./pages/CampaignsPage"));
|
||||
const CampaignDetailPage = React.lazy(() => import("./pages/CampaignDetailPage"));
|
||||
const ComparisonPage = React.lazy(() => import("./pages/ComparisonPage"));
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<Routes>
|
||||
@@ -37,35 +43,61 @@ export default function App() {
|
||||
</ProtectedRoute>
|
||||
}
|
||||
>
|
||||
{/* ── Core ─────────────────────────────────────────────── */}
|
||||
<Route path="/dashboard" element={<DashboardPage />} />
|
||||
<Route path="/techniques" element={<TechniquesPage />} />
|
||||
<Route path="/matrix" element={<MatrixPage />} />
|
||||
|
||||
<Route path="/techniques" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TechniquesPage /></Suspense>} />
|
||||
<Route path="/techniques/:mitreId" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TechniqueDetailPage /></Suspense>} />
|
||||
|
||||
<Route path="/matrix" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><MatrixPage /></Suspense>} />
|
||||
|
||||
{/* ── Executive Dashboard (leads + admin) ──────────────── */}
|
||||
<Route
|
||||
path="/executive-dashboard"
|
||||
element={
|
||||
<ProtectedRoute roles={["admin", "red_lead", "blue_lead"]}>
|
||||
<ExecutiveDashboardPage />
|
||||
<Suspense fallback={<LoadingSpinner text="Loading…" />}><ExecutiveDashboardPage /></Suspense>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route path="/techniques/:mitreId" element={<TechniqueDetailPage />} />
|
||||
<Route path="/tests" element={<TestsPage />} />
|
||||
<Route path="/tests/new" element={<TestCreatePage />} />
|
||||
<Route path="/tests/:testId" element={<TestDetailPage />} />
|
||||
<Route path="/test-catalog" element={<TestCatalogPage />} />
|
||||
<Route path="/test-catalog/:templateId/use" element={<TestCatalogPage />} />
|
||||
<Route path="/reports" element={<ReportsPage />} />
|
||||
<Route path="/threat-actors" element={<ThreatActorsPage />} />
|
||||
<Route path="/threat-actors/:actorId" element={<ThreatActorDetailPage />} />
|
||||
<Route path="/campaigns" element={<CampaignsPage />} />
|
||||
<Route path="/campaigns/:campaignId" element={<CampaignDetailPage />} />
|
||||
<Route path="/comparison" element={<ComparisonPage />} />
|
||||
<Route path="/compliance" element={<CompliancePage />} />
|
||||
|
||||
{/* ── Tests ────────────────────────────────────────────── */}
|
||||
<Route path="/tests" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestsPage /></Suspense>} />
|
||||
<Route path="/tests/new" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestCreatePage /></Suspense>} />
|
||||
<Route path="/tests/:testId" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestDetailPage /></Suspense>} />
|
||||
<Route path="/test-catalog" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestCatalogPage /></Suspense>} />
|
||||
<Route path="/test-catalog/:templateId/use" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestCatalogPage /></Suspense>} />
|
||||
|
||||
{/* ── Campaigns ────────────────────────────────────────── */}
|
||||
<Route path="/campaigns" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><CampaignsPage /></Suspense>} />
|
||||
<Route path="/campaigns/:campaignId" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><CampaignDetailPage /></Suspense>} />
|
||||
|
||||
{/* ── Threat Actors ────────────────────────────────────── */}
|
||||
<Route path="/threat-actors" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><ThreatActorsPage /></Suspense>} />
|
||||
<Route path="/threat-actors/:actorId" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><ThreatActorDetailPage /></Suspense>} />
|
||||
|
||||
{/* ── Compliance ───────────────────────────────────────── */}
|
||||
<Route path="/compliance" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><CompliancePage /></Suspense>} />
|
||||
|
||||
{/* ── Comparison (leads + admin) ───────────────────────── */}
|
||||
<Route
|
||||
path="/comparison"
|
||||
element={
|
||||
<ProtectedRoute roles={["admin", "red_lead", "blue_lead"]}>
|
||||
<Suspense fallback={<LoadingSpinner text="Loading…" />}><ComparisonPage /></Suspense>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
|
||||
{/* ── Reports ──────────────────────────────────────────── */}
|
||||
<Route path="/reports" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><ReportsPage /></Suspense>} />
|
||||
|
||||
{/* ── System (admin only) ──────────────────────────────── */}
|
||||
<Route
|
||||
path="/system"
|
||||
element={
|
||||
<ProtectedRoute roles={["admin"]}>
|
||||
<SystemPage />
|
||||
<Suspense fallback={<LoadingSpinner text="Loading…" />}><SystemPage /></Suspense>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
@@ -73,7 +105,7 @@ export default function App() {
|
||||
path="/users"
|
||||
element={
|
||||
<ProtectedRoute roles={["admin"]}>
|
||||
<UsersPage />
|
||||
<Suspense fallback={<LoadingSpinner text="Loading…" />}><UsersPage /></Suspense>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
@@ -81,7 +113,7 @@ export default function App() {
|
||||
path="/audit"
|
||||
element={
|
||||
<ProtectedRoute roles={["admin"]}>
|
||||
<AuditLogPage />
|
||||
<Suspense fallback={<LoadingSpinner text="Loading…" />}><AuditLogPage /></Suspense>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
@@ -89,7 +121,7 @@ export default function App() {
|
||||
path="/data-sources"
|
||||
element={
|
||||
<ProtectedRoute roles={["admin"]}>
|
||||
<DataSourcesPage />
|
||||
<Suspense fallback={<LoadingSpinner text="Loading…" />}><DataSourcesPage /></Suspense>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user