@adminforth/dashboard 1.3.0 → 1.4.1
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/README.md +103 -15
- package/custom/api/dashboardApi.ts +9 -8
- package/custom/model/dashboard.types.ts +63 -270
- package/custom/model/dashboardTopics.ts +5 -0
- package/custom/runtime/DashboardGroup.vue +2 -2
- package/custom/runtime/DashboardPage.vue +17 -7
- package/custom/runtime/DashboardRuntime.vue +20 -8
- package/custom/runtime/WidgetRenderer.vue +1 -2
- package/custom/runtime/WidgetShell.vue +3 -3
- package/custom/skills/adminforth-dashboard/SKILL.md +110 -3
- package/custom/widgets/{gauge-card/GaugeCardWidget.vue → GaugeCardWidget.vue} +63 -61
- package/custom/widgets/{kpi-card/KpiCardWidget.vue → KpiCardWidget.vue} +35 -33
- package/custom/widgets/{pivot-table/PivotTableWidget.vue → PivotTableWidget.vue} +71 -68
- package/custom/widgets/{table/TableWidget.vue → TableWidget.vue} +5 -5
- package/custom/widgets/chart/{bar/BarChart.vue → BarChart.vue} +2 -2
- package/custom/widgets/chart/ChartWidget.vue +24 -18
- package/{dist/custom/widgets/chart/funnel → custom/widgets/chart}/FunnelChart.vue +80 -78
- package/{dist/custom/widgets/chart/line → custom/widgets/chart}/LineChart.vue +2 -2
- package/custom/widgets/chart/{pie/PieChart.vue → PieChart.vue} +2 -2
- package/{dist/custom/widgets/chart/stacked-bar → custom/widgets/chart}/StackedBarChart.vue +97 -95
- package/custom/widgets/chart/chart.types.ts +0 -28
- package/dist/custom/api/dashboardApi.d.ts +4 -7
- package/dist/custom/api/dashboardApi.js +5 -0
- package/dist/custom/api/dashboardApi.ts +9 -8
- package/dist/custom/model/dashboard.types.d.ts +40 -31
- package/dist/custom/model/dashboard.types.js +13 -152
- package/dist/custom/model/dashboard.types.ts +63 -270
- package/dist/custom/model/dashboardTopics.d.ts +2 -0
- package/dist/custom/model/dashboardTopics.js +8 -0
- package/dist/custom/model/dashboardTopics.ts +5 -0
- package/dist/custom/queries/useDashboardConfig.d.ts +116 -96
- package/dist/custom/queries/useWidgetData.d.ts +116 -96
- package/dist/custom/runtime/DashboardGroup.vue +2 -2
- package/dist/custom/runtime/DashboardPage.vue +17 -7
- package/dist/custom/runtime/DashboardRuntime.vue +20 -8
- package/dist/custom/runtime/WidgetRenderer.vue +1 -2
- package/dist/custom/runtime/WidgetShell.vue +3 -3
- package/dist/custom/skills/adminforth-dashboard/SKILL.md +110 -3
- package/dist/custom/widgets/{gauge-card/GaugeCardWidget.vue → GaugeCardWidget.vue} +63 -61
- package/dist/custom/widgets/{kpi-card/KpiCardWidget.vue → KpiCardWidget.vue} +35 -33
- package/dist/custom/widgets/{pivot-table/PivotTableWidget.vue → PivotTableWidget.vue} +71 -68
- package/dist/custom/widgets/{table/TableWidget.vue → TableWidget.vue} +5 -5
- package/dist/custom/widgets/chart/{bar/BarChart.vue → BarChart.vue} +2 -2
- package/dist/custom/widgets/chart/ChartWidget.vue +24 -18
- package/{custom/widgets/chart/funnel → dist/custom/widgets/chart}/FunnelChart.vue +80 -78
- package/{custom/widgets/chart/line → dist/custom/widgets/chart}/LineChart.vue +2 -2
- package/dist/custom/widgets/chart/{pie/PieChart.vue → PieChart.vue} +2 -2
- package/{custom/widgets/chart/stacked-bar → dist/custom/widgets/chart}/StackedBarChart.vue +97 -95
- package/dist/custom/widgets/chart/chart.types.d.ts +0 -2
- package/dist/custom/widgets/chart/chart.types.js +0 -23
- package/dist/custom/widgets/chart/chart.types.ts +0 -28
- package/dist/endpoint/dashboard.d.ts +6 -2
- package/dist/endpoint/dashboard.js +29 -5
- package/dist/endpoint/groups.d.ts +2 -21
- package/dist/endpoint/groups.js +18 -16
- package/dist/endpoint/widgets.d.ts +2 -4
- package/dist/endpoint/widgets.js +28 -74
- package/dist/index.js +1 -3
- package/dist/schema/api.d.ts +2172 -500
- package/dist/schema/api.js +21 -13
- package/dist/schema/widget.d.ts +1076 -263
- package/dist/schema/widget.js +108 -49
- package/dist/services/dashboardConfigService.d.ts +0 -10
- package/dist/services/dashboardConfigService.js +6 -21
- package/dist/services/widgetDataService.d.ts +2 -1
- package/dist/services/widgetDataService.js +266 -206
- package/endpoint/dashboard.ts +47 -7
- package/endpoint/groups.ts +25 -42
- package/endpoint/widgets.ts +41 -96
- package/index.ts +0 -3
- package/package.json +3 -3
- package/schema/api.ts +23 -13
- package/schema/widget.ts +119 -55
- package/services/dashboardConfigService.ts +6 -25
- package/services/widgetDataService.ts +350 -237
- package/custom/widgets/chart/histogram/HistogramChart.vue +0 -21
- package/dist/custom/widgets/chart/histogram/HistogramChart.vue +0 -21
- package/dist/services/widgetConfigValidator.d.ts +0 -8
- package/dist/services/widgetConfigValidator.js +0 -27
- package/services/widgetConfigValidator.ts +0 -61
package/dist/schema/widget.js
CHANGED
|
@@ -28,6 +28,14 @@ const FieldRefSchema = z.union([
|
|
|
28
28
|
format: ValueFormatSchema,
|
|
29
29
|
}).strict(),
|
|
30
30
|
]);
|
|
31
|
+
const JsonValueSchema = z.lazy(() => z.union([
|
|
32
|
+
z.string(),
|
|
33
|
+
z.number(),
|
|
34
|
+
z.boolean(),
|
|
35
|
+
z.null(),
|
|
36
|
+
z.array(JsonValueSchema),
|
|
37
|
+
z.record(z.string(), JsonValueSchema),
|
|
38
|
+
]));
|
|
31
39
|
const FilterExpressionSchema = z.lazy(() => z.union([
|
|
32
40
|
z.array(FilterExpressionSchema),
|
|
33
41
|
z.object({
|
|
@@ -38,16 +46,16 @@ const FilterExpressionSchema = z.lazy(() => z.union([
|
|
|
38
46
|
}).strict(),
|
|
39
47
|
z.object({
|
|
40
48
|
field: z.string(),
|
|
41
|
-
eq:
|
|
42
|
-
neq:
|
|
43
|
-
gt:
|
|
44
|
-
gte:
|
|
45
|
-
lt:
|
|
46
|
-
lte:
|
|
47
|
-
in: z.array(
|
|
48
|
-
not_in: z.array(
|
|
49
|
-
like:
|
|
50
|
-
ilike:
|
|
49
|
+
eq: JsonValueSchema.optional(),
|
|
50
|
+
neq: JsonValueSchema.optional(),
|
|
51
|
+
gt: JsonValueSchema.optional(),
|
|
52
|
+
gte: JsonValueSchema.optional(),
|
|
53
|
+
lt: JsonValueSchema.optional(),
|
|
54
|
+
lte: JsonValueSchema.optional(),
|
|
55
|
+
in: z.array(JsonValueSchema).optional(),
|
|
56
|
+
not_in: z.array(JsonValueSchema).optional(),
|
|
57
|
+
like: JsonValueSchema.optional(),
|
|
58
|
+
ilike: JsonValueSchema.optional(),
|
|
51
59
|
}).strict(),
|
|
52
60
|
]));
|
|
53
61
|
const QueryAggregateOperationSchema = z.enum([
|
|
@@ -62,7 +70,7 @@ const QueryAggregateOperationSchema = z.enum([
|
|
|
62
70
|
const QueryFieldSelectItemSchema = z.object({
|
|
63
71
|
field: z.string(),
|
|
64
72
|
as: z.string().optional(),
|
|
65
|
-
grain: z.enum(['
|
|
73
|
+
grain: z.enum(['day', 'week', 'month', 'year']).optional(),
|
|
66
74
|
}).strict();
|
|
67
75
|
const QueryAggregateSelectItemSchema = z.object({
|
|
68
76
|
agg: QueryAggregateOperationSchema,
|
|
@@ -72,7 +80,7 @@ const QueryAggregateSelectItemSchema = z.object({
|
|
|
72
80
|
}).strict().superRefine((item, ctx) => {
|
|
73
81
|
if (!['count'].includes(item.agg) && !item.field) {
|
|
74
82
|
ctx.addIssue({
|
|
75
|
-
code:
|
|
83
|
+
code: 'custom',
|
|
76
84
|
path: ['field'],
|
|
77
85
|
message: `field is required for ${item.agg}`,
|
|
78
86
|
});
|
|
@@ -92,7 +100,7 @@ const QueryGroupByItemSchema = z.union([
|
|
|
92
100
|
z.object({
|
|
93
101
|
field: z.string(),
|
|
94
102
|
as: z.string().optional(),
|
|
95
|
-
grain: z.enum(['
|
|
103
|
+
grain: z.enum(['day', 'week', 'month', 'year']).optional(),
|
|
96
104
|
timezone: z.string().optional(),
|
|
97
105
|
}).strict(),
|
|
98
106
|
]);
|
|
@@ -102,13 +110,13 @@ const QueryOrderByItemSchema = z.object({
|
|
|
102
110
|
}).strict();
|
|
103
111
|
const TimeSeriesConfigSchema = z.object({
|
|
104
112
|
field: z.string(),
|
|
105
|
-
grain: z.enum(['
|
|
113
|
+
grain: z.enum(['day', 'week', 'month', 'year']),
|
|
106
114
|
timezone: z.string().optional(),
|
|
107
115
|
}).strict();
|
|
108
116
|
const PeriodConfigSchema = z.object({
|
|
109
117
|
field: z.string(),
|
|
110
|
-
gte:
|
|
111
|
-
lt:
|
|
118
|
+
gte: JsonValueSchema.optional(),
|
|
119
|
+
lt: JsonValueSchema.optional(),
|
|
112
120
|
}).strict();
|
|
113
121
|
const BucketConfigSchema = z.object({
|
|
114
122
|
field: z.string(),
|
|
@@ -122,16 +130,17 @@ const QueryCalcItemSchema = z.object({
|
|
|
122
130
|
calc: z.string(),
|
|
123
131
|
as: z.string(),
|
|
124
132
|
}).strict();
|
|
125
|
-
const FormattingConfigSchema = z.record(z.string(),
|
|
133
|
+
const FormattingConfigSchema = z.record(z.string(), JsonValueSchema);
|
|
134
|
+
const VariablesConfigSchema = z.record(z.string(), JsonValueSchema);
|
|
126
135
|
export const QueryConfigSchema = z.object({
|
|
127
136
|
resource: z.string(),
|
|
128
137
|
select: z.array(QuerySelectItemSchema).optional(),
|
|
129
138
|
filters: FilterExpressionSchema.optional(),
|
|
130
|
-
|
|
131
|
-
|
|
139
|
+
group_by: z.array(QueryGroupByItemSchema).optional(),
|
|
140
|
+
order_by: z.array(QueryOrderByItemSchema).optional(),
|
|
132
141
|
limit: z.number().int().positive().optional(),
|
|
133
142
|
offset: z.number().int().nonnegative().optional(),
|
|
134
|
-
|
|
143
|
+
time_series: TimeSeriesConfigSchema.optional(),
|
|
135
144
|
period: PeriodConfigSchema.optional(),
|
|
136
145
|
bucket: BucketConfigSchema.optional(),
|
|
137
146
|
calcs: z.array(QueryCalcItemSchema).optional(),
|
|
@@ -145,26 +154,30 @@ const FunnelQueryStepSchema = z.object({
|
|
|
145
154
|
}).strict();
|
|
146
155
|
export const FunnelQueryConfigSchema = z.object({
|
|
147
156
|
steps: z.array(FunnelQueryStepSchema).min(1),
|
|
157
|
+
calcs: z.array(QueryCalcItemSchema).optional(),
|
|
148
158
|
}).strict();
|
|
149
|
-
const
|
|
150
|
-
id: z.string().optional(),
|
|
151
|
-
group_id: z.string().optional(),
|
|
159
|
+
const EditableWidgetBaseSchema = z.object({
|
|
152
160
|
label: z.string().optional(),
|
|
161
|
+
variables: VariablesConfigSchema.optional(),
|
|
153
162
|
size: DashboardWidgetSizeSchema.optional(),
|
|
154
163
|
width: z.number().positive('Width must be greater than 0').optional(),
|
|
155
164
|
height: z.number().positive('Height must be greater than 0').optional(),
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
+
const StoredWidgetBaseSchema = EditableWidgetBaseSchema.extend({
|
|
169
|
+
id: z.string(),
|
|
170
|
+
group_id: z.string(),
|
|
171
|
+
order: z.number(),
|
|
159
172
|
});
|
|
160
173
|
const TableViewConfigSchema = z.object({
|
|
161
174
|
columns: z.array(FieldRefSchema).optional(),
|
|
162
175
|
pagination: z.boolean().optional(),
|
|
163
|
-
|
|
176
|
+
page_size: z.number().int().positive().optional(),
|
|
164
177
|
}).strict();
|
|
165
178
|
const ChartBaseSchema = z.object({
|
|
166
179
|
title: z.string().optional(),
|
|
167
|
-
});
|
|
180
|
+
}).strict();
|
|
168
181
|
const ChartBucketSchema = z.object({
|
|
169
182
|
label: z.string().min(1, 'Bucket label is required'),
|
|
170
183
|
min: z.number().optional(),
|
|
@@ -191,8 +204,8 @@ const BarChartSchema = ChartBaseSchema.extend({
|
|
|
191
204
|
const StackedBarChartSchema = ChartBaseSchema.extend({
|
|
192
205
|
type: z.literal('stacked_bar'),
|
|
193
206
|
x: ChartFieldRefSchema,
|
|
194
|
-
y: ChartFieldRefSchema,
|
|
195
|
-
series: ChartSeriesRefSchema,
|
|
207
|
+
y: z.union([ChartFieldRefSchema, z.array(ChartFieldRefSchema).min(1)]),
|
|
208
|
+
series: ChartSeriesRefSchema.optional(),
|
|
196
209
|
colors: z.array(z.string()).optional(),
|
|
197
210
|
});
|
|
198
211
|
const PieChartSchema = ChartBaseSchema.extend({
|
|
@@ -234,8 +247,8 @@ const KpiCardViewConfigSchema = z.object({
|
|
|
234
247
|
text: z.string().optional(),
|
|
235
248
|
field: z.string().optional(),
|
|
236
249
|
}).strict().optional(),
|
|
237
|
-
comparison:
|
|
238
|
-
sparkline:
|
|
250
|
+
comparison: JsonValueSchema.optional(),
|
|
251
|
+
sparkline: JsonValueSchema.optional(),
|
|
239
252
|
}).strict();
|
|
240
253
|
const GaugeCardViewConfigSchema = z.object({
|
|
241
254
|
title: z.string().optional(),
|
|
@@ -251,9 +264,9 @@ const GaugeCardViewConfigSchema = z.object({
|
|
|
251
264
|
label: z.string().optional(),
|
|
252
265
|
}).strict().optional(),
|
|
253
266
|
progress: z.object({
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
267
|
+
value_field: z.string(),
|
|
268
|
+
target_value: z.number().optional(),
|
|
269
|
+
target_field: z.string().optional(),
|
|
257
270
|
format: ValueFormatSchema,
|
|
258
271
|
}).strict().optional(),
|
|
259
272
|
color: z.string().optional(),
|
|
@@ -268,50 +281,96 @@ const PivotTableViewConfigSchema = z.object({
|
|
|
268
281
|
aggregation: z.enum(['sum', 'count', 'avg', 'min', 'max']).optional(),
|
|
269
282
|
}).strict()).min(1),
|
|
270
283
|
}).strict();
|
|
271
|
-
|
|
284
|
+
const EditableEmptyWidgetConfigSchema = EditableWidgetBaseSchema.extend({
|
|
272
285
|
target: z.literal('empty'),
|
|
273
286
|
});
|
|
274
|
-
const
|
|
287
|
+
export const EmptyWidgetConfigSchema = StoredWidgetBaseSchema.extend({
|
|
288
|
+
target: z.literal('empty'),
|
|
289
|
+
});
|
|
290
|
+
const EditableTableWidgetConfigSchema = EditableWidgetBaseSchema.extend({
|
|
291
|
+
target: z.literal('table'),
|
|
292
|
+
table: TableViewConfigSchema.optional(),
|
|
293
|
+
query: QueryConfigSchema,
|
|
294
|
+
});
|
|
295
|
+
const TableWidgetConfigSchema = StoredWidgetBaseSchema.extend({
|
|
275
296
|
target: z.literal('table'),
|
|
276
297
|
table: TableViewConfigSchema.optional(),
|
|
277
298
|
query: QueryConfigSchema,
|
|
278
299
|
});
|
|
279
|
-
const
|
|
300
|
+
const EditableChartWidgetTargetConfigSchema = EditableWidgetBaseSchema.extend({
|
|
280
301
|
target: z.literal('chart'),
|
|
281
302
|
chart: ChartConfigSchema,
|
|
282
303
|
query: z.union([QueryConfigSchema, FunnelQueryConfigSchema]),
|
|
283
304
|
}).superRefine((widget, ctx) => {
|
|
284
305
|
const isFunnelChart = widget.chart.type === 'funnel';
|
|
285
306
|
const isFunnelQuery = 'steps' in widget.query;
|
|
286
|
-
if (isFunnelChart
|
|
307
|
+
if (isFunnelChart && !isFunnelQuery) {
|
|
287
308
|
ctx.addIssue({
|
|
288
|
-
code:
|
|
309
|
+
code: 'custom',
|
|
289
310
|
path: ['query'],
|
|
290
|
-
message: 'Funnel charts must use steps query
|
|
311
|
+
message: 'Funnel charts must use steps query',
|
|
291
312
|
});
|
|
292
313
|
}
|
|
293
314
|
});
|
|
294
|
-
const
|
|
315
|
+
const ChartWidgetTargetConfigSchema = StoredWidgetBaseSchema.extend({
|
|
316
|
+
target: z.literal('chart'),
|
|
317
|
+
chart: ChartConfigSchema,
|
|
318
|
+
query: z.union([QueryConfigSchema, FunnelQueryConfigSchema]),
|
|
319
|
+
}).superRefine((widget, ctx) => {
|
|
320
|
+
const isFunnelChart = widget.chart.type === 'funnel';
|
|
321
|
+
const isFunnelQuery = 'steps' in widget.query;
|
|
322
|
+
if (isFunnelChart && !isFunnelQuery) {
|
|
323
|
+
ctx.addIssue({
|
|
324
|
+
code: 'custom',
|
|
325
|
+
path: ['query'],
|
|
326
|
+
message: 'Funnel charts must use steps query',
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
const EditableKpiCardWidgetConfigSchema = EditableWidgetBaseSchema.extend({
|
|
295
331
|
target: z.literal('kpi_card'),
|
|
296
332
|
card: KpiCardViewConfigSchema,
|
|
297
333
|
query: QueryConfigSchema,
|
|
298
334
|
});
|
|
299
|
-
const
|
|
335
|
+
const KpiCardWidgetConfigSchema = StoredWidgetBaseSchema.extend({
|
|
336
|
+
target: z.literal('kpi_card'),
|
|
337
|
+
card: KpiCardViewConfigSchema,
|
|
338
|
+
query: QueryConfigSchema,
|
|
339
|
+
});
|
|
340
|
+
const EditableGaugeCardWidgetConfigSchema = EditableWidgetBaseSchema.extend({
|
|
341
|
+
target: z.literal('gauge_card'),
|
|
342
|
+
card: GaugeCardViewConfigSchema,
|
|
343
|
+
query: QueryConfigSchema,
|
|
344
|
+
});
|
|
345
|
+
const GaugeCardWidgetConfigSchema = StoredWidgetBaseSchema.extend({
|
|
300
346
|
target: z.literal('gauge_card'),
|
|
301
347
|
card: GaugeCardViewConfigSchema,
|
|
302
348
|
query: QueryConfigSchema,
|
|
303
349
|
});
|
|
304
|
-
const
|
|
350
|
+
const EditablePivotTableWidgetConfigSchema = EditableWidgetBaseSchema.extend({
|
|
305
351
|
target: z.literal('pivot_table'),
|
|
306
352
|
pivot: PivotTableViewConfigSchema,
|
|
307
353
|
query: QueryConfigSchema,
|
|
308
354
|
});
|
|
355
|
+
const PivotTableWidgetConfigSchema = StoredWidgetBaseSchema.extend({
|
|
356
|
+
target: z.literal('pivot_table'),
|
|
357
|
+
pivot: PivotTableViewConfigSchema,
|
|
358
|
+
query: QueryConfigSchema,
|
|
359
|
+
});
|
|
360
|
+
export const EditableDashboardWidgetConfigSchema = z.discriminatedUnion('target', [
|
|
361
|
+
EditableEmptyWidgetConfigSchema,
|
|
362
|
+
EditableTableWidgetConfigSchema,
|
|
363
|
+
EditableChartWidgetTargetConfigSchema,
|
|
364
|
+
EditableKpiCardWidgetConfigSchema,
|
|
365
|
+
EditableGaugeCardWidgetConfigSchema,
|
|
366
|
+
EditablePivotTableWidgetConfigSchema,
|
|
367
|
+
]);
|
|
309
368
|
export const WidgetConfigSchema = z.discriminatedUnion('target', [
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
369
|
+
EditableTableWidgetConfigSchema,
|
|
370
|
+
EditableChartWidgetTargetConfigSchema,
|
|
371
|
+
EditableKpiCardWidgetConfigSchema,
|
|
372
|
+
EditableGaugeCardWidgetConfigSchema,
|
|
373
|
+
EditablePivotTableWidgetConfigSchema,
|
|
315
374
|
]);
|
|
316
375
|
export const StoredWidgetConfigSchema = z.discriminatedUnion('target', [
|
|
317
376
|
EmptyWidgetConfigSchema,
|
|
@@ -8,13 +8,6 @@ export type DashboardRecord = {
|
|
|
8
8
|
config: unknown;
|
|
9
9
|
};
|
|
10
10
|
export declare function parseStoredDashboardConfig(config: unknown): DashboardConfig;
|
|
11
|
-
export declare function buildDashboardResponse(dashboard: DashboardRecord): {
|
|
12
|
-
id: string;
|
|
13
|
-
slug: string;
|
|
14
|
-
label: string;
|
|
15
|
-
revision: number;
|
|
16
|
-
config: DashboardConfig;
|
|
17
|
-
};
|
|
18
11
|
export type PersistedDashboardResponse = {
|
|
19
12
|
id: string;
|
|
20
13
|
slug: string;
|
|
@@ -22,14 +15,11 @@ export type PersistedDashboardResponse = {
|
|
|
22
15
|
revision: number;
|
|
23
16
|
config: DashboardConfig;
|
|
24
17
|
};
|
|
25
|
-
export declare function dashboardConfigUpdatedTopic(slug: string): string;
|
|
26
|
-
export declare function normalizeDashboardOrder(config: DashboardConfig): DashboardConfig;
|
|
27
18
|
export declare function getDashboardRecord(adminforth: IAdminForth, dashboardConfigsResourceId: string, slug: string): Promise<DashboardRecord | null>;
|
|
28
19
|
export declare function persistDashboardConfig(adminforth: IAdminForth, dashboardConfigsResourceId: string, dashboard: DashboardRecord, config: DashboardConfig): Promise<PersistedDashboardResponse>;
|
|
29
20
|
export type DashboardConfigService = {
|
|
30
21
|
getDashboardRecord: (slug: string) => Promise<DashboardRecord | null>;
|
|
31
22
|
parseStoredDashboardConfig: typeof parseStoredDashboardConfig;
|
|
32
23
|
persistDashboardConfig: (dashboard: DashboardRecord, config: DashboardConfig) => Promise<PersistedDashboardResponse>;
|
|
33
|
-
buildDashboardResponse: typeof buildDashboardResponse;
|
|
34
24
|
};
|
|
35
25
|
export declare function createDashboardConfigService(adminforth: IAdminForth, dashboardConfigsResourceId: string): DashboardConfigService;
|
|
@@ -8,27 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { Filters } from 'adminforth';
|
|
11
|
-
import {
|
|
12
|
-
|
|
11
|
+
import { getDashboardConfigUpdatedTopic } from '../custom/model/dashboardTopics.js';
|
|
12
|
+
import { DashboardConfigZodSchema } from '../schema/api.js';
|
|
13
13
|
export function parseStoredDashboardConfig(config) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
return normalizeDashboardConfig(config);
|
|
18
|
-
}
|
|
19
|
-
export function buildDashboardResponse(dashboard) {
|
|
20
|
-
return {
|
|
21
|
-
id: dashboard.id,
|
|
22
|
-
slug: dashboard.slug,
|
|
23
|
-
label: dashboard.label,
|
|
24
|
-
revision: dashboard.revision,
|
|
25
|
-
config: parseStoredDashboardConfig(dashboard.config),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
export function dashboardConfigUpdatedTopic(slug) {
|
|
29
|
-
return `${DASHBOARD_CONFIG_UPDATED_TOPIC_PREFIX}/${slug}`;
|
|
14
|
+
const parsedConfig = typeof config === 'string' ? JSON.parse(config) : config;
|
|
15
|
+
return DashboardConfigZodSchema.parse(parsedConfig);
|
|
30
16
|
}
|
|
31
|
-
|
|
17
|
+
function normalizeDashboardOrder(config) {
|
|
32
18
|
var _a;
|
|
33
19
|
const widgetsByGroupId = new Map();
|
|
34
20
|
for (const widget of config.widgets) {
|
|
@@ -55,7 +41,7 @@ export function persistDashboardConfig(adminforth, dashboardConfigsResourceId, d
|
|
|
55
41
|
config: normalizedConfig,
|
|
56
42
|
revision: dashboard.revision + 1,
|
|
57
43
|
});
|
|
58
|
-
yield adminforth.websocket.publish(
|
|
44
|
+
yield adminforth.websocket.publish(getDashboardConfigUpdatedTopic(dashboard.slug), {
|
|
59
45
|
id: dashboard.id,
|
|
60
46
|
slug: dashboard.slug,
|
|
61
47
|
revision: dashboard.revision + 1,
|
|
@@ -74,6 +60,5 @@ export function createDashboardConfigService(adminforth, dashboardConfigsResourc
|
|
|
74
60
|
getDashboardRecord: (slug) => getDashboardRecord(adminforth, dashboardConfigsResourceId, slug),
|
|
75
61
|
parseStoredDashboardConfig,
|
|
76
62
|
persistDashboardConfig: (dashboard, config) => persistDashboardConfig(adminforth, dashboardConfigsResourceId, dashboard, config),
|
|
77
|
-
buildDashboardResponse,
|
|
78
63
|
};
|
|
79
64
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { IAdminForth } from 'adminforth';
|
|
2
|
-
import type { DashboardWidgetConfig, DashboardWidgetData } from '../custom/model/dashboard.types.js';
|
|
2
|
+
import type { DashboardWidgetConfig, DashboardWidgetData, DashboardVariables } from '../custom/model/dashboard.types.js';
|
|
3
3
|
export type DashboardWidgetDataOptions = {
|
|
4
4
|
pagination?: {
|
|
5
5
|
page: number;
|
|
6
6
|
pageSize: number;
|
|
7
7
|
};
|
|
8
|
+
variables?: DashboardVariables;
|
|
8
9
|
};
|
|
9
10
|
export type WidgetDataService = {
|
|
10
11
|
getWidgetData: (widget: DashboardWidgetConfig, options?: DashboardWidgetDataOptions) => Promise<DashboardWidgetData | null>;
|