@adminforth/dashboard 1.4.1 → 1.5.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.
@@ -21,19 +21,20 @@ export function registerGroupEndpoints(server, ctx) {
21
21
  response.setStatus(403);
22
22
  return { error: 'Dashboard edit is not allowed' };
23
23
  }
24
- const dashboard = yield ctx.getDashboardRecord(body.slug);
25
- if (!dashboard) {
24
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
25
+ const nextOrder = config.groups.length + 1;
26
+ const group = {
27
+ id: `group_${randomUUID()}`,
28
+ label: 'New group',
29
+ order: nextOrder,
30
+ };
31
+ return Object.assign(Object.assign({}, config), { groups: [...config.groups, group] });
32
+ });
33
+ if (!updatedDashboard) {
26
34
  response.setStatus(404);
27
35
  return { error: 'Dashboard not found' };
28
36
  }
29
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
30
- const nextOrder = config.groups.length + 1;
31
- const group = {
32
- id: `group_${randomUUID()}`,
33
- label: 'New group',
34
- order: nextOrder,
35
- };
36
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { groups: [...config.groups, group] }));
37
+ return updatedDashboard;
37
38
  }),
38
39
  });
39
40
  server.endpoint({
@@ -48,21 +49,27 @@ export function registerGroupEndpoints(server, ctx) {
48
49
  return { error: 'Dashboard edit is not allowed' };
49
50
  }
50
51
  const groupId = body.groupId;
51
- const dashboard = yield ctx.getDashboardRecord(body.slug);
52
- if (!dashboard) {
52
+ let mutationError = null;
53
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
54
+ const group = config.groups.find((item) => item.id === groupId);
55
+ if (!group) {
56
+ mutationError = 'Dashboard group not found';
57
+ return null;
58
+ }
59
+ const nextGroup = Object.assign(Object.assign({}, body.config), { id: group.id, order: group.order });
60
+ return Object.assign(Object.assign({}, config), { groups: config.groups.map((item) => item.id === groupId
61
+ ? nextGroup
62
+ : item) });
63
+ });
64
+ if (!updatedDashboard) {
53
65
  response.setStatus(404);
54
66
  return { error: 'Dashboard not found' };
55
67
  }
56
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
57
- const group = config.groups.find((item) => item.id === groupId);
58
- if (!group) {
68
+ if (mutationError) {
59
69
  response.setStatus(404);
60
- return { error: 'Dashboard group not found' };
70
+ return { error: mutationError };
61
71
  }
62
- const nextGroup = Object.assign(Object.assign({}, body.config), { id: group.id, order: group.order });
63
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { groups: config.groups.map((item) => item.id === groupId
64
- ? nextGroup
65
- : item) }));
72
+ return updatedDashboard;
66
73
  }),
67
74
  });
68
75
  server.endpoint({
@@ -76,32 +83,32 @@ export function registerGroupEndpoints(server, ctx) {
76
83
  response.setStatus(403);
77
84
  return { error: 'Dashboard edit is not allowed' };
78
85
  }
79
- const dashboard = yield ctx.getDashboardRecord(body.slug);
80
- if (!dashboard) {
86
+ let mutationError = null;
87
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
88
+ const sortedGroups = [...config.groups].sort((a, b) => a.order - b.order);
89
+ const currentIndex = sortedGroups.findIndex((group) => group.id === body.groupId);
90
+ if (currentIndex === -1) {
91
+ mutationError = 'Dashboard group not found';
92
+ return null;
93
+ }
94
+ const targetIndex = body.direction === 'up' ? currentIndex - 1 : currentIndex + 1;
95
+ if (targetIndex < 0 || targetIndex >= sortedGroups.length) {
96
+ return null;
97
+ }
98
+ const reorderedGroups = [...sortedGroups];
99
+ const [group] = reorderedGroups.splice(currentIndex, 1);
100
+ reorderedGroups.splice(targetIndex, 0, group);
101
+ return Object.assign(Object.assign({}, config), { groups: reorderedGroups });
102
+ });
103
+ if (!updatedDashboard) {
81
104
  response.setStatus(404);
82
105
  return { error: 'Dashboard not found' };
83
106
  }
84
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
85
- const sortedGroups = [...config.groups].sort((a, b) => a.order - b.order);
86
- const currentIndex = sortedGroups.findIndex((group) => group.id === body.groupId);
87
- if (currentIndex === -1) {
107
+ if (mutationError) {
88
108
  response.setStatus(404);
89
- return { error: 'Dashboard group not found' };
90
- }
91
- const targetIndex = body.direction === 'up' ? currentIndex - 1 : currentIndex + 1;
92
- if (targetIndex < 0 || targetIndex >= sortedGroups.length) {
93
- return {
94
- id: dashboard.id,
95
- slug: dashboard.slug,
96
- label: dashboard.label,
97
- revision: dashboard.revision,
98
- config: ctx.parseStoredDashboardConfig(dashboard.config),
99
- };
109
+ return { error: mutationError };
100
110
  }
101
- const reorderedGroups = [...sortedGroups];
102
- const [group] = reorderedGroups.splice(currentIndex, 1);
103
- reorderedGroups.splice(targetIndex, 0, group);
104
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { groups: reorderedGroups }));
111
+ return updatedDashboard;
105
112
  }),
