From b0003532981dcc4b748c8a051d918dd0e73536a5 Mon Sep 17 00:00:00 2001 From: Thomas Reitz Date: Thu, 12 Mar 2026 18:39:50 +0100 Subject: [PATCH] docs(crm): add Phase 2.1 Custom Fields frontend completion report Documents all new/changed files, architecture decisions, supported field types, admin UI features, and deployment notes for the CRM custom fields frontend integration. Co-Authored-By: Claude Opus 4.6 --- docs/INSIGHT-CRM.md | 84 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/docs/INSIGHT-CRM.md b/docs/INSIGHT-CRM.md index 51ccd92..e915bf4 100644 --- a/docs/INSIGHT-CRM.md +++ b/docs/INSIGHT-CRM.md @@ -2281,13 +2281,79 @@ Das Array enthaelt ALLE definierten Custom Fields fuer den jeweiligen Entity-Typ - **Orphan-Cleanup**: Beim Loeschen eines Contacts/Company/Deal werden zugehoerige Custom-Field-Werte automatisch entfernt. - **isRequired** wird aktuell nur client-seitig ausgewertet (das Flag wird mitgeliefert). Server-seitige Pflichtfeld-Pruefung kann spaeter ergaenzt werden. -### TODO fuer Frontend +### ~~TODO fuer Frontend~~ — ERLEDIGT (2026-03-12) -1. **Admin-Bereich:** CRUD-UI fuer Custom Field Definitionen (pro Entity-Typ: PERSON, COMPANY, DEAL) - - Felder: Label (→ Slug auto), Feldtyp (immutable nach Erstellung), Options-Editor fuer DROPDOWN/MULTI_SELECT, Pflichtfeld-Toggle, Drag&Drop fuer Position -2. **Entity-Detail-Pages:** `customFields`-Array aus Response auslesen und dynamisch rendern - - Pro Feldtyp: Text-Input, Textarea, Number-Input, Date-Picker, Select, Multi-Select, Checkbox, URL-Input -3. **Entity-Formulare:** Custom Fields im Erstellen/Bearbeiten-Formular einbinden - - `PUT /custom-fields/:entityId/values` nach Entity-Speichern aufrufen - - `isRequired` client-seitig validieren -4. **API-Aufrufe:** `GET /custom-fields?entityType=PERSON` fuer Feld-Definitionen, `PUT/GET /custom-fields/:entityId/values` fuer Werte +Alle 4 Punkte wurden im Frontend umgesetzt und deployed (Commit `aaedf68`). + +--- + +## 2026-03-12 | Frontend: Phase 2.1 Custom Fields — Frontend-Integration + +### Was wurde umgesetzt + +Die komplette Frontend-Integration fuer Custom Fields ist implementiert und auf dem Server deployed. + +#### Neue Dateien (2 Dateien) + +``` +packages/frontend/src/crm/ + CustomFieldsDisplay.tsx -- Read-only Anzeige von Custom Fields in Detail-Pages + CustomFieldsForm.tsx -- Editierbare Custom Fields in Entity-Formularen +``` + +#### Geaenderte Dateien (10 Dateien) + +| Datei | Aenderung | +|-------|-----------| +| `types.ts` | Neue Typen: `CustomFieldEntityType`, `CustomFieldType`, `CustomFieldDef`, `CustomFieldValue`, `CustomFieldOption`, Payload-Interfaces. `customFields?: CustomFieldValue[]` zu Contact/Company/Deal hinzugefuegt. | +| `api.ts` | `customFieldsApi`-Objekt mit 7 Methoden: listDefs, getDef, createDef, updateDef, deleteDef, getValues, setValues | +| `hooks.ts` | 6 neue Hooks: `useCustomFieldDefs`, `useCreateCustomFieldDef`, `useUpdateCustomFieldDef`, `useDeleteCustomFieldDef`, `useCustomFieldValues`, `useSetCustomFieldValues`. Query-Key-Factory `crmKeys.customFields`. | +| `settings/CrmSettingsPage.tsx` | Neuer Tab "Eigene Felder" mit `CustomFieldsConfig`-Komponente (~490 Zeilen): Entity-Typ-Filter, Add/Edit-Formular, Options-Editor fuer DROPDOWN/MULTI_SELECT, Sortierung, Loeschen mit Warnung. | +| `contacts/ContactDetailPage.tsx` | `CustomFieldsDisplay` nach Notizen-Sektion eingebunden | +| `companies/CompanyDetailPage.tsx` | `CustomFieldsDisplay` nach Notizen-Sektion eingebunden | +| `deals/DealDetailPage.tsx` | `CustomFieldsDisplay` nach Notizen-Sektion eingebunden | +| `contacts/ContactFormModal.tsx` | `CustomFieldsForm` + `useSetCustomFieldValues` integriert, `saveCustomFields` in onSuccess-Handlers | +| `companies/CompanyFormModal.tsx` | Gleiche Integration wie ContactFormModal | +| `deals/DealFormModal.tsx` | Gleiche Integration wie ContactFormModal | + +### Architektur-Entscheidungen + +1. **Zwei getrennte Komponenten**: `CustomFieldsDisplay` (read-only, Detail-Pages) und `CustomFieldsForm` (editierbar, Formulare) — saubere Trennung von Anzeige und Bearbeitung. +2. **Ref-basierter State in Formularen**: `customFieldValuesRef` statt useState, um unnoetige Re-Renders zu vermeiden. Werte werden erst beim Submit ausgelesen. +3. **Post-Save-Pattern**: Custom Fields werden NACH dem Entity-Save gespeichert (`PUT /custom-fields/:entityId/values`), da bei Create die Entity-ID erst aus der Response kommt. +4. **DROPDOWN Fallback**: `CustomFieldValue` liefert keine Options-Liste (nur Definitionen haben sie). DROPDOWN rendert daher als Text-Input. Verbesserung: Options aus Definitionen nachladen. + +### Unterstuetzte Feldtypen (alle 8) + +| Typ | Display (Detail) | Form (Formular) | +|-----|-------------------|------------------| +| TEXT | String | `` | +| TEXTAREA | Pre-wrap String | `