Files
gremiumhub/legalconsenthub/app/pages/application-forms/[id]/[sectionIndex].vue

158 lines
5.0 KiB
Vue

<template>
<UDashboardPanel id="home">
<template #header>
<UDashboardNavbar :title="$t('common.home')" :ui="{ right: 'gap-3' }">
<template #leading>
<UDashboardSidebarCollapse />
</template>
<template #right>
<UButton
icon="i-lucide-circle-plus"
:label="$t('applicationForms.createNew')"
to="/create"
:disabled="!canWriteApplicationForms"
size="xl"
variant="outline"
color="neutral"
:ui="{
leadingIcon: 'text-primary'
}"
/>
</template>
</UDashboardNavbar>
<UDashboardToolbar>
<UNavigationMenu :items="links" highlight class="-mx-1 flex-1" />
<USeparator orientation="vertical" class="h-8 mx-2" />
<FormValidationIndicator :status="validationStatus" />
</UDashboardToolbar>
</template>
<template #body>
<div class="flex flex-col gap-4 sm:gap-6 lg:gap-12 w-full lg:max-w-4xl mx-auto">
<FormStepperWithNavigation
:form-element-sections="applicationForm.formElementSections"
:initial-section-index="sectionIndex"
:application-form-id="applicationForm.id ?? undefined"
:disabled="isReadOnly"
@save="onSave"
@submit="onSubmit"
@navigate="handleNavigate"
@add-input-form="handleAddInputForm"
@update:form-element-sections="handleFormElementSectionsUpdate"
/>
</div>
</template>
</UDashboardPanel>
</template>
<script setup lang="ts">
import {
ComplianceStatus,
type ApplicationFormDto,
type FormElementDto,
type FormElementSectionDto
} from '~~/.api-client'
import type { FormElementId } from '~~/types/formElement'
import { useApplicationFormValidator } from '~/composables/useApplicationFormValidator'
import { useUserStore } from '~~/stores/useUserStore'
import { useCommentStore } from '~~/stores/useCommentStore'
const route = useRoute()
const toast = useToast()
const { t: $t } = useI18n()
const commentStore = useCommentStore()
definePageMeta({
// Prevent whole page from re-rendering when navigating between sections to keep state
key: (route) => `${route.params.id}`
})
const applicationFormId = Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
const {
applicationForm,
navigationLinks: links,
updateApplicationForm
} = await useApplicationFormNavigation(applicationFormId!)
if (applicationFormId) {
await commentStore.loadCounts(applicationFormId)
}
const { updateApplicationForm: updateForm, submitApplicationForm } = useApplicationForm()
const { validateFormElements, getHighestComplianceStatus } = useApplicationFormValidator()
const { evaluateVisibility } = useFormElementVisibility()
const { canWriteApplicationForms } = usePermissions()
const userStore = useUserStore()
const { user } = storeToRefs(userStore)
const sectionIndex = computed(() => {
const param = route.params.sectionIndex
const index = parseInt(Array.isArray(param) ? param[0]! : (param ?? '0'))
return !isNaN(index) ? index : 0
})
const isReadOnly = computed(() => {
return applicationForm.value?.createdBy?.keycloakId !== user.value?.keycloakId
})
const validationMap = ref<Map<FormElementId, ComplianceStatus> | undefined>()
const validationStatus = ref<ComplianceStatus>(ComplianceStatus.NonCritical)
const allFormElements = computed(() => {
return (
applicationForm.value?.formElementSections?.flatMap((section: FormElementSectionDto) =>
section.formElementSubSections.flatMap((subsection) => subsection.formElements)
) ?? []
)
})
const visibilityMap = computed(() => {
return evaluateVisibility(allFormElements.value)
})
watch(
() => allFormElements.value,
(updatedFormElements: FormElementDto[]) => {
validationMap.value = validateFormElements(updatedFormElements, visibilityMap.value)
validationStatus.value = getHighestComplianceStatus()
},
{ deep: true }
)
async function onSave() {
if (applicationForm.value?.id) {
const updated = await updateForm(applicationForm.value.id, applicationForm.value)
if (updated) {
updateApplicationForm(updated)
toast.add({ title: $t('common.success'), description: $t('applicationForms.saved'), color: 'success' })
}
}
}
async function onSubmit() {
if (applicationForm.value?.id) {
await submitApplicationForm(applicationForm.value.id)
await navigateTo('/')
toast.add({ title: $t('common.success'), description: $t('applicationForms.submitted'), color: 'success' })
}
}
async function handleNavigate({ index }: { direction: 'forward' | 'backward'; index: number }) {
await navigateTo(`/application-forms/${applicationFormId}/${index}`)
}
function handleAddInputForm(updatedForm: ApplicationFormDto | undefined) {
if (updatedForm) {
updateApplicationForm(updatedForm)
}
}
function handleFormElementSectionsUpdate(sections: FormElementSectionDto[]) {
if (applicationForm.value) {
applicationForm.value.formElementSections = sections
}
}
</script>