|
|
@@ -61,6 +61,7 @@ de quitter si des données ont été modifiées.
|
|
|
<!-- Confirmation dialog -->
|
|
|
<LazyLayoutDialog
|
|
|
:show="isConfirmationDialogShowing"
|
|
|
+ :maxWidth="1000"
|
|
|
>
|
|
|
<template #dialogText>
|
|
|
<v-card-title class="text-h5 theme-neutral">
|
|
|
@@ -68,19 +69,24 @@ de quitter si des données ont été modifiées.
|
|
|
</v-card-title>
|
|
|
<v-card-text>
|
|
|
<br>
|
|
|
- <p>{{ $t('quit_without_saving_warning') }}</p>
|
|
|
+ <p>{{ $t('quit_without_saving_warning') }}.</p>
|
|
|
</v-card-text>
|
|
|
</template>
|
|
|
+
|
|
|
<template #dialogBtn>
|
|
|
- <v-btn class="mr-4 submitBtn theme-primary" @click="closeConfirmationDialog">
|
|
|
- {{ $t('back_to_form') }}
|
|
|
- </v-btn>
|
|
|
- <v-btn class="mr-4 submitBtn theme-primary" @click="saveAndQuit">
|
|
|
- {{ $t('save_and_quit') }}
|
|
|
- </v-btn>
|
|
|
- <v-btn class="mr-4 submitBtn theme-danger" @click="cancel">
|
|
|
- {{ $t('quit_form') }}
|
|
|
- </v-btn>
|
|
|
+ <div class="confirmation-dlg-actions">
|
|
|
+ <v-btn class="theme-primary" @click="closeConfirmationDialog">
|
|
|
+ {{ $t('cancel') }}
|
|
|
+ </v-btn>
|
|
|
+
|
|
|
+ <v-btn class="theme-primary" @click="saveAndQuit">
|
|
|
+ {{ $t('save_and_quit') }}
|
|
|
+ </v-btn>
|
|
|
+
|
|
|
+ <v-btn class="theme-danger" @click="cancel">
|
|
|
+ {{ $t('quit_with_no_saving') }}
|
|
|
+ </v-btn>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
</LazyLayoutDialog>
|
|
|
|
|
|
@@ -92,7 +98,7 @@ import {computed, ref} from "@vue/reactivity";
|
|
|
import type {ComputedRef, Ref} from "@vue/reactivity";
|
|
|
import {FORM_FUNCTION, SUBMIT_TYPE, TYPE_ALERT} from "~/types/enum/enums";
|
|
|
import { useFormStore } from "~/stores/form";
|
|
|
-import type {Route, RouteLocationRaw} from "@intlify/vue-router-bridge";
|
|
|
+import type {Route, RouteLocationNormalized, RouteLocationRaw} from "@intlify/vue-router-bridge";
|
|
|
import {useEntityManager} from "~/composables/data/useEntityManager";
|
|
|
import ApiModel from "~/models/ApiModel";
|
|
|
import {usePageStore} from "~/stores/page";
|
|
|
@@ -170,6 +176,7 @@ const i18n = useI18n()
|
|
|
const router = useRouter()
|
|
|
const { em } = useEntityManager()
|
|
|
const { refreshProfile } = useRefreshProfile()
|
|
|
+const route = useRoute();
|
|
|
|
|
|
// Le formulaire est-il valide
|
|
|
const isValid: Ref<boolean> = ref(true)
|
|
|
@@ -180,21 +187,31 @@ const errors: Ref<Array<string>> = ref([])
|
|
|
// Référence au component v-form
|
|
|
const form: Ref = ref(null)
|
|
|
|
|
|
+const formStore = useFormStore()
|
|
|
+
|
|
|
// Le formulaire est-il en lecture seule
|
|
|
const readonly: ComputedRef<boolean> = computed(() => {
|
|
|
- return useFormStore().readonly
|
|
|
+ return formStore.readonly
|
|
|
})
|
|
|
|
|
|
+/**
|
|
|
+ * Si l'utilisateur veut quitter le formulaire sans enregistrer ses modifications,
|
|
|
+ * on affiche la fenêtre de confirmation. En attendant, on garde en mémoire la route qu'il
|
|
|
+ * voulait suivre au cas où il confirmerait.
|
|
|
+ */
|
|
|
+const requestedLeavingRoute: Ref<RouteLocationNormalized | null> = ref(null)
|
|
|
+
|
|
|
// La fenêtre de confirmation est-elle affichée
|
|
|
const isConfirmationDialogShowing: ComputedRef<boolean> = computed(() => {
|
|
|
- return useFormStore().showConfirmToLeave
|
|
|
+ return formStore.showConfirmToLeave
|
|
|
})
|
|
|
|
|
|
/**
|
|
|
* Ferme la fenêtre de confirmation
|
|
|
*/
|
|
|
const closeConfirmationDialog = () => {
|
|
|
- useFormStore().setShowConfirmToLeave(false)
|
|
|
+ requestedLeavingRoute.value = null
|
|
|
+ formStore.setShowConfirmToLeave(false)
|
|
|
}
|
|
|
|
|
|
// ### Actions du formulaire
|
|
|
@@ -251,7 +268,7 @@ const submit = async (next: string|null = null) => {
|
|
|
fields = Object.assign(fields, {[violation['propertyPath']] : violation['message']})
|
|
|
}
|
|
|
|
|
|
- useFormStore().addViolation(fields)
|
|
|
+ formStore.addViolation(fields)
|
|
|
|
|
|
usePageStore().addAlert(TYPE_ALERT.ALERT, ['invalid_form'])
|
|
|
} else {
|
|
|
@@ -280,7 +297,7 @@ const saveAndQuit = async () => {
|
|
|
* @param id
|
|
|
*/
|
|
|
function onSaveAction(route: Route, id: number){
|
|
|
- if (useFormStore().formFunction === FORM_FUNCTION.CREATE) {
|
|
|
+ if (formStore.formFunction === FORM_FUNCTION.CREATE) {
|
|
|
route.path += id
|
|
|
navigateTo(route)
|
|
|
}
|
|
|
@@ -293,23 +310,39 @@ function onSaveAction(route: Route, id: number){
|
|
|
*
|
|
|
* @param route
|
|
|
*/
|
|
|
-function onSaveAndQuitAction(route: Route){
|
|
|
+function onSaveAndQuitAction(route: Route) {
|
|
|
navigateTo(route)
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Avant de quitter le formulaire, si le formulaire a été modifié, on demande confirmation
|
|
|
+ */
|
|
|
+onBeforeRouteLeave((to: RouteLocationNormalized, from: RouteLocationNormalized) => {
|
|
|
+ if (formStore.dirty === true) {
|
|
|
+ requestedLeavingRoute.value = to
|
|
|
+ formStore.setShowConfirmToLeave(true)
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+});
|
|
|
+
|
|
|
/**
|
|
|
* Quitte le formulaire sans enregistrer
|
|
|
*/
|
|
|
const cancel = () => {
|
|
|
setIsDirty(false)
|
|
|
|
|
|
- useFormStore().setShowConfirmToLeave(false)
|
|
|
+ formStore.setShowConfirmToLeave(false)
|
|
|
|
|
|
- em.reset(props.model, props.entity.value)
|
|
|
+ em.reset(props.model, props.entity)
|
|
|
|
|
|
if (router) {
|
|
|
- // @ts-ignore
|
|
|
- router.push(useFormStore().goAfterLeave) // TODO: voir si on peut pas passer ça comme prop du component
|
|
|
+ if (requestedLeavingRoute.value !== null) {
|
|
|
+ navigateTo(requestedLeavingRoute.value)
|
|
|
+ } else {
|
|
|
+ //@ts-ignore
|
|
|
+ router.push(formStore.goAfterLeave) // TODO: voir si on peut pas passer ça comme prop du component
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -367,7 +400,7 @@ const preventSubmit = (e: any) => {
|
|
|
* Applique ou retire l'état dirty (modifié) du formulaire
|
|
|
*/
|
|
|
const setIsDirty = (dirty: boolean) => {
|
|
|
- useFormStore().setDirty(dirty)
|
|
|
+ formStore.setDirty(dirty)
|
|
|
}
|
|
|
|
|
|
defineExpose({ validate })
|
|
|
@@ -378,4 +411,30 @@ defineExpose({ validate })
|
|
|
.btnActions {
|
|
|
text-align: right;
|
|
|
}
|
|
|
+
|
|
|
+.confirmation-dlg-actions {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+}
|
|
|
+
|
|
|
+.confirmation-dlg-actions .v-btn {
|
|
|
+ min-width: 255px;
|
|
|
+ max-width: 255px;
|
|
|
+ margin: 0 8px;
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 960px) {
|
|
|
+ .confirmation-dlg-actions {
|
|
|
+ width: 100%;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .confirmation-dlg-actions .v-btn {
|
|
|
+ min-width: 80%;
|
|
|
+ max-width: 80%;
|
|
|
+ margin: 6px 0 !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
</style>
|