adminforth 2.17.0-next.71 → 2.17.0-next.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
<BreadcrumbsWithButtons>
|
|
14
14
|
<!-- save and cancle -->
|
|
15
|
-
<button @click="$router.back()"
|
|
15
|
+
<button @click="() => {cancelButtonClicked = true; $router.back()}"
|
|
16
16
|
class="af-cancel-button flex items-center py-1 px-3 me-2 text-sm font-medium rounded-default text-lightCreateViewButtonText focus:outline-none bg-lightCreateViewButtonBackground rounded border border-lightCreateViewButtonBorder hover:bg-lightCreateViewButtonBackgroundHover hover:text-lightCreateViewButtonTextHover focus:z-10 focus:ring-4 focus:ring-lightCreateViewButtonFocusRing dark:focus:ring-darkCreateViewButtonFocusRing dark:bg-darkCreateViewButtonBackground dark:text-darkCreateViewButtonText dark:border-darkCreateViewButtonBorder dark:hover:text-darkCreateViewButtonTextHover dark:hover:bg-darkCreateViewButtonBackgroundHover"
|
|
17
17
|
>
|
|
18
18
|
{{ $t('Cancel') }}
|
|
@@ -81,8 +81,8 @@ import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
|
81
81
|
import { useCoreStore } from '@/stores/core';
|
|
82
82
|
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown, checkShowIf } from '@/utils';
|
|
83
83
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
84
|
-
import { onMounted, onBeforeMount, ref, watch, nextTick } from 'vue';
|
|
85
|
-
import { useRoute, useRouter } from 'vue-router';
|
|
84
|
+
import { onMounted, onBeforeMount, onBeforeUnmount, ref, watch, nextTick } from 'vue';
|
|
85
|
+
import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router';
|
|
86
86
|
import { computed } from 'vue';
|
|
87
87
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
88
88
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
@@ -103,7 +103,7 @@ const router = useRouter();
|
|
|
103
103
|
const record = ref({});
|
|
104
104
|
|
|
105
105
|
const coreStore = useCoreStore();
|
|
106
|
-
const { clearSaveInterceptors, runSaveInterceptors, alert } = useAdminforth();
|
|
106
|
+
const { clearSaveInterceptors, runSaveInterceptors, alert, confirm } = useAdminforth();
|
|
107
107
|
|
|
108
108
|
const { t } = useI18n();
|
|
109
109
|
|
|
@@ -113,11 +113,38 @@ const initialValues = ref({});
|
|
|
113
113
|
|
|
114
114
|
const readonlyColumns = ref([]);
|
|
115
115
|
|
|
116
|
+
const cancelButtonClicked = ref(false);
|
|
117
|
+
const wasSaveSuccessful = ref(false);
|
|
116
118
|
|
|
117
119
|
async function onUpdateRecord(newRecord: any) {
|
|
118
120
|
record.value = newRecord;
|
|
119
121
|
}
|
|
120
122
|
|
|
123
|
+
function checkIfWeCanLeavePage() {
|
|
124
|
+
return wasSaveSuccessful.value || cancelButtonClicked.value || JSON.stringify(record.value) === JSON.stringify(initialValues.value);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function onBeforeUnload(event: BeforeUnloadEvent) {
|
|
128
|
+
if (!checkIfWeCanLeavePage()) {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
event.returnValue = '';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
window.addEventListener('beforeunload', onBeforeUnload);
|
|
135
|
+
|
|
136
|
+
onBeforeUnmount(() => {
|
|
137
|
+
window.removeEventListener('beforeunload', onBeforeUnload);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
onBeforeRouteLeave(async (to, from, next) => {
|
|
141
|
+
if (!checkIfWeCanLeavePage()) {
|
|
142
|
+
const answer = await confirm({message: t('There are unsaved changes. Are you sure you want to leave this page?'), yes: 'Yes', no: 'No'});
|
|
143
|
+
if (!answer) return next(false);
|
|
144
|
+
}
|
|
145
|
+
next();
|
|
146
|
+
});
|
|
147
|
+
|
|
121
148
|
onBeforeMount(() => {
|
|
122
149
|
clearSaveInterceptors(route.params.resourceId as string);
|
|
123
150
|
});
|
|
@@ -202,6 +229,7 @@ async function saveRecord() {
|
|
|
202
229
|
showErrorTost(response.error);
|
|
203
230
|
} else {
|
|
204
231
|
saving.value = false;
|
|
232
|
+
wasSaveSuccessful.value = true;
|
|
205
233
|
if (route.query.returnTo) {
|
|
206
234
|
router.push(<string>route.query.returnTo);
|
|
207
235
|
} else {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
<BreadcrumbsWithButtons>
|
|
13
13
|
<!-- save and cancle -->
|
|
14
|
-
<button @click="$router.back()"
|
|
14
|
+
<button @click="() => {cancelButtonClicked = true; $router.back()}"
|
|
15
15
|
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"
|
|
16
16
|
>
|
|
17
17
|
{{ $t('Cancel') }}
|
|
@@ -76,8 +76,8 @@ import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
|
76
76
|
import { useCoreStore } from '@/stores/core';
|
|
77
77
|
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown } from '@/utils';
|
|
78
78
|
import { 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';
|
|
81
81
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
82
82
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
83
83
|
import { useAdminforth } from '@/adminforth';
|
|
@@ -87,7 +87,7 @@ import type { AdminForthResourceColumn } from '@/types/Back';
|
|
|
87
87
|
|
|
88
88
|
const { t } = useI18n();
|
|
89
89
|
const coreStore = useCoreStore();
|
|
90
|
-
const { clearSaveInterceptors, runSaveInterceptors, alert } = useAdminforth();
|
|
90
|
+
const { clearSaveInterceptors, runSaveInterceptors, alert, confirm } = useAdminforth();
|
|
91
91
|
|
|
92
92
|
const isValid = ref(false);
|
|
93
93
|
const validating = ref(false);
|
|
@@ -101,6 +101,36 @@ const saving = ref(false);
|
|
|
101
101
|
|
|
102
102
|
const record: Ref<Record<string, any>> = ref({});
|
|
103
103
|
|
|
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
|
+
|
|
104
134
|
watch(record, (newVal) => {
|
|
105
135
|
console.log('Record updated:', newVal);
|
|
106
136
|
}, { deep: true });
|
|
@@ -198,24 +228,28 @@ async function saveRecord() {
|
|
|
198
228
|
if (columnIsUpdated) {
|
|
199
229
|
updates[key] = record.value[key];
|
|
200
230
|
}
|
|
201
|
-
saving.value = false;
|
|
202
231
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
+
},
|
|
213
244
|
},
|
|
214
|
-
}
|
|
215
|
-
}
|
|
245
|
+
});
|
|
246
|
+
} finally {
|
|
247
|
+
saving.value = false;
|
|
248
|
+
}
|
|
216
249
|
if (resp.error && resp.error !== 'Operation aborted by hook') {
|
|
217
250
|
showErrorTost(resp.error);
|
|
218
251
|
} else {
|
|
252
|
+
wasSaveSuccessful.value = true;
|
|
219
253
|
alert({
|
|
220
254
|
message: t('Record updated successfully'),
|
|
221
255
|
variant: 'success',
|