fix(frontend): Keep dirty state when switching sections
This commit is contained in:
@@ -72,6 +72,16 @@ const { getApplicationFormById, updateApplicationForm } = useApplicationForm()
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { user } = useAuth()
|
const { user } = useAuth()
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
// Prevent whole page from re-rendering when navigating between sections to keep state
|
||||||
|
key: (route) => `${route.params.id}`,
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const sectionIndex = parseInt(route.params.sectionIndex[0])
|
||||||
|
activeStepperItemIndex.value = !isNaN(sectionIndex) ? sectionIndex : 0
|
||||||
|
})
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -85,25 +95,12 @@ const items = [
|
|||||||
const stepper = useTemplateRef('stepper')
|
const stepper = useTemplateRef('stepper')
|
||||||
const activeStepperItemIndex = ref<number>(0)
|
const activeStepperItemIndex = ref<number>(0)
|
||||||
|
|
||||||
const currentFormElementSection = computed<FormElementSectionDto>(() => {
|
const currentFormElementSection = computed<FormElementSectionDto>(
|
||||||
return applicationForm.value?.formElementSections[activeStepperItemIndex.value]
|
() => applicationForm.value?.formElementSections[activeStepperItemIndex.value]
|
||||||
})
|
|
||||||
|
|
||||||
watch(activeStepperItemIndex, async (newActiveStepperItem: number) => {
|
|
||||||
activeStepperItemIndex.value = newActiveStepperItem
|
|
||||||
await navigateTo(`/application-forms/${route.params.id}/${newActiveStepperItem}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => route.path,
|
|
||||||
(_) => {
|
|
||||||
const sectionIndex = parseInt(route.params.sectionIndex[0])
|
|
||||||
activeStepperItemIndex.value = !isNaN(sectionIndex) ? sectionIndex : 0
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const { data, error } = await useAsyncData<ApplicationFormDto>(async () => {
|
const { data, error } = await useAsyncData<ApplicationFormDto>(`application-form-${route.params.id}`, async () => {
|
||||||
|
console.log('Fetching application form with ID:', route.params.id)
|
||||||
return await getApplicationFormById(Array.isArray(route.params.id) ? route.params.id[0] : route.params.id)
|
return await getApplicationFormById(Array.isArray(route.params.id) ? route.params.id[0] : route.params.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -111,14 +108,7 @@ if (error.value) {
|
|||||||
throw createError({ statusText: error.value.message })
|
throw createError({ statusText: error.value.message })
|
||||||
}
|
}
|
||||||
|
|
||||||
const applicationForm = computed<ApplicationFormDto>({
|
const applicationForm = computed<ApplicationFormDto>(() => data?.value as ApplicationFormDto)
|
||||||
get: () => data?.value as ApplicationFormDto,
|
|
||||||
set: (val: ApplicationFormDto) => {
|
|
||||||
if (val && data.value) {
|
|
||||||
data.value = val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const isReadOnly = computed(() => {
|
const isReadOnly = computed(() => {
|
||||||
return applicationForm.value?.createdBy.id !== user.value?.id
|
return applicationForm.value?.createdBy.id !== user.value?.id
|
||||||
@@ -126,7 +116,7 @@ const isReadOnly = computed(() => {
|
|||||||
|
|
||||||
const stepperItems = computed(() => {
|
const stepperItems = computed(() => {
|
||||||
const stepperItems: StepperItem[] = []
|
const stepperItems: StepperItem[] = []
|
||||||
applicationForm.value.formElementSections.forEach((section: FormElementSectionDto, index: number, _) => {
|
applicationForm.value.formElementSections.forEach((section: FormElementSectionDto) => {
|
||||||
stepperItems.push({
|
stepperItems.push({
|
||||||
title: section.shortTitle,
|
title: section.shortTitle,
|
||||||
description: section.description
|
description: section.description
|
||||||
@@ -141,9 +131,7 @@ async function navigateStepper(direction: 'forward' | 'backward') {
|
|||||||
} else {
|
} else {
|
||||||
stepper.value?.prev()
|
stepper.value?.prev()
|
||||||
}
|
}
|
||||||
const targetSectionIndex =
|
await navigateTo(`/application-forms/${route.params.id}/${activeStepperItemIndex.value}`)
|
||||||
direction === 'forward' ? activeStepperItemIndex.value + 1 : activeStepperItemIndex.value - 1
|
|
||||||
await navigateTo(`/application-forms/${route.params.id}/${targetSectionIndex}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onSubmit() {
|
async function onSubmit() {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<UFormField label="Name">
|
<UFormField label="Name">
|
||||||
<UInput v-if="applicationFormTemplate" v-model="applicationFormTemplate.name" />
|
<UInput v-if="applicationFormTemplate" v-model="applicationFormTemplate.name" />
|
||||||
</UFormField>
|
</UFormField>
|
||||||
<UStepper ref="stepper" v-model="activeStepperItem" :items="stepperItems" class="w-full" />
|
<UStepper ref="stepper" v-model="activeStepperItemIndex" :items="stepperItems" class="w-full" />
|
||||||
<h1 v-if="currentFormElementSection?.title" class="text-xl text-pretty font-bold text-highlighted">
|
<h1 v-if="currentFormElementSection?.title" class="text-xl text-pretty font-bold text-highlighted">
|
||||||
{{ currentFormElementSection.title }}
|
{{ currentFormElementSection.title }}
|
||||||
</h1>
|
</h1>
|
||||||
@@ -72,14 +72,14 @@ const { validateFormElements, getHighestComplianceStatus } = useApplicationFormV
|
|||||||
const { userDto, selectedOrganization } = useAuth()
|
const { userDto, selectedOrganization } = useAuth()
|
||||||
|
|
||||||
const stepper = useTemplateRef('stepper')
|
const stepper = useTemplateRef('stepper')
|
||||||
const activeStepperItem = ref<number>(0)
|
const activeStepperItemIndex = ref<number>(0)
|
||||||
|
|
||||||
const currentFormElementSection = computed(() => {
|
const currentFormElementSection = computed(
|
||||||
return applicationFormTemplate.value?.formElementSections[activeStepperItem.value]
|
() => applicationFormTemplate.value?.formElementSections[activeStepperItemIndex.value]
|
||||||
})
|
)
|
||||||
|
|
||||||
watch(activeStepperItem, async (newActiveStepperItem: number) => {
|
watch(activeStepperItemIndex, async (newActiveStepperItem: number) => {
|
||||||
activeStepperItem.value = newActiveStepperItem
|
activeStepperItemIndex.value = newActiveStepperItem
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data, error } = await useAsyncData<PagedApplicationFormDto>(async () => {
|
const { data, error } = await useAsyncData<PagedApplicationFormDto>(async () => {
|
||||||
@@ -113,15 +113,10 @@ async function navigateStepper(direction: 'forward' | 'backward') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const applicationFormTemplate = computed({
|
const applicationFormTemplate = computed(
|
||||||
// TODO: Don't select always the first item, allow user to select a template
|
// TODO: Don't select always the first item, allow user to select a template
|
||||||
get: () => data?.value?.content[0] ?? undefined,
|
() => data?.value?.content[0] ?? undefined
|
||||||
set: (val) => {
|
)
|
||||||
if (val && data.value) {
|
|
||||||
data.value.content[0] = val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const formElements = computed({
|
const formElements = computed({
|
||||||
get: () => currentFormElementSection?.value?.formElements ?? [],
|
get: () => currentFormElementSection?.value?.formElements ?? [],
|
||||||
|
|||||||
Reference in New Issue
Block a user