1111
1212 <BreadcrumbsWithButtons >
1313 <!-- save and cancle -->
14- <button @click =" $router.back()"
14+ <button @click =" () => {cancelButtonClicked = true; $router.back()} "
1515 class =" flex items-center py-1 px-3 me-2 text-sm font-medium text-lightEditViewButtonText rounded-default focus:outline-none bg-lightEditViewButtonBackground rounded border border-lightEditViewButtonBorder hover:bg-lightEditViewButtonBackgroundHover hover:text-lightEditViewButtonTextHover focus:z-10 focus:ring-4 focus:ring-lightEditViewButtonFocusRing dark:focus:ring-darkEditViewButtonFocusRing dark:bg-darkEditViewButtonBackground dark:text-darkEditViewButtonText dark:border-darkEditViewButtonBorder dark:hover:text-darkEditViewButtonTextHover dark:hover:bg-darkEditViewButtonBackgroundHover"
1616 >
1717 {{ $t('Cancel') }}
@@ -76,8 +76,8 @@ import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
7676import { useCoreStore } from ' @/stores/core' ;
7777import { callAdminForthApi , getCustomComponent ,checkAcessByAllowedActions , initThreeDotsDropdown } from ' @/utils' ;
7878import { IconFloppyDiskSolid } from ' @iconify-prerendered/vue-flowbite' ;
79- import { computed , onMounted , onBeforeMount , ref , type Ref , nextTick , watch } from ' vue' ;
80- import { useRoute , useRouter } from ' vue-router' ;
79+ import { computed , onMounted , onBeforeMount , ref , type Ref , nextTick , watch , onBeforeUnmount } from ' vue' ;
80+ import { useRoute , useRouter , onBeforeRouteLeave } from ' vue-router' ;
8181import { showErrorTost } from ' @/composables/useFrontendApi' ;
8282import ThreeDotsMenu from ' @/components/ThreeDotsMenu.vue' ;
8383import { useAdminforth } from ' @/adminforth' ;
@@ -87,7 +87,7 @@ import type { AdminForthResourceColumn } from '@/types/Back';
8787
8888const { t } = useI18n ();
8989const coreStore = useCoreStore ();
90- const { clearSaveInterceptors, runSaveInterceptors, alert } = useAdminforth ();
90+ const { clearSaveInterceptors, runSaveInterceptors, alert, confirm } = useAdminforth ();
9191
9292const isValid = ref (false );
9393const validating = ref (false );
@@ -101,6 +101,36 @@ const saving = ref(false);
101101
102102const record: Ref <Record <string , any >> = ref ({});
103103
104+ const initialRecord = computed (() => coreStore .record );
105+ const wasSaveSuccessful = ref (false );
106+ const cancelButtonClicked = ref (false );
107+
108+ function onBeforeUnload(event : BeforeUnloadEvent ) {
109+ if (! checkIfWeCanLeavePage ()) {
110+ event .preventDefault ();
111+ event .returnValue = ' ' ;
112+ }
113+ }
114+
115+ function checkIfWeCanLeavePage() {
116+ return wasSaveSuccessful .value || cancelButtonClicked .value || JSON .stringify (record .value ) === JSON .stringify (initialRecord .value );
117+ }
118+
119+ window .addEventListener (' beforeunload' , onBeforeUnload );
120+
121+ onBeforeUnmount (() => {
122+ window .removeEventListener (' beforeunload' , onBeforeUnload );
123+ });
124+
125+ onBeforeRouteLeave (async (to , from , next ) => {
126+ if (! checkIfWeCanLeavePage ()) {
127+ const answer = await confirm ({message: t (' There are unsaved changes. Are you sure you want to leave this page?' ), yes: ' Yes' , no: ' No' });
128+ if (! answer ) return next (false );
129+ }
130+ next ();
131+ });
132+
133+
104134watch (record , (newVal ) => {
105135 console .log (' Record updated:' , newVal );
106136}, { deep: true });
@@ -198,24 +228,28 @@ async function saveRecord() {
198228 if (columnIsUpdated ) {
199229 updates [key ] = record .value [key ];
200230 }
201- saving .value = false ;
202231 }
203-
204- const resp = await callAdminForthApi ({
205- method: ' POST' ,
206- path: ` /update_record ` ,
207- body: {
208- resourceId: route .params .resourceId ,
209- recordId: route .params .primaryKey ,
210- record: updates ,
211- meta: {
212- ... (interceptorConfirmationResult ? { confirmationResult: interceptorConfirmationResult } : {}),
232+ let resp = null ;
233+ try {
234+ resp = await callAdminForthApi ({
235+ method: ' POST' ,
236+ path: ` /update_record ` ,
237+ body: {
238+ resourceId: route .params .resourceId ,
239+ recordId: route .params .primaryKey ,
240+ record: updates ,
241+ meta: {
242+ ... (interceptorConfirmationResult ? { confirmationResult: interceptorConfirmationResult } : {}),
243+ },
213244 },
214- },
215- });
245+ });
246+ } finally {
247+ saving .value = false ;
248+ }
216249 if (resp .error && resp .error !== ' Operation aborted by hook' ) {
217250 showErrorTost (resp .error );
218251 } else {
252+ wasSaveSuccessful .value = true ;
219253 alert ({
220254 message: t (' Record updated successfully' ),
221255 variant: ' success' ,
0 commit comments