Skip to content

Commit 22efca4

Browse files
committed
feat: refactor widget schemas and data service
- Consolidated widget configuration schemas into separate files for better organization. - Introduced new schemas for various chart types, gauge cards, KPI cards, and pivot tables. - Updated the main API schema to utilize the new widget configurations. - Enhanced the widget data service to support metric-based queries and sparkline data retrieval. - Improved filter value resolution to handle relative date durations. - Added utility functions for handling aggregate metrics and relative date calculations.
1 parent e9788df commit 22efca4

17 files changed

Lines changed: 1343 additions & 530 deletions

File tree

custom/api/dashboardApi.ts

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import type {
22
DashboardConfig,
33
EditableDashboardGroupConfig,
4-
EditableDashboardWidgetConfig,
54
DashboardGroupMoveDirection,
5+
ChartDashboardWidgetConfig,
66
DashboardWidgetConfig,
77
DashboardWidgetConfigValidationError,
88
DashboardWidgetMoveDirection,
9+
GaugeCardWidgetConfig,
10+
KpiCardWidgetConfig,
11+
PivotTableWidgetConfig,
12+
TableWidgetConfig,
913
} from '../model/dashboard.types.js'
1014

1115
export type DashboardResponse = {
@@ -28,6 +32,18 @@ export type DashboardWidgetDataRequest = {
2832
}
2933
}
3034

35+
export type ConfigurableTableWidgetConfig = Omit<TableWidgetConfig, 'id' | 'group_id' | 'order'>
36+
export type ConfigurableKpiCardWidgetConfig = Omit<KpiCardWidgetConfig, 'id' | 'group_id' | 'order'>
37+
export type ConfigurableGaugeCardWidgetConfig = Omit<GaugeCardWidgetConfig, 'id' | 'group_id' | 'order'>
38+
export type ConfigurableChartWidgetConfig = Omit<ChartDashboardWidgetConfig, 'id' | 'group_id' | 'order'>
39+
export type ConfigurableLineChartWidgetConfig = ConfigurableChartWidgetConfig & { chart: { type: 'line' } }
40+
export type ConfigurableBarChartWidgetConfig = ConfigurableChartWidgetConfig & { chart: { type: 'bar' } }
41+
export type ConfigurableStackedBarChartWidgetConfig = ConfigurableChartWidgetConfig & { chart: { type: 'stacked_bar' } }
42+
export type ConfigurablePieChartWidgetConfig = ConfigurableChartWidgetConfig & { chart: { type: 'pie' } }
43+
export type ConfigurableHistogramChartWidgetConfig = ConfigurableChartWidgetConfig & { chart: { type: 'histogram' } }
44+
export type ConfigurableFunnelChartWidgetConfig = ConfigurableChartWidgetConfig & { chart: { type: 'funnel' } }
45+
export type ConfigurablePivotTableWidgetConfig = Omit<PivotTableWidgetConfig, 'id' | 'group_id' | 'order'>
46+
3147
export class DashboardApiError extends Error {
3248
validationErrors: DashboardWidgetConfigValidationError[]
3349

@@ -205,6 +221,126 @@ export const dashboardApi = {
205221
})
206222
},
207223

