major(fullstack): Add dynamic section spawning, removal of app. form create DTOs,
This commit is contained in:
115
CLAUDE.md
115
CLAUDE.md
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user