adminforth 2.4.0-next.331 → 2.4.0-next.332
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.
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
|
|
63
63
|
<ResourceForm
|
|
64
64
|
v-else-if="coreStore.resource"
|
|
65
|
+
ref="resourceFormRef"
|
|
65
66
|
:record="editableRecord"
|
|
66
67
|
:resource="coreStore.resource"
|
|
67
68
|
:adminUser="coreStore.adminUser"
|
|
@@ -93,13 +94,14 @@ import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
|
93
94
|
import { useCoreStore } from '@/stores/core';
|
|
94
95
|
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown } from '@/utils';
|
|
95
96
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
96
|
-
import { computed, onMounted, ref, type Ref } from 'vue';
|
|
97
|
+
import { computed, onMounted, ref, type Ref, nextTick } from 'vue';
|
|
97
98
|
import { useRoute, useRouter } from 'vue-router';
|
|
98
99
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
99
100
|
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
100
101
|
import adminforth from '@/adminforth';
|
|
101
102
|
import { useI18n } from 'vue-i18n';
|
|
102
103
|
import { type AdminForthComponentDeclarationFull } from '@/types/Common.js';
|
|
104
|
+
import type { AdminForthResourceColumn } from '@/types/Back';
|
|
103
105
|
|
|
104
106
|
const { t } = useI18n();
|
|
105
107
|
const coreStore = useCoreStore();
|
|
@@ -116,6 +118,8 @@ const saving = ref(false);
|
|
|
116
118
|
|
|
117
119
|
const record: Ref<Record<string, any>> = ref({});
|
|
118
120
|
|
|
121
|
+
const resourceFormRef = ref<InstanceType<typeof ResourceForm> | null>(null);
|
|
122
|
+
|
|
119
123
|
const editSaveButtonInjection = computed<AdminForthComponentDeclarationFull | null>(() => {
|
|
120
124
|
const raw: any = coreStore.resourceOptions?.pageInjections?.edit?.saveButton as any;
|
|
121
125
|
if (!raw) return null;
|
|
@@ -168,6 +172,8 @@ onMounted(async () => {
|
|
|
168
172
|
async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
169
173
|
if (!isValid.value) {
|
|
170
174
|
validating.value = true;
|
|
175
|
+
await nextTick();
|
|
176
|
+
scrollToInvalidField();
|
|
171
177
|
return;
|
|
172
178
|
} else {
|
|
173
179
|
validating.value = false;
|
|
@@ -223,4 +229,23 @@ async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
|
223
229
|
saving.value = false;
|
|
224
230
|
}
|
|
225
231
|
|
|
232
|
+
function scrollToInvalidField() {
|
|
233
|
+
let columnsWithErrors: {column: AdminForthResourceColumn, error: string}[] = [];
|
|
234
|
+
for (const column of resourceFormRef.value?.editableColumns || []) {
|
|
235
|
+
const error = resourceFormRef.value?.columnError(column);
|
|
236
|
+
if (error) {
|
|
237
|
+
columnsWithErrors.push({column, error});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const errorMessage = t('Failed to save. Please fix errors for the following fields:') + '<ul class="mt-2 list-disc list-inside">' + columnsWithErrors.map(c => `<li><strong>${c.column.label || c.column.name}</strong>: ${c.error}</li>`).join('') + '</ul>';
|
|
241
|
+
adminforth.alert({
|
|
242
|
+
messageHtml: errorMessage,
|
|
243
|
+
variant: 'danger'
|
|
244
|
+
});
|
|
245
|
+
const firstInvalidElement = document.querySelector('.af-invalid-field-message');
|
|
246
|
+
if (firstInvalidElement) {
|
|
247
|
+
firstInvalidElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
226
251
|
</script>
|