@adminforth/dashboard 1.7.0 → 1.8.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/custom/model/dashboard.types.ts +25 -10
- package/custom/skills/adminforth-dashboard/SKILL.md +26 -3
- package/dist/custom/model/dashboard.types.d.ts +19 -7
- package/dist/custom/model/dashboard.types.ts +25 -10
- package/dist/custom/queries/useDashboardConfig.d.ts +322 -4
- package/dist/custom/queries/useWidgetData.d.ts +322 -4
- package/dist/custom/skills/adminforth-dashboard/SKILL.md +26 -3
- package/dist/schema/api.d.ts +8099 -1620
- package/dist/schema/api.js +2 -2
- package/dist/schema/widget.d.ts +622 -33
- package/dist/schema/widget.js +1 -1
- package/dist/schema/widgets/charts.d.ts +785 -39
- package/dist/schema/widgets/charts.js +2 -2
- package/dist/schema/widgets/common.d.ts +35 -6
- package/dist/schema/widgets/common.js +23 -5
- package/dist/schema/widgets/gauge-card.d.ts +56 -2
- package/dist/schema/widgets/kpi-card.d.ts +56 -2
- package/dist/schema/widgets/pivot-table.d.ts +56 -2
- package/dist/schema/widgets/table.d.ts +56 -2
- package/dist/services/widgetDataService.js +37 -32
- package/package.json +1 -1
- package/schema/api.ts +1 -2
- package/schema/widget.ts +0 -1
- package/schema/widgets/charts.ts +1 -2
- package/schema/widgets/common.ts +24 -5
- package/services/widgetDataService.ts +62 -50
|
@@ -9,7 +9,6 @@ import type {
|
|
|
9
9
|
DashboardWidgetConfig,
|
|
10
10
|
DashboardWidgetData,
|
|
11
11
|
DashboardVariables,
|
|
12
|
-
FunnelQueryConfig,
|
|
13
12
|
FilterExpression,
|
|
14
13
|
QueryAggregateSelectItem,
|
|
15
14
|
QueryCalcSelectItem,
|
|
@@ -17,6 +16,8 @@ import type {
|
|
|
17
16
|
QueryFieldSelectItem,
|
|
18
17
|
QueryGroupByItem,
|
|
19
18
|
QueryOrderByItem,
|
|
19
|
+
ResourceQueryConfig,
|
|
20
|
+
StepsQueryStepConfig,
|
|
20
21
|
QuerySelectItem,
|
|
21
22
|
TimeGrain,
|
|
22
23
|
} from '../custom/model/dashboard.types.js';
|
|
@@ -98,9 +99,7 @@ export async function getWidgetData(
|
|
|
98
99
|
return null;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
const data =
|
|
102
|
-
? await getFunnelWidgetData(adminforth, widget.query, options.variables ?? {})
|
|
103
|
-
: await getQueryWidgetData(adminforth, widget.query, options.variables ?? {});
|
|
102
|
+
const data = await getQueryWidgetData(adminforth, widget.query, options.variables ?? {});
|
|
104
103
|
|
|
105
104
|
if (widget.target !== 'table' || !options.pagination) {
|
|
106
105
|
return data;
|
|
@@ -122,50 +121,15 @@ export async function getWidgetData(
|
|
|
122
121
|
};
|
|
123
122
|
}
|
|
124
123
|
|
|
125
|
-
async function getFunnelWidgetData(
|
|
126
|
-
adminforth: IAdminForth,
|
|
127
|
-
query: FunnelQueryConfig,
|
|
128
|
-
variables: DashboardVariables,
|
|
129
|
-
): Promise<DashboardWidgetData> {
|
|
130
|
-
const rows = await Promise.all(query.steps.map(async (step) => {
|
|
131
|
-
const valueField = step.metric.as;
|
|
132
|
-
const [values = {}] = await getAggregateRows(
|
|
133
|
-
adminforth,
|
|
134
|
-
step.resource,
|
|
135
|
-
step.filters,
|
|
136
|
-
[step.metric],
|
|
137
|
-
[],
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
const row: Record<string, unknown> = {
|
|
141
|
-
name: step.name,
|
|
142
|
-
resource: step.resource,
|
|
143
|
-
[valueField]: values[valueField] ?? 0,
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
for (const calc of query.calcs ?? []) {
|
|
147
|
-
row[calc.as] = evaluateCalc(calc.calc, row, variables);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return row;
|
|
151
|
-
}));
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
kind: 'aggregate',
|
|
155
|
-
columns: [
|
|
156
|
-
'name',
|
|
157
|
-
...Array.from(new Set(query.steps.map((step) => step.metric.as))),
|
|
158
|
-
...Array.from(new Set((query.calcs ?? []).map((calc) => calc.as))),
|
|
159
|
-
],
|
|
160
|
-
rows,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
124
|
async function getQueryWidgetData(
|
|
165
125
|
adminforth: IAdminForth,
|
|
166
126
|
query: QueryConfig,
|
|
167
127
|
variables: DashboardVariables,
|
|
168
128
|
): Promise<DashboardWidgetData> {
|
|
129
|
+
if (isStepsQuery(query)) {
|
|
130
|
+
return getStepsQueryData(adminforth, query, variables);
|
|
131
|
+
}
|
|
132
|
+
|
|
169
133
|
const metricSelect = getSingleAggregateMetricSelect(query);
|
|
170
134
|
|
|
171
135
|
if (metricSelect) {
|
|
@@ -203,9 +167,49 @@ async function getQueryWidgetData(
|
|
|
203
167
|
};
|
|
204
168
|
}
|
|
205
169
|
|
|
170
|
+
async function getStepsQueryData(
|
|
171
|
+
adminforth: IAdminForth,
|
|
172
|
+
query: Extract<QueryConfig, { source: 'steps' }>,
|
|
173
|
+
variables: DashboardVariables,
|
|
174
|
+
): Promise<DashboardWidgetData> {
|
|
175
|
+
const rows = await Promise.all(query.steps.map(async (step) => {
|
|
176
|
+
const select = getStepSelect(step);
|
|
177
|
+
const [values = {}] = await getAggregateRows(
|
|
178
|
+
adminforth,
|
|
179
|
+
step.resource,
|
|
180
|
+
step.filters,
|
|
181
|
+
select,
|
|
182
|
+
[],
|
|
183
|
+
);
|
|
184
|
+
const row = buildCalculatedRow({
|
|
185
|
+
name: step.name,
|
|
186
|
+
resource: step.resource,
|
|
187
|
+
...values,
|
|
188
|
+
}, select, query.calcs, variables);
|
|
189
|
+
|
|
190
|
+
return row;
|
|
191
|
+
}));
|
|
192
|
+
const orderedRows = sortRows(rows, query.order_by);
|
|
193
|
+
const slicedRows = typeof query.limit === 'number'
|
|
194
|
+
? orderedRows.slice(query.offset ?? 0, (query.offset ?? 0) + query.limit)
|
|
195
|
+
: orderedRows.slice(query.offset ?? 0);
|
|
196
|
+
const columns = Array.from(new Set([
|
|
197
|
+
'name',
|
|
198
|
+
'resource',
|
|
199
|
+
...query.steps.flatMap((step) => getStepSelect(step).map((item) => item.as)),
|
|
200
|
+
...(query.calcs ?? []).map((item) => item.as),
|
|
201
|
+
]));
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
kind: 'aggregate',
|
|
205
|
+
columns,
|
|
206
|
+
rows: slicedRows,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
206
210
|
async function getMetricWidgetData(
|
|
207
211
|
adminforth: IAdminForth,
|
|
208
|
-
query:
|
|
212
|
+
query: ResourceQueryConfig,
|
|
209
213
|
metric: QueryAggregateSelectItem,
|
|
210
214
|
): Promise<DashboardWidgetData> {
|
|
211
215
|
const [currentValues = {}] = await getAggregateRows(
|
|
@@ -237,7 +241,7 @@ async function getMetricWidgetData(
|
|
|
237
241
|
|
|
238
242
|
async function getMetricSparklineRows(
|
|
239
243
|
adminforth: IAdminForth,
|
|
240
|
-
query:
|
|
244
|
+
query: ResourceQueryConfig,
|
|
241
245
|
metric: QueryAggregateSelectItem,
|
|
242
246
|
filters: DashboardWidgetFilters,
|
|
243
247
|
) {
|
|
@@ -275,14 +279,14 @@ async function getResourceRows(
|
|
|
275
279
|
);
|
|
276
280
|
}
|
|
277
281
|
|
|
278
|
-
function buildPlainQueryRows(rows: Record<string, unknown>[], query:
|
|
282
|
+
function buildPlainQueryRows(rows: Record<string, unknown>[], query: ResourceQueryConfig, variables: DashboardVariables) {
|
|
279
283
|
const select = query.select ?? getDefaultSelect(rows);
|
|
280
284
|
return rows.map((row) => buildPlainRow(row, select, query.calcs, variables));
|
|
281
285
|
}
|
|
282
286
|
|
|
283
287
|
async function buildAggregateQueryRows(
|
|
284
288
|
adminforth: IAdminForth,
|
|
285
|
-
query:
|
|
289
|
+
query: ResourceQueryConfig,
|
|
286
290
|
variables: DashboardVariables,
|
|
287
291
|
) {
|
|
288
292
|
const select = query.select ?? [];
|
|
@@ -449,7 +453,7 @@ function getBackendSort(orderBy: QueryOrderByItem[] | undefined) {
|
|
|
449
453
|
: Sorts.DESC(order.field));
|
|
450
454
|
}
|
|
451
455
|
|
|
452
|
-
function getColumns(rows: Record<string, unknown>[], query:
|
|
456
|
+
function getColumns(rows: Record<string, unknown>[], query: ResourceQueryConfig) {
|
|
453
457
|
const selectColumns = [
|
|
454
458
|
...(query.group_by ?? []).map(getGroupByAlias),
|
|
455
459
|
...(query.select ?? []).map(getSelectAlias),
|
|
@@ -463,14 +467,14 @@ function getDefaultSelect(rows: Record<string, unknown>[]): QuerySelectItem[] {
|
|
|
463
467
|
return Object.keys(rows[0] ?? {}).map((field) => ({ field }));
|
|
464
468
|
}
|
|
465
469
|
|
|
466
|
-
function isAggregateQuery(query:
|
|
470
|
+
function isAggregateQuery(query: ResourceQueryConfig) {
|
|
467
471
|
return Boolean(
|
|
468
472
|
query.group_by?.length
|
|
469
473
|
|| query.select?.some((item) => isAggregateSelectItem(item)),
|
|
470
474
|
);
|
|
471
475
|
}
|
|
472
476
|
|
|
473
|
-
function getSingleAggregateMetricSelect(query:
|
|
477
|
+
function getSingleAggregateMetricSelect(query: ResourceQueryConfig) {
|
|
474
478
|
if (query.group_by?.length) {
|
|
475
479
|
return undefined;
|
|
476
480
|
}
|
|
@@ -485,6 +489,14 @@ function getSingleAggregateMetricSelect(query: QueryConfig) {
|
|
|
485
489
|
return aggregateItems[0];
|
|
486
490
|
}
|
|
487
491
|
|
|
492
|
+
function isStepsQuery(query: QueryConfig): query is Extract<QueryConfig, { source: 'steps' }> {
|
|
493
|
+
return query.source === 'steps';
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function getStepSelect(step: StepsQueryStepConfig): QueryAggregateSelectItem[] {
|
|
497
|
+
return 'select' in step ? step.select : [step.metric];
|
|
498
|
+
}
|
|
499
|
+
|
|
488
500
|
function isFieldSelectItem(item: QuerySelectItem): item is QueryFieldSelectItem {
|
|
489
501
|
return 'field' in item && !('agg' in item);
|
|
490
502
|
}
|