@adminforth/dashboard 1.1.0 → 1.3.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/README.md +43 -52
- package/custom/composables/useElementSize.ts +17 -2
- package/custom/model/dashboard.types.ts +385 -98
- package/custom/runtime/DashboardRuntime.vue +2 -1
- package/custom/runtime/WidgetRenderer.vue +2 -1
- package/custom/skills/adminforth-dashboard/SKILL.md +8 -4
- package/custom/widgets/chart/ChartWidget.vue +36 -35
- package/custom/widgets/chart/bar/BarChart.vue +20 -12
- package/custom/widgets/chart/chart.types.ts +42 -8
- package/custom/widgets/chart/chart.utils.ts +11 -0
- package/custom/widgets/chart/funnel/FunnelChart.vue +6 -4
- package/custom/widgets/chart/line/LineChart.vue +23 -15
- package/custom/widgets/chart/stacked-bar/StackedBarChart.vue +28 -43
- package/custom/widgets/gauge-card/GaugeCardWidget.vue +7 -43
- package/custom/widgets/kpi-card/KpiCardWidget.vue +6 -10
- package/custom/widgets/pivot-table/PivotTableWidget.vue +10 -11
- package/custom/widgets/table/TableWidget.vue +9 -4
- package/dist/custom/composables/useElementSize.js +14 -2
- package/dist/custom/composables/useElementSize.ts +17 -2
- package/dist/custom/model/dashboard.types.d.ts +179 -38
- package/dist/custom/model/dashboard.types.js +108 -42
- package/dist/custom/model/dashboard.types.ts +385 -98
- package/dist/custom/queries/useDashboardConfig.d.ts +832 -68
- package/dist/custom/queries/useWidgetData.d.ts +828 -64
- package/dist/custom/runtime/DashboardRuntime.vue +2 -1
- package/dist/custom/runtime/WidgetRenderer.vue +2 -1
- package/dist/custom/skills/adminforth-dashboard/SKILL.md +8 -4
- package/dist/custom/widgets/chart/ChartWidget.vue +36 -35
- package/dist/custom/widgets/chart/bar/BarChart.vue +20 -12
- package/dist/custom/widgets/chart/chart.types.d.ts +14 -8
- package/dist/custom/widgets/chart/chart.types.js +23 -0
- package/dist/custom/widgets/chart/chart.types.ts +42 -8
- package/dist/custom/widgets/chart/chart.utils.d.ts +1 -0
- package/dist/custom/widgets/chart/chart.utils.js +7 -0
- package/dist/custom/widgets/chart/chart.utils.ts +11 -0
- package/dist/custom/widgets/chart/funnel/FunnelChart.vue +6 -4
- package/dist/custom/widgets/chart/line/LineChart.vue +23 -15
- package/dist/custom/widgets/chart/stacked-bar/StackedBarChart.vue +28 -43
- package/dist/custom/widgets/gauge-card/GaugeCardWidget.vue +7 -43
- package/dist/custom/widgets/kpi-card/KpiCardWidget.vue +6 -10
- package/dist/custom/widgets/pivot-table/PivotTableWidget.vue +10 -11
- package/dist/custom/widgets/table/TableWidget.vue +9 -4
- package/dist/endpoint/widgets.js +23 -3
- package/dist/schema/api.d.ts +2637 -933
- package/dist/schema/widget.d.ts +1562 -582
- package/dist/schema/widget.js +207 -127
- package/dist/services/widgetConfigValidator.js +16 -80
- package/dist/services/widgetDataService.d.ts +0 -9
- package/dist/services/widgetDataService.js +356 -97
- package/endpoint/dashboard.ts +1 -1
- package/endpoint/widgets.ts +29 -3
- package/package.json +1 -1
- package/schema/widget.ts +221 -121
- package/services/widgetConfigValidator.ts +29 -100
- package/services/widgetDataService.ts +478 -129
package/README.md
CHANGED
|
@@ -30,79 +30,70 @@ Each widget has common fields:
|
|
|
30
30
|
| `target` | Widget type: `table`, `chart`, `kpi_card`, `pivot_table`, or `gauge_card`. |
|
|
31
31
|
| `order` | Widget order inside its group. |
|
|
32
32
|
| `size` | Preset width: `small`, `medium`, `large`, `wide`, or `full`. |
|
|
33
|
-
| `width`, `height`, `
|
|
34
|
-
| `
|
|
35
|
-
| `query` | Optional AdminForth resource query used to load widget data. |
|
|
33
|
+
| `width`, `height`, `min_width`, `max_width` | Optional explicit layout constraints. |
|
|
34
|
+
| `query` | Data query definition. |
|
|
36
35
|
|
|
37
36
|
## Widget Support Matrix
|
|
38
37
|
|
|
39
38
|
| Widget target | Config field | Main settings | Data usage |
|
|
40
39
|
| --- | --- | --- | --- |
|
|
41
|
-
| `table` | `table` | `
|
|
42
|
-
| `chart` | `chart` | `type`, `
|
|
43
|
-
| `kpi_card` | `
|
|
44
|
-
| `gauge_card` | `
|
|
45
|
-
| `pivot_table` | `
|
|
40
|
+
| `table` | `table` | `pagination`, `page_size`, `columns` | Uses `query` to display raw or aggregate rows. |
|
|
41
|
+
| `chart` | `chart` | `type`, `x`, `y`, `label`, `value`, `series`, `buckets`, `color`, `colors` | Uses `query`; funnel charts use `query.steps`. |
|
|
42
|
+
| `kpi_card` | `card` | `value`, `subtitle`, `comparison`, `sparkline` | Reads the first returned query row. |
|
|
43
|
+
| `gauge_card` | `card` | `value`, `target`, `progress`, `color` | Reads the first returned query row. |
|
|
44
|
+
| `pivot_table` | `pivot` | `rows`, `columns`, `values` | Uses query rows to build a pivot table. |
|
|
46
45
|
|
|
47
46
|
Chart widget types:
|
|
48
47
|
|
|
49
48
|
| Chart type | Notes |
|
|
50
49
|
| --- | --- |
|
|
51
|
-
| `line` | Uses `
|
|
52
|
-
| `pie` | Uses `
|
|
53
|
-
| `bar` | Uses `
|
|
54
|
-
| `stacked_bar` | Uses `
|
|
55
|
-
| `funnel` | Uses `
|
|
56
|
-
| `histogram` | Uses
|
|
50
|
+
| `line` | Uses `x` and `y`; `y` may contain multiple fields in config. |
|
|
51
|
+
| `pie` | Uses `label` and `value`. |
|
|
52
|
+
| `bar` | Uses `x` and `y`. |
|
|
53
|
+
| `stacked_bar` | Uses `x`, `y`, and `series`. |
|
|
54
|
+
| `funnel` | Uses `query.steps` and optional `label`, `value`, `colors`. |
|
|
55
|
+
| `histogram` | Uses `x`, `y`, and optional `buckets`. |
|
|
57
56
|
|
|
58
57
|
## Query Shape
|
|
59
58
|
|
|
60
59
|
```ts
|
|
61
|
-
type
|
|
60
|
+
type QueryConfig = {
|
|
62
61
|
resource: string
|
|
63
|
-
select?:
|
|
64
|
-
|
|
65
|
-
field: string
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
select?: Array<
|
|
63
|
+
| { field: string; as?: string; grain?: 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year' }
|
|
64
|
+
| { agg: 'sum' | 'count' | 'count_distinct' | 'avg' | 'min' | 'max' | 'median'; field?: string; as: string; filters?: unknown }
|
|
65
|
+
| { calc: string; as: string }
|
|
66
|
+
>
|
|
67
|
+
filters?: unknown
|
|
68
|
+
group_by?: Array<string | { field: string; as?: string; grain?: 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'; timezone?: string }>
|
|
69
|
+
order_by?: Array<{ field: string; direction?: 'asc' | 'desc' }>
|
|
68
70
|
limit?: number
|
|
71
|
+
offset?: number
|
|
69
72
|
}
|
|
70
73
|
```
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
type
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
field
|
|
91
|
-
|
|
92
|
-
groupBy?:
|
|
93
|
-
| { type: 'field'; field: string }
|
|
94
|
-
| {
|
|
95
|
-
type: 'date_trunc'
|
|
96
|
-
field: string
|
|
97
|
-
truncation: 'day' | 'week' | 'month' | 'year'
|
|
98
|
-
timezone?: string
|
|
99
|
-
}
|
|
100
|
-
filters?: unknown
|
|
101
|
-
}
|
|
75
|
+
Funnel charts use a steps query:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
target: chart
|
|
79
|
+
chart:
|
|
80
|
+
type: funnel
|
|
81
|
+
title: Sales funnel
|
|
82
|
+
query:
|
|
83
|
+
steps:
|
|
84
|
+
- name: Leads
|
|
85
|
+
resource: leads
|
|
86
|
+
metric:
|
|
87
|
+
agg: count
|
|
88
|
+
as: value
|
|
89
|
+
- name: Customers
|
|
90
|
+
resource: orders
|
|
91
|
+
metric:
|
|
92
|
+
agg: count_distinct
|
|
93
|
+
field: customer_id
|
|
94
|
+
as: value
|
|
102
95
|
```
|
|
103
96
|
|
|
104
|
-
`query` remains supported for backwards compatibility. When both are present, widgets prefer `dataSource`.
|
|
105
|
-
|
|
106
97
|
## Runtime Structure
|
|
107
98
|
|
|
108
99
|
```text
|
|
@@ -13,6 +13,7 @@ export function useElementSize<T extends HTMLElement>(): ElementSizeState<T> {
|
|
|
13
13
|
const height = ref(0)
|
|
14
14
|
|
|
15
15
|
let observer: ResizeObserver | undefined
|
|
16
|
+
let frameId: number | undefined
|
|
16
17
|
|
|
17
18
|
onMounted(() => {
|
|
18
19
|
observer = new ResizeObserver(([entry]) => {
|
|
@@ -20,8 +21,18 @@ export function useElementSize<T extends HTMLElement>(): ElementSizeState<T> {
|
|
|
20
21
|
return
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
const nextWidth = Math.floor(entry.contentRect.width)
|
|
25
|
+
const nextHeight = Math.floor(entry.contentRect.height)
|
|
26
|
+
|
|
27
|
+
if (frameId !== undefined) {
|
|
28
|
+
cancelAnimationFrame(frameId)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
frameId = requestAnimationFrame(() => {
|
|
32
|
+
frameId = undefined
|
|
33
|
+
width.value = nextWidth
|
|
34
|
+
height.value = nextHeight
|
|
35
|
+
})
|
|
25
36
|
})
|
|
26
37
|
|
|
27
38
|
if (el.value) {
|
|
@@ -30,6 +41,10 @@ export function useElementSize<T extends HTMLElement>(): ElementSizeState<T> {
|
|
|
30
41
|
})
|
|
31
42
|
|
|
32
43
|
onBeforeUnmount(() => {
|
|
44
|
+
if (frameId !== undefined) {
|
|
45
|
+
cancelAnimationFrame(frameId)
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
observer?.disconnect()
|
|
34
49
|
})
|
|
35
50
|
|