feat(#13): Show form elements depending on other form element values
This commit is contained in:
@@ -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
|
||||
|
||||
83
legalconsenthub/app/composables/useFormElementVisibility.ts
Normal file
83
legalconsenthub/app/composables/useFormElementVisibility.ts
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user