@omnitend/dashboard-for-laravel 0.33.0 → 0.34.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/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 +91 -2
- package/dist/components/extended/DXTableEditorModal.vue.d.ts +17 -2
- package/dist/components/extended/DXUserAvatar.vue.d.ts +1 -1
- package/dist/composables/useAsyncOptions.d.ts +20 -0
- package/dist/composables/useResourceEditor.d.ts +2 -1
- package/dist/dashboard-for-laravel.js +9987 -10054
- 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 +3 -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 +464 -30
- package/docs/public/docs-map.md +1 -1
- package/docs/public/llms.txt +5 -2
- package/package.json +1 -1
- 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/DXField.vue +328 -615
- package/resources/js/components/extended/DXFieldShell.vue +124 -0
- package/resources/js/components/extended/DXForm.vue +9 -5
- 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 +250 -37
- package/resources/js/components/extended/DXTableEditorModal.vue +34 -2
- package/resources/js/composables/defineForm.ts +8 -44
- package/resources/js/composables/useAsyncOptions.ts +61 -0
- package/resources/js/composables/useResourceEditor.ts +24 -38
- package/resources/js/index.ts +33 -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
|
+
};
|
|
@@ -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,8 +1,28 @@
|
|
|
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;
|
|
4
5
|
text: string;
|
|
5
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Adapts the built-in `apiUrl` provider's request/response to a backend whose
|
|
9
|
+
* convention differs from dfl's (spatie query-builder params, an envelope
|
|
10
|
+
* without the `{data, pagination}` shape). The sanctioned replacement for the
|
|
11
|
+
* axios-interceptor bridges #132 removed the route for: `request` maps the
|
|
12
|
+
* outgoing params (its return is what goes on the wire); `response` maps the
|
|
13
|
+
* body back, receiving the ORIGINAL dfl-shape params (`page`, `perPage`, …)
|
|
14
|
+
* so it can synthesize paginator metadata a foreign envelope lacks.
|
|
15
|
+
*/
|
|
16
|
+
export interface DXTableApiAdapter {
|
|
17
|
+
request?: (params: Record<string, any>) => Record<string, any>;
|
|
18
|
+
response?: (body: any, context: {
|
|
19
|
+
params: Record<string, any>;
|
|
20
|
+
}) => {
|
|
21
|
+
data: any[];
|
|
22
|
+
pagination?: PaginationData;
|
|
23
|
+
filterValues?: Record<string, string[]>;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
6
26
|
export interface TableField {
|
|
7
27
|
key: string;
|
|
8
28
|
label?: string;
|
|
@@ -98,6 +118,35 @@ export interface EditTab {
|
|
|
98
118
|
/** Lazy load tab content (optional, default false) */
|
|
99
119
|
lazy?: boolean;
|
|
100
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Discriminated data-source descriptor (#130). The additive, type-safe
|
|
123
|
+
* replacement for the legacy `items` / `provider` / `apiUrl` / `inertiaUrl` /
|
|
124
|
+
* `clientSide` prop matrix, in which every prop was independently optional and
|
|
125
|
+
* the mode was inferred by precedence — so invalid combinations compiled and
|
|
126
|
+
* some were silently ignored.
|
|
127
|
+
*
|
|
128
|
+
* Pass ONE `source`: the mode is explicit and its required companion prop is
|
|
129
|
+
* enforced by the compiler (`{ mode: 'provider' }` without a `provider` won't
|
|
130
|
+
* type-check). The legacy props still work and take over when `source` is
|
|
131
|
+
* omitted; a future major removes them with a codemod (#130 Phase 3).
|
|
132
|
+
*
|
|
133
|
+
* `apiAdapter` (transport translation) and `pagination` (server-supplied page
|
|
134
|
+
* metadata) stay sibling props — they're orthogonal to which mode is active.
|
|
135
|
+
*/
|
|
136
|
+
export type DXTableSource<TItem = any> = {
|
|
137
|
+
mode: 'client';
|
|
138
|
+
items: TItem[];
|
|
139
|
+
} | {
|
|
140
|
+
mode: 'provider';
|
|
141
|
+
provider: BTableProvider<TItem>;
|
|
142
|
+
} | {
|
|
143
|
+
mode: 'api';
|
|
144
|
+
url: string;
|
|
145
|
+
} | {
|
|
146
|
+
mode: 'inertia';
|
|
147
|
+
items: TItem[];
|
|
148
|
+
url?: string;
|
|
149
|
+
};
|
|
101
150
|
export interface Props<TItem = any> {
|
|
102
151
|
/** Table title */
|
|
103
152
|
title?: string;
|
|
@@ -109,6 +158,16 @@ export interface Props<TItem = any> {
|
|
|
109
158
|
provider?: BTableProvider<TItem>;
|
|
110
159
|
/** API endpoint URL for auto-provider mode (alternative to provider function) */
|
|
111
160
|
apiUrl?: string;
|
|
161
|
+
/** Adapts the built-in provider's request params / response body to a
|
|
162
|
+
* backend convention that differs from dfl's (see DXTableApiAdapter). */
|
|
163
|
+
apiAdapter?: DXTableApiAdapter;
|
|
164
|
+
/**
|
|
165
|
+
* Discriminated data-source (#130) — the type-safe alternative to the
|
|
166
|
+
* legacy `items` / `provider` / `apiUrl` / `inertiaUrl` / `clientSide`
|
|
167
|
+
* props. When set it WINS over those props; when omitted, the legacy props
|
|
168
|
+
* apply unchanged. See `DXTableSource`.
|
|
169
|
+
*/
|
|
170
|
+
source?: DXTableSource<TItem>;
|
|
112
171
|
/** Table field definitions */
|
|
113
172
|
fields: TableField[];
|
|
114
173
|
/** Sort configuration (v-model support) */
|
|
@@ -176,14 +235,44 @@ export interface Props<TItem = any> {
|
|
|
176
235
|
* data-heavy admin index pages that read as busy inside a card.
|
|
177
236
|
*/
|
|
178
237
|
card?: boolean;
|
|
179
|
-
/**
|
|
180
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Form field definitions for edit modal (if provided, enables edit on row
|
|
240
|
+
* click). `import type` is erased at compile time, so this creates no
|
|
241
|
+
* runtime import cycle (#131).
|
|
242
|
+
*/
|
|
243
|
+
editFields?: FieldDefinition[];
|
|
181
244
|
/** Tab definitions for organizing edit modal content */
|
|
182
245
|
editTabs?: EditTab[];
|
|
183
246
|
/** Edit modal title (can be function for dynamic titles) */
|
|
184
247
|
editModalTitle?: string | ((item: any) => string);
|
|
185
248
|
/** Edit modal size */
|
|
186
249
|
editModalSize?: 'sm' | 'md' | 'lg' | 'xl';
|
|
250
|
+
/**
|
|
251
|
+
* Field layout for the edit/create modal's form, forwarded to its `DXForm`
|
|
252
|
+
* ("vertical" = label above input, "horizontal" = label left). Defaults to
|
|
253
|
+
* **"horizontal"** to match the Omni Tend form convention (a raw modal form
|
|
254
|
+
* previously fell back to DXForm's vertical default, which looked out of
|
|
255
|
+
* place next to horizontal page forms). Pass `"vertical"` to opt out.
|
|
256
|
+
*/
|
|
257
|
+
editLayout?: 'vertical' | 'horizontal';
|
|
258
|
+
/**
|
|
259
|
+
* Label column width for the edit modal's horizontal layout, forwarded to
|
|
260
|
+
* `DXForm`'s `labelCols` (a single width or a per-breakpoint object). Only
|
|
261
|
+
* meaningful when `editLayout` is "horizontal".
|
|
262
|
+
*/
|
|
263
|
+
editLabelCols?: LabelCols;
|
|
264
|
+
/**
|
|
265
|
+
* Wrap the edit/create modal's form in a bordered card. Off by default (the
|
|
266
|
+
* modal body already provides a boundary); opt in for a more contained,
|
|
267
|
+
* panelled look around a tabbed edit form.
|
|
268
|
+
*/
|
|
269
|
+
editCard?: boolean;
|
|
270
|
+
/** Override the modal's Save button label (default: "Save {item}"). */
|
|
271
|
+
saveText?: string;
|
|
272
|
+
/** Override the modal's Create button label (default: "Create {item}"). */
|
|
273
|
+
createText?: string;
|
|
274
|
+
/** Override the modal's Delete button label (default: "Delete {item}"). */
|
|
275
|
+
deleteText?: string;
|
|
187
276
|
/** API endpoint pattern for updates (e.g., "/api/products/:id") */
|
|
188
277
|
editUrl?: string;
|
|
189
278
|
/**
|
|
@@ -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,20 @@ interface Props {
|
|
|
26
27
|
pendingAction: 'save' | 'delete' | null;
|
|
27
28
|
/** Delete endpoint — gates the Delete button. */
|
|
28
29
|
deleteUrl?: string;
|
|
30
|
+
/** Field layout forwarded to the modal's DXForm (defaults handled upstream). */
|
|
31
|
+
layout?: 'vertical' | 'horizontal';
|
|
32
|
+
/** Label column width forwarded to DXForm (horizontal layout). */
|
|
33
|
+
labelCols?: LabelCols;
|
|
34
|
+
/** Wrap the modal form in a card (opt-in — off by default). */
|
|
35
|
+
card?: boolean;
|
|
36
|
+
/** Singular item noun for the default button labels (e.g. "customer"). */
|
|
37
|
+
itemName?: string;
|
|
38
|
+
/** Override the Save button label (edit mode). */
|
|
39
|
+
saveText?: string;
|
|
40
|
+
/** Override the Create button label (create mode). */
|
|
41
|
+
createText?: string;
|
|
42
|
+
/** Override the Delete button label. */
|
|
43
|
+
deleteText?: string;
|
|
29
44
|
}
|
|
30
45
|
declare var __VLS_21: `edit-value(${string})`, __VLS_22: {
|
|
31
46
|
item: any;
|
|
@@ -59,16 +74,16 @@ type __VLS_Slots = {} & {
|
|
|
59
74
|
[K in NonNullable<typeof __VLS_37>]?: (props: typeof __VLS_38) => any;
|
|
60
75
|
};
|
|
61
76
|
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
77
|
+
cancel: () => any;
|
|
62
78
|
delete: () => any;
|
|
63
79
|
"update:activeTab": (value: number) => any;
|
|
64
80
|
save: () => any;
|
|
65
|
-
cancel: () => any;
|
|
66
81
|
"update:show": (value: boolean) => any;
|
|
67
82
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
83
|
+
onCancel?: (() => any) | undefined;
|
|
68
84
|
onDelete?: (() => any) | undefined;
|
|
69
85
|
"onUpdate:activeTab"?: ((value: number) => any) | undefined;
|
|
70
86
|
onSave?: (() => any) | undefined;
|
|
71
|
-
onCancel?: (() => any) | undefined;
|
|
72
87
|
"onUpdate:show"?: ((value: boolean) => any) | undefined;
|
|
73
88
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
74
89
|
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;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ComputedRef, type Ref } from "vue";
|
|
2
|
+
import type { FieldDefinition, FieldOption } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Async option loading for a `DXField`: runs `field.optionsLoader` on mount and
|
|
5
|
+
* (when `field.reloadOptionsOnChange` is set) whenever the model changes,
|
|
6
|
+
* exposing the loaded options. A monotonic request token guards against
|
|
7
|
+
* out-of-order responses clobbering newer ones; loader failures are swallowed
|
|
8
|
+
* so the last good options (or the static `field.options` fallback) stay put.
|
|
9
|
+
*
|
|
10
|
+
* Extracted verbatim from DXField's inline logic (#135) — behaviour unchanged.
|
|
11
|
+
* `getField` is an accessor (props aren't destructurable without losing
|
|
12
|
+
* reactivity); `effectiveModel` is the model passed to the loader.
|
|
13
|
+
*/
|
|
14
|
+
export interface UseAsyncOptionsReturn {
|
|
15
|
+
/** Options returned by the most recent successful load, or null if none yet. */
|
|
16
|
+
loadedOptions: Ref<FieldOption[] | null>;
|
|
17
|
+
/** Trigger a load (no-op when the field has no `optionsLoader`). */
|
|
18
|
+
loadOptions: () => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export declare function useAsyncOptions(getField: () => FieldDefinition, effectiveModel: ComputedRef<any> | Ref<any>): UseAsyncOptionsReturn;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Ref } from "vue";
|
|
2
|
+
import type { FieldDefinition } from "../types";
|
|
2
3
|
/**
|
|
3
4
|
* The subset of `DXTable`'s props the resource editor reads. Declared
|
|
4
5
|
* structurally (not imported from DXTable.vue) so the composable stays a
|
|
@@ -7,7 +8,7 @@ import { type Ref } from "vue";
|
|
|
7
8
|
*/
|
|
8
9
|
export interface ResourceEditorProps<T = any> {
|
|
9
10
|
/** Field definitions for the edit/create modal (enables edit-on-row-click). */
|
|
10
|
-
editFields?:
|
|
11
|
+
editFields?: FieldDefinition[];
|
|
11
12
|
/** Tab definitions — only their `key` is read here (DXForm consumes the rest). */
|
|
12
13
|
editTabs?: Array<{
|
|
13
14
|
key: string;
|