@adminforth/dashboard 1.8.0 → 1.10.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 +81 -55
- package/custom/api/dashboardApi.ts +73 -36
- package/custom/model/dashboard.types.ts +6 -13
- package/custom/runtime/DashboardRuntime.vue +26 -22
- package/custom/skills/adminforth-dashboard/SKILL.md +13 -20
- package/dist/custom/api/dashboardApi.d.ts +24 -18
- package/dist/custom/api/dashboardApi.js +42 -18
- package/dist/custom/api/dashboardApi.ts +73 -36
- package/dist/custom/model/dashboard.types.d.ts +0 -5
- package/dist/custom/model/dashboard.types.ts +6 -13
- package/dist/custom/queries/useDashboardConfig.d.ts +20 -120
- package/dist/custom/queries/useWidgetData.d.ts +20 -120
- package/dist/custom/runtime/DashboardRuntime.vue +26 -22
- package/dist/custom/skills/adminforth-dashboard/SKILL.md +13 -20
- package/dist/endpoint/groups.js +22 -20
- package/dist/endpoint/widgets.js +28 -26
- package/dist/schema/api.d.ts +230 -3936
- package/dist/schema/api.js +7 -12
- package/dist/schema/widget.d.ts +20 -200
- package/dist/schema/widgets/charts.d.ts +24 -240
- package/dist/schema/widgets/common.d.ts +2 -20
- package/dist/schema/widgets/common.js +1 -10
- package/dist/schema/widgets/gauge-card.d.ts +2 -20
- package/dist/schema/widgets/kpi-card.d.ts +2 -20
- package/dist/schema/widgets/pivot-table.d.ts +2 -20
- package/dist/schema/widgets/table.d.ts +2 -20
- package/dist/services/calc-evaluator.d.ts +2 -0
- package/dist/services/calc-evaluator.js +54 -0
- package/dist/services/dashboardFilterService.d.ts +5 -0
- package/dist/services/dashboardFilterService.js +125 -0
- package/dist/services/widgetDataService.js +15 -168
- package/endpoint/groups.ts +22 -20
- package/endpoint/widgets.ts +28 -26
- package/package.json +2 -1
- package/schema/api.ts +7 -12
- package/schema/widgets/common.ts +1 -11
- package/services/calc-evaluator.ts +71 -0
- package/services/dashboardFilterService.ts +162 -0
- package/services/widgetDataService.ts +26 -213
|
@@ -169,21 +169,18 @@ query:
|
|
|
169
169
|
steps:
|
|
170
170
|
- name: Leads
|
|
171
171
|
resource: leads
|
|
172
|
-
|
|
173
|
-
agg: count
|
|
174
|
-
|
|
172
|
+
select:
|
|
173
|
+
- agg: count
|
|
174
|
+
as: value
|
|
175
175
|
- name: Customers
|
|
176
176
|
resource: orders
|
|
177
|
-
|
|
178
|
-
agg: count_distinct
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
Each step may use either:
|
|
183
|
-
- metric for one aggregate
|
|
184
|
-
- select for multiple aggregate fields
|
|
177
|
+
select:
|
|
178
|
+
- agg: count_distinct
|
|
179
|
+
field: customer_id
|
|
180
|
+
as: value
|
|
185
181
|
|
|
186
182
|
Do not use bare query.steps without source: steps.
|
|
183
|
+
Do not use metric. Use select even when a step has only one aggregate.
|
|
187
184
|
|
|
188
185
|
## Date range rules
|
|
189
186
|
|
|
@@ -224,22 +221,18 @@ select raw token totals:
|
|
|
224
221
|
- sum output_tokens as output_tokens
|
|
225
222
|
|
|
226
223
|
then query.calcs:
|
|
227
|
-
- calculate total_spend from those aliases
|
|
224
|
+
- calculate total_spend from those aliases with explicit constants
|
|
228
225
|
|
|
229
226
|
For today vs yesterday KPI, use multiple aggregate select items with filters and distinct aliases, then calcs.
|
|
230
227
|
|
|
231
|
-
## Calc
|
|
228
|
+
## Calc rules
|
|
232
229
|
|
|
233
|
-
|
|
234
|
-
Use
|
|
230
|
+
Calcs can reference only fields already present in the current row.
|
|
231
|
+
Use explicit constants for rates.
|
|
235
232
|
|
|
236
233
|
Minimal example:
|
|
237
234
|
|
|
238
|
-
variables:
|
|
239
|
-
prices:
|
|
240
|
-
gpt-5.4: 2.5
|
|
241
|
-
|
|
242
235
|
query:
|
|
243
236
|
calcs:
|
|
244
|
-
- calc: tokens / 1000000 *
|
|
237
|
+
- calc: tokens / 1000000 * 2.5
|
|
245
238
|
as: cost
|
package/dist/endpoint/groups.js
CHANGED
|
@@ -8,19 +8,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { randomUUID } from 'crypto';
|
|
11
|
-
import {
|
|
11
|
+
import { DashboardMutationResponseSchema, GroupIdRequestSchema, MoveGroupRequestSchema, SetGroupConfigRequestSchema, SlugRequestSchema, } from '../schema/api.js';
|
|
12
12
|
export function registerGroupEndpoints(server, ctx) {
|
|
13
13
|
server.endpoint({
|
|
14
14
|
method: 'POST',
|
|
15
15
|
path: '/dashboard/add_dashboard_group',
|
|
16
16
|
description: 'Adds a new group to a dashboard configuration. Superadmin only.',
|
|
17
17
|
request_schema: SlugRequestSchema,
|
|
18
|
-
response_schema:
|
|
18
|
+
response_schema: DashboardMutationResponseSchema,
|
|
19
19
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
20
20
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
21
21
|
response.setStatus(403);
|
|
22
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
22
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
23
23
|
}
|
|
24
|
+
let groupId = null;
|
|
24
25
|
const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
|
|
25
26
|
const nextOrder = config.groups.length + 1;
|
|
26
27
|
const group = {
|
|
@@ -28,13 +29,14 @@ export function registerGroupEndpoints(server, ctx) {
|
|
|
28
29
|
label: 'New group',
|
|
29
30
|
order: nextOrder,
|
|
30
31
|
};
|
|
32
|
+
groupId = group.id;
|
|
31
33
|
return Object.assign(Object.assign({}, config), { groups: [...config.groups, group] });
|
|
32
34
|
});
|
|
33
35
|
if (!updatedDashboard) {
|
|
34
36
|
response.setStatus(404);
|
|
35
|
-
return { error: 'Dashboard not found' };
|
|
37
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
36
38
|
}
|
|
37
|
-
return
|
|
39
|
+
return { ok: true, groupId };
|
|
38
40
|
}),
|
|
39
41
|
});
|
|
40
42
|
server.endpoint({
|
|
@@ -42,11 +44,11 @@ export function registerGroupEndpoints(server, ctx) {
|
|
|
42
44
|
path: '/dashboard/set_dashboard_group_config',
|
|
43
45
|
description: 'Replaces editable JSON configuration for a dashboard group while preserving group id and order. Superadmin only.',
|
|
44
46
|
request_schema: SetGroupConfigRequestSchema,
|
|
45
|
-
response_schema:
|
|
47
|
+
response_schema: DashboardMutationResponseSchema,
|
|
46
48
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
47
49
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
48
50
|
response.setStatus(403);
|
|
49
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
51
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
50
52
|
}
|
|
51
53
|
const groupId = body.groupId;
|
|
52
54
|
let mutationError = null;
|
|
@@ -63,13 +65,13 @@ export function registerGroupEndpoints(server, ctx) {
|
|
|
63
65
|
});
|
|
64
66
|
if (!updatedDashboard) {
|
|
65
67
|
response.setStatus(404);
|
|
66
|
-
return { error: 'Dashboard not found' };
|
|
68
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
67
69
|
}
|
|
68
70
|
if (mutationError) {
|
|
69
71
|
response.setStatus(404);
|
|
70
|
-
return { error: mutationError };
|
|
72
|
+
return { ok: false, error: mutationError };
|
|
71
73
|
}
|
|
72
|
-
return
|
|
74
|
+
return { ok: true };
|
|
73
75
|
}),
|
|
74
76
|
});
|
|
75
77
|
server.endpoint({
|
|
@@ -77,11 +79,11 @@ export function registerGroupEndpoints(server, ctx) {
|
|
|
77
79
|
path: '/dashboard/move_dashboard_group',
|
|
78
80
|
description: 'Moves a dashboard group up or down in its dashboard. Superadmin only.',
|
|
79
81
|
request_schema: MoveGroupRequestSchema,
|
|
80
|
-
response_schema:
|
|
82
|
+
response_schema: DashboardMutationResponseSchema,
|
|
81
83
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
82
84
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
83
85
|
response.setStatus(403);
|
|
84
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
86
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
85
87
|
}
|
|
86
88
|
let mutationError = null;
|
|
87
89
|
const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
|
|
@@ -102,13 +104,13 @@ export function registerGroupEndpoints(server, ctx) {
|
|
|
102
104
|
});
|
|
103
105
|
if (!updatedDashboard) {
|
|
104
106
|
response.setStatus(404);
|
|
105
|
-
return { error: 'Dashboard not found' };
|
|
107
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
106
108
|
}
|
|
107
109
|
if (mutationError) {
|
|
108
110
|
response.setStatus(404);
|
|
109
|
-
return { error: mutationError };
|
|
111
|
+
return { ok: false, error: mutationError };
|
|
110
112
|
}
|
|
111
|
-
return
|
|
113
|
+
return { ok: true };
|
|
112
114
|
}),
|
|
113
115
|
});
|
|
114
116
|
server.endpoint({
|
|
@@ -116,11 +118,11 @@ export function registerGroupEndpoints(server, ctx) {
|
|
|
116
118
|
path: '/dashboard/remove_dashboard_group',
|
|
117
119
|
description: 'Removes a dashboard group and all widgets inside it. Superadmin only.',
|
|
118
120
|
request_schema: GroupIdRequestSchema,
|
|
119
|
-
response_schema:
|
|
121
|
+
response_schema: DashboardMutationResponseSchema,
|
|
120
122
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
121
123
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
122
124
|
response.setStatus(403);
|
|
123
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
125
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
124
126
|
}
|
|
125
127
|
const groupId = body.groupId;
|
|
126
128
|
let mutationError = null;
|
|
@@ -134,13 +136,13 @@ export function registerGroupEndpoints(server, ctx) {
|
|
|
134
136
|
});
|
|
135
137
|
if (!updatedDashboard) {
|
|
136
138
|
response.setStatus(404);
|
|
137
|
-
return { error: 'Dashboard not found' };
|
|
139
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
138
140
|
}
|
|
139
141
|
if (mutationError) {
|
|
140
142
|
response.setStatus(404);
|
|
141
|
-
return { error: mutationError };
|
|
143
|
+
return { ok: false, error: mutationError };
|
|
142
144
|
}
|
|
143
|
-
return
|
|
145
|
+
return { ok: true };
|
|
144
146
|
}),
|
|
145
147
|
});
|
|
146
148
|
}
|
package/dist/endpoint/widgets.js
CHANGED
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { randomUUID } from 'crypto';
|
|
11
|
-
import { ConfigureBarChartWidgetRequestSchema, ConfigureFunnelChartWidgetRequestSchema, ConfigureGaugeCardWidgetRequestSchema, ConfigureHistogramChartWidgetRequestSchema, ConfigureKpiCardWidgetRequestSchema, ConfigureLineChartWidgetRequestSchema, ConfigurePieChartWidgetRequestSchema, ConfigurePivotTableWidgetRequestSchema, ConfigureStackedBarChartWidgetRequestSchema, ConfigureTableWidgetRequestSchema,
|
|
11
|
+
import { ConfigureBarChartWidgetRequestSchema, ConfigureFunnelChartWidgetRequestSchema, ConfigureGaugeCardWidgetRequestSchema, ConfigureHistogramChartWidgetRequestSchema, ConfigureKpiCardWidgetRequestSchema, ConfigureLineChartWidgetRequestSchema, ConfigurePieChartWidgetRequestSchema, ConfigurePivotTableWidgetRequestSchema, ConfigureStackedBarChartWidgetRequestSchema, ConfigureTableWidgetRequestSchema, DashboardMutationResponseSchema, DashboardWidgetDataResponseSchema, GroupIdRequestSchema, MoveWidgetRequestSchema, SetWidgetConfigRequestSchema, WidgetDataRequestSchema, WidgetIdRequestSchema, } from '../schema/api.js';
|
|
12
12
|
function replaceWidgetConfig(ctx, slug, widgetId, widgetConfig) {
|
|
13
13
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14
14
|
let mutationError = null;
|
|
@@ -35,23 +35,23 @@ function registerConfigureWidgetEndpoint(server, ctx, options) {
|
|
|
35
35
|
path: options.path,
|
|
36
36
|
description: options.description,
|
|
37
37
|
request_schema: options.requestSchema,
|
|
38
|
-
response_schema:
|
|
38
|
+
response_schema: DashboardMutationResponseSchema,
|
|
39
39
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
40
40
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
41
41
|
response.setStatus(403);
|
|
42
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
42
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
43
43
|
}
|
|
44
44
|
const request = body;
|
|
45
45
|
const { updatedDashboard, mutationError } = yield replaceWidgetConfig(ctx, request.slug, request.widgetId, request.config);
|
|
46
46
|
if (!updatedDashboard) {
|
|
47
47
|
response.setStatus(404);
|
|
48
|
-
return { error: 'Dashboard not found' };
|
|
48
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
49
49
|
}
|
|
50
50
|
if (mutationError) {
|
|
51
51
|
response.setStatus(404);
|
|
52
|
-
return { error: mutationError };
|
|
52
|
+
return { ok: false, error: mutationError };
|
|
53
53
|
}
|
|
54
|
-
return
|
|
54
|
+
return { ok: true };
|
|
55
55
|
}),
|
|
56
56
|
});
|
|
57
57
|
}
|
|
@@ -61,13 +61,14 @@ export function registerWidgetEndpoints(server, ctx) {
|
|
|
61
61
|
path: '/dashboard/add_dashboard_widget',
|
|
62
62
|
description: 'Adds a new empty widget to a dashboard group. Superadmin only.',
|
|
63
63
|
request_schema: GroupIdRequestSchema,
|
|
64
|
-
response_schema:
|
|
64
|
+
response_schema: DashboardMutationResponseSchema,
|
|
65
65
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
66
66
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
67
67
|
response.setStatus(403);
|
|
68
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
68
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
69
69
|
}
|
|
70
70
|
let mutationError = null;
|
|
71
|
+
let widgetId = null;
|
|
71
72
|
const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
|
|
72
73
|
const group = config.groups.find((item) => item.id === body.groupId);
|
|
73
74
|
if (!group) {
|
|
@@ -83,17 +84,18 @@ export function registerWidgetEndpoints(server, ctx) {
|
|
|
83
84
|
order: nextOrder,
|
|
84
85
|
target: 'empty',
|
|
85
86
|
};
|
|
87
|
+
widgetId = widget.id;
|
|
86
88
|
return Object.assign(Object.assign({}, config), { widgets: [...config.widgets, widget] });
|
|
87
89
|
});
|
|
88
90
|
if (!updatedDashboard) {
|
|
89
91
|
response.setStatus(404);
|
|
90
|
-
return { error: 'Dashboard not found' };
|
|
92
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
91
93
|
}
|
|
92
94
|
if (mutationError) {
|
|
93
95
|
response.setStatus(404);
|
|
94
|
-
return { error: mutationError };
|
|
96
|
+
return { ok: false, error: mutationError };
|
|
95
97
|
}
|
|
96
|
-
return
|
|
98
|
+
return { ok: true, widgetId };
|
|
97
99
|
}),
|
|
98
100
|
});
|
|
99
101
|
server.endpoint({
|
|
@@ -101,11 +103,11 @@ export function registerWidgetEndpoints(server, ctx) {
|
|
|
101
103
|
path: '/dashboard/move_dashboard_widget',
|
|
102
104
|
description: 'Moves a dashboard widget up or down inside its group. Superadmin only.',
|
|
103
105
|
request_schema: MoveWidgetRequestSchema,
|
|
104
|
-
response_schema:
|
|
106
|
+
response_schema: DashboardMutationResponseSchema,
|
|
105
107
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
106
108
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
107
109
|
response.setStatus(403);
|
|
108
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
110
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
109
111
|
}
|
|
110
112
|
let mutationError = null;
|
|
111
113
|
const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
|
|
@@ -133,13 +135,13 @@ export function registerWidgetEndpoints(server, ctx) {
|
|
|
133
135
|
});
|
|
134
136
|
if (!updatedDashboard) {
|
|
135
137
|
response.setStatus(404);
|
|
136
|
-
return { error: 'Dashboard not found' };
|
|
138
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
137
139
|
}
|
|
138
140
|
if (mutationError) {
|
|
139
141
|
response.setStatus(404);
|
|
140
|
-
return { error: mutationError };
|
|
142
|
+
return { ok: false, error: mutationError };
|
|
141
143
|
}
|
|
142
|
-
return
|
|
144
|
+
return { ok: true };
|
|
143
145
|
}),
|
|
144
146
|
});
|
|
145
147
|
server.endpoint({
|
|
@@ -147,11 +149,11 @@ export function registerWidgetEndpoints(server, ctx) {
|
|
|
147
149
|
path: '/dashboard/remove_dashboard_widget',
|
|
148
150
|
description: 'Removes one dashboard widget by id. Superadmin only.',
|
|
149
151
|
request_schema: WidgetIdRequestSchema,
|
|
150
|
-
response_schema:
|
|
152
|
+
response_schema: DashboardMutationResponseSchema,
|
|
151
153
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
152
154
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
153
155
|
response.setStatus(403);
|
|
154
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
156
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
155
157
|
}
|
|
156
158
|
let mutationError = null;
|
|
157
159
|
const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
|
|
@@ -164,13 +166,13 @@ export function registerWidgetEndpoints(server, ctx) {
|
|
|
164
166
|
});
|
|
165
167
|
if (!updatedDashboard) {
|
|
166
168
|
response.setStatus(404);
|
|
167
|
-
return { error: 'Dashboard not found' };
|
|
169
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
168
170
|
}
|
|
169
171
|
if (mutationError) {
|
|
170
172
|
response.setStatus(404);
|
|
171
|
-
return { error: mutationError };
|
|
173
|
+
return { ok: false, error: mutationError };
|
|
172
174
|
}
|
|
173
|
-
return
|
|
175
|
+
return { ok: true };
|
|
174
176
|
}),
|
|
175
177
|
});
|
|
176
178
|
server.endpoint({
|
|
@@ -178,23 +180,23 @@ export function registerWidgetEndpoints(server, ctx) {
|
|
|
178
180
|
path: '/dashboard/set_widget_config',
|
|
179
181
|
description: 'Replaces editable JSON configuration for a dashboard widget while preserving widget id, group id, and order. Superadmin only.',
|
|
180
182
|
request_schema: SetWidgetConfigRequestSchema,
|
|
181
|
-
response_schema:
|
|
183
|
+
response_schema: DashboardMutationResponseSchema,
|
|
182
184
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
183
185
|
if (!ctx.canEditDashboard(adminUser)) {
|
|
184
186
|
response.setStatus(403);
|
|
185
|
-
return { error: 'Dashboard edit is not allowed' };
|
|
187
|
+
return { ok: false, error: 'Dashboard edit is not allowed' };
|
|
186
188
|
}
|
|
187
189
|
const request = body;
|
|
188
190
|
const { updatedDashboard, mutationError } = yield replaceWidgetConfig(ctx, request.slug, request.widgetId, request.config);
|
|
189
191
|
if (!updatedDashboard) {
|
|
190
192
|
response.setStatus(404);
|
|
191
|
-
return { error: 'Dashboard not found' };
|
|
193
|
+
return { ok: false, error: 'Dashboard not found' };
|
|
192
194
|
}
|
|
193
195
|
if (mutationError) {
|
|
194
196
|
response.setStatus(404);
|
|
195
|
-
return { error: mutationError };
|
|
197
|
+
return { ok: false, error: mutationError };
|
|
196
198
|
}
|
|
197
|
-
return
|
|
199
|
+
return { ok: true };
|
|
198
200
|
}),
|
|
199
201
|
});
|
|
200
202
|
registerConfigureWidgetEndpoint(server, ctx, {
|