@omnitend/dashboard-for-laravel 0.43.0 → 0.44.0
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.
- package/dist/components/base/DFormSelect.vue.d.ts +1 -1
- package/dist/components/extended/DXChoiceField.vue.d.ts +3 -3
- package/dist/components/extended/DXForm.vue.d.ts +66 -1
- package/dist/components/extended/DXFormErrorSummary.vue.d.ts +70 -0
- package/dist/components/extended/DXFormField.vue.d.ts +3 -0
- package/dist/components/extended/DXTable.vue.d.ts +20 -0
- package/dist/components/extended/DXTableEditorModal.vue.d.ts +14 -10
- package/dist/composables/useAsyncOptions.d.ts +14 -1
- package/dist/composables/useForm.d.ts +26 -0
- package/dist/dashboard-for-laravel.js +13374 -12823
- package/dist/dashboard-for-laravel.js.map +1 -1
- package/dist/dashboard-for-laravel.umd.cjs +8 -8
- package/dist/dashboard-for-laravel.umd.cjs.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +12 -0
- package/dist/utils/formErrorTargets.d.ts +86 -0
- package/docs/public/api-reference.json +146 -6
- package/docs/public/docs-map.md +3 -2
- package/docs/public/llms.txt +3 -2
- package/package.json +9 -8
- package/resources/css/theme.scss +56 -0
- package/resources/js/components/base/DFormSelect.vue +5 -2
- package/resources/js/components/extended/DXChoiceField.vue +42 -26
- package/resources/js/components/extended/DXField.vue +15 -9
- package/resources/js/components/extended/DXForm.vue +676 -28
- package/resources/js/components/extended/DXFormErrorSummary.vue +232 -0
- package/resources/js/components/extended/DXFormField.vue +11 -2
- package/resources/js/components/extended/DXRepeater.vue +30 -4
- package/resources/js/components/extended/DXTable.vue +36 -4
- package/resources/js/components/extended/DXTableEditorModal.vue +29 -1
- package/resources/js/composables/useAsyncOptions.ts +30 -5
- package/resources/js/composables/useForm.ts +196 -18
- package/resources/js/composables/useResourceEditor.ts +140 -107
- package/resources/js/index.ts +15 -0
- package/resources/js/types/index.ts +13 -0
- package/resources/js/utils/formErrorTargets.ts +317 -0
- package/scripts/mcp-server.mjs +58 -6
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
<template>
|
|
14
14
|
<!-- Full-width span field: delegate entirely to the #span slot, bypassing
|
|
15
15
|
the label and built-in control (and the shell). -->
|
|
16
|
-
|
|
16
|
+
<!-- `data-dx-field-key` (the field's data path: `name`, or
|
|
17
|
+
`lines.0.price` inside a repeater) is how DXForm finds a field to
|
|
18
|
+
scroll to and focus after a failed submit (#194). -->
|
|
19
|
+
<div v-if="field.span" :class="field.class || 'mb-3'" :data-dx-field-key="valuePath">
|
|
17
20
|
<!--
|
|
18
21
|
@slot Replaces the entire field with custom full-width content when `field.span` is set, bypassing the label and built-in control.
|
|
19
22
|
@binding {FieldDefinition} field The field definition being rendered.
|
|
@@ -34,6 +37,7 @@
|
|
|
34
37
|
control that goes inside is chosen by field.type in the default slot. -->
|
|
35
38
|
<DXFieldShell
|
|
36
39
|
v-else
|
|
40
|
+
:data-dx-field-key="valuePath"
|
|
37
41
|
:field="field"
|
|
38
42
|
:form="form"
|
|
39
43
|
:error-key="errorKey"
|
|
@@ -264,7 +268,7 @@
|
|
|
264
268
|
:state="fieldState"
|
|
265
269
|
:disabled="isDisabled || isReadonly || isPlaintext"
|
|
266
270
|
:control-props="controlPropsWithGuards"
|
|
267
|
-
:options-
|
|
271
|
+
:options-pending="optionsPending"
|
|
268
272
|
@update:model-value="setValue"
|
|
269
273
|
/>
|
|
270
274
|
|
|
@@ -780,12 +784,6 @@ const isPlaintext = computed(() => resolveMaybe(props.field.plaintext) ?? false)
|
|
|
780
784
|
|
|
781
785
|
const passwordRevealed = ref(false);
|
|
782
786
|
|
|
783
|
-
// See the template: the searchable select can't render before its options
|
|
784
|
-
// resolve, or it shows the raw id instead of the option's label.
|
|
785
|
-
const searchableOptionsReady = computed(
|
|
786
|
-
() => !props.field.optionsLoader || loadedOptions.value !== null,
|
|
787
|
-
);
|
|
788
|
-
|
|
789
787
|
const isRevealablePassword = computed(
|
|
790
788
|
() =>
|
|
791
789
|
props.field.type === "password" &&
|
|
@@ -856,7 +854,15 @@ const datalistId = useId();
|
|
|
856
854
|
|
|
857
855
|
// ————————————————— async options
|
|
858
856
|
|
|
859
|
-
const { loadedOptions } = useAsyncOptions(
|
|
857
|
+
const { loadedOptions, firstLoadSettled } = useAsyncOptions(
|
|
858
|
+
() => props.field,
|
|
859
|
+
effectiveModel,
|
|
860
|
+
);
|
|
861
|
+
|
|
862
|
+
// The first load has not settled: nothing to label the value with yet. Once
|
|
863
|
+
// it has (even by failing, which leaves the static options), a reload never
|
|
864
|
+
// makes the field pending again: it keeps what it already shows.
|
|
865
|
+
const optionsPending = computed(() => !firstLoadSettled.value);
|
|
860
866
|
|
|
861
867
|
const resolvedOptions = computed<FieldOption[] | undefined>(
|
|
862
868
|
() => loadedOptions.value ?? props.field.options,
|