@adminforth/dashboard 1.11.2 → 1.12.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.
Files changed (40) hide show
  1. package/README.md +43 -2
  2. package/custom/api/dashboardApi.ts +72 -10
  3. package/custom/model/dashboard.types.ts +6 -0
  4. package/custom/runtime/DashboardGroup.vue +15 -68
  5. package/custom/runtime/DashboardToolbarButton.vue +32 -0
  6. package/custom/runtime/DashboardToolbarIcon.vue +52 -0
  7. package/custom/runtime/WidgetShell.vue +15 -68
  8. package/custom/skills/adminforth-dashboard/SKILL.md +63 -13
  9. package/custom/widgets/chart/StackedBarChart.vue +64 -7
  10. package/dist/custom/api/dashboardApi.js +59 -10
  11. package/dist/custom/api/dashboardApi.ts +72 -10
  12. package/dist/custom/model/dashboard.types.d.ts +9 -0
  13. package/dist/custom/model/dashboard.types.ts +6 -0
  14. package/dist/custom/queries/useDashboardConfig.d.ts +80 -0
  15. package/dist/custom/queries/useWidgetData.d.ts +80 -0
  16. package/dist/custom/runtime/DashboardGroup.vue +15 -68
  17. package/dist/custom/runtime/DashboardToolbarButton.vue +32 -0
  18. package/dist/custom/runtime/DashboardToolbarIcon.vue +52 -0
  19. package/dist/custom/runtime/WidgetShell.vue +15 -68
  20. package/dist/custom/skills/adminforth-dashboard/SKILL.md +63 -13
  21. package/dist/custom/widgets/chart/StackedBarChart.vue +64 -7
  22. package/dist/schema/api.d.ts +742 -802
  23. package/dist/schema/api.js +2 -2
  24. package/dist/schema/widget.d.ts +75 -81
  25. package/dist/schema/widget.js +1 -1
  26. package/dist/schema/widgets/charts.d.ts +84 -160
  27. package/dist/schema/widgets/charts.js +2 -2
  28. package/dist/schema/widgets/common.d.ts +115 -0
  29. package/dist/schema/widgets/common.js +17 -1
  30. package/dist/schema/widgets/gauge-card.d.ts +8 -0
  31. package/dist/schema/widgets/kpi-card.d.ts +8 -0
  32. package/dist/schema/widgets/pivot-table.d.ts +8 -0
  33. package/dist/schema/widgets/table.d.ts +8 -0
  34. package/dist/services/widgetDataService.js +42 -0
  35. package/package.json +3 -3
  36. package/schema/api.ts +2 -1
  37. package/schema/widget.ts +2 -0
  38. package/schema/widgets/charts.ts +2 -1
  39. package/schema/widgets/common.ts +19 -1
  40. package/services/widgetDataService.ts +68 -0
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <div
3
3
  ref="rootEl"
4
- class="grid h-full min-h-0 w-full grid-rows-[auto_minmax(0,1fr)] gap-3 overflow-hidden"
4
+ class="relative grid h-full min-h-0 w-full grid-rows-[auto_minmax(0,1fr)] gap-3 overflow-hidden"
5
+ @mouseleave="hideTooltip"
5
6
  >
6
7
  <div
7
8
  v-if="showLegend"
@@ -70,9 +71,9 @@
70
71
  :height="segment.height"
71
72
  :fill="segment.color"
72
73
  rx="3"
73
- >
74
- <title>{{ getBarTooltip(bar) }}</title>
75
- </rect>
74
+ @mouseenter="showTooltip($event, bar)"
75
+ @mousemove="moveTooltip($event)"
76
+ />
76
77
 
77
78
  <text
78
79
  v-if="visibleLabelIndexes.has(barIndex)"
@@ -88,13 +89,29 @@
88
89
  </g>
89
90
  </svg>
90
91
  </div>
