import { useState } from 'react'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useTrackedMutation } from '../hooks/useTrackedMutation'; import { getPolicies, updatePolicy, deletePolicy, createPolicy } from '../api/client'; import PageHeader from '../components/PageHeader'; import DataTable from '../components/DataTable'; import type { Column } from '../components/DataTable'; import ErrorState from '../components/ErrorState'; import { formatDateTime } from '../api/utils'; import { POLICY_TYPES, POLICY_SEVERITIES, type PolicyRule, type PolicyType, type PolicySeverity, } from '../api/types'; /** * Severity → badge style. Keyed on the backend's TitleCase PolicySeverity * enum values (D-006). The pre-fix map keyed on `low`/`medium`/`high`/`critical` * which never matched the backend's `Warning`/`Error`/`Critical`, so every * existing rule fell through to the `badge-neutral` default. */ const severityStyles: Record = { Warning: 'badge-warning', Error: 'badge-danger', Critical: 'badge-danger', }; const severityDots: Record = { Warning: 'bg-amber-500', Error: 'bg-orange-500', Critical: 'bg-red-500', }; /** * Convert TitleCase enum value to a human-readable label for display. * "AllowedIssuers" → "Allowed Issuers" */ function humanize(s: string): string { return s.replace(/([A-Z])/g, ' $1').trim(); } interface CreatePolicyModalProps { isOpen: boolean; onClose: () => void; onSuccess: () => void; isLoading: boolean; error: string | null; } function CreatePolicyModal({ isOpen, onClose, onSuccess, isLoading, error }: CreatePolicyModalProps) { const [name, setName] = useState(''); const [type, setType] = useState(POLICY_TYPES[0]); const [severity, setSeverity] = useState('Warning'); const [configStr, setConfigStr] = useState('{}'); const [enabled, setEnabled] = useState(true); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!name.trim()) return; const config = JSON.parse(configStr); await createPolicy({ name: name.trim(), type, severity, config, enabled }); setName(''); setType(POLICY_TYPES[0]); setSeverity('Warning'); setConfigStr('{}'); setEnabled(true); onSuccess(); }; if (!isOpen) return null; return (
e.stopPropagation()}>

Create Policy

{error &&
{error}
}
setName(e.target.value)} className="w-full bg-white border border-surface-border rounded px-3 py-2 text-sm text-ink focus:outline-none focus:border-brand-400" placeholder="e.g., Key Length Enforcement" required />