@omnitend/dashboard-for-laravel 0.23.0 → 0.24.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.
@@ -85,6 +85,16 @@ export interface FieldDefinition {
85
85
  optionsLoader?: OptionsLoader;
86
86
  /** Re-run `optionsLoader` whenever the form model changes. */
87
87
  reloadOptionsOnChange?: boolean;
88
+ /**
89
+ * For `select` fields: render a **searchable** select — type to filter a
90
+ * long option list, while the model still holds `option.value` (an id).
91
+ *
92
+ * A plain `select` is fine for ten options and unusable for hundreds; the
93
+ * `autocomplete` type filters but models the *typed text*, so it can't back
94
+ * a foreign key (picking "Tesco" gives you `"Tesco"`, not `37`). This is the
95
+ * combination high-frequency data entry against a long list needs.
96
+ */
97
+ searchable?: boolean;
88
98
  /** Number of rows for textarea (default: 3) */
89
99
  rows?: number;
90
100
  /** Step for numeric/currency/percentage inputs */
@@ -254,6 +264,17 @@ export interface FieldDefinition {
254
264
  * `false` to render a bare password input.
255
265
  */
256
266
  revealable?: boolean;
267
+ /**
268
+ * Include this field's value in the submitted payload. Default `true`.
269
+ *
270
+ * Set `false` for a **presentational** field — a header, an alert, an
271
+ * explanatory block rendered via `span` — that exists to lay out the form,
272
+ * not to hold data. Without it, `DXTable`'s edit modal seeds its form from
273
+ * every `editFields` key, so those decorative fields are POSTed alongside
274
+ * the real ones (an empty string, an empty array) purely because they were
275
+ * declared.
276
+ */
277
+ submit?: boolean;
257
278
  /**
258
279
  * Conditionally show or hide this field. When omitted the field is
259
280
  * always visible. Boolean or a function of the form model; evaluated
@@ -1,8 +1,8 @@
1
1
  {
2
- "generated": "2026-07-11T08:44:15.505Z",
2
+ "generated": "2026-07-11T10:04:02.971Z",
3
3
  "package": {
4
4
  "name": "@omnitend/dashboard-for-laravel",
5
- "version": "0.22.0"
5
+ "version": "0.24.0"
6
6
  },
7
7
  "components": {
8
8
  "base": [
@@ -1,7 +1,7 @@
1
1
  # Documentation Map
2
2
 
3
3
  > Auto-generated hierarchical overview of all documentation
4
- > Last updated: 2026-07-11T08:44:15.559Z
4
+ > Last updated: 2026-07-11T10:04:03.051Z
5
5
 
6
6
  This file provides a complete map of all available documentation for AI agents and developers.
7
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnitend/dashboard-for-laravel",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Vue 3 dashboard components for Laravel with Bootstrap Vue Next",
5
5
  "type": "module",
6
6
  "main": "./dist/dashboard-for-laravel.umd.cjs",
@@ -324,6 +324,30 @@
324
324
  v-bind="inputPropsWithGuards"
325
325
  />
326
326
 
327
+ <!-- Searchable select: type to filter a long option list, while the
328
+ model keeps the option's VALUE (an id), not the typed text. The
329
+ `autocomplete` type below models the text, so it can't back a
330
+ foreign key. -->
331
+ <template v-else-if="field.type === 'select' && field.searchable">
332
+ <DAutocomplete
333
+ v-if="searchableOptionsReady"
334
+ v-model="fieldValue"
335
+ :options="resolvedOptions"
336
+ :placeholder="field.placeholder"
337
+ :required="field.required"
338
+ :state="fieldState"
339
+ :disabled="isDisabled || isReadonly || isPlaintext"
340
+ open-on-focus
341
+ v-bind="controlPropsWithGuards"
342
+ />
343
+ <!-- BAutocomplete resolves the input's display text from the model
344
+ AT MOUNT and doesn't re-derive it when `options` arrive later,
345
+ so an async list would leave the raw id showing ("51" instead
346
+ of "Waitrose") — and a long list is exactly the case that loads
347
+ async. Hold the control until the options are in. -->
348
+ <DFormInput v-else placeholder="Loading…" disabled />
349
+ </template>
350
+
327
351
  <!-- Select (sync or async options) -->
328
352
  <DFormSelect
329
353
  v-else-if="field.type === 'select'"
@@ -535,6 +559,7 @@ import DXSwitch from "./DXSwitch.vue";
535
559
  import DFormInvalidFeedback from "../base/DFormInvalidFeedback.vue";
536
560
  import DFormText from "../base/DFormText.vue";
537
561
  import DInputGroup from "../base/DInputGroup.vue";
562
+ import DAutocomplete from "../base/DAutocomplete.vue";
538
563
  import DButton from "../base/DButton.vue";
539
564
  import DXFieldLabel from "./DXFieldLabel.vue";
540
565
  import type { UseFormReturn } from "../../composables/useForm";
@@ -918,6 +943,12 @@ const isPlaintext = computed(() => resolveMaybe(props.field.plaintext) ?? false)
918
943
 
919
944
  const passwordRevealed = ref(false);
920
945
 
946
+ // See the template: the searchable select can't render before its options
947
+ // resolve, or it shows the raw id instead of the option's label.
948
+ const searchableOptionsReady = computed(
949
+ () => !props.field.optionsLoader || loadedOptions.value !== null,
950
+ );
951
+
921
952
  const isRevealablePassword = computed(
922
953
  () =>
923
954
  props.field.type === "password" &&