diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 7f8b2f8..286279b 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -14,7 +14,7 @@ server { # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # CSP: allow self + inline styles (React build) + data: URIs for fonts/images - add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'sha256-31OgE8E9uFi947Hj0TYz0o9NSyrQOewgXrj1ZPfYDaY='; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' ws: wss:; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'sha256-31OgE8E9uFi947Hj0TYz0o9NSyrQOewgXrj1ZPfYDaY=' 'sha256-Yvj83pg9TGSmhZQWii1NGmFCIaX9trnlTFVkemiMlS8='; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' ws: wss:; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always; # Hide Nginx version server_tokens off; diff --git a/frontend/src/pages/SystemPage.tsx b/frontend/src/pages/SystemPage.tsx index 567851f..eb8d5df 100644 --- a/frontend/src/pages/SystemPage.tsx +++ b/frontend/src/pages/SystemPage.tsx @@ -18,7 +18,6 @@ import { ToggleRight, BarChart3, X, - Pencil, } from "lucide-react"; import { triggerMitreSync, @@ -30,6 +29,7 @@ import { import { getTemplateStats, getAllTemplates, + getTemplateById, createTemplate, updateTemplate, toggleTemplateActive, @@ -45,7 +45,7 @@ export default function SystemPage() { const [intelResult, setIntelResult] = useState(null); const [showCreateForm, setShowCreateForm] = useState(false); const [bulkConfirm, setBulkConfirm] = useState<"activate" | "deactivate" | null>(null); - const [selectedTemplate, setSelectedTemplate] = useState(null); + const [selectedTemplateId, setSelectedTemplateId] = useState(null); // ── Existing queries ───────────────────────────────────────────── const { @@ -75,6 +75,15 @@ export default function SystemPage() { queryFn: () => getAllTemplates({ limit: 200 }), }); + const { + data: selectedTemplate, + isLoading: selectedTemplateLoading, + } = useQuery({ + queryKey: ["template-detail", selectedTemplateId], + queryFn: () => getTemplateById(selectedTemplateId!), + enabled: !!selectedTemplateId, + }); + // ── Mutations ──────────────────────────────────────────────────── const mitreSyncMutation = useMutation({ mutationFn: triggerMitreSync, @@ -125,10 +134,10 @@ export default function SystemPage() { const updateTemplateMutation = useMutation({ mutationFn: ({ id, payload }: { id: string; payload: Partial }) => updateTemplate(id, payload), - onSuccess: (updated) => { - setSelectedTemplate(updated); + onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["templates-admin"] }); queryClient.invalidateQueries({ queryKey: ["test-templates"] }); + queryClient.invalidateQueries({ queryKey: ["template-detail", selectedTemplateId] }); }, }); @@ -481,12 +490,11 @@ export default function SystemPage() { > @@ -704,15 +712,21 @@ export default function SystemPage() { {/* Template Detail Modal */} - {selectedTemplate && ( - setSelectedTemplate(null)} - onSave={(id, payload) => updateTemplateMutation.mutate({ id, payload })} - onToggleActive={(id) => toggleActiveMutation.mutate(id)} - isSaving={updateTemplateMutation.isPending} - isToggling={toggleActiveMutation.isPending} - /> + {selectedTemplateId && ( + selectedTemplateLoading ? ( +
+ +
+ ) : selectedTemplate ? ( + setSelectedTemplateId(null)} + onSave={(id, payload) => updateTemplateMutation.mutate({ id, payload })} + onToggleActive={(id) => toggleActiveMutation.mutate(id)} + isSaving={updateTemplateMutation.isPending} + isToggling={toggleActiveMutation.isPending} + /> + ) : null )} );