106
113
  });
107
114
  server.endpoint({
@@ -116,18 +123,24 @@ export function registerGroupEndpoints(server, ctx) {
116
123
  return { error: 'Dashboard edit is not allowed' };
117
124
  }
118
125
  const groupId = body.groupId;
119
- const dashboard = yield ctx.getDashboardRecord(body.slug);
120
- if (!dashboard) {
126
+ let mutationError = null;
127
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
128
+ const nextGroups = config.groups.filter((group) => group.id !== groupId);
129
+ if (nextGroups.length === config.groups.length) {
130
+ mutationError = 'Dashboard group not found';
131
+ return null;
132
+ }
133
+ return Object.assign(Object.assign({}, config), { groups: nextGroups, widgets: config.widgets.filter((widget) => widget.group_id !== groupId) });
134
+ });
135
+ if (!updatedDashboard) {
121
136
  response.setStatus(404);
122
137
  return { error: 'Dashboard not found' };
123
138
  }
124
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
125
- const nextGroups = config.groups.filter((group) => group.id !== groupId);
126
- if (nextGroups.length === config.groups.length) {
139
+ if (mutationError) {
127
140
  response.setStatus(404);
128
- return { error: 'Dashboard group not found' };
141
+ return { error: mutationError };
129
142
  }
130
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { groups: nextGroups, widgets: config.widgets.filter((widget) => widget.group_id !== groupId) }));
143
+ return updatedDashboard;
131
144
  }),
132
145
  });
133
146
  }
@@ -6,6 +6,7 @@ type WidgetEndpointsContext = {
6
6
  getDashboardRecord: (slug: string) => Promise<DashboardRecord | null>;
7
7
  parseStoredDashboardConfig: (config: unknown) => DashboardConfig;
8
8
  persistDashboardConfig: (dashboard: DashboardRecord, config: DashboardConfig) => Promise<PersistedDashboardResponse>;
9
+ updateDashboardConfig: (slug: string, mutateConfig: (config: DashboardConfig, dashboard: DashboardRecord) => DashboardConfig | null | Promise<DashboardConfig | null>) => Promise<PersistedDashboardResponse | null>;
9
10
  getWidgetData: (widget: DashboardWidgetConfig, options?: {
10
11
  pagination?: {
11
12
  page: number;
@@ -21,27 +21,33 @@ export function registerWidgetEndpoints(server, ctx) {
21
21
  response.setStatus(403);
22
22
  return { error: 'Dashboard edit is not allowed' };
23
23
  }
24
- const dashboard = yield ctx.getDashboardRecord(body.slug);
25
- if (!dashboard) {
24
+ let mutationError = null;
25
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
26
+ const group = config.groups.find((item) => item.id === body.groupId);
27
+ if (!group) {
28
+ mutationError = 'Dashboard group not found';
29
+ return null;
30
+ }
31
+ const nextOrder = config.widgets.filter((item) => item.group_id === body.groupId).length + 1;
32
+ const widget = {
33
+ id: `widget_${randomUUID()}`,
34
+ group_id: body.groupId,
35
+ label: 'New widget',
36
+ size: 'small',
37
+ order: nextOrder,
38
+ target: 'empty',
39
+ };
40
+ return Object.assign(Object.assign({}, config), { widgets: [...config.widgets, widget] });
41
+ });
42
+ if (!updatedDashboard) {
26
43
  response.setStatus(404);
27
44
  return { error: 'Dashboard not found' };
28
45
  }
29
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
30
- const group = config.groups.find((item) => item.id === body.groupId);
31
- if (!group) {
46
+ if (mutationError) {
32
47
  response.setStatus(404);
33
- return { error: 'Dashboard group not found' };
48
+ return { error: mutationError };
34
49
  }
35
- const nextOrder = config.widgets.filter((item) => item.group_id === body.groupId).length + 1;
36
- const widget = {
37
- id: `widget_${randomUUID()}`,
38
- group_id: body.groupId,
39
- label: 'New widget',
40
- size: 'small',
41
- order: nextOrder,
42
- target: 'empty',
43
- };
44
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { widgets: [...config.widgets, widget] }));
50
+ return updatedDashboard;
45
51
  }),
