@adminforth/dashboard 1.5.0 → 1.6.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.
Files changed (50) hide show
  1. package/custom/api/dashboardApi.ts +137 -1
  2. package/custom/model/dashboard.types.ts +32 -22
  3. package/custom/runtime/DashboardRuntime.vue +2 -3
  4. package/custom/skills/adminforth-dashboard/SKILL.md +66 -10
  5. package/custom/widgets/KpiCardWidget.vue +172 -9
  6. package/custom/widgets/chart/ChartWidget.vue +5 -5
  7. package/custom/widgets/registry.ts +4 -4
  8. package/dist/custom/api/dashboardApi.d.ts +46 -1
  9. package/dist/custom/api/dashboardApi.js +90 -0
  10. package/dist/custom/api/dashboardApi.ts +137 -1
  11. package/dist/custom/model/dashboard.types.d.ts +30 -14
  12. package/dist/custom/model/dashboard.types.js +2 -2
  13. package/dist/custom/model/dashboard.types.ts +32 -22
  14. package/dist/custom/queries/useDashboardConfig.d.ts +106 -104
  15. package/dist/custom/queries/useWidgetData.d.ts +106 -104
  16. package/dist/custom/runtime/DashboardRuntime.vue +2 -3
  17. package/dist/custom/skills/adminforth-dashboard/SKILL.md +66 -10
  18. package/dist/custom/widgets/KpiCardWidget.vue +172 -9
  19. package/dist/custom/widgets/chart/ChartWidget.vue +5 -5
  20. package/dist/custom/widgets/registry.js +4 -4
  21. package/dist/custom/widgets/registry.ts +4 -4
  22. package/dist/endpoint/widgets.js +99 -14
  23. package/dist/schema/api.d.ts +11426 -1634
  24. package/dist/schema/api.js +118 -21
  25. package/dist/schema/widget.d.ts +425 -1980
  26. package/dist/schema/widget.js +13 -374
  27. package/dist/schema/widgets/charts.d.ts +1689 -0
  28. package/dist/schema/widgets/charts.js +92 -0
  29. package/dist/schema/widgets/common.d.ts +275 -0
  30. package/dist/schema/widgets/common.js +171 -0
  31. package/dist/schema/widgets/gauge-card.d.ts +172 -0
  32. package/dist/schema/widgets/gauge-card.js +28 -0
  33. package/dist/schema/widgets/kpi-card.d.ts +212 -0
  34. package/dist/schema/widgets/kpi-card.js +43 -0
  35. package/dist/schema/widgets/pivot-table.d.ts +196 -0
  36. package/dist/schema/widgets/pivot-table.js +17 -0
  37. package/dist/schema/widgets/table.d.ts +130 -0
  38. package/dist/schema/widgets/table.js +12 -0
  39. package/dist/services/widgetDataService.js +96 -2
  40. package/endpoint/widgets.ts +173 -26
  41. package/package.json +1 -1
  42. package/schema/api.ts +148 -22
  43. package/schema/widget.ts +43 -425
  44. package/schema/widgets/charts.ts +113 -0
  45. package/schema/widgets/common.ts +194 -0
  46. package/schema/widgets/gauge-card.ts +34 -0
  47. package/schema/widgets/kpi-card.ts +49 -0
  48. package/schema/widgets/pivot-table.ts +24 -0
  49. package/schema/widgets/table.ts +18 -0
  50. package/services/widgetDataService.ts +129 -3
