'use client' /** * Template Rule Editor — Editorial-UI fuer Anwaelte/DSBs. * * Architektur: * - Links: RuleList mit Filter * - Rechts: RuleEditor mit Klassifikation, Condition-Builder, Source-Citation, * Approval-Workflow (draft → review → approved → published) * * Backend: /api/sdk/v1/compliance/template-rules + /template-rule-versions/* */ import { useEffect, useState, useCallback } from 'react' import { useSDK } from '@/lib/sdk' import StepHeader from '@/components/sdk/StepHeader/StepHeader' import { useRuleEditorActions } from './_hooks/useRuleEditorActions' import type { ApprovalHistoryEntry, Classification, Rule, RuleCondition, RuleVersion, } from './_types' import RuleList from './_components/RuleList' import RuleEditor from './_components/RuleEditor' export default function TemplateRuleEditorPage() { useSDK() const actions = useRuleEditorActions() const [rules, setRules] = useState([]) const [liveVersionsByRule, setLiveVersionsByRule] = useState>({}) const [selectedRuleId, setSelectedRuleId] = useState(null) const [selectedVersions, setSelectedVersions] = useState([]) const [selectedHistory, setSelectedHistory] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) // Initial: Regeln laden + Live-Versions const loadRules = useCallback(async () => { setLoading(true) setError(null) try { const list = await actions.listRules() setRules(list) const byRule: Record = {} // Live-Versionen parallel await Promise.all( list.map(async (r) => { try { const versions = await actions.listVersions(r.id) const live = versions.find((v) => v.is_live) byRule[r.id] = live } catch { byRule[r.id] = undefined } }), ) setLiveVersionsByRule(byRule) if (list.length > 0 && !selectedRuleId) { setSelectedRuleId(list[0].id) } } catch (e) { setError((e as Error).message) } finally { setLoading(false) } }, [actions, selectedRuleId]) // Bei Selektions-Wechsel: Versions + History laden const loadSelected = useCallback(async () => { if (!selectedRuleId) { setSelectedVersions([]) setSelectedHistory([]) return } try { const versions = await actions.listVersions(selectedRuleId) setSelectedVersions(versions) const live = versions.find((v) => v.is_live) if (live) { const history = await actions.getApprovalHistory(live.id) setSelectedHistory(history) } else { setSelectedHistory([]) } } catch (e) { setError((e as Error).message) } }, [actions, selectedRuleId]) useEffect(() => { loadRules() }, []) useEffect(() => { loadSelected() }, [selectedRuleId]) const handleCreateDraft = async (payload: { classification: Classification conditions: RuleCondition source_citation: string rationale?: string | null }) => { if (!selectedRuleId) return try { await actions.createDraftVersion(selectedRuleId, payload) await loadSelected() } catch (e) { setError((e as Error).message) } } const handleUpdateDraft = async (versionId: string, patch: { classification?: Classification conditions?: RuleCondition source_citation?: string rationale?: string | null }) => { try { await actions.updateDraftVersion(versionId, patch) await loadSelected() } catch (e) { setError((e as Error).message) } } const handleSubmitForReview = async (versionId: string, changeSummary: string) => { try { await actions.submitForReview(versionId, { change_summary: changeSummary }) await loadSelected() } catch (e) { setError((e as Error).message) } } const handleApprove = async (versionId: string) => { try { await actions.approveVersion(versionId) await loadSelected() } catch (e) { setError((e as Error).message) } } const handlePublish = async (versionId: string) => { try { await actions.publishVersion(versionId) await loadRules() await loadSelected() } catch (e) { setError((e as Error).message) } } const handleReject = async (versionId: string, reason: string) => { try { await actions.rejectVersion(versionId, { rejection_reason: reason }) await loadSelected() } catch (e) { setError((e as Error).message) } } const selectedRule = rules.find((r) => r.id === selectedRuleId) return (
{error && (
{error}
)} {loading && (
Lade Regeln…
)} {!loading && (
{selectedRule ? ( ) : (
Wähle links eine Regel zum Bearbeiten.
)}
)}
) }