224+
async configureTableWidget(
225+
slug: string,
226+
widgetId: string,
227+
config: ConfigurableTableWidgetConfig,
228+
): Promise<DashboardResponse> {
229+
return callDashboardApi('/adminapi/v1/dashboard/configure_table_widget', {
230+
slug,
231+
widgetId,
232+
config,
233+
})
234+
},
235+
236+
async configureKpiCardWidget(
237+
slug: string,
238+
widgetId: string,
239+
config: ConfigurableKpiCardWidgetConfig,
240+
): Promise<DashboardResponse> {
241+
return callDashboardApi('/adminapi/v1/dashboard/configure_kpi_card_widget', {
242+
slug,
243+
widgetId,
244+
config,
245+
})
246+
},
247+
248+
async configureGaugeCardWidget(
249+
slug: string,
250+
widgetId: string,
251+
config: ConfigurableGaugeCardWidgetConfig,
252+
): Promise<DashboardResponse> {
253+
return callDashboardApi('/adminapi/v1/dashboard/configure_gauge_card_widget', {
254+
slug,
255+
widgetId,
256+
config,
257+
})
258+
},
259+
260+
async configureLineChartWidget(
261+
slug: string,
262+
widgetId: string,
263+
config: ConfigurableLineChartWidgetConfig,
264+
): Promise<DashboardResponse> {
265+
return callDashboardApi('/adminapi/v1/dashboard/configure_line_chart_widget', {
266+
slug,
267+
widgetId,
268+
config,
269+
})
270+
},
271+
272+
async configureBarChartWidget(
273+
slug: string,
274+
widgetId: string,
275+
config: ConfigurableBarChartWidgetConfig,
276+
): Promise<DashboardResponse> {
277+
return callDashboardApi('/adminapi/v1/dashboard/configure_bar_chart_widget', {
278+
slug,
279+
widgetId,
280+
config,
281+
})
282+
},
283+
284+
async configureStackedBarChartWidget(
285+
slug: string,
286+
widgetId: string,
287+
config: ConfigurableStackedBarChartWidgetConfig,
288+
): Promise<DashboardResponse> {
289+
return callDashboardApi('/adminapi/v1/dashboard/configure_stacked_bar_chart_widget', {
290+
slug,
291+
widgetId,
292+
config,
293+
})
294+
},
295+
296+
async configurePieChartWidget(
297+
slug: string,
298+
widgetId: string,
299+
config: ConfigurablePieChartWidgetConfig,
300+
): Promise<DashboardResponse> {
301+
return callDashboardApi('/adminapi/v1/dashboard/configure_pie_chart_widget', {
302+
slug,
303+
widgetId,
304+
config,
305+
})
306+
},
307+
308+
async configureHistogramChartWidget(
309+
slug: string,
310+
widgetId: string,
311+
config: ConfigurableHistogramChartWidgetConfig,
312+
): Promise<DashboardResponse> {
313+
return callDashboardApi('/adminapi/v1/dashboard/configure_histogram_chart_widget', {
314+
slug,
315+
widgetId,
316+
config,
317+
})
318+
},
319+
320+
async configureFunnelChartWidget(
321+
slug: string,
322+
widgetId: string,
323+
config: ConfigurableFunnelChartWidgetConfig,
324+
): Promise<DashboardResponse> {
325+
return callDashboardApi('/adminapi/v1/dashboard/configure_funnel_chart_widget', {
326+
slug,
327+
widgetId,
328+
config,
329+
})
330+
},
331+
332+
async configurePivotTableWidget(
333+
slug: string,
334+
widgetId: string,
335+
config: ConfigurablePivotTableWidgetConfig,
336+
): Promise<DashboardResponse> {
337+
return callDashboardApi('/adminapi/v1/dashboard/configure_pivot_table_widget', {
338+
slug,
339+
widgetId,
340+
config,
341+
})
342+
},
343+
208344
async getDashboardWidgetData(
209345
slug: string,
210346
widgetId: string,

custom/model/dashboard.types.ts

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export type QueryAggregateOperation = 'sum' | 'count' | 'count_distinct' | 'avg'
3636
export type TimeGrain = 'day' | 'week' | 'month' | 'year'
3737
export type ValueFormat =
3838
| 'number'
39+
| 'integer'
3940
| 'compact_number'
4041
| 'currency'
4142
| 'percent'
@@ -119,21 +120,17 @@ export type QueryOrderByItem = {
119120
export type QueryConfig = {
120121
resource: string
121122
select?: QuerySelectItem[]
123+
sparkline?: {
124+
field: string
125+
grain: TimeGrain
126+
as: string
127+
fill_missing?: Record<string, JsonValue>
128+
}
122129
filters?: FilterExpression
123130
group_by?: QueryGroupByItem[]
124131
order_by?: QueryOrderByItem[]
125132
limit?: number
126133
offset?: number
127-
time_series?: {
128-
field: string
129-
grain: TimeGrain
130-
timezone?: string
131-
}
132-
period?: {
133-
field: string
134-
gte?: JsonValue
135-
lt?: JsonValue
136-
}
137134
bucket?: {
138135
field: string
139136
buckets: Array<{ label: string, min?: number, max?: number }>
@@ -178,8 +175,29 @@ export type KpiCardViewConfig = {
178175
text?: string
179176
field?: string
180177
}
181-
comparison?: JsonValue
182-
sparkline?: JsonValue
178+
comparison?: {
179+
field: string
180+
format?: ValueFormat
181+
positive_is_good?: boolean
182+
compact?: {
183+
show?: boolean
184+
template?: string
185+
}
186+
tooltip?: {
187+
label?: string
188+
template?: string
189+
}
190+
}
191+
sparkline?: {
192+
type?: 'line'
193+
field: string
194+
x: string
195+
show_axes?: boolean
196+
show_labels?: boolean
197+
fill?: {
198+
type?: 'gradient' | 'solid'
199+
}
200+
}
183201
}
184202

185203
export type GaugeCardViewConfig = {
@@ -257,14 +275,6 @@ export type DashboardWidgetConfig =
257275
| GaugeCardWidgetConfig
258276
| PivotTableWidgetConfig
259277

260-
export type EditableDashboardWidgetConfig =
261-
| Omit<EmptyWidgetConfig, 'id' | 'group_id' | 'order'>
262-
| Omit<TableWidgetConfig, 'id' | 'group_id' | 'order'>
263-
| Omit<ChartDashboardWidgetConfig, 'id' | 'group_id' | 'order'>
264-
| Omit<KpiCardWidgetConfig, 'id' | 'group_id' | 'order'>
265-
| Omit<GaugeCardWidgetConfig, 'id' | 'group_id' | 'order'>
266-
| Omit<PivotTableWidgetConfig, 'id' | 'group_id' | 'order'>
267-
268278
export type DashboardWidgetTableData = {
269279
kind?: 'table'
270280
columns: string[]
@@ -299,10 +309,10 @@ export function serializeDashboardWidgetConfigForEditor(
299309
id: _id,
300310
group_id: _groupId,
301311
order: _order,
302-
...editableWidget
312+
...editableWidgetConfig
303313
} = widget
304314

305-
return editableWidget
315+
return editableWidgetConfig
306316
}
307317

308318
export function getFieldRefField(value: FieldRef | undefined) {

custom/runtime/DashboardRuntime.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ import type {
208208
DashboardConfig,
209209
DashboardGroupConfig,
210210
EditableDashboardGroupConfig,
211-
EditableDashboardWidgetConfig,
212211
DashboardGroupMoveDirection,
213212
DashboardWidgetConfig,
214213
DashboardWidgetMoveDirection,
@@ -414,13 +413,13 @@ async function saveWidgetConfig() {
414413
try {
415414
widgetConfigError.value = ''
416415
widgetConfigFieldErrors.value = []
417-
const widgetConfig = parseYaml(widgetConfigCode.value) as EditableDashboardWidgetConfig
416+
const widgetConfig = parseYaml(widgetConfigCode.value) as DashboardWidgetConfig
418417
419418
applyDashboardResponse(
420419
await dashboardApi.setWidgetConfig(
421420
props.dashboardSlug,
422421
editingWidgetId.value,
423-
widgetConfig,
422+
serializeDashboardWidgetConfigForEditor(widgetConfig),
424423
),
425424
)
426425
closeWidgetConfigEditor()

0 commit comments

Comments
 (0)