@omnitend/dashboard-for-laravel 0.33.1 → 0.35.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/charts.js +82 -90
- package/dist/charts.js.map +1 -1
- package/dist/charts.umd.cjs +1 -1
- package/dist/charts.umd.cjs.map +1 -1
- package/dist/components/base/DButton.vue.d.ts +1 -1
- package/dist/components/charts/DXBarChart.vue.d.ts +3 -18
- package/dist/components/charts/DXLineChart.vue.d.ts +3 -18
- package/dist/components/charts/useThemedChart.d.ts +35 -0
- package/dist/components/extended/DXChoiceField.vue.d.ts +26 -0
- package/dist/components/extended/DXDashboardSidebar.vue.d.ts +1 -1
- package/dist/components/extended/DXField.vue.d.ts +10 -113
- package/dist/components/extended/DXFieldShell.vue.d.ts +73 -0
- package/dist/components/extended/DXForm.vue.d.ts +28 -6
- package/dist/components/extended/DXNumericField.vue.d.ts +23 -0
- package/dist/components/extended/DXRepeater.vue.d.ts +4 -4
- package/dist/components/extended/DXRepeaterCards.vue.d.ts +45 -0
- package/dist/components/extended/DXTable.vue.d.ts +107 -2
- package/dist/components/extended/DXTableEditorModal.vue.d.ts +22 -2
- package/dist/components/extended/DXUserAvatar.vue.d.ts +1 -1
- package/dist/composables/useAsyncOptions.d.ts +20 -0
- package/dist/composables/useContainerWidth.d.ts +96 -0
- package/dist/composables/useResourceEditor.d.ts +2 -1
- package/dist/dashboard-for-laravel.js +10513 -10443
- package/dist/dashboard-for-laravel.js.map +1 -1
- package/dist/dashboard-for-laravel.umd.cjs +7 -7
- package/dist/dashboard-for-laravel.umd.cjs.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +146 -0
- package/dist/utils/formSchema.d.ts +59 -0
- package/docs/public/api-reference.json +494 -33
- package/docs/public/docs-map.md +1 -1
- package/docs/public/llms.txt +5 -2
- package/package.json +1 -1
- package/resources/css/theme.scss +80 -2
- package/resources/js/components/charts/DXBarChart.vue +4 -43
- package/resources/js/components/charts/DXLineChart.vue +4 -43
- package/resources/js/components/charts/useThemedChart.ts +69 -0
- package/resources/js/components/extended/DXChoiceField.vue +114 -0
- package/resources/js/components/extended/DXDashboardSidebar.vue +1 -1
- package/resources/js/components/extended/DXField.vue +328 -615
- package/resources/js/components/extended/DXFieldShell.vue +124 -0
- package/resources/js/components/extended/DXForm.vue +92 -14
- package/resources/js/components/extended/DXNumericField.vue +144 -0
- package/resources/js/components/extended/DXRepeater.vue +53 -175
- package/resources/js/components/extended/DXRepeaterCards.vue +133 -0
- package/resources/js/components/extended/DXTable.vue +418 -43
- package/resources/js/components/extended/DXTableEditorModal.vue +39 -2
- package/resources/js/components/extended/DXTablePagination.vue +19 -3
- package/resources/js/components/extended/DXTableShell.vue +70 -1
- package/resources/js/composables/defineForm.ts +8 -44
- package/resources/js/composables/useAsyncOptions.ts +61 -0
- package/resources/js/composables/useContainerWidth.ts +303 -0
- package/resources/js/composables/useResourceEditor.ts +24 -38
- package/resources/js/index.ts +40 -0
- package/resources/js/types/index.ts +231 -0
- package/resources/js/utils/formSchema.ts +126 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ComputedRef } from "vue";
|
|
2
|
+
import type { ChartData, ChartDataset, ChartOptions } from "chart.js";
|
|
3
|
+
import { type ChartValueFormat } from "./chartTheme";
|
|
4
|
+
/**
|
|
5
|
+
* Shared props for the value-axis chart wrappers (`DXBarChart`, `DXLineChart`).
|
|
6
|
+
* `DXBarChart` and `DXLineChart` differ ONLY in the chart.js component they
|
|
7
|
+
* render and the palette kind — everything else (theming, option-merge,
|
|
8
|
+
* legend-default) is identical, and lived duplicated in both SFCs (#135).
|
|
9
|
+
*/
|
|
10
|
+
export interface ThemedChartProps<TType extends "bar" | "line"> {
|
|
11
|
+
/** X-axis category labels. */
|
|
12
|
+
labels: string[];
|
|
13
|
+
/** Chart.js datasets. Colours are themed when a dataset omits them. */
|
|
14
|
+
datasets: ChartDataset<TType>[];
|
|
15
|
+
/** Chart.js options; deep-merged over the themed defaults. */
|
|
16
|
+
options?: ChartOptions<TType>;
|
|
17
|
+
/** Format value-axis ticks and tooltips. */
|
|
18
|
+
valueFormat?: ChartValueFormat;
|
|
19
|
+
/** Currency symbol for valueFormat: "currency" (default "£"). */
|
|
20
|
+
currencySymbol?: string;
|
|
21
|
+
/** Locale for number formatting. */
|
|
22
|
+
locale?: string;
|
|
23
|
+
/** Show the legend (default: only when there is more than one dataset). */
|
|
24
|
+
showLegend?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The themed-chart body shared by `DXBarChart` and `DXLineChart`: applies the
|
|
28
|
+
* data-viz palette to un-coloured datasets and deep-merges the consumer's
|
|
29
|
+
* `options` over the dashboard-friendly defaults. Pass the reactive `props`
|
|
30
|
+
* object (property access stays reactive inside the computeds).
|
|
31
|
+
*/
|
|
32
|
+
export declare function useThemedChart<TType extends "bar" | "line">(type: TType, props: ThemedChartProps<TType>): {
|
|
33
|
+
chartData: ComputedRef<ChartData<TType>>;
|
|
34
|
+
mergedOptions: ComputedRef<ChartOptions<TType>>;
|
|
35
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FieldDefinition, FieldOption } from "../../types";
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Field definition (type select/radio/checkbox-group + `searchable`). */
|
|
4
|
+
field: FieldDefinition;
|
|
5
|
+
/** Current model value. */
|
|
6
|
+
modelValue: any;
|
|
7
|
+
/** Resolved options (async-loaded or static). */
|
|
8
|
+
options?: FieldOption[];
|
|
9
|
+
/** Validation state passed to the control. */
|
|
10
|
+
state?: boolean | null;
|
|
11
|
+
/** Pre-merged disabled state (`isDisabled || isReadonly || isPlaintext`). */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** Escape-hatch control props, already guard-merged by DXField. */
|
|
14
|
+
controlProps?: Record<string, any>;
|
|
15
|
+
/**
|
|
16
|
+
* Whether async options have resolved (a searchable select must not render
|
|
17
|
+
* before its options load, or it shows the raw id instead of the label).
|
|
18
|
+
*/
|
|
19
|
+
optionsReady?: boolean;
|
|
20
|
+
}
|
|
21
|
+
declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
22
|
+
"update:modelValue": (value: any) => any;
|
|
23
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
24
|
+
"onUpdate:modelValue"?: ((value: any) => any) | undefined;
|
|
25
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
26
|
+
export default _default;
|
|
@@ -46,8 +46,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}
|
|
|
46
46
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
47
47
|
onToggle?: (() => any) | undefined;
|
|
48
48
|
}>, {
|
|
49
|
-
title: string;
|
|
50
49
|
hidden: boolean;
|
|
50
|
+
title: string;
|
|
51
51
|
collapsed: boolean;
|
|
52
52
|
collapsibleGroups: boolean;
|
|
53
53
|
autoCollapseInactiveGroups: boolean;
|
|
@@ -42,142 +42,39 @@ declare var __VLS_1: {
|
|
|
42
42
|
model: any;
|
|
43
43
|
value: any;
|
|
44
44
|
update: typeof setValue;
|
|
45
|
-
},
|
|
45
|
+
}, __VLS_6: {
|
|
46
46
|
field: FieldDefinition;
|
|
47
47
|
model: any;
|
|
48
|
-
},
|
|
48
|
+
}, __VLS_8: {
|
|
49
49
|
field: FieldDefinition;
|
|
50
50
|
model: any;
|
|
51
|
-
|
|
52
|
-
update: typeof setValue;
|
|
53
|
-
}, __VLS_22: {
|
|
54
|
-
field: FieldDefinition;
|
|
55
|
-
model: any;
|
|
56
|
-
}, __VLS_27: {
|
|
57
|
-
field: FieldDefinition;
|
|
58
|
-
model: any;
|
|
59
|
-
}, __VLS_32: {
|
|
51
|
+
}, __VLS_10: {
|
|
60
52
|
field: FieldDefinition;
|
|
61
53
|
model: any;
|
|
62
54
|
value: any;
|
|
63
55
|
update: typeof setValue;
|
|
64
|
-
},
|
|
65
|
-
field: FieldDefinition;
|
|
66
|
-
model: any;
|
|
67
|
-
}, __VLS_48: {
|
|
68
|
-
field: FieldDefinition;
|
|
69
|
-
model: any;
|
|
70
|
-
}, __VLS_59: {
|
|
71
|
-
field: FieldDefinition;
|
|
72
|
-
model: any;
|
|
73
|
-
}, __VLS_61: {
|
|
74
|
-
field: FieldDefinition;
|
|
75
|
-
model: any;
|
|
76
|
-
value: any;
|
|
77
|
-
update: typeof setValue;
|
|
78
|
-
}, __VLS_72: {
|
|
79
|
-
field: FieldDefinition;
|
|
80
|
-
model: any;
|
|
81
|
-
}, __VLS_77: {
|
|
82
|
-
field: FieldDefinition;
|
|
83
|
-
model: any;
|
|
84
|
-
}, __VLS_82: {
|
|
85
|
-
field: FieldDefinition;
|
|
86
|
-
model: any;
|
|
87
|
-
value: any;
|
|
88
|
-
update: typeof setValue;
|
|
89
|
-
}, __VLS_93: {
|
|
90
|
-
field: FieldDefinition;
|
|
91
|
-
model: any;
|
|
92
|
-
}, __VLS_98: {
|
|
93
|
-
field: FieldDefinition;
|
|
94
|
-
model: any;
|
|
95
|
-
}, __VLS_119: {
|
|
56
|
+
}, __VLS_52: {
|
|
96
57
|
option: FieldOption;
|
|
97
58
|
on: boolean;
|
|
98
|
-
},
|
|
99
|
-
field: FieldDefinition;
|
|
100
|
-
model: any;
|
|
101
|
-
}, __VLS_129: {
|
|
102
|
-
field: FieldDefinition;
|
|
103
|
-
model: any;
|
|
104
|
-
}, __VLS_144: {
|
|
59
|
+
}, __VLS_64: {
|
|
105
60
|
row: any;
|
|
106
61
|
index: number;
|
|
107
62
|
fields: FieldDefinition[];
|
|
108
63
|
remove: () => void;
|
|
109
64
|
path: string;
|
|
110
|
-
}, __VLS_146: {
|
|
111
|
-
field: FieldDefinition;
|
|
112
|
-
model: any;
|
|
113
|
-
}, __VLS_151: {
|
|
114
|
-
field: FieldDefinition;
|
|
115
|
-
model: any;
|
|
116
|
-
}, __VLS_162: {
|
|
117
|
-
field: FieldDefinition;
|
|
118
|
-
model: any;
|
|
119
|
-
}, __VLS_164: {
|
|
120
|
-
field: FieldDefinition;
|
|
121
|
-
model: any;
|
|
122
|
-
value: any;
|
|
123
|
-
update: typeof setValue;
|
|
124
|
-
}, __VLS_230: {
|
|
125
|
-
field: FieldDefinition;
|
|
126
|
-
model: any;
|
|
127
|
-
}, __VLS_235: {
|
|
128
|
-
field: FieldDefinition;
|
|
129
|
-
model: any;
|
|
130
65
|
};
|
|
131
66
|
type __VLS_Slots = {} & {
|
|
132
67
|
span?: (props: typeof __VLS_1) => any;
|
|
133
68
|
} & {
|
|
134
|
-
hint?: (props: typeof
|
|
135
|
-
} & {
|
|
136
|
-
value?: (props: typeof __VLS_11) => any;
|
|
137
|
-
} & {
|
|
138
|
-
info?: (props: typeof __VLS_22) => any;
|
|
139
|
-
} & {
|
|
140
|
-
hint?: (props: typeof __VLS_27) => any;
|
|
141
|
-
} & {
|
|
142
|
-
value?: (props: typeof __VLS_32) => any;
|
|
143
|
-
} & {
|
|
144
|
-
info?: (props: typeof __VLS_43) => any;
|
|
145
|
-
} & {
|
|
146
|
-
hint?: (props: typeof __VLS_48) => any;
|
|
147
|
-
} & {
|
|
148
|
-
hint?: (props: typeof __VLS_59) => any;
|
|
149
|
-
} & {
|
|
150
|
-
value?: (props: typeof __VLS_61) => any;
|
|
151
|
-
} & {
|
|
152
|
-
info?: (props: typeof __VLS_72) => any;
|
|
153
|
-
} & {
|
|
154
|
-
hint?: (props: typeof __VLS_77) => any;
|
|
155
|
-
} & {
|
|
156
|
-
value?: (props: typeof __VLS_82) => any;
|
|
157
|
-
} & {
|
|
158
|
-
info?: (props: typeof __VLS_93) => any;
|
|
159
|
-
} & {
|
|
160
|
-
hint?: (props: typeof __VLS_98) => any;
|
|
161
|
-
} & {
|
|
162
|
-
'switch-list-item'?: (props: typeof __VLS_119) => any;
|
|
163
|
-
} & {
|
|
164
|
-
info?: (props: typeof __VLS_124) => any;
|
|
165
|
-
} & {
|
|
166
|
-
hint?: (props: typeof __VLS_129) => any;
|
|
167
|
-
} & {
|
|
168
|
-
'repeater-row'?: (props: typeof __VLS_144) => any;
|
|
169
|
-
} & {
|
|
170
|
-
info?: (props: typeof __VLS_146) => any;
|
|
171
|
-
} & {
|
|
172
|
-
hint?: (props: typeof __VLS_151) => any;
|
|
69
|
+
hint?: (props: typeof __VLS_6) => any;
|
|
173
70
|
} & {
|
|
174
|
-
|
|
71
|
+
info?: (props: typeof __VLS_8) => any;
|
|
175
72
|
} & {
|
|
176
|
-
value?: (props: typeof
|
|
73
|
+
value?: (props: typeof __VLS_10) => any;
|
|
177
74
|
} & {
|
|
178
|
-
|
|
75
|
+
'switch-list-item'?: (props: typeof __VLS_52) => any;
|
|
179
76
|
} & {
|
|
180
|
-
|
|
77
|
+
'repeater-row'?: (props: typeof __VLS_64) => any;
|
|
181
78
|
};
|
|
182
79
|
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
183
80
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { UseFormReturn } from "../../composables/useForm";
|
|
2
|
+
import type { FieldDefinition } from "../../types";
|
|
3
|
+
interface Props {
|
|
4
|
+
/** The field definition (for `field.help` and slot props). */
|
|
5
|
+
field: FieldDefinition;
|
|
6
|
+
/** Form instance owning the field's errors. */
|
|
7
|
+
form: UseFormReturn<any>;
|
|
8
|
+
/** Error key for validation lookups. */
|
|
9
|
+
errorKey: string;
|
|
10
|
+
/** Model passed to `hint`/`info` slot props. */
|
|
11
|
+
model?: any;
|
|
12
|
+
/**
|
|
13
|
+
* Layout shape. `group` = DFormGroup root with a label column; `plain` =
|
|
14
|
+
* plain div, the control owning its own inline label/heading.
|
|
15
|
+
*/
|
|
16
|
+
mode: "group" | "plain";
|
|
17
|
+
/** Wrapper class (`field.class || 'mb-3'`). */
|
|
18
|
+
wrapperClass?: string;
|
|
19
|
+
/** BFormGroup attrs (horizontal label-cols etc.); group mode only. */
|
|
20
|
+
groupAttrs?: Record<string, any>;
|
|
21
|
+
/** Resolved label text (group mode). Always supplied by DXField. */
|
|
22
|
+
label: string;
|
|
23
|
+
/** Resolved info text for the label popover (group mode). */
|
|
24
|
+
info?: string;
|
|
25
|
+
/** Skip the label column entirely (group mode). */
|
|
26
|
+
hideLabel?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the hint sits in the label column (horizontal) rather than below
|
|
29
|
+
* the control. Group mode only; plain mode always renders the hint below.
|
|
30
|
+
*/
|
|
31
|
+
hintInLabel?: boolean;
|
|
32
|
+
/** Resolved hint text (fallback when no `hint` slot is supplied). */
|
|
33
|
+
resolvedHint?: string;
|
|
34
|
+
}
|
|
35
|
+
declare var __VLS_8: {
|
|
36
|
+
field: FieldDefinition;
|
|
37
|
+
model: any;
|
|
38
|
+
}, __VLS_10: {}, __VLS_15: {
|
|
39
|
+
field: FieldDefinition;
|
|
40
|
+
model: any;
|
|
41
|
+
}, __VLS_20: {
|
|
42
|
+
field: FieldDefinition;
|
|
43
|
+
model: any;
|
|
44
|
+
}, __VLS_25: {}, __VLS_30: {
|
|
45
|
+
field: FieldDefinition;
|
|
46
|
+
model: any;
|
|
47
|
+
}, __VLS_35: {
|
|
48
|
+
field: FieldDefinition;
|
|
49
|
+
model: any;
|
|
50
|
+
};
|
|
51
|
+
type __VLS_Slots = {} & {
|
|
52
|
+
hint?: (props: typeof __VLS_8) => any;
|
|
53
|
+
} & {
|
|
54
|
+
default?: (props: typeof __VLS_10) => any;
|
|
55
|
+
} & {
|
|
56
|
+
info?: (props: typeof __VLS_15) => any;
|
|
57
|
+
} & {
|
|
58
|
+
hint?: (props: typeof __VLS_20) => any;
|
|
59
|
+
} & {
|
|
60
|
+
default?: (props: typeof __VLS_25) => any;
|
|
61
|
+
} & {
|
|
62
|
+
info?: (props: typeof __VLS_30) => any;
|
|
63
|
+
} & {
|
|
64
|
+
hint?: (props: typeof __VLS_35) => any;
|
|
65
|
+
};
|
|
66
|
+
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
67
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
68
|
+
export default _default;
|
|
69
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
70
|
+
new (): {
|
|
71
|
+
$slots: S;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
@@ -44,12 +44,33 @@ interface Props {
|
|
|
44
44
|
*/
|
|
45
45
|
cardTabs?: boolean;
|
|
46
46
|
/**
|
|
47
|
-
* Form-wide field layout:
|
|
48
|
-
*
|
|
49
|
-
* `
|
|
50
|
-
*
|
|
47
|
+
* Form-wide field layout:
|
|
48
|
+
*
|
|
49
|
+
* - `"vertical"` (default) — label above input, always.
|
|
50
|
+
* - `"horizontal"` — label left, input right, always.
|
|
51
|
+
* - `"auto"` — horizontal when the form's **own container** is at least
|
|
52
|
+
* `layoutThreshold` px wide, vertical below that. Container-driven, not
|
|
53
|
+
* viewport-driven: a page narrowed by the dashboard sidebar, or a form
|
|
54
|
+
* inside a modal, stacks even though the window is wide (which no
|
|
55
|
+
* Bootstrap media query can see).
|
|
56
|
+
*
|
|
57
|
+
* Overridable per-field via `field.layout`. A field with `span: true`
|
|
58
|
+
* always renders full-width, regardless of layout.
|
|
51
59
|
*/
|
|
52
|
-
layout?: "vertical" | "horizontal";
|
|
60
|
+
layout?: "vertical" | "horizontal" | "auto";
|
|
61
|
+
/**
|
|
62
|
+
* Container width (px) at or above which `layout: "auto"` goes horizontal.
|
|
63
|
+
* Ignored for the explicit `"vertical"`/`"horizontal"` layouts.
|
|
64
|
+
*
|
|
65
|
+
* Default 640, measured rather than guessed: with the default 3-column
|
|
66
|
+
* label the label's text area is `containerWidth / 4 - 18` px, so 640 gives
|
|
67
|
+
* it 142px — enough for a ~20-character label ("Unit price (ex VAT)"
|
|
68
|
+
* measures 128px at the theme's label font) to stay on one line, with the
|
|
69
|
+
* control column still 474px. Below ~584px that label starts wrapping,
|
|
70
|
+
* which is the cramped-label symptom this exists to avoid. Raise it if your
|
|
71
|
+
* labels run longer, or lower `labelCols` instead.
|
|
72
|
+
*/
|
|
73
|
+
layoutThreshold?: number;
|
|
53
74
|
/**
|
|
54
75
|
* Label column width for horizontal layout (mirrors BFormGroup's
|
|
55
76
|
* `labelCols`/`labelCols*` props). Overridable per-field via
|
|
@@ -73,13 +94,14 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
|
|
|
73
94
|
onSubmit?: (() => any) | undefined;
|
|
74
95
|
"onUpdate:activeTab"?: ((value: number) => any) | undefined;
|
|
75
96
|
}>, {
|
|
76
|
-
layout: "vertical" | "horizontal";
|
|
97
|
+
layout: "vertical" | "horizontal" | "auto";
|
|
77
98
|
card: boolean;
|
|
78
99
|
submitText: string;
|
|
79
100
|
submitLoadingText: string;
|
|
80
101
|
showSubmit: boolean;
|
|
81
102
|
autoErrorTab: boolean;
|
|
82
103
|
cardTabs: boolean;
|
|
104
|
+
layoutThreshold: number;
|
|
83
105
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
84
106
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
85
107
|
export default _default;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FieldDefinition } from "../../types";
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Field definition (type currency/percentage/number + numeric options). */
|
|
4
|
+
field: FieldDefinition;
|
|
5
|
+
/** Current model value. */
|
|
6
|
+
modelValue: any;
|
|
7
|
+
/** Validation state passed to the control. */
|
|
8
|
+
state?: boolean | null;
|
|
9
|
+
/** Disabled state (`isDisabled`). */
|
|
10
|
+
isDisabled?: boolean;
|
|
11
|
+
/** Readonly state (`isReadonly`). */
|
|
12
|
+
isReadonly?: boolean;
|
|
13
|
+
/** Plaintext (display-only) state (`isPlaintext`). */
|
|
14
|
+
isPlaintext?: boolean;
|
|
15
|
+
/** Escape-hatch input props, already guard-merged by DXField. */
|
|
16
|
+
inputProps?: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
19
|
+
"update:modelValue": (value: any) => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
21
|
+
"onUpdate:modelValue"?: ((value: any) => any) | undefined;
|
|
22
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
export default _default;
|
|
@@ -16,13 +16,13 @@ declare var __VLS_1: {
|
|
|
16
16
|
fields: FieldDefinition[];
|
|
17
17
|
remove: () => void;
|
|
18
18
|
path: string;
|
|
19
|
-
},
|
|
19
|
+
}, __VLS_27: {
|
|
20
20
|
row: any;
|
|
21
21
|
index: number;
|
|
22
22
|
fields: FieldDefinition[];
|
|
23
23
|
remove: () => void;
|
|
24
24
|
path: string;
|
|
25
|
-
},
|
|
25
|
+
}, __VLS_32: {
|
|
26
26
|
row: any;
|
|
27
27
|
index: number;
|
|
28
28
|
fields: FieldDefinition[];
|
|
@@ -32,9 +32,9 @@ declare var __VLS_1: {
|
|
|
32
32
|
type __VLS_Slots = {} & {
|
|
33
33
|
row?: (props: typeof __VLS_1) => any;
|
|
34
34
|
} & {
|
|
35
|
-
row?: (props: typeof
|
|
35
|
+
row?: (props: typeof __VLS_27) => any;
|
|
36
36
|
} & {
|
|
37
|
-
row?: (props: typeof
|
|
37
|
+
row?: (props: typeof __VLS_32) => any;
|
|
38
38
|
};
|
|
39
39
|
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
40
40
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { UseFormReturn } from "../../composables/useForm";
|
|
2
|
+
import type { FieldDefinition } from "../../types";
|
|
3
|
+
interface Props {
|
|
4
|
+
/** Rows shown in the UI, each paired with its real (unfiltered) array index. */
|
|
5
|
+
visibleRows: Array<{
|
|
6
|
+
row: any;
|
|
7
|
+
index: number;
|
|
8
|
+
}>;
|
|
9
|
+
/** Sub-field definitions for a row. */
|
|
10
|
+
subFields: FieldDefinition[];
|
|
11
|
+
/** Form instance owning the repeater array. */
|
|
12
|
+
form: UseFormReturn<any>;
|
|
13
|
+
/** The repeater field definition (for `showRowIndex` and `addLabel`). */
|
|
14
|
+
field: FieldDefinition;
|
|
15
|
+
/** Minimum rows — the Remove button disables at this count. */
|
|
16
|
+
minItems: number;
|
|
17
|
+
/** Maximum rows — the Add button disables at this count. */
|
|
18
|
+
maxItems: number | undefined;
|
|
19
|
+
/** Stable v-for key for a row (owned by DXRepeater — row identity, not index). */
|
|
20
|
+
rowKey: (row: any, fallbackPosition: number) => string | number;
|
|
21
|
+
/** Dot path into form.data for a row at the given true index. */
|
|
22
|
+
rowPath: (index: number) => string;
|
|
23
|
+
/** Remove the row at the given true index (respects minItems / soft-delete). */
|
|
24
|
+
removeRow: (index: number) => void;
|
|
25
|
+
/** Append a fresh row (respects maxItems). */
|
|
26
|
+
addRow: () => void;
|
|
27
|
+
}
|
|
28
|
+
declare var __VLS_1: {
|
|
29
|
+
row: any;
|
|
30
|
+
index: number;
|
|
31
|
+
fields: FieldDefinition[];
|
|
32
|
+
remove: () => void;
|
|
33
|
+
path: string;
|
|
34
|
+
};
|
|
35
|
+
type __VLS_Slots = {} & {
|
|
36
|
+
row?: (props: typeof __VLS_1) => any;
|
|
37
|
+
};
|
|
38
|
+
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
39
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
40
|
+
export default _default;
|
|
41
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
42
|
+
new (): {
|
|
43
|
+
$slots: S;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FieldDefinition, LabelCols } from "../../types";
|
|
1
2
|
export type FilterType = 'text' | 'select' | 'number' | 'date' | false;
|
|
2
3
|
export interface FilterOption {
|
|
3
4
|
value: string;
|
|
@@ -66,6 +67,21 @@ export interface TableField {
|
|
|
66
67
|
filter?: FilterType;
|
|
67
68
|
filterOptions?: FilterOption[];
|
|
68
69
|
filterPlaceholder?: string;
|
|
70
|
+
/**
|
|
71
|
+
* For a `select` filter on a **client-side** table: derive the dropdown's
|
|
72
|
+
* options from the distinct values present in the loaded rows. Defaults to
|
|
73
|
+
* `true` — with no `filterOptions` and no server `filterValues` the
|
|
74
|
+
* alternative is an empty dropdown, which can only ever be a bug.
|
|
75
|
+
*
|
|
76
|
+
* Set `false` to opt out (e.g. a column whose raw values are opaque ids you
|
|
77
|
+
* would rather label yourself via `filterOptions`).
|
|
78
|
+
*
|
|
79
|
+
* Explicit `filterOptions` and server-supplied `filterValues` still WIN, in
|
|
80
|
+
* that order. Provider/API and Inertia modes ignore this flag: they only
|
|
81
|
+
* ever hold one page of rows, so there is no complete value set to derive
|
|
82
|
+
* from (see `getFieldFilterOptions`).
|
|
83
|
+
*/
|
|
84
|
+
deriveFilterOptions?: boolean;
|
|
69
85
|
/**
|
|
70
86
|
* Fixed width for this column, applied via a `<colgroup>` `<col>`. A number
|
|
71
87
|
* is treated as pixels (`200` → `200px`); a string is used verbatim
|
|
@@ -117,6 +133,35 @@ export interface EditTab {
|
|
|
117
133
|
/** Lazy load tab content (optional, default false) */
|
|
118
134
|
lazy?: boolean;
|
|
119
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Discriminated data-source descriptor (#130). The additive, type-safe
|
|
138
|
+
* replacement for the legacy `items` / `provider` / `apiUrl` / `inertiaUrl` /
|
|
139
|
+
* `clientSide` prop matrix, in which every prop was independently optional and
|
|
140
|
+
* the mode was inferred by precedence — so invalid combinations compiled and
|
|
141
|
+
* some were silently ignored.
|
|
142
|
+
*
|
|
143
|
+
* Pass ONE `source`: the mode is explicit and its required companion prop is
|
|
144
|
+
* enforced by the compiler (`{ mode: 'provider' }` without a `provider` won't
|
|
145
|
+
* type-check). The legacy props still work and take over when `source` is
|
|
146
|
+
* omitted; a future major removes them with a codemod (#130 Phase 3).
|
|
147
|
+
*
|
|
148
|
+
* `apiAdapter` (transport translation) and `pagination` (server-supplied page
|
|
149
|
+
* metadata) stay sibling props — they're orthogonal to which mode is active.
|
|
150
|
+
*/
|
|
151
|
+
export type DXTableSource<TItem = any> = {
|
|
152
|
+
mode: 'client';
|
|
153
|
+
items: TItem[];
|
|
154
|
+
} | {
|
|
155
|
+
mode: 'provider';
|
|
156
|
+
provider: BTableProvider<TItem>;
|
|
157
|
+
} | {
|
|
158
|
+
mode: 'api';
|
|
159
|
+
url: string;
|
|
160
|
+
} | {
|
|
161
|
+
mode: 'inertia';
|
|
162
|
+
items: TItem[];
|
|
163
|
+
url?: string;
|
|
164
|
+
};
|
|
120
165
|
export interface Props<TItem = any> {
|
|
121
166
|
/** Table title */
|
|
122
167
|
title?: string;
|
|
@@ -131,6 +176,13 @@ export interface Props<TItem = any> {
|
|
|
131
176
|
/** Adapts the built-in provider's request params / response body to a
|
|
132
177
|
* backend convention that differs from dfl's (see DXTableApiAdapter). */
|
|
133
178
|
apiAdapter?: DXTableApiAdapter;
|
|
179
|
+
/**
|
|
180
|
+
* Discriminated data-source (#130) — the type-safe alternative to the
|
|
181
|
+
* legacy `items` / `provider` / `apiUrl` / `inertiaUrl` / `clientSide`
|
|
182
|
+
* props. When set it WINS over those props; when omitted, the legacy props
|
|
183
|
+
* apply unchanged. See `DXTableSource`.
|
|
184
|
+
*/
|
|
185
|
+
source?: DXTableSource<TItem>;
|
|
134
186
|
/** Table field definitions */
|
|
135
187
|
fields: TableField[];
|
|
136
188
|
/** Sort configuration (v-model support) */
|
|
@@ -196,16 +248,64 @@ export interface Props<TItem = any> {
|
|
|
196
248
|
* borderless variant — the same header, filter row, table and pagination
|
|
197
249
|
* rendered directly on the page background (no card border/shadow), for
|
|
198
250
|
* data-heavy admin index pages that read as busy inside a card.
|
|
251
|
+
*
|
|
252
|
+
* The table renders FLUSH to the card border (rows and stripes reach the
|
|
253
|
+
* edge) while the header and pagination stay padded, which requires the card
|
|
254
|
+
* to clip to its radius (`overflow: hidden`).
|
|
255
|
+
*
|
|
256
|
+
* **Consequence for slot content:** anything you render into a slot that
|
|
257
|
+
* positions itself OUTSIDE the card and does not teleport is clipped at the
|
|
258
|
+
* card edge. Library components are unaffected — `DDropdown` teleports to
|
|
259
|
+
* `<body>` by default, and the column-filter menus position themselves
|
|
260
|
+
* `fixed` — so this only bites a hand-rolled `position: absolute` overlay
|
|
261
|
+
* (a custom popover in a `cell(<key>)` or `#header` slot). Teleport it, or
|
|
262
|
+
* use `:card="false"`. Narrowing the clip to the table region is tracked
|
|
263
|
+
* as #166.
|
|
199
264
|
*/
|
|
200
265
|
card?: boolean;
|
|
201
|
-
/**
|
|
202
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Form field definitions for edit modal (if provided, enables edit on row
|
|
268
|
+
* click). `import type` is erased at compile time, so this creates no
|
|
269
|
+
* runtime import cycle (#131).
|
|
270
|
+
*/
|
|
271
|
+
editFields?: FieldDefinition[];
|
|
203
272
|
/** Tab definitions for organizing edit modal content */
|
|
204
273
|
editTabs?: EditTab[];
|
|
205
274
|
/** Edit modal title (can be function for dynamic titles) */
|
|
206
275
|
editModalTitle?: string | ((item: any) => string);
|
|
207
276
|
/** Edit modal size */
|
|
208
277
|
editModalSize?: 'sm' | 'md' | 'lg' | 'xl';
|
|
278
|
+
/**
|
|
279
|
+
* Field layout for the edit/create modal's form, forwarded to its `DXForm`
|
|
280
|
+
* ("vertical" = label above input, "horizontal" = label left). Defaults to
|
|
281
|
+
* **"horizontal"** to match the Omni Tend form convention (a raw modal form
|
|
282
|
+
* previously fell back to DXForm's vertical default, which looked out of
|
|
283
|
+
* place next to horizontal page forms). Pass `"vertical"` to opt out.
|
|
284
|
+
*
|
|
285
|
+
* `"auto"` hands the decision to `DXForm`'s container-width observer, which
|
|
286
|
+
* measures the FORM rather than the window — so a modal narrowed by its own
|
|
287
|
+
* breakpoint stacks to vertical even on a wide viewport, where a media query
|
|
288
|
+
* would still report "plenty of room". See `useContainerWidth`.
|
|
289
|
+
*/
|
|
290
|
+
editLayout?: 'vertical' | 'horizontal' | 'auto';
|
|
291
|
+
/**
|
|
292
|
+
* Label column width for the edit modal's horizontal layout, forwarded to
|
|
293
|
+
* `DXForm`'s `labelCols` (a single width or a per-breakpoint object). Only
|
|
294
|
+
* meaningful when `editLayout` is "horizontal".
|
|
295
|
+
*/
|
|
296
|
+
editLabelCols?: LabelCols;
|
|
297
|
+
/**
|
|
298
|
+
* Wrap the edit/create modal's form in a bordered card. Off by default (the
|
|
299
|
+
* modal body already provides a boundary); opt in for a more contained,
|
|
300
|
+
* panelled look around a tabbed edit form.
|
|
301
|
+
*/
|
|
302
|
+
editCard?: boolean;
|
|
303
|
+
/** Override the modal's Save button label (default: "Save {item}"). */
|
|
304
|
+
saveText?: string;
|
|
305
|
+
/** Override the modal's Create button label (default: "Create {item}"). */
|
|
306
|
+
createText?: string;
|
|
307
|
+
/** Override the modal's Delete button label (default: "Delete {item}"). */
|
|
308
|
+
deleteText?: string;
|
|
209
309
|
/** API endpoint pattern for updates (e.g., "/api/products/:id") */
|
|
210
310
|
editUrl?: string;
|
|
211
311
|
/**
|
|
@@ -323,6 +423,11 @@ declare const _default: <T = any>(__VLS_props: NonNullable<Awaited<typeof __VLS_
|
|
|
323
423
|
}>): void;
|
|
324
424
|
attrs: any;
|
|
325
425
|
slots: {
|
|
426
|
+
[x: `head-end(${string})`]: ((props: {
|
|
427
|
+
field: TableField;
|
|
428
|
+
label: string;
|
|
429
|
+
}) => any) | undefined;
|
|
430
|
+
} & {
|
|
326
431
|
[x: string]: ((props: any) => any) | undefined;
|
|
327
432
|
} & {
|
|
328
433
|
[x: string]: ((props: any) => any) | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EditTab } from "./DXTable.vue";
|
|
2
|
+
import type { LabelCols } from "../../types";
|
|
2
3
|
interface Props {
|
|
3
4
|
/** Whether the modal is open (v-model:show). */
|
|
4
5
|
show: boolean;
|
|
@@ -26,6 +27,25 @@ interface Props {
|
|
|
26
27
|
pendingAction: 'save' | 'delete' | null;
|
|
27
28
|
/** Delete endpoint — gates the Delete button. */
|
|
28
29
|
deleteUrl?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Field layout forwarded to the modal's DXForm (defaults handled upstream).
|
|
32
|
+
* Includes `"auto"`, which lets the form stack to vertical when the MODAL is
|
|
33
|
+
* narrow even though the viewport is wide — the container-query case a
|
|
34
|
+
* viewport media query cannot see.
|
|
35
|
+
*/
|
|
36
|
+
layout?: 'vertical' | 'horizontal' | 'auto';
|
|
37
|
+
/** Label column width forwarded to DXForm (horizontal layout). */
|
|
38
|
+
labelCols?: LabelCols;
|
|
39
|
+
/** Wrap the modal form in a card (opt-in — off by default). */
|
|
40
|
+
card?: boolean;
|
|
41
|
+
/** Singular item noun for the default button labels (e.g. "customer"). */
|
|
42
|
+
itemName?: string;
|
|
43
|
+
/** Override the Save button label (edit mode). */
|
|
44
|
+
saveText?: string;
|
|
45
|
+
/** Override the Create button label (create mode). */
|
|
46
|
+
createText?: string;
|
|
47
|
+
/** Override the Delete button label. */
|
|
48
|
+
deleteText?: string;
|
|
29
49
|
}
|
|
30
50
|
declare var __VLS_21: `edit-value(${string})`, __VLS_22: {
|
|
31
51
|
item: any;
|
|
@@ -59,16 +79,16 @@ type __VLS_Slots = {} & {
|
|
|
59
79
|
[K in NonNullable<typeof __VLS_37>]?: (props: typeof __VLS_38) => any;
|
|
60
80
|
};
|
|
61
81
|
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
82
|
+
cancel: () => any;
|
|
62
83
|
delete: () => any;
|
|
63
84
|
"update:activeTab": (value: number) => any;
|
|
64
85
|
save: () => any;
|
|
65
|
-
cancel: () => any;
|
|
66
86
|
"update:show": (value: boolean) => any;
|
|
67
87
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
88
|
+
onCancel?: (() => any) | undefined;
|
|
68
89
|
onDelete?: (() => any) | undefined;
|
|
69
90
|
"onUpdate:activeTab"?: ((value: number) => any) | undefined;
|
|
70
91
|
onSave?: (() => any) | undefined;
|
|
71
|
-
onCancel?: (() => any) | undefined;
|
|
72
92
|
"onUpdate:show"?: ((value: boolean) => any) | undefined;
|
|
73
93
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
74
94
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
@@ -22,11 +22,11 @@ type __VLS_Slots = {} & {
|
|
|
22
22
|
default?: (props: typeof __VLS_1) => any;
|
|
23
23
|
};
|
|
24
24
|
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
25
|
+
initial: string;
|
|
25
26
|
user: {
|
|
26
27
|
name: string;
|
|
27
28
|
[key: string]: any;
|
|
28
29
|
} | null;
|
|
29
|
-
initial: string;
|
|
30
30
|
badge: boolean;
|
|
31
31
|
badgeVariant: ColorVariant;
|
|
32
32
|
badgeLabel: string;
|