feat(frontend): sprint 5 — templates CRUD pages + nav + picker modal + dropdown
- types.ts: SimulationTemplate, SimulationTemplateCreateInput, SimulationTemplatePatchInput, extend SimulationCreateInput with template_id - api/templates.ts: listTemplates, getTemplate, createTemplate, updateTemplate, deleteTemplate - hooks/useTemplates.ts: useTemplates, useTemplate, useCreateTemplate, useUpdateTemplate, useDeleteTemplate (TanStack Query, invalidates ["templates"]) - TemplatesListPage: /admin/templates — table (name, MITRE count, created by, updated), New/Edit/Delete actions, loading/error/empty states - TemplateFormPage: /admin/templates/new + /admin/templates/:id/edit — controlled form with inline MITRE field (picker + matrix modal), ConfirmDialog for delete - TemplatePickerModal: reusable modal listing templates with empty state (AC-27.6) - SimulationList: replace "New simulation" link with split-button dropdown (Blank → /simulations/new | From template… → TemplatePickerModal + POST template_id) - Layout: "Templates" nav link (admin | redteam, before "Users") - App.tsx: /admin/templates routes gated roles=["admin","redteam"] - 26 new Vitest tests (118 total, 92 original preserved) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,8 @@ import { EngagementFormPage } from '@/pages/EngagementFormPage';
|
||||
import { EngagementDetailPage } from '@/pages/EngagementDetailPage';
|
||||
import { UsersAdminPage } from '@/pages/UsersAdminPage';
|
||||
import { SimulationFormPage } from '@/pages/SimulationFormPage';
|
||||
import { TemplatesListPage } from '@/pages/TemplatesListPage';
|
||||
import { TemplateFormPage } from '@/pages/TemplateFormPage';
|
||||
|
||||
/**
|
||||
* Router. Auth + role gates handled by <ProtectedRoute />.
|
||||
@@ -43,6 +45,13 @@ export function App(): JSX.Element {
|
||||
<Route element={<ProtectedRoute roles={['admin']} />}>
|
||||
<Route path="/admin/users" element={<UsersAdminPage />} />
|
||||
</Route>
|
||||
|
||||
{/* admin + redteam routes */}
|
||||
<Route element={<ProtectedRoute roles={['admin', 'redteam']} />}>
|
||||
<Route path="/admin/templates" element={<TemplatesListPage />} />
|
||||
<Route path="/admin/templates/new" element={<TemplateFormPage />} />
|
||||
<Route path="/admin/templates/:id/edit" element={<TemplateFormPage />} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user