major(fullstack): Add dynamic section spawning, removal of app. form create DTOs,

This commit is contained in:
2025-12-15 19:12:00 +01:00
parent 7bacff967e
commit 844ab8661c
47 changed files with 1283 additions and 511 deletions

115
CLAUDE.md
View File

@@ -106,10 +106,10 @@ Application Form
│ ├── processingPurpose
│ └── employeeDataCategory
└── visibilityCondition (FormElementVisibilityCondition)
├── conditionType (SHOW, HIDE)
├── formElementConditionType (SHOW, HIDE)
├── sourceFormElementReference (string - reference key of source element)
├── expectedValue (string - value to compare against)
└── operator (EQUALS, NOT_EQUALS, IS_EMPTY, IS_NOT_EMPTY)
├── formElementExpectedValue (string - value to compare against)
└── formElementOperator (EQUALS, NOT_EQUALS, IS_EMPTY, IS_NOT_EMPTY)
```
**Dynamic Addition**: Users can add new form elements to any subsection at runtime via the API endpoint:
@@ -237,10 +237,10 @@ Form elements can be conditionally shown or hidden based on the values of other
}
],
"visibilityCondition": {
"conditionType": "SHOW",
"formElementConditionType": "SHOW",
"sourceFormElementReference": "testphase_findet_statt",
"expectedValue": "Ja",
"operator": "EQUALS"
"formElementExpectedValue": "Ja",
"formElementOperator": "EQUALS"
}
}
```
@@ -269,6 +269,106 @@ In this example, the "Testphase Zeitraum" field is only visible when the form el
- For checkboxes, checked = "true", unchecked = "false"
- Test visibility conditions thoroughly before deployment
### 11. Dynamic Section Spawning
Form elements can trigger the dynamic creation of full sections based on user input. This enables complex workflows where additional form sections appear when certain conditions are met.
**Key Concepts**:
- **Section Templates**: Pre-defined section blueprints marked with `isTemplate: true`
- **Spawn Triggers**: Rules on form elements that define when to spawn a section template
- **Clonable Elements**: Form elements that can be duplicated by users (e.g., adding multiple modules)
- **Title Interpolation**: Section titles can include placeholders like `{{triggerValue}}`
**Section Template Properties**:
- `isTemplate: boolean` - If true, section is a template (excluded from display/PDF)
- `templateReference: string` - Unique identifier for the template
- `titleTemplate: string` - Title with placeholder (e.g., "Modul: {{triggerValue}}")
- `spawnedFromElementReference: string` - Links spawned instance to trigger element
**Form Element Properties for Spawning**:
- `sectionSpawnTrigger`: Defines spawn conditions
- `templateReference`: Which template to spawn
- `sectionSpawnConditionType`: SHOW or HIDE
- `sectionSpawnExpectedValue`: Value to trigger spawning
- `sectionSpawnOperator`: EQUALS, NOT_EQUALS, IS_EMPTY, IS_NOT_EMPTY
- `isClonable: boolean` - Shows "Add another" button when true
**Example - Clonable Module with Dynamic Section**:
```json
{
"reference": "modul_1",
"title": "Modulname",
"type": "TEXTAREA",
"isClonable": true,
"sectionSpawnTrigger": {
"templateReference": "module_details_template",
"sectionSpawnConditionType": "SHOW",
"sectionSpawnOperator": "IS_NOT_EMPTY"
}
}
```
**Example - Template Section**:
```json
{
"title": "Moduldetails",
"isTemplate": true,
"templateReference": "module_details_template",
"titleTemplate": "Modul: {{triggerValue}}",
"formElementSubSections": [
{
"title": "Modulinformationen",
"formElements": [...]
}
]
}
```
**Client-Side Spawning Flow**:
1. User fills trigger element (e.g., types "SAP Finance")
2. Frontend clones template into CreateFormElementSectionDto (no ID)
3. Title interpolated: "Modul: SAP Finance"
4. User clicks "Add another" → new element clone created
5. User saves → backend generates IDs
**Element Cloning Implementation**:
- **Deep Cloning**: Elements are deep-cloned using `JSON.parse(JSON.stringify())` to avoid shared references between cloned elements
- **Reference Generation**: Cloned elements get auto-generated references (e.g., `modul_1``modul_2``modul_3`)
- **Value Reset**: TEXTAREA and TEXTFIELD elements have their values reset to empty string when cloned
- **ID Removal**: Cloned elements don't have IDs (they're `CreateFormElementDto`), IDs are generated by the backend on save
- **Independent Instances**: Each cloned element is completely independent - updating one doesn't affect others
**Spawn Trigger Evaluation**:
- Spawn triggers are evaluated when form element values change
- Each element with a unique reference can spawn its own section independently
- Multiple spawns are handled sequentially using `resultSections` to ensure correct state
- Spawned sections are linked to their trigger element via `spawnedFromElementReference`
**Element Update Matching**:
- Form element updates use unique identifiers (`id` or `reference`) instead of array indices
- This prevents cross-element updates when elements are filtered by visibility
- Matching priority: `id` (if present) → `reference` (fallback)
**Backend Behavior**:
- Template sections (`isTemplate=true`) are filtered out from PDF/HTML exports
- Spawned sections are included in exports with their interpolated titles
- Versioning captures all template and spawn trigger fields
**Frontend Composables**:
- `useSectionSpawning`: Handles spawn trigger evaluation and template cloning
- `useClonableElements`: Handles element cloning with reference generation and deep cloning
---
## Project Structure
@@ -303,9 +403,12 @@ legalconsenthub/
│ │ ├── complianceMap.ts
│ │ ├── useApplicationFormNavigation.ts
│ │ ├── useApplicationFormValidator.ts
│ │ ├── useClonableElements.ts
│ │ ├── useFormElementManagement.ts
│ │ ├── useFormElementVisibility.ts
│ │ ├── useFormStepper.ts
│ │ ├── usePermissions.ts
│ │ ├── useSectionSpawning.ts
│ │ └── useServerHealth.ts
│ ├── layouts/ # Layout components
│ │ ├── auth.vue