46
52
  });
47
53
  server.endpoint({
@@ -55,39 +61,39 @@ export function registerWidgetEndpoints(server, ctx) {
55
61
  response.setStatus(403);
56
62
  return { error: 'Dashboard edit is not allowed' };
57
63
  }
58
- const dashboard = yield ctx.getDashboardRecord(body.slug);
59
- if (!dashboard) {
64
+ let mutationError = null;
65
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
66
+ const widget = config.widgets.find((item) => item.id === body.widgetId);
67
+ if (!widget) {
68
+ mutationError = 'Dashboard widget not found';
69
+ return null;
70
+ }
71
+ const sortedWidgets = config.widgets
72
+ .filter((item) => item.group_id === widget.group_id)
73
+ .sort((a, b) => a.order - b.order);
74
+ const currentIndex = sortedWidgets.findIndex((item) => item.id === body.widgetId);
75
+ const targetIndex = body.direction === 'up' ? currentIndex - 1 : currentIndex + 1;
76
+ if (targetIndex < 0 || targetIndex >= sortedWidgets.length) {
77
+ return null;
78
+ }
79
+ const reorderedWidgets = [...sortedWidgets];
80
+ const [movedWidget] = reorderedWidgets.splice(currentIndex, 1);
81
+ reorderedWidgets.splice(targetIndex, 0, movedWidget);
82
+ const reorderedWidgetIds = new Map(reorderedWidgets.map((item, index) => [item.id, index + 1]));
83
+ return Object.assign(Object.assign({}, config), { widgets: config.widgets.map((item) => {
84
+ var _a;
85
+ return (Object.assign(Object.assign({}, item), { order: (_a = reorderedWidgetIds.get(item.id)) !== null && _a !== void 0 ? _a : item.order }));
86
+ }) });
87
+ });
88
+ if (!updatedDashboard) {
60
89
  response.setStatus(404);
61
90
  return { error: 'Dashboard not found' };
62
91
  }
63
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
64
- const widget = config.widgets.find((item) => item.id === body.widgetId);
65
- if (!widget) {
92
+ if (mutationError) {
66
93
  response.setStatus(404);
67
- return { error: 'Dashboard widget not found' };
94
+ return { error: mutationError };
68
95
  }
69
- const sortedWidgets = config.widgets
70
- .filter((item) => item.group_id === widget.group_id)
71
- .sort((a, b) => a.order - b.order);
72
- const currentIndex = sortedWidgets.findIndex((item) => item.id === body.widgetId);
73
- const targetIndex = body.direction === 'up' ? currentIndex - 1 : currentIndex + 1;
74
- if (targetIndex < 0 || targetIndex >= sortedWidgets.length) {
75
- return {
76
- id: dashboard.id,
77
- slug: dashboard.slug,
78
- label: dashboard.label,
79
- revision: dashboard.revision,
80
- config: ctx.parseStoredDashboardConfig(dashboard.config),
81
- };
82
- }
83
- const reorderedWidgets = [...sortedWidgets];
84
- const [movedWidget] = reorderedWidgets.splice(currentIndex, 1);
85
- reorderedWidgets.splice(targetIndex, 0, movedWidget);
86
- const reorderedWidgetIds = new Map(reorderedWidgets.map((item, index) => [item.id, index + 1]));
87
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { widgets: config.widgets.map((item) => {
88
- var _a;
89
- return (Object.assign(Object.assign({}, item), { order: (_a = reorderedWidgetIds.get(item.id)) !== null && _a !== void 0 ? _a : item.order }));
90
- }) }));
96
+ return updatedDashboard;
91
97
  }),
