@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
|
@@ -1,42 +1,5 @@
|
|
|
1
1
|
import type { ChartWidgetConfig } from '../widgets/chart/chart.types.js'
|
|
2
2
|
|
|
3
|
-
export type AggregationOperation = 'sum' | 'count' | 'avg' | 'min' | 'max' | 'median'
|
|
4
|
-
|
|
5
|
-
export type AggregationRule = {
|
|
6
|
-
operation: AggregationOperation
|
|
7
|
-
field?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type GroupByRule =
|
|
11
|
-
| {
|
|
12
|
-
type: 'field'
|
|
13
|
-
field: string
|
|
14
|
-
}
|
|
15
|
-
| {
|
|
16
|
-
type: 'date_trunc'
|
|
17
|
-
field: string
|
|
18
|
-
truncation: 'day' | 'week' | 'month' | 'year'
|
|
19
|
-
timezone?: string
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type ResourceWidgetDataSource = {
|
|
23
|
-
type: 'resource'
|
|
24
|
-
resourceId: string
|
|
25
|
-
columns?: string[]
|
|
26
|
-
sort?: unknown
|
|
27
|
-
filters?: unknown
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type AggregateWidgetDataSource = {
|
|
31
|
-
type: 'aggregate'
|
|
32
|
-
resourceId: string
|
|
33
|
-
aggregations: Record<string, AggregationRule>
|
|
34
|
-
groupBy?: GroupByRule
|
|
35
|
-
filters?: unknown
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type WidgetDataSource = ResourceWidgetDataSource | AggregateWidgetDataSource
|
|
39
|
-
|
|
40
3
|
export type DashboardConfig = {
|
|
41
4
|
version: number
|
|
42
5
|
groups: DashboardGroupConfig[]
|
|
@@ -50,18 +13,19 @@ export type DashboardGroupConfig = {
|
|
|
50
13
|
}
|
|
51
14
|
|
|
52
15
|
export type DashboardGroupMoveDirection = 'up' | 'down'
|
|
53
|
-
|
|
54
16
|
export type DashboardWidgetMoveDirection = 'up' | 'down'
|
|
55
|
-
|
|
56
|
-
export type DashboardWidgetTarget =
|
|
57
|
-
| 'empty'
|
|
58
|
-
| 'table'
|
|
59
|
-
| 'chart'
|
|
60
|
-
| 'kpi_card'
|
|
61
|
-
| 'pivot_table'
|
|
62
|
-
| 'gauge_card'
|
|
63
|
-
|
|
17
|
+
export type DashboardWidgetTarget = 'empty' | 'table' | 'chart' | 'kpi_card' | 'pivot_table' | 'gauge_card'
|
|
64
18
|
export type DashboardWidgetSize = 'small' | 'medium' | 'large' | 'wide' | 'full'
|
|
19
|
+
export type QueryAggregateOperation = 'sum' | 'count' | 'count_distinct' | 'avg' | 'min' | 'max' | 'median'
|
|
20
|
+
export type TimeGrain = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
|
|
21
|
+
export type ValueFormat =
|
|
22
|
+
| 'number'
|
|
23
|
+
| 'compact_number'
|
|
24
|
+
| 'currency'
|
|
25
|
+
| 'percent'
|
|
26
|
+
| 'percent_delta'
|
|
27
|
+
| 'number_delta'
|
|
28
|
+
| 'currency_delta'
|
|
65
29
|
|
|
66
30
|
export type WidgetLayout = {
|
|
67
31
|
size?: DashboardWidgetSize
|
|
@@ -71,7 +35,7 @@ export type WidgetLayout = {
|
|
|
71
35
|
height?: number
|
|
72
36
|
}
|
|
73
37
|
|
|
74
|
-
export type
|
|
38
|
+
export type WidgetBaseConfig = {
|
|
75
39
|
id: string
|
|
76
40
|
group_id: string
|
|
77
41
|
label?: string
|
|
@@ -81,16 +45,200 @@ export type DashboardWidgetConfig = {
|
|
|
81
45
|
minWidth?: number
|
|
82
46
|
maxWidth?: number | null
|
|
83
47
|
order: number
|
|
84
|
-
target: DashboardWidgetTarget
|
|
85
|
-
dataSource?: WidgetDataSource
|
|
86
|
-
chart?: ChartWidgetConfig
|
|
87
|
-
table?: unknown
|
|
88
|
-
kpi_card?: unknown
|
|
89
|
-
pivot_table?: unknown
|
|
90
|
-
gauge_card?: unknown
|
|
91
|
-
query?: unknown
|
|
92
48
|
}
|
|
93
49
|
|
|
50
|
+
export type FilterExpression =
|
|
51
|
+
| { and: FilterExpression[] }
|
|
52
|
+
| { or: FilterExpression[] }
|
|
53
|
+
| Array<FilterExpression>
|
|
54
|
+
| {
|
|
55
|
+
field: string
|
|
56
|
+
eq?: unknown
|
|
57
|
+
neq?: unknown
|
|
58
|
+
gt?: unknown
|
|
59
|
+
gte?: unknown
|
|
60
|
+
lt?: unknown
|
|
61
|
+
lte?: unknown
|
|
62
|
+
in?: unknown[]
|
|
63
|
+
not_in?: unknown[]
|
|
64
|
+
like?: unknown
|
|
65
|
+
ilike?: unknown
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type QueryFieldSelectItem = {
|
|
69
|
+
field: string
|
|
70
|
+
as?: string
|
|
71
|
+
grain?: TimeGrain
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export type QueryAggregateSelectItem = {
|
|
75
|
+
agg: QueryAggregateOperation
|
|
76
|
+
field?: string
|
|
77
|
+
as: string
|
|
78
|
+
filters?: FilterExpression
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export type QueryCalcSelectItem = {
|
|
82
|
+
calc: string
|
|
83
|
+
as: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type QuerySelectItem = QueryFieldSelectItem | QueryAggregateSelectItem | QueryCalcSelectItem
|
|
87
|
+
|
|
88
|
+
export type QueryGroupByItem =
|
|
89
|
+
| string
|
|
90
|
+
| {
|
|
91
|
+
field: string
|
|
92
|
+
as?: string
|
|
93
|
+
grain?: TimeGrain
|
|
94
|
+
timezone?: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type QueryOrderByItem = {
|
|
98
|
+
field: string
|
|
99
|
+
direction?: 'asc' | 'desc'
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type QueryConfig = {
|
|
103
|
+
resource: string
|
|
104
|
+
select?: QuerySelectItem[]
|
|
105
|
+
filters?: FilterExpression
|
|
106
|
+
groupBy?: QueryGroupByItem[]
|
|
107
|
+
orderBy?: QueryOrderByItem[]
|
|
108
|
+
limit?: number
|
|
109
|
+
offset?: number
|
|
110
|
+
timeSeries?: {
|
|
111
|
+
field: string
|
|
112
|
+
grain: TimeGrain
|
|
113
|
+
timezone?: string
|
|
114
|
+
}
|
|
115
|
+
period?: {
|
|
116
|
+
field: string
|
|
117
|
+
gte?: unknown
|
|
118
|
+
lt?: unknown
|
|
119
|
+
}
|
|
120
|
+
bucket?: {
|
|
121
|
+
field: string
|
|
122
|
+
buckets: Array<{ label: string, min?: number, max?: number }>
|
|
123
|
+
}
|
|
124
|
+
calcs?: QueryCalcSelectItem[]
|
|
125
|
+
formatting?: Record<string, unknown>
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export type FunnelQueryConfig = {
|
|
129
|
+
steps: FunnelQueryStep[]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type FunnelQueryStep = {
|
|
133
|
+
name: string
|
|
134
|
+
resource: string
|
|
135
|
+
metric: QueryAggregateSelectItem
|
|
136
|
+
filters?: FilterExpression
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export type FieldRef = string | {
|
|
140
|
+
field: string
|
|
141
|
+
label?: string
|
|
142
|
+
format?: ValueFormat
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type TableViewConfig = {
|
|
146
|
+
columns?: FieldRef[]
|
|
147
|
+
pagination?: boolean
|
|
148
|
+
pageSize?: number
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export type KpiCardViewConfig = {
|
|
152
|
+
title?: string
|
|
153
|
+
value: {
|
|
154
|
+
field: string
|
|
155
|
+
format?: ValueFormat
|
|
156
|
+
prefix?: string
|
|
157
|
+
suffix?: string
|
|
158
|
+
}
|
|
159
|
+
subtitle?: {
|
|
160
|
+
text?: string
|
|
161
|
+
field?: string
|
|
162
|
+
}
|
|
163
|
+
comparison?: unknown
|
|
164
|
+
sparkline?: unknown
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export type GaugeCardViewConfig = {
|
|
168
|
+
title?: string
|
|
169
|
+
value: {
|
|
170
|
+
field: string
|
|
171
|
+
format?: ValueFormat
|
|
172
|
+
prefix?: string
|
|
173
|
+
suffix?: string
|
|
174
|
+
}
|
|
175
|
+
target?: {
|
|
176
|
+
value?: number
|
|
177
|
+
field?: string
|
|
178
|
+
label?: string
|
|
179
|
+
}
|
|
180
|
+
progress?: {
|
|
181
|
+
valueField: string
|
|
182
|
+
targetValue?: number
|
|
183
|
+
targetField?: string
|
|
184
|
+
format?: ValueFormat
|
|
185
|
+
}
|
|
186
|
+
color?: string
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export type PivotTableViewConfig = {
|
|
190
|
+
rows: FieldRef[]
|
|
191
|
+
columns?: FieldRef[]
|
|
192
|
+
values: Array<{
|
|
193
|
+
field: string
|
|
194
|
+
label?: string
|
|
195
|
+
format?: ValueFormat
|
|
196
|
+
aggregation?: 'sum' | 'count' | 'avg' | 'min' | 'max'
|
|
197
|
+
}>
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export type EmptyWidgetConfig = WidgetBaseConfig & {
|
|
201
|
+
target: 'empty'
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export type TableWidgetConfig = WidgetBaseConfig & {
|
|
205
|
+
target: 'table'
|
|
206
|
+
table?: TableViewConfig
|
|
207
|
+
query: QueryConfig
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export type ChartDashboardWidgetConfig = WidgetBaseConfig & {
|
|
211
|
+
target: 'chart'
|
|
212
|
+
chart: ChartWidgetConfig
|
|
213
|
+
query: QueryConfig | FunnelQueryConfig
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export type KpiCardWidgetConfig = WidgetBaseConfig & {
|
|
217
|
+
target: 'kpi_card'
|
|
218
|
+
card: KpiCardViewConfig
|
|
219
|
+
query: QueryConfig
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export type GaugeCardWidgetConfig = WidgetBaseConfig & {
|
|
223
|
+
target: 'gauge_card'
|
|
224
|
+
card: GaugeCardViewConfig
|
|
225
|
+
query: QueryConfig
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export type PivotTableWidgetConfig = WidgetBaseConfig & {
|
|
229
|
+
target: 'pivot_table'
|
|
230
|
+
pivot: PivotTableViewConfig
|
|
231
|
+
query: QueryConfig
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export type DashboardWidgetConfig =
|
|
235
|
+
| EmptyWidgetConfig
|
|
236
|
+
| TableWidgetConfig
|
|
237
|
+
| ChartDashboardWidgetConfig
|
|
238
|
+
| KpiCardWidgetConfig
|
|
239
|
+
| GaugeCardWidgetConfig
|
|
240
|
+
| PivotTableWidgetConfig
|
|
241
|
+
|
|
94
242
|
export type DashboardWidgetTableData = {
|
|
95
243
|
kind?: 'table'
|
|
96
244
|
columns: string[]
|
|
@@ -108,6 +256,12 @@ export type DashboardWidgetAggregateData = {
|
|
|
108
256
|
columns: string[]
|
|
109
257
|
rows: Record<string, unknown>[]
|
|
110
258
|
values?: Record<string, unknown>
|
|
259
|
+
pagination?: {
|
|
260
|
+
page: number
|
|
261
|
+
pageSize: number
|
|
262
|
+
total: number
|
|
263
|
+
totalPages: number
|
|
264
|
+
}
|
|
111
265
|
}
|
|
112
266
|
|
|
113
267
|
export type DashboardWidgetData = DashboardWidgetTableData | DashboardWidgetAggregateData
|
|
@@ -130,31 +284,73 @@ export function normalizeDashboardWidgetConfig(config: unknown) {
|
|
|
130
284
|
}
|
|
131
285
|
|
|
132
286
|
const normalized: Record<string, unknown> = { ...config }
|
|
133
|
-
|
|
287
|
+
normalizeWidgetLayoutConfig(normalized)
|
|
134
288
|
|
|
135
|
-
if (
|
|
136
|
-
normalized.
|
|
289
|
+
if (normalized.query !== undefined) {
|
|
290
|
+
normalized.query = normalizeQueryConfig(normalized.query)
|
|
137
291
|
}
|
|
138
292
|
|
|
139
|
-
if (
|
|
140
|
-
|
|
293
|
+
if (normalized.table !== undefined) {
|
|
294
|
+
normalized.table = normalizeTableConfig(normalized.table)
|
|
295
|
+
}
|
|
141
296
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
297
|
+
if (normalized.card !== undefined) {
|
|
298
|
+
normalized.card = normalizeCardConfig(normalized.card)
|
|
145
299
|
}
|
|
146
300
|
|
|
147
|
-
if (
|
|
148
|
-
|
|
301
|
+
if (normalized.pivot !== undefined) {
|
|
302
|
+
normalized.pivot = normalizePivotConfig(normalized.pivot)
|
|
303
|
+
}
|
|
149
304
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
305
|
+
const target = normalizeDashboardWidgetTarget(normalized.target)
|
|
306
|
+
|
|
307
|
+
if (target !== undefined) {
|
|
308
|
+
normalized.target = target
|
|
153
309
|
}
|
|
154
310
|
|
|
155
311
|
return normalized
|
|
156
312
|
}
|
|
157
313
|
|
|
314
|
+
export function serializeDashboardWidgetConfigForEditor(widget: DashboardWidgetConfig) {
|
|
315
|
+
const serialized: Record<string, unknown> = { ...widget }
|
|
316
|
+
|
|
317
|
+
if (Object.prototype.hasOwnProperty.call(serialized, 'minWidth')) {
|
|
318
|
+
serialized.min_width = widget.minWidth
|
|
319
|
+
delete serialized.minWidth
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (Object.prototype.hasOwnProperty.call(serialized, 'maxWidth')) {
|
|
323
|
+
serialized.max_width = widget.maxWidth
|
|
324
|
+
delete serialized.maxWidth
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if ('query' in widget) {
|
|
328
|
+
serialized.query = serializeQueryConfigForEditor(widget.query)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if ('table' in widget && widget.table !== undefined) {
|
|
332
|
+
serialized.table = serializeTableConfigForEditor(widget.table)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if ('card' in widget && widget.card !== undefined) {
|
|
336
|
+
serialized.card = serializeCardConfigForEditor(widget.card)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if ('pivot' in widget && widget.pivot !== undefined) {
|
|
340
|
+
serialized.pivot = serializePivotConfigForEditor(widget.pivot)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return serialized
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export function getFieldRefField(value: FieldRef | undefined) {
|
|
347
|
+
return typeof value === 'string' ? value : value?.field
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export function getFieldRefLabel(value: FieldRef | undefined) {
|
|
351
|
+
return typeof value === 'string' ? value : value?.label
|
|
352
|
+
}
|
|
353
|
+
|
|
158
354
|
function normalizeDashboardWidgetTarget(value: unknown): DashboardWidgetTarget | undefined {
|
|
159
355
|
switch (value) {
|
|
160
356
|
case 'empty':
|
|
@@ -169,62 +365,153 @@ function normalizeDashboardWidgetTarget(value: unknown): DashboardWidgetTarget |
|
|
|
169
365
|
}
|
|
170
366
|
}
|
|
171
367
|
|
|
172
|
-
function
|
|
173
|
-
|
|
368
|
+
function normalizeWidgetLayoutConfig(value: Record<string, unknown>) {
|
|
369
|
+
if (value.min_width !== undefined) {
|
|
370
|
+
value.minWidth = value.min_width
|
|
371
|
+
}
|
|
174
372
|
|
|
175
|
-
if (
|
|
176
|
-
|
|
373
|
+
if (value.max_width !== undefined) {
|
|
374
|
+
value.maxWidth = value.max_width
|
|
177
375
|
}
|
|
376
|
+
}
|
|
178
377
|
|
|
179
|
-
|
|
180
|
-
|
|
378
|
+
function normalizeQueryConfig(value: unknown): unknown {
|
|
379
|
+
if (!isRecord(value)) {
|
|
380
|
+
return value
|
|
181
381
|
}
|
|
182
382
|
|
|
183
|
-
if (
|
|
184
|
-
|
|
383
|
+
if (Array.isArray(value.steps)) {
|
|
384
|
+
return {
|
|
385
|
+
steps: value.steps.map((step) => normalizeFunnelQueryStep(step)),
|
|
386
|
+
}
|
|
185
387
|
}
|
|
186
388
|
|
|
187
|
-
|
|
188
|
-
|
|
389
|
+
return {
|
|
390
|
+
...value,
|
|
391
|
+
...(Array.isArray(value.group_by) ? { groupBy: value.group_by } : {}),
|
|
392
|
+
...(Array.isArray(value.order_by) ? { orderBy: value.order_by } : {}),
|
|
393
|
+
...(value.time_series !== undefined ? { timeSeries: value.time_series } : {}),
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function normalizeFunnelQueryStep(value: unknown) {
|
|
398
|
+
if (!isRecord(value)) {
|
|
399
|
+
return value
|
|
189
400
|
}
|
|
190
401
|
|
|
191
|
-
return
|
|
402
|
+
return {
|
|
403
|
+
...value,
|
|
404
|
+
...(typeof value.resource_id === 'string' ? { resource: value.resource_id } : {}),
|
|
405
|
+
}
|
|
192
406
|
}
|
|
193
407
|
|
|
194
|
-
function
|
|
195
|
-
|
|
408
|
+
function normalizeTableConfig(value: unknown) {
|
|
409
|
+
if (!isRecord(value)) {
|
|
410
|
+
return value
|
|
411
|
+
}
|
|
196
412
|
|
|
197
|
-
|
|
198
|
-
|
|
413
|
+
return {
|
|
414
|
+
...value,
|
|
415
|
+
...(value.page_size !== undefined ? { pageSize: value.page_size } : {}),
|
|
199
416
|
}
|
|
417
|
+
}
|
|
200
418
|
|
|
201
|
-
|
|
202
|
-
|
|
419
|
+
function normalizeCardConfig(value: unknown): unknown {
|
|
420
|
+
if (!isRecord(value)) {
|
|
421
|
+
return value
|
|
203
422
|
}
|
|
204
423
|
|
|
205
|
-
|
|
206
|
-
|
|
424
|
+
const normalized = { ...value }
|
|
425
|
+
|
|
426
|
+
if (isRecord(normalized.progress)) {
|
|
427
|
+
normalized.progress = {
|
|
428
|
+
...normalized.progress,
|
|
429
|
+
...(normalized.progress.value_field !== undefined ? { valueField: normalized.progress.value_field } : {}),
|
|
430
|
+
...(normalized.progress.target_value !== undefined ? { targetValue: normalized.progress.target_value } : {}),
|
|
431
|
+
...(normalized.progress.target_field !== undefined ? { targetField: normalized.progress.target_field } : {}),
|
|
432
|
+
}
|
|
207
433
|
}
|
|
208
434
|
|
|
209
|
-
if (
|
|
210
|
-
|
|
435
|
+
if (isRecord(normalized.comparison)) {
|
|
436
|
+
normalized.comparison = {
|
|
437
|
+
...normalized.comparison,
|
|
438
|
+
...(normalized.comparison.positive_is_good !== undefined ? { positiveIsGood: normalized.comparison.positive_is_good } : {}),
|
|
439
|
+
}
|
|
211
440
|
}
|
|
212
441
|
|
|
213
|
-
|
|
214
|
-
|
|
442
|
+
return normalized
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function normalizePivotConfig(value: unknown): unknown {
|
|
446
|
+
return value
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function serializeQueryConfigForEditor(value: QueryConfig | FunnelQueryConfig) {
|
|
450
|
+
if ('steps' in value) {
|
|
451
|
+
return {
|
|
452
|
+
steps: value.steps.map((step) => ({
|
|
453
|
+
...step,
|
|
454
|
+
resource_id: step.resource,
|
|
455
|
+
resource: undefined,
|
|
456
|
+
})).map((step) => removeUndefinedFields(step)),
|
|
457
|
+
}
|
|
215
458
|
}
|
|
216
459
|
|
|
217
|
-
|
|
218
|
-
|
|
460
|
+
return removeUndefinedFields({
|
|
461
|
+
...value,
|
|
462
|
+
group_by: value.groupBy,
|
|
463
|
+
groupBy: undefined,
|
|
464
|
+
order_by: value.orderBy,
|
|
465
|
+
orderBy: undefined,
|
|
466
|
+
time_series: value.timeSeries,
|
|
467
|
+
timeSeries: undefined,
|
|
468
|
+
})
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function serializeTableConfigForEditor(value: TableViewConfig) {
|
|
472
|
+
return removeUndefinedFields({
|
|
473
|
+
...value,
|
|
474
|
+
page_size: value.pageSize,
|
|
475
|
+
pageSize: undefined,
|
|
476
|
+
})
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function serializeCardConfigForEditor(value: KpiCardViewConfig | GaugeCardViewConfig) {
|
|
480
|
+
const serialized: Record<string, unknown> = { ...value }
|
|
481
|
+
|
|
482
|
+
if (isRecord(serialized.progress)) {
|
|
483
|
+
serialized.progress = removeUndefinedFields({
|
|
484
|
+
...serialized.progress,
|
|
485
|
+
value_field: serialized.progress.valueField,
|
|
486
|
+
valueField: undefined,
|
|
487
|
+
target_value: serialized.progress.targetValue,
|
|
488
|
+
targetValue: undefined,
|
|
489
|
+
target_field: serialized.progress.targetField,
|
|
490
|
+
targetField: undefined,
|
|
491
|
+
})
|
|
219
492
|
}
|
|
220
493
|
|
|
221
|
-
if (
|
|
222
|
-
|
|
494
|
+
if (isRecord(serialized.comparison)) {
|
|
495
|
+
serialized.comparison = removeUndefinedFields({
|
|
496
|
+
...serialized.comparison,
|
|
497
|
+
positive_is_good: serialized.comparison.positiveIsGood,
|
|
498
|
+
positiveIsGood: undefined,
|
|
499
|
+
})
|
|
223
500
|
}
|
|
224
501
|
|
|
225
|
-
return
|
|
502
|
+
return removeUndefinedFields(serialized)
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function serializePivotConfigForEditor(value: PivotTableViewConfig) {
|
|
506
|
+
return value
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function removeUndefinedFields<T extends Record<string, unknown>>(value: T) {
|
|
510
|
+
return Object.fromEntries(
|
|
511
|
+
Object.entries(value).filter(([, item]) => item !== undefined),
|
|
512
|
+
)
|
|
226
513
|
}
|
|
227
514
|
|
|
228
|
-
function isRecord(value: unknown): value is Record<string,
|
|
515
|
+
function isRecord(value: unknown): value is Record<string, any> {
|
|
229
516
|
return typeof value === 'object' && value !== null
|
|
230
517
|
}
|