feat(#13): Show form elements depending on other form element values

This commit is contained in:
2025-11-30 18:10:51 +01:00
parent 79fbf7ce1b
commit 9dc690715b
19 changed files with 1187 additions and 116 deletions

View File

@@ -13,10 +13,17 @@ export function useApplicationFormValidator() {
return Object.values(ComplianceStatus)[highestComplianceNumber] ?? ComplianceStatus.NonCritical
}
function validateFormElements(formElements: FormElementDto[]): Map<FormElementId, ComplianceStatus> {
function validateFormElements(
formElements: FormElementDto[],
visibilityMap?: Map<string, boolean>
): Map<FormElementId, ComplianceStatus> {
formElementComplianceMap.value.clear()
formElements.forEach((formElement) => {
if (visibilityMap && visibilityMap.get(formElement.id) === false) {
return
}
if (!complianceCheckableElementTypes.includes(formElement.type)) return
// Reset any previously set compliance status when all options are false

View File

@@ -0,0 +1,83 @@
import type { FormElementDto, VisibilityConditionOperator } from '~~/.api-client'
import { VisibilityConditionOperator as VCOperator, VisibilityConditionType as VCType } from '~~/.api-client'
export function useFormElementVisibility() {
function evaluateVisibility(allFormElements: FormElementDto[]): Map<string, boolean> {
const formElementsByRef = buildFormElementsMap(allFormElements)
const visibilityMap = new Map<string, boolean>()
allFormElements.forEach((element) => {
const isVisible = isElementVisible(element, formElementsByRef, visibilityMap)
visibilityMap.set(element.id, isVisible)
})
return visibilityMap
}
function buildFormElementsMap(formElements: FormElementDto[]): Map<string, FormElementDto> {
const map = new Map<string, FormElementDto>()
formElements.forEach((element) => {
if (element.reference) {
map.set(element.reference, element)
}
})
return map
}
function isElementVisible(
element: FormElementDto,
formElementsByRef: Map<string, FormElementDto>,
_visibilityMap: Map<string, boolean>
): boolean {
if (!element.visibilityCondition) {
return true
}
const condition = element.visibilityCondition
const sourceElement = formElementsByRef.get(condition.sourceFormElementReference)
if (!sourceElement) {
return false
}
const sourceValue = getFormElementValue(sourceElement)
const operator = condition.operator || VCOperator.Equals
const conditionMet = evaluateCondition(sourceValue, condition.expectedValue, operator)
return condition.conditionType === VCType.Show ? conditionMet : !conditionMet
}
function getFormElementValue(element: FormElementDto): string {
const selectedOption = element.options.find((option) => option.value === 'true')
return selectedOption?.label || ''
}
function evaluateCondition(
actualValue: string,
expectedValue: string,
operator: VisibilityConditionOperator
): boolean {
let result: boolean
switch (operator) {
case VCOperator.Equals:
result = actualValue.toLowerCase() === expectedValue.toLowerCase()
return result
case VCOperator.NotEquals:
result = actualValue.toLowerCase() !== expectedValue.toLowerCase()
return result
case VCOperator.IsEmpty:
result = actualValue === ''
return result
case VCOperator.IsNotEmpty:
result = actualValue !== ''
return result
default:
return false
}
}
return {
evaluateVisibility
}
}