92
98
  });
93
99
  server.endpoint({
@@ -101,18 +107,24 @@ export function registerWidgetEndpoints(server, ctx) {
101
107
  response.setStatus(403);
102
108
  return { error: 'Dashboard edit is not allowed' };
103
109
  }
104
- const dashboard = yield ctx.getDashboardRecord(body.slug);
105
- if (!dashboard) {
110
+ let mutationError = null;
111
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
112
+ const nextWidgets = config.widgets.filter((item) => item.id !== body.widgetId);
113
+ if (nextWidgets.length === config.widgets.length) {
114
+ mutationError = 'Dashboard widget not found';
115
+ return null;
116
+ }
117
+ return Object.assign(Object.assign({}, config), { widgets: nextWidgets });
118
+ });
119
+ if (!updatedDashboard) {
106
120
  response.setStatus(404);
107
121
  return { error: 'Dashboard not found' };
108
122
  }
109
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
110
- const nextWidgets = config.widgets.filter((item) => item.id !== body.widgetId);
111
- if (nextWidgets.length === config.widgets.length) {
123
+ if (mutationError) {
112
124
  response.setStatus(404);
113
- return { error: 'Dashboard widget not found' };
125
+ return { error: mutationError };
114
126
  }
115
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { widgets: nextWidgets }));
127
+ return updatedDashboard;
116
128
  }),
117
129
  });
118
130
  server.endpoint({
@@ -126,22 +138,28 @@ export function registerWidgetEndpoints(server, ctx) {
126
138
  response.setStatus(403);
127
139
  return { error: 'Dashboard edit is not allowed' };
128
140
  }
129
- const dashboard = yield ctx.getDashboardRecord(body.slug);
130
- if (!dashboard) {
141
+ let mutationError = null;
142
+ const updatedDashboard = yield ctx.updateDashboardConfig(body.slug, (config) => {
143
+ const widget = config.widgets.find((item) => item.id === body.widgetId);
144
+ if (!widget) {
145
+ mutationError = 'Dashboard widget not found';
146
+ return null;
147
+ }
148
+ const typedWidgetConfig = body.config;
149
+ const nextWidget = Object.assign(Object.assign({}, typedWidgetConfig), { id: widget.id, group_id: widget.group_id, order: widget.order });
150
+ return Object.assign(Object.assign({}, config), { widgets: config.widgets.map((item) => item.id === body.widgetId
151
+ ? nextWidget
152
+ : item) });
153
+ });
154
+ if (!updatedDashboard) {
131
155
  response.setStatus(404);
132
156
  return { error: 'Dashboard not found' };
133
157
  }
134
- const config = ctx.parseStoredDashboardConfig(dashboard.config);
135
- const widget = config.widgets.find((item) => item.id === body.widgetId);
136
- if (!widget) {
158
+ if (mutationError) {
137
159
  response.setStatus(404);
138
- return { error: 'Dashboard widget not found' };
160
+ return { error: mutationError };
139
161
  }
140
- const typedWidgetConfig = body.config;
141
- const nextWidget = Object.assign(Object.assign({}, typedWidgetConfig), { id: widget.id, group_id: widget.group_id, order: widget.order });
142
- return ctx.persistDashboardConfig(dashboard, Object.assign(Object.assign({}, config), { widgets: config.widgets.map((item) => item.id === body.widgetId
143
- ? nextWidget
144
- : item) }));
162
+ return updatedDashboard;
145
163
  }),
146
164
  });
147
165
  server.endpoint({