feat: Document Workflow wiring + Email system consolidation
Document Workflow: - "Als Version speichern" button in Document Generator preview - Creates document + version via /legal-documents/documents API - Saved documents appear in /sdk/workflow module - Status indicator (saving/saved/error) in toolbar Email Consolidation: - consent-management Emails tab now redirects to /sdk/email-templates - Single source of truth for all email templates - Old tab replaced with redirect card explaining the change Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -141,16 +141,24 @@ export default function ConsentManagementPage() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'emails' && (
|
{activeTab === 'emails' && (
|
||||||
<EmailsTab
|
<div className="bg-purple-50 border border-purple-200 rounded-xl p-8 text-center">
|
||||||
apiEmailTemplates={apiEmailTemplates}
|
<div className="w-14 h-14 mx-auto mb-4 bg-purple-100 rounded-xl flex items-center justify-center">
|
||||||
templatesLoading={templatesLoading}
|
<svg className="w-7 h-7 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
savingTemplateId={savingTemplateId}
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||||
savedTemplates={savedTemplates}
|
</svg>
|
||||||
setShowCreateTemplateModal={setShowCreateTemplateModal}
|
</div>
|
||||||
saveApiEmailTemplate={saveApiEmailTemplate}
|
<h3 className="font-semibold text-gray-900 mb-2">E-Mail-Templates wurden zentralisiert</h3>
|
||||||
setPreviewTemplate={setPreviewTemplate}
|
<p className="text-sm text-gray-600 mb-4">
|
||||||
setEditingTemplate={setEditingTemplate}
|
Alle E-Mail-Vorlagen (DSR, Consent, Breach, Training, etc.) werden jetzt zentral
|
||||||
/>
|
im E-Mail-Template-Modul verwaltet — mit Versionierung, Freigabe-Workflow und Audit-Log.
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={() => router.push('/sdk/email-templates')}
|
||||||
|
className="px-6 py-2.5 bg-purple-600 text-white text-sm font-medium rounded-lg hover:bg-purple-700 transition-colors"
|
||||||
|
>
|
||||||
|
Zu E-Mail-Templates
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'gdpr' && (
|
{activeTab === 'gdpr' && (
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ interface GeneratorPreviewTabProps {
|
|||||||
missing: string[]
|
missing: string[]
|
||||||
onCopy: () => void
|
onCopy: () => void
|
||||||
onExportMarkdown: () => void
|
onExportMarkdown: () => void
|
||||||
|
onSaveToWorkflow?: () => void
|
||||||
|
saveStatus?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -87,6 +89,8 @@ export default function GeneratorPreviewTab({
|
|||||||
missing,
|
missing,
|
||||||
onCopy,
|
onCopy,
|
||||||
onExportMarkdown,
|
onExportMarkdown,
|
||||||
|
onSaveToWorkflow,
|
||||||
|
saveStatus,
|
||||||
}: GeneratorPreviewTabProps) {
|
}: GeneratorPreviewTabProps) {
|
||||||
const [viewMode, setViewMode] = useState<'preview' | 'markdown'>('preview')
|
const [viewMode, setViewMode] = useState<'preview' | 'markdown'>('preview')
|
||||||
|
|
||||||
@@ -196,6 +200,22 @@ export default function GeneratorPreviewTab({
|
|||||||
>
|
>
|
||||||
PDF drucken
|
PDF drucken
|
||||||
</button>
|
</button>
|
||||||
|
{onSaveToWorkflow && (
|
||||||
|
<button
|
||||||
|
onClick={onSaveToWorkflow}
|
||||||
|
disabled={saveStatus === 'saving'}
|
||||||
|
className={`px-4 py-1.5 text-xs rounded-lg transition-colors ${
|
||||||
|
saveStatus === 'saved' ? 'bg-green-600 text-white' :
|
||||||
|
saveStatus === 'error' ? 'bg-red-600 text-white' :
|
||||||
|
'bg-indigo-600 text-white hover:bg-indigo-700'
|
||||||
|
} disabled:opacity-50`}
|
||||||
|
>
|
||||||
|
{saveStatus === 'saving' ? 'Speichern...' :
|
||||||
|
saveStatus === 'saved' ? 'Gespeichert!' :
|
||||||
|
saveStatus === 'error' ? 'Fehler' :
|
||||||
|
'Als Version speichern'}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,45 @@ export default function GeneratorSection({
|
|||||||
|
|
||||||
const handleCopy = () => navigator.clipboard.writeText(renderedContent)
|
const handleCopy = () => navigator.clipboard.writeText(renderedContent)
|
||||||
|
|
||||||
|
const [saveStatus, setSaveStatus] = useState<string | null>(null)
|
||||||
|
|
||||||
|
const handleSaveToWorkflow = async () => {
|
||||||
|
setSaveStatus('saving')
|
||||||
|
try {
|
||||||
|
// 1. Create or find document
|
||||||
|
const docRes = await fetch('/api/sdk/v1/compliance/legal-documents/documents', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: template.templateType || 'custom',
|
||||||
|
name: template.documentTitle || 'Dokument',
|
||||||
|
description: `Generiert aus Template: ${template.templateType}`,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
if (!docRes.ok) throw new Error('Dokument konnte nicht erstellt werden')
|
||||||
|
const doc = await docRes.json()
|
||||||
|
|
||||||
|
// 2. Create version
|
||||||
|
const verRes = await fetch('/api/sdk/v1/compliance/legal-documents/versions', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
document_id: doc.id,
|
||||||
|
title: template.documentTitle || 'Dokument',
|
||||||
|
content: renderedContent,
|
||||||
|
language: template.language || 'de',
|
||||||
|
version: '1.0',
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
if (!verRes.ok) throw new Error('Version konnte nicht erstellt werden')
|
||||||
|
setSaveStatus('saved')
|
||||||
|
setTimeout(() => setSaveStatus(null), 3000)
|
||||||
|
} catch (e) {
|
||||||
|
setSaveStatus('error')
|
||||||
|
setTimeout(() => setSaveStatus(null), 3000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleExportMarkdown = () => {
|
const handleExportMarkdown = () => {
|
||||||
const blob = new Blob([renderedContent], { type: 'text/markdown' })
|
const blob = new Blob([renderedContent], { type: 'text/markdown' })
|
||||||
const url = URL.createObjectURL(blob)
|
const url = URL.createObjectURL(blob)
|
||||||
@@ -250,6 +289,8 @@ export default function GeneratorSection({
|
|||||||
missing={missing}
|
missing={missing}
|
||||||
onCopy={handleCopy}
|
onCopy={handleCopy}
|
||||||
onExportMarkdown={handleExportMarkdown}
|
onExportMarkdown={handleExportMarkdown}
|
||||||
|
onSaveToWorkflow={handleSaveToWorkflow}
|
||||||
|
saveStatus={saveStatus}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user