adminforth 2.4.0-next.321 → 2.4.0-next.323
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.
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
@update:emptiness="customComponentsEmptiness[$event.name] = $event.value"
|
|
56
56
|
:readonly="readonlyColumns?.includes(column.name)"
|
|
57
57
|
/>
|
|
58
|
-
<div v-if="columnError(column) && validating" class="mt-1 text-xs text-lightInputErrorColor dark:text-darkInputErrorColor">{{ columnError(column) }}</div>
|
|
58
|
+
<div v-if="columnError(column) && validating" class="af-invalid-field-message mt-1 text-xs text-lightInputErrorColor dark:text-darkInputErrorColor">{{ columnError(column) }}</div>
|
|
59
59
|
<div v-if="column.editingNote && column.editingNote[mode]" class="mt-1 text-xs text-lightFormFieldTextColor dark:text-darkFormFieldTextColor">{{ column.editingNote[mode] }}</div>
|
|
60
60
|
</td>
|
|
61
61
|
</tr>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="min-w-40">
|
|
2
|
+
<div v-if="options && options.length" class="min-w-40">
|
|
3
3
|
<div class="cursor-pointer flex items-center justify-between gap-1 block px-4 py-2 text-sm
|
|
4
4
|
bg-lightUserMenuItemBackground hover:bg-lightUserMenuItemBackgroundHover text-lightUserMenuItemText
|
|
5
5
|
hover:text-lightUserMenuItemText dark:bg-darkUserMenuItemBackground dark:hover:bg-darkUserMenuItemBackgroundHover
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
|
|
68
68
|
<ResourceForm
|
|
69
69
|
v-else
|
|
70
|
+
ref="resourceFormRef"
|
|
70
71
|
:record="record"
|
|
71
72
|
:resource="coreStore.resource!"
|
|
72
73
|
@update:record="onUpdateRecord"
|
|
@@ -98,7 +99,7 @@ import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
|
|
|
98
99
|
import { useCoreStore } from '@/stores/core';
|
|
99
100
|
import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown } from '@/utils';
|
|
100
101
|
import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
|
|
101
|
-
import { onMounted, ref, watch } from 'vue';
|
|
102
|
+
import { onMounted, ref, watch, nextTick } from 'vue';
|
|
102
103
|
import { useRoute, useRouter } from 'vue-router';
|
|
103
104
|
import { computed } from 'vue';
|
|
104
105
|
import { showErrorTost } from '@/composables/useFrontendApi';
|
|
@@ -106,6 +107,7 @@ import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
|
|
|
106
107
|
import adminforth from '@/adminforth';
|
|
107
108
|
import { useI18n } from 'vue-i18n';
|
|
108
109
|
import { type AdminForthComponentDeclarationFull } from '@/types/Common.js';
|
|
110
|
+
import type { AdminForthResourceColumn } from '@/types/Back';
|
|
109
111
|
|
|
110
112
|
const isValid = ref(false);
|
|
111
113
|
const validating = ref(false);
|
|
@@ -122,6 +124,8 @@ const coreStore = useCoreStore();
|
|
|
122
124
|
|
|
123
125
|
const { t } = useI18n();
|
|
124
126
|
|
|
127
|
+
const resourceFormRef = ref<InstanceType<typeof ResourceForm> | null>(null);
|
|
128
|
+
|
|
125
129
|
const createSaveButtonInjection = computed<AdminForthComponentDeclarationFull | null>(() => {
|
|
126
130
|
const raw: any = coreStore.resourceOptions?.pageInjections?.create?.saveButton as any;
|
|
127
131
|
if (!raw) return null;
|
|
@@ -180,6 +184,8 @@ onMounted(async () => {
|
|
|
180
184
|
async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
181
185
|
if (!isValid.value) {
|
|
182
186
|
validating.value = true;
|
|
187
|
+
await nextTick();
|
|
188
|
+
scrollToInvalidField();
|
|
183
189
|
return;
|
|
184
190
|
} else {
|
|
185
191
|
validating.value = false;
|
|
@@ -217,5 +223,23 @@ async function saveRecord(opts?: { confirmationResult?: any }) {
|
|
|
217
223
|
}
|
|
218
224
|
}
|
|
219
225
|
|
|
226
|
+
function scrollToInvalidField() {
|
|
227
|
+
let columnsWithErrors: {column: AdminForthResourceColumn, error: string}[] = [];
|
|
228
|
+
for (const column of resourceFormRef.value?.editableColumns || []) {
|
|
229
|
+
const error = resourceFormRef.value?.columnError(column);
|
|
230
|
+
if (error) {
|
|
231
|
+
columnsWithErrors.push({column, error});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
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>';
|
|
235
|
+
adminforth.alert({
|
|
236
|
+
messageHtml: errorMessage,
|
|
237
|
+
variant: 'danger'
|
|
238
|
+
});
|
|
239
|
+
const firstInvalidElement = document.querySelector('.af-invalid-field-message');
|
|
240
|
+
if (firstInvalidElement) {
|
|
241
|
+
firstInvalidElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
242
|
+
}
|
|
243
|
+
}
|
|
220
244
|
|
|
221
245
|
</script>
|