92
+
93
+ <Teleport to="body">
94
+ <div
95
+ v-if="tooltip"
96
+ class="pointer-events-none fixed z-[1000] min-w-44 rounded border border-lightTableBorder bg-lightTableBackground px-3 py-2 text-xs leading-5 text-lightListTableText shadow-lg dark:border-darkTableBorder dark:bg-darkTableBackground dark:text-darkListTableText"
97
+ :style="{ left: `${tooltip.x}px`, top: `${tooltip.y}px` }"
98
+ >
99
+ <div
100
+ v-for="line in tooltip.lines"
101
+ :key="line"
102
+ class="whitespace-nowrap"
103
+ >
104
+ {{ line }}
105
+ </div>
106
+ </div>
107
+ </Teleport>
91
108
  </div>
92
109
  </template>
93
110
 
94
111
 
95
112
 
96
113
  <script setup lang="ts">
97
- import { computed } from 'vue'
114
+ import { computed, ref } from 'vue'
98
115
  import { useElementSize } from '../../composables/useElementSize.js'
99
116
  import {
100
117
  CHART_COLORS,
@@ -120,6 +137,17 @@ const { el: rootEl, width: rootWidth } = useElementSize<HTMLDivElement>()
120
137
  const { el: svgEl, width: svgWidth, height: svgHeight } = useElementSize<HTMLDivElement>()
121
138
 
122
139
  const barGap = 10
140
+ type StackedBarTooltipBar = {
141
+ label: string
142
+ total: number
143
+ segments: Array<{ name: string, value: number }>
144
+ }
145
+
146
+ const tooltip = ref<{
147
+ x: number
148
+ y: number
149
+ lines: string[]
150
+ } | null>(null)
123
151
  const seriesNames = computed(() => Array.from(new Set(props.rows.map((row) => formatSeriesLabel(row[props.seriesField])))))
124
152
  const normalizedSeries = computed(() => seriesNames.value.map((name, index) => ({
125
153
  name,
@@ -223,7 +251,36 @@ const yTicks = computed(() => [0, 0.5, 1].map((ratio) => ({
223
251
  y: padding.value.top + innerHeight.value * ratio,
224
252
  })))
225
253
 
226
- function getBarTooltip(bar: { label: string, total: number, segments: Array<{ name: string, value: number }> }) {
254
+ function showTooltip(event: MouseEvent, bar: StackedBarTooltipBar) {
255
+ tooltip.value = {
256
+ ...getTooltipPosition(event),
257
+ lines: getBarTooltipLines(bar),
258
+ }
259
+ }
260
+
261
+ function moveTooltip(event: MouseEvent) {
262
+ if (!tooltip.value) {
263
+ return
264
+ }
265
+
266
+ tooltip.value = {
267
+ ...tooltip.value,
268
+ ...getTooltipPosition(event),
269
+ }
270
+ }
271
+
272
+ function hideTooltip() {
273
+ tooltip.value = null
274
+ }
275
+
276
+ function getTooltipPosition(event: MouseEvent) {
277
+ return {
278
+ x: event.clientX + 12,
279
+ y: event.clientY + 12,
280
+ }
281
+ }
282
+
283
+ function getBarTooltipLines(bar: StackedBarTooltipBar) {
227
284
  const percentFormatter = new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 })
228
285
 
229
286
  const segmentLines = bar.segments.map((segment) => {
@@ -238,7 +295,7 @@ function getBarTooltip(bar: { label: string, total: number, segments: Array<{ na
238
295
  `${bar.label}`,
239
296
  `Total: ${formatChartValue(bar.total)}`,
240
297
  ...segmentLines,
241
- ].join('\n')
298
+ ]
242
299
  }
243
300
 
244
301
  function formatSeriesLabel(value: unknown) {
@@ -15,18 +15,67 @@ export class DashboardApiError extends Error {
15
15
  }
16
16
  }
17
17
  function normalizeValidationErrors(response) {
18
- if (Array.isArray(response === null || response === void 0 ? void 0 : response.validationErrors)) {
19
- return response.validationErrors;
18
+ const errors = Array.isArray(response === null || response === void 0 ? void 0 : response.validationErrors)
19
+ ? response.validationErrors
20
+ : Array.isArray(response === null || response === void 0 ? void 0 : response.details)
21
+ ? response.details.map((detail) => ({
22
+ field: getValidationErrorField(detail),
23
+ message: String(detail.message || 'Invalid value'),
24
+ }))
25
+ : [];
26
+ return simplifyValidationErrors(errors);
27
+ }
28
+ function getValidationErrorField(detail) {
29
+ return Array.isArray(detail.instancePath)
30
+ ? detail.instancePath.join('.')
31
+ : String(detail.instancePath || detail.path || 'config').replace(/^\//, '').replaceAll('/', '.');
32
+ }
33
+ function simplifyValidationErrors(errors) {
34
+ const collapsed = new Map();
35
+ for (const error of errors) {
36
+ const selectItemMatch = error.field.match(/^config\.query\.select\.(\d+)$/);
37
+ if (selectItemMatch) {
38
+ const field = error.field;
39
+ collapsed.set(field, {
40
+ field,
41
+ message: 'must be a valid select item: field, aggregate, or calc',
42
+ });
43
+ continue;
44
+ }
45
+ if (isUnionBranchNoise(error)) {
46
+ continue;
47
+ }
48
+ const key = `${error.field}:${error.message}`;
49
+ collapsed.set(key, error);
20
50
  }
21
- if (Array.isArray(response === null || response === void 0 ? void 0 : response.details)) {
22
- return response.details.map((detail) => ({
23
- field: Array.isArray(detail.instancePath)
24
- ? detail.instancePath.join('.')
25
- : String(detail.instancePath || detail.path || 'config').replace(/^\//, '').replaceAll('/', '.'),
26
- message: String(detail.message || 'Invalid value'),
27
- }));
51
+ const simplifiedErrors = Array.from(collapsed.values());
52
+ if (simplifiedErrors.length) {
53
+ return simplifiedErrors;
54
+ }
55
+ return dedupeValidationErrors(errors).filter((error) => error.message !== 'must match a schema in anyOf').slice(0, 5);
56
+ }
57
+ function dedupeValidationErrors(errors) {
58
+ const deduped = new Map();
59
+ for (const error of errors) {
60
+ deduped.set(`${error.field}:${error.message}`, error);
61
+ }
62
+ return Array.from(deduped.values());
63
+ }
64
+ function isUnionBranchNoise(error) {
65
+ if (error.field !== 'config') {
66
+ return false;
28
67
  }
29
- return [];
68
+ return error.message === 'must NOT have additional properties'
69
+ || error.message === 'must match a schema in anyOf'
70
+ || error.message === 'must match exactly one schema in oneOf'
71
+ || error.message === 'must have required property \'chart\''
72
+ || error.message === 'must have required property "chart"'
73
+ || error.message === 'must have required property \'card\''
74
+ || error.message === 'must have required property "card"'
75
+ || error.message === 'must have required property \'table\''
76
+ || error.message === 'must have required property "table"'
77
+ || error.message === 'must have required property \'pivot\''
78
+ || error.message === 'must have required property "pivot"';
30
79
  }
31
80
  function parseDashboardResponse(rawResponse) {
32
81
  return __awaiter(this, void 0, void 0, function* () {
@@ -62,20 +62,82 @@ export class DashboardApiError extends Error {
62
62
  }
63
63
 
64
64
  function normalizeValidationErrors(response: any): DashboardWidgetConfigValidationError[] {
65
- if (Array.isArray(response?.validationErrors)) {
66
- return response.validationErrors
65
+ const errors = Array.isArray(response?.validationErrors)
66
+ ? response.validationErrors
67
+ : Array.isArray(response?.details)
68
+ ? response.details.map((detail: any) => ({
69
+ field: getValidationErrorField(detail),
70
+ message: String(detail.message || 'Invalid value'),
71
+ }))
72
+ : []
73
+
74
+ return simplifyValidationErrors(errors)
75
+ }
76
+
77
+ function getValidationErrorField(detail: any) {
78
+ return Array.isArray(detail.instancePath)
79
+ ? detail.instancePath.join('.')
80
+ : String(detail.instancePath || detail.path || 'config').replace(/^\//, '').replaceAll('/', '.')
81
+ }
82
+
83
+ function simplifyValidationErrors(errors: DashboardWidgetConfigValidationError[]) {
84
+ const collapsed = new Map<string, DashboardWidgetConfigValidationError>()
85
+
86
+ for (const error of errors) {
87
+ const selectItemMatch = error.field.match(/^config\.query\.select\.(\d+)$/)
88
+
89
+ if (selectItemMatch) {
90
+ const field = error.field
91
+ collapsed.set(field, {
92
+ field,
93
+ message: 'must be a valid select item: field, aggregate, or calc',
94
+ })
95
+ continue
96
+ }
97
+
98
+ if (isUnionBranchNoise(error)) {
99
+ continue
100
+ }
101
+
102
+ const key = `${error.field}:${error.message}`
103
+ collapsed.set(key, error)
67
104
  }
68
105
 
69
- if (Array.isArray(response?.details)) {
70
- return response.details.map((detail: any) => ({
71
- field: Array.isArray(detail.instancePath)
72
- ? detail.instancePath.join('.')
73
- : String(detail.instancePath || detail.path || 'config').replace(/^\//, '').replaceAll('/', '.'),
74
- message: String(detail.message || 'Invalid value'),
75
- }))
106
+ const simplifiedErrors = Array.from(collapsed.values())
107
+
108
+ if (simplifiedErrors.length) {
109
+ return simplifiedErrors
110
+ }
111
+
112
+ return dedupeValidationErrors(errors).filter((error) => error.message !== 'must match a schema in anyOf').slice(0, 5)
113
+ }
114
+
115
+ function dedupeValidationErrors(errors: DashboardWidgetConfigValidationError[]) {
116
+ const deduped = new Map<string, DashboardWidgetConfigValidationError>()
117
+
118
+ for (const error of errors) {
119
+ deduped.set(`${error.field}:${error.message}`, error)
120
+ }
121
+
122
+ return Array.from(deduped.values())
123
+ }
124
+
125
+ function isUnionBranchNoise(error: DashboardWidgetConfigValidationError) {
126
+ if (error.field !== 'config') {
127
+ return false
76
128
  }
77
129
 
78
- return []
130
+ return error.message === 'must NOT have additional properties'
131
+ || error.message === 'must match a schema in anyOf'
132
+ || error.message === 'must match exactly one schema in oneOf'
133
+ || error.message === 'must have required property \'chart\''
134
+ || error.message === 'must have required property "chart"'
135
+ || error.message === 'must have required property \'card\''
136
+ || error.message === 'must have required property "card"'
137
+ || error.message === 'must have required property \'table\''
138
+ || error.message === 'must have required property "table"'
139
+ || error.message === 'must have required property \'pivot\''
140
+ || error.message === 'must have required property "pivot"'
79
141
  }
80
142
 
81
143
  async function parseDashboardResponse(rawResponse: Response) {
@@ -113,6 +113,14 @@ export type ResourceQueryConfig = {
113
113
  calcs?: QueryCalcSelectItem[];
114
114
  formatting?: Record<string, JsonValue>;
115
115
  };
116
+ export type QueryBucketConfig = {
117
+ field: string;
118
+ buckets: Array<{
119
+ label: string;
120
+ min?: number;
121
+ max?: number;
122
+ }>;
123
+ };
116
124
  export type StepsQueryStepConfig = {
117
125
  name: string;
118
126
  resource: string;
@@ -122,6 +130,7 @@ export type StepsQueryStepConfig = {
122
130
  export type StepsQueryConfig = {
123
131
  source: 'steps';
124
132
  steps: StepsQueryStepConfig[];
133
+ bucket?: QueryBucketConfig;
125
134
  calcs?: QueryCalcSelectItem[];
126
135
  order_by?: QueryOrderByItem[];
127
136
  limit?: number;
@@ -140,6 +140,11 @@ export type ResourceQueryConfig = {
140
140
  formatting?: Record<string, JsonValue>
141
141
  }
142
142
 
143
+ export type QueryBucketConfig = {
144
+ field: string
145
+ buckets: Array<{ label: string, min?: number, max?: number }>
146
+ }
147
+
143
148
  export type StepsQueryStepConfig = {
144
149
  name: string
145
150
  resource: string
@@ -150,6 +155,7 @@ export type StepsQueryStepConfig = {
150
155
  export type StepsQueryConfig = {
151
156
  source: 'steps'
152
157
  steps: StepsQueryStepConfig[]
158
+ bucket?: QueryBucketConfig
153
159
  calcs?: QueryCalcSelectItem[]
154
160
  order_by?: QueryOrderByItem[]
155
161
  limit?: number
@@ -106,6 +106,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
106
106
  }[];
107
107
  filters?: any;
108
108
  }[];
109
+ bucket?: {
110
+ field: string;
111
+ buckets: {
112
+ label: string;
113
+ min?: number | undefined;
114
+ max?: number | undefined;
115
+ }[];
116
+ } | undefined;
109
117
  calcs?: {
110
118
  calc: string;
111
119
  as: string;
@@ -231,6 +239,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
231
239
  }[];
232
240
  filters?: any;
233
241
  }[];
242
+ bucket?: {
243
+ field: string;
244
+ buckets: {
245
+ label: string;
246
+ min?: number | undefined;
247
+ max?: number | undefined;
248
+ }[];
249
+ } | undefined;
234
250
  calcs?: {
235
251
  calc: string;
236
252
  as: string;
@@ -352,6 +368,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
352
368
  }[];
353
369
  filters?: any;
354
370
  }[];
371
+ bucket?: {
372
+ field: string;
373
+ buckets: {
374
+ label: string;
375
+ min?: number | undefined;
376
+ max?: number | undefined;
377
+ }[];
378
+ } | undefined;
355
379
  calcs?: {
356
380
  calc: string;
357
381
  as: string;
@@ -458,6 +482,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
458
482
  }[];
459
483
  filters?: any;
460
484
  }[];
485
+ bucket?: {
486
+ field: string;
487
+ buckets: {
488
+ label: string;
489
+ min?: number | undefined;
490
+ max?: number | undefined;
491
+ }[];
492
+ } | undefined;
461
493
  calcs?: {
462
494
  calc: string;
463
495
  as: string;
@@ -561,6 +593,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
561
593
  }[];
562
594
  filters?: any;
563
595
  }[];
596
+ bucket?: {
597
+ field: string;
598
+ buckets: {
599
+ label: string;
600
+ min?: number | undefined;
601
+ max?: number | undefined;
602
+ }[];
603
+ } | undefined;
564
604
  calcs?: {
565
605
  calc: string;
566
606
  as: string;
@@ -681,6 +721,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
681
721
  }[];
682
722
  filters?: any;
683
723
  }[];
724
+ bucket?: {
725
+ field: string;
726
+ buckets: {
727
+ label: string;
728
+ min?: number | undefined;
729
+ max?: number | undefined;
730
+ }[];
731
+ } | undefined;
684
732
  calcs?: {
685
733
  calc: string;
686
734
  as: string;
@@ -806,6 +854,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
806
854
  }[];
807
855
  filters?: any;
808
856
  }[];
857
+ bucket?: {
858
+ field: string;
859
+ buckets: {
860
+ label: string;
861
+ min?: number | undefined;
862
+ max?: number | undefined;
863
+ }[];
864
+ } | undefined;
809
865
  calcs?: {
810
866
  calc: string;
811
867
  as: string;
@@ -927,6 +983,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
927
983
  }[];
928
984
  filters?: any;
929
985
  }[];
986
+ bucket?: {
987
+ field: string;
988
+ buckets: {
989
+ label: string;
990
+ min?: number | undefined;
991
+ max?: number | undefined;
992
+ }[];
993
+ } | undefined;
930
994
  calcs?: {
931
995
  calc: string;
932
996
  as: string;
@@ -1033,6 +1097,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
1033
1097
  }[];
1034
1098
  filters?: any;
1035
1099
  }[];
1100
+ bucket?: {
1101
+ field: string;
1102
+ buckets: {
1103
+ label: string;
1104
+ min?: number | undefined;
1105
+ max?: number | undefined;
1106
+ }[];
1107
+ } | undefined;
1036
1108
  calcs?: {
1037
1109
  calc: string;
1038
1110
  as: string;
@@ -1136,6 +1208,14 @@ export declare function useDashboardConfig(slug: Ref<string>): {
1136
1208
  }[];
1137
1209
  filters?: any;
1138
1210
  }[];
1211
+ bucket?: {
1212
+ field: string;
1213
+ buckets: {
1214
+ label: string;
1215
+ min?: number | undefined;
1216
+ max?: number | undefined;
1217
+ }[];
1218
+ } | undefined;
1139
1219
  calcs?: {
1140
1220
  calc: string;
1141
1221
  as: string;
@@ -96,6 +96,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
96
96
  }[];
97
97
  filters?: any;
98
98
  }[];
99
+ bucket?: {
100
+ field: string;
101
+ buckets: {
102
+ label: string;
103
+ min?: number | undefined;
104
+ max?: number | undefined;
105
+ }[];
106
+ } | undefined;
99
107
  calcs?: {
100
108
  calc: string;
101
109
  as: string;
@@ -221,6 +229,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
221
229
  }[];
222
230
  filters?: any;
223
231
  }[];
232
+ bucket?: {
233
+ field: string;
234
+ buckets: {
235
+ label: string;
236
+ min?: number | undefined;
237
+ max?: number | undefined;
238
+ }[];
239
+ } | undefined;
224
240
  calcs?: {
225
241
  calc: string;
226
242
  as: string;
@@ -342,6 +358,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
342
358
  }[];
343
359
  filters?: any;
344
360
  }[];
361
+ bucket?: {
362
+ field: string;
363
+ buckets: {
364
+ label: string;
365
+ min?: number | undefined;
366
+ max?: number | undefined;
367
+ }[];
368
+ } | undefined;
345
369
  calcs?: {
346
370
  calc: string;
347
371
  as: string;
@@ -448,6 +472,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
448
472
  }[];
449
473
  filters?: any;
450
474
  }[];
475
+ bucket?: {
476
+ field: string;
477
+ buckets: {
478
+ label: string;
479
+ min?: number | undefined;
480
+ max?: number | undefined;
481
+ }[];
482
+ } | undefined;
451
483
  calcs?: {
452
484
  calc: string;
453
485
  as: string;
@@ -551,6 +583,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
551
583
  }[];
552
584
  filters?: any;
553
585
  }[];
586
+ bucket?: {
587
+ field: string;
588
+ buckets: {
589
+ label: string;
590
+ min?: number | undefined;
591
+ max?: number | undefined;
592
+ }[];
593
+ } | undefined;
554
594
  calcs?: {
555
595
  calc: string;
556
596
  as: string;
@@ -660,6 +700,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
660
700
  }[];
661
701
  filters?: any;
662
702
  }[];
703
+ bucket?: {
704
+ field: string;
705
+ buckets: {
706
+ label: string;
707
+ min?: number | undefined;
708
+ max?: number | undefined;
709
+ }[];
710
+ } | undefined;
663
711
  calcs?: {
664
712
  calc: string;
665
713
  as: string;
@@ -785,6 +833,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
785
833
  }[];
786
834
  filters?: any;
787
835
  }[];
836
+ bucket?: {
837
+ field: string;
838
+ buckets: {
839
+ label: string;
840
+ min?: number | undefined;
841
+ max?: number | undefined;
842
+ }[];
843
+ } | undefined;
788
844
  calcs?: {
789
845
  calc: string;
790
846
  as: string;
@@ -906,6 +962,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
906
962
  }[];
907
963
  filters?: any;
908
964
  }[];
965
+ bucket?: {
966
+ field: string;
967
+ buckets: {
968
+ label: string;
969
+ min?: number | undefined;
970
+ max?: number | undefined;
971
+ }[];
972
+ } | undefined;
909
973
  calcs?: {
910
974
  calc: string;
911
975
  as: string;
@@ -1012,6 +1076,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
1012
1076
  }[];
1013
1077
  filters?: any;
1014
1078
  }[];
1079
+ bucket?: {
1080
+ field: string;
1081
+ buckets: {
1082
+ label: string;
1083
+ min?: number | undefined;
1084
+ max?: number | undefined;
1085
+ }[];
1086
+ } | undefined;
1015
1087
  calcs?: {
1016
1088
  calc: string;
1017
1089
  as: string;
@@ -1115,6 +1187,14 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
1115
1187
  }[];
1116
1188
  filters?: any;
1117
1189
  }[];
1190
+ bucket?: {
1191
+ field: string;
1192
+ buckets: {
1193
+ label: string;
1194
+ min?: number | undefined;
1195
+ max?: number | undefined;
1196
+ }[];
1197
+ } | undefined;
1118
1198
  calcs?: {
1119
1199
  calc: string;
1120
1200
  as: string;