@@ -0,0 +1,92 @@
1
+ import { z } from 'zod';
2
+ import { ChartFieldRefSchema, FunnelQueryConfigSchema, QueryConfigSchema, WidgetBaseSchema, } from './common.js';
3
+ const ChartBaseSchema = z.object({
4
+ title: z.string().optional(),
5
+ }).strict();
6
+ const ChartBucketSchema = z.object({
7
+ label: z.string().min(1, 'Bucket label is required'),
8
+ min: z.number().optional(),
9
+ max: z.number().optional(),
10
+ }).strict();
11
+ const ChartSeriesRefSchema = z.object({
12
+ field: z.string(),
13
+ label: z.string().optional(),
14
+ }).strict();
15
+ export const LineChartSchema = ChartBaseSchema.extend({
16
+ type: z.literal('line'),
17
+ x: ChartFieldRefSchema,
18
+ y: z.array(ChartFieldRefSchema).min(1),
19
+ series: ChartSeriesRefSchema.optional(),
20
+ color: z.string().optional(),
21
+ colors: z.array(z.string()).optional(),
22
+ });
23
+ export const BarChartSchema = ChartBaseSchema.extend({
24
+ type: z.literal('bar'),
25
+ x: ChartFieldRefSchema,
26
+ y: ChartFieldRefSchema,
27
+ color: z.string().optional(),
28
+ });
29
+ export const StackedBarChartSchema = ChartBaseSchema.extend({
30
+ type: z.literal('stacked_bar'),
31
+ x: ChartFieldRefSchema,
32
+ y: z.union([ChartFieldRefSchema, z.array(ChartFieldRefSchema).min(1)]),
33
+ series: ChartSeriesRefSchema.optional(),
34
+ colors: z.array(z.string()).optional(),
35
+ });
36
+ export const PieChartSchema = ChartBaseSchema.extend({
37
+ type: z.literal('pie'),
38
+ label: ChartFieldRefSchema,
39
+ value: ChartFieldRefSchema,
40
+ colors: z.array(z.string()).optional(),
41
+ });
42
+ export const HistogramChartSchema = ChartBaseSchema.extend({
43
+ type: z.literal('histogram'),
44
+ x: ChartFieldRefSchema,
45
+ y: ChartFieldRefSchema,
46
+ buckets: z.array(ChartBucketSchema).optional(),
47
+ color: z.string().optional(),
48
+ });
49
+ export const FunnelChartSchema = ChartBaseSchema.extend({
50
+ type: z.literal('funnel'),
51
+ label: ChartFieldRefSchema.optional(),
52
+ value: ChartFieldRefSchema.optional(),
53
+ colors: z.array(z.string()).optional(),
54
+ });
55
+ export const LineChartWidgetConfigSchema = WidgetBaseSchema.extend({
56
+ target: z.literal('chart'),
57
+ chart: LineChartSchema,
58
+ query: QueryConfigSchema,
59
+ });
60
+ export const BarChartWidgetConfigSchema = WidgetBaseSchema.extend({
61
+ target: z.literal('chart'),
62
+ chart: BarChartSchema,
63
+ query: QueryConfigSchema,
64
+ });
65
+ export const StackedBarChartWidgetConfigSchema = WidgetBaseSchema.extend({
66
+ target: z.literal('chart'),
67
+ chart: StackedBarChartSchema,
68
+ query: QueryConfigSchema,
69
+ });
70
+ export const PieChartWidgetConfigSchema = WidgetBaseSchema.extend({
71
+ target: z.literal('chart'),
72
+ chart: PieChartSchema,
73
+ query: QueryConfigSchema,
74
+ });
75
+ export const HistogramChartWidgetConfigSchema = WidgetBaseSchema.extend({
76
+ target: z.literal('chart'),
77
+ chart: HistogramChartSchema,
78
+ query: QueryConfigSchema,
79
+ });
80
+ export const FunnelChartWidgetConfigSchema = WidgetBaseSchema.extend({
81
+ target: z.literal('chart'),
82
+ chart: FunnelChartSchema,
83
+ query: FunnelQueryConfigSchema,
84
+ });
85
+ export const ChartWidgetTargetConfigSchema = z.union([
86
+ LineChartWidgetConfigSchema,
87
+ BarChartWidgetConfigSchema,
88
+ StackedBarChartWidgetConfigSchema,
89
+ PieChartWidgetConfigSchema,
90
+ HistogramChartWidgetConfigSchema,
91
+ FunnelChartWidgetConfigSchema,
92
+ ]);
@@ -0,0 +1,275 @@
1
+ import { z } from 'zod';
2
+ export declare const DashboardWidgetSizeSchema: z.ZodEnum<{
3
+ small: "small";
4
+ medium: "medium";
5
+ large: "large";
6
+ wide: "wide";
7
+ full: "full";
8
+ }>;
9
+ export declare const ValueFormatSchema: z.ZodOptional<z.ZodEnum<{
10
+ number: "number";
11
+ integer: "integer";
12
+ compact_number: "compact_number";
13
+ currency: "currency";
14
+ percent: "percent";
15
+ percent_delta: "percent_delta";
16
+ number_delta: "number_delta";
17
+ currency_delta: "currency_delta";
18
+ }>>;
19
+ export declare const VariablesConfigSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
20
+ export declare const ChartFieldRefSchema: z.ZodObject<{
21
+ field: z.ZodString;
22
+ label: z.ZodOptional<z.ZodString>;
23
+ format: z.ZodOptional<z.ZodEnum<{
24
+ number: "number";
25
+ integer: "integer";
26
+ compact_number: "compact_number";
27
+ currency: "currency";
28
+ percent: "percent";
29
+ percent_delta: "percent_delta";
30
+ number_delta: "number_delta";
31
+ currency_delta: "currency_delta";
32
+ }>>;
33
+ }, z.core.$strict>;
34
+ export declare const FilterExpressionSchema: z.ZodType;
35
+ export declare const QueryAggregateOperationSchema: z.ZodEnum<{
36
+ sum: "sum";
37
+ count: "count";
38
+ count_distinct: "count_distinct";
39
+ avg: "avg";
40
+ min: "min";
41
+ max: "max";
42
+ median: "median";
43
+ }>;
44
+ export declare const QueryFieldSelectItemSchema: z.ZodObject<{
45
+ field: z.ZodString;
46
+ as: z.ZodOptional<z.ZodString>;
47
+ grain: z.ZodOptional<z.ZodEnum<{
48
+ day: "day";
49
+ week: "week";
50
+ month: "month";
51
+ year: "year";
52
+ }>>;
53
+ }, z.core.$strict>;
54
+ export declare const QueryAggregateSelectItemSchema: z.ZodObject<{
55
+ agg: z.ZodEnum<{
56
+ sum: "sum";
57
+ count: "count";
58
+ count_distinct: "count_distinct";
59
+ avg: "avg";
60
+ min: "min";
61
+ max: "max";
62
+ median: "median";
63
+ }>;
64
+ field: z.ZodOptional<z.ZodString>;
65
+ as: z.ZodString;
66
+ filters: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
67
+ }, z.core.$strict>;
68
+ export declare const QueryCalcSelectItemSchema: z.ZodObject<{
69
+ calc: z.ZodString;
70
+ as: z.ZodString;
71
+ }, z.core.$strict>;
72
+ export declare const QuerySelectItemSchema: z.ZodUnion<readonly [z.ZodObject<{
73
+ field: z.ZodString;
74
+ as: z.ZodOptional<z.ZodString>;
75
+ grain: z.ZodOptional<z.ZodEnum<{
76
+ day: "day";
77
+ week: "week";
78
+ month: "month";
79
+ year: "year";
80
+ }>>;
81
+ }, z.core.$strict>, z.ZodObject<{
82
+ agg: z.ZodEnum<{
83
+ sum: "sum";
84
+ count: "count";
85
+ count_distinct: "count_distinct";
86
+ avg: "avg";
87
+ min: "min";
88
+ max: "max";
89
+ median: "median";
90
+ }>;
91
+ field: z.ZodOptional<z.ZodString>;
92
+ as: z.ZodString;
93
+ filters: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
94
+ }, z.core.$strict>, z.ZodObject<{
95
+ calc: z.ZodString;
96
+ as: z.ZodString;
97
+ }, z.core.$strict>]>;
98
+ export declare const QueryGroupByItemSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
99
+ field: z.ZodString;
100
+ as: z.ZodOptional<z.ZodString>;
101
+ grain: z.ZodOptional<z.ZodEnum<{
102
+ day: "day";
103
+ week: "week";
104
+ month: "month";
105
+ year: "year";
106
+ }>>;
107
+ timezone: z.ZodOptional<z.ZodString>;
108
+ }, z.core.$strict>]>;
109
+ export declare const QueryOrderByItemSchema: z.ZodObject<{
110
+ field: z.ZodString;
111
+ direction: z.ZodOptional<z.ZodEnum<{
112
+ asc: "asc";
113
+ desc: "desc";
114
+ }>>;
115
+ }, z.core.$strict>;
116
+ export declare const QueryCalcItemSchema: z.ZodObject<{
117
+ calc: z.ZodString;
118
+ as: z.ZodString;
119
+ }, z.core.$strict>;
120
+ export declare const QueryConfigSchema: z.ZodObject<{
121
+ resource: z.ZodString;
122
+ select: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
123
+ field: z.ZodString;
124
+ as: z.ZodOptional<z.ZodString>;
125
+ grain: z.ZodOptional<z.ZodEnum<{
126
+ day: "day";
127
+ week: "week";
128
+ month: "month";
129
+ year: "year";
130
+ }>>;
131
+ }, z.core.$strict>, z.ZodObject<{
132
+ agg: z.ZodEnum<{
133
+ sum: "sum";
134
+ count: "count";
135
+ count_distinct: "count_distinct";
136
+ avg: "avg";
137
+ min: "min";
138
+ max: "max";
139
+ median: "median";
140
+ }>;
141
+ field: z.ZodOptional<z.ZodString>;
142
+ as: z.ZodString;
143
+ filters: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
144
+ }, z.core.$strict>, z.ZodObject<{
145
+ calc: z.ZodString;
146
+ as: z.ZodString;
147
+ }, z.core.$strict>]>>>;
148
+ sparkline: z.ZodOptional<z.ZodObject<{
149
+ field: z.ZodString;
150
+ grain: z.ZodEnum<{
151
+ day: "day";
152
+ week: "week";
153
+ month: "month";
154
+ year: "year";
155
+ }>;
156
+ as: z.ZodString;
157
+ fill_missing: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
158
+ }, z.core.$strict>>;
159
+ filters: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
160
+ group_by: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
161
+ field: z.ZodString;
162
+ as: z.ZodOptional<z.ZodString>;
163
+ grain: z.ZodOptional<z.ZodEnum<{
164
+ day: "day";
165
+ week: "week";
166
+ month: "month";
167
+ year: "year";
168
+ }>>;
169
+ timezone: z.ZodOptional<z.ZodString>;
170
+ }, z.core.$strict>]>>>;
171
+ order_by: z.ZodOptional<z.ZodArray<z.ZodObject<{
172
+ field: z.ZodString;
173
+ direction: z.ZodOptional<z.ZodEnum<{
174
+ asc: "asc";
175
+ desc: "desc";
176
+ }>>;
177
+ }, z.core.$strict>>>;
178
+ limit: z.ZodOptional<z.ZodNumber>;
179
+ offset: z.ZodOptional<z.ZodNumber>;
180
+ bucket: z.ZodOptional<z.ZodObject<{
181
+ field: z.ZodString;
182
+ buckets: z.ZodArray<z.ZodObject<{
183
+ label: z.ZodString;
184
+ min: z.ZodOptional<z.ZodNumber>;
185
+ max: z.ZodOptional<z.ZodNumber>;
186
+ }, z.core.$strict>>;
187
+ }, z.core.$strict>>;
188
+ calcs: z.ZodOptional<z.ZodArray<z.ZodObject<{
189
+ calc: z.ZodString;
190
+ as: z.ZodString;
191
+ }, z.core.$strict>>>;
192
+ formatting: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
193
+ }, z.core.$strict>;
194
+ export declare const FunnelQueryConfigSchema: z.ZodObject<{
195
+ steps: z.ZodArray<z.ZodObject<{
196
+ name: z.ZodString;
197
+ resource: z.ZodString;
198
+ metric: z.ZodObject<{
199
+ agg: z.ZodEnum<{
200
+ sum: "sum";
201
+ count: "count";
202
+ count_distinct: "count_distinct";
203
+ avg: "avg";
204
+ min: "min";
205
+ max: "max";
206
+ median: "median";
207
+ }>;
208
+ field: z.ZodOptional<z.ZodString>;
209
+ as: z.ZodString;
210
+ filters: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
211
+ }, z.core.$strict>;
212
+ filters: z.ZodOptional<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
213
+ }, z.core.$strict>>;
214
+ calcs: z.ZodOptional<z.ZodArray<z.ZodObject<{
215
+ calc: z.ZodString;
216
+ as: z.ZodString;
217
+ }, z.core.$strict>>>;
218
+ }, z.core.$strict>;
219
+ export declare const WidgetPersistedFieldsSchema: z.ZodObject<{
220
+ id: z.ZodString;
221
+ group_id: z.ZodString;
222
+ order: z.ZodNumber;
223
+ }, z.core.$strict>;
224
+ export declare const WidgetEditableBaseSchema: z.ZodObject<{
225
+ label: z.ZodOptional<z.ZodString>;
226
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
227
+ size: z.ZodOptional<z.ZodEnum<{
228
+ small: "small";
229
+ medium: "medium";
230
+ large: "large";
231
+ wide: "wide";
232
+ full: "full";
233
+ }>>;
234
+ width: z.ZodOptional<z.ZodNumber>;
235
+ height: z.ZodOptional<z.ZodNumber>;
236
+ min_width: z.ZodOptional<z.ZodNumber>;
237
+ max_width: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
238
+ }, z.core.$strict>;
239
+ export declare const WidgetBaseSchema: z.ZodObject<{
240
+ id: z.ZodString;
241
+ group_id: z.ZodString;
242
+ order: z.ZodNumber;
243
+ label: z.ZodOptional<z.ZodString>;
244
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
245
+ size: z.ZodOptional<z.ZodEnum<{
246
+ small: "small";
247
+ medium: "medium";
248
+ large: "large";
249
+ wide: "wide";
250
+ full: "full";
251
+ }>>;
252
+ width: z.ZodOptional<z.ZodNumber>;
253
+ height: z.ZodOptional<z.ZodNumber>;
254
+ min_width: z.ZodOptional<z.ZodNumber>;
255
+ max_width: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
256
+ }, z.core.$strict>;
257
+ export declare const EmptyWidgetConfigSchema: z.ZodObject<{
258
+ id: z.ZodString;
259
+ group_id: z.ZodString;
260
+ order: z.ZodNumber;
261
+ label: z.ZodOptional<z.ZodString>;
262
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
263
+ size: z.ZodOptional<z.ZodEnum<{
264
+ small: "small";
265
+ medium: "medium";
266
+ large: "large";
267
+ wide: "wide";
268
+ full: "full";
269
+ }>>;
270
+ width: z.ZodOptional<z.ZodNumber>;
271
+ height: z.ZodOptional<z.ZodNumber>;
272
+ min_width: z.ZodOptional<z.ZodNumber>;
273
+ max_width: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
274
+ target: z.ZodLiteral<"empty">;
275
+ }, z.core.$strict>;
@@ -0,0 +1,171 @@
1
+ import { z } from 'zod';
2
+ export const DashboardWidgetSizeSchema = z.enum([
3
+ 'small',
4
+ 'medium',
5
+ 'large',
6
+ 'wide',
7
+ 'full',
8
+ ]);
9
+ export const ValueFormatSchema = z.enum([
10
+ 'number',
11
+ 'integer',
12
+ 'compact_number',
13
+ 'currency',
14
+ 'percent',
15
+ 'percent_delta',
16
+ 'number_delta',
17
+ 'currency_delta',
18
+ ]).optional();
19
+ export const VariablesConfigSchema = z.record(z.string(), z.unknown());
20
+ export const ChartFieldRefSchema = z.object({
21
+ field: z.string(),
22
+ label: z.string().optional(),
23
+ format: ValueFormatSchema,
24
+ }).strict();
25
+ const RelativeDateValueSchema = z.union([
26
+ z.object({
27
+ now: z.literal(true),
28
+ }).strict(),
29
+ z.object({
30
+ now_minus: z.string().regex(/^\d+(h|d|w|mo|y)$/),
31
+ }).strict(),
32
+ ]);
33
+ const FilterValueSchema = z.lazy(() => z.union([
34
+ RelativeDateValueSchema,
35
+ z.string(),
36
+ z.number(),
37
+ z.boolean(),
38
+ z.null(),
39
+ z.array(FilterValueSchema),
40
+ z.record(z.string(), FilterValueSchema),
41
+ ]));
42
+ export const FilterExpressionSchema = z.lazy(() => z.union([
43
+ z.array(FilterExpressionSchema),
44
+ z.object({
45
+ and: z.array(FilterExpressionSchema),
46
+ }).strict(),
47
+ z.object({
48
+ or: z.array(FilterExpressionSchema),
49
+ }).strict(),
50
+ z.object({
51
+ field: z.string(),
52
+ eq: FilterValueSchema.optional(),
53
+ neq: FilterValueSchema.optional(),
54
+ gt: FilterValueSchema.optional(),
55
+ gte: FilterValueSchema.optional(),
56
+ lt: FilterValueSchema.optional(),
57
+ lte: FilterValueSchema.optional(),
58
+ in: z.array(FilterValueSchema).optional(),
59
+ not_in: z.array(FilterValueSchema).optional(),
60
+ like: FilterValueSchema.optional(),
61
+ ilike: FilterValueSchema.optional(),
62
+ }).strict(),
63
+ ]));
64
+ export const QueryAggregateOperationSchema = z.enum([
65
+ 'sum',
66
+ 'count',
67
+ 'count_distinct',
68
+ 'avg',
69
+ 'min',
70
+ 'max',
71
+ 'median',
72
+ ]);
73
+ export const QueryFieldSelectItemSchema = z.object({
74
+ field: z.string(),
75
+ as: z.string().optional(),
76
+ grain: z.enum(['day', 'week', 'month', 'year']).optional(),
77
+ }).strict();
78
+ export const QueryAggregateSelectItemSchema = z.object({
79
+ agg: QueryAggregateOperationSchema,
80
+ field: z.string().optional(),
81
+ as: z.string(),
82
+ filters: FilterExpressionSchema.optional(),
83
+ }).strict().superRefine((item, ctx) => {
84
+ if (!['count'].includes(item.agg) && !item.field) {
85
+ ctx.addIssue({
86
+ code: 'custom',
87
+ path: ['field'],
88
+ message: `field is required for ${item.agg}`,
89
+ });
90
+ }
91
+ });
92
+ export const QueryCalcSelectItemSchema = z.object({
93
+ calc: z.string(),
94
+ as: z.string(),
95
+ }).strict();
96
+ export const QuerySelectItemSchema = z.union([
97
+ QueryFieldSelectItemSchema,
98
+ QueryAggregateSelectItemSchema,
99
+ QueryCalcSelectItemSchema,
100
+ ]);
101
+ export const QueryGroupByItemSchema = z.union([
102
+ z.string(),
103
+ z.object({
104
+ field: z.string(),
105
+ as: z.string().optional(),
106
+ grain: z.enum(['day', 'week', 'month', 'year']).optional(),
107
+ timezone: z.string().optional(),
108
+ }).strict(),
109
+ ]);
110
+ export const QueryOrderByItemSchema = z.object({
111
+ field: z.string(),
112
+ direction: z.enum(['asc', 'desc']).optional(),
113
+ }).strict();
114
+ const BucketConfigSchema = z.object({
115
+ field: z.string(),
116
+ buckets: z.array(z.object({
117
+ label: z.string(),
118
+ min: z.number().optional(),
119
+ max: z.number().optional(),
120
+ }).strict()),
121
+ }).strict();
122
+ export const QueryCalcItemSchema = z.object({
123
+ calc: z.string(),
124
+ as: z.string(),
125
+ }).strict();
126
+ export const QueryConfigSchema = z.object({
127
+ resource: z.string(),
128
+ select: z.array(QuerySelectItemSchema).optional(),
129
+ sparkline: z.object({
130
+ field: z.string(),
131
+ grain: z.enum(['day', 'week', 'month', 'year']),
132
+ as: z.string(),
133
+ fill_missing: z.record(z.string(), z.unknown()).optional(),
134
+ }).strict().optional(),
135
+ filters: FilterExpressionSchema.optional(),
136
+ group_by: z.array(QueryGroupByItemSchema).optional(),
137
+ order_by: z.array(QueryOrderByItemSchema).optional(),
138
+ limit: z.number().int().positive().optional(),
139
+ offset: z.number().int().nonnegative().optional(),
140
+ bucket: BucketConfigSchema.optional(),
141
+ calcs: z.array(QueryCalcItemSchema).optional(),
142
+ formatting: z.record(z.string(), z.unknown()).optional(),
143
+ }).strict();
144
+ const FunnelQueryStepSchema = z.object({
145
+ name: z.string(),
146
+ resource: z.string(),
147
+ metric: QueryAggregateSelectItemSchema,
148
+ filters: FilterExpressionSchema.optional(),
149
+ }).strict();
150
+ export const FunnelQueryConfigSchema = z.object({
151
+ steps: z.array(FunnelQueryStepSchema).min(1),
152
+ calcs: z.array(QueryCalcItemSchema).optional(),
153
+ }).strict();
154
+ export const WidgetPersistedFieldsSchema = z.object({
155
+ id: z.string(),
156
+ group_id: z.string(),
157
+ order: z.number(),
158
+ }).strict();
159
+ export const WidgetEditableBaseSchema = z.object({
160
+ label: z.string().optional(),
161
+ variables: VariablesConfigSchema.optional(),
162
+ size: DashboardWidgetSizeSchema.optional(),
163
+ width: z.number().positive('Width must be greater than 0').optional(),
164
+ height: z.number().positive('Height must be greater than 0').optional(),
165
+ min_width: z.number().nonnegative('Min width must be a non-negative number').optional(),
166
+ max_width: z.number().nonnegative('Max width must be a non-negative number').nullable().optional(),
167
+ }).strict();
168
+ export const WidgetBaseSchema = WidgetPersistedFieldsSchema.merge(WidgetEditableBaseSchema);
169
+ export const EmptyWidgetConfigSchema = WidgetBaseSchema.extend({
170
+ target: z.literal('empty'),
171
+ });