@adminforth/dashboard 1.4.2 → 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.
@@ -26,6 +26,39 @@ export type PersistedDashboardResponse = {
26
26
  config: DashboardConfig;
27
27
  };
28
28
 
29
+ type DashboardConfigMutator = (
30
+ config: DashboardConfig,
31
+ dashboard: DashboardRecord,
32
+ ) => DashboardConfig | null | Promise<DashboardConfig | null>;
33
+
34
+ const dashboardConfigUpdateQueues = new Map<string, Promise<void>>();
35
+
36
+ async function runDashboardConfigUpdateQueued<T>(
37
+ dashboardSlug: string,
38
+ callback: () => Promise<T>,
39
+ ): Promise<T> {
40
+ const previousUpdate = dashboardConfigUpdateQueues.get(dashboardSlug) ?? Promise.resolve();
41
+ let releaseCurrentUpdate!: () => void;
42
+ const currentUpdate = new Promise<void>((resolve) => {
43
+ releaseCurrentUpdate = resolve;
44
+ });
45
+ const queuedUpdate = previousUpdate.then(() => currentUpdate, () => currentUpdate);
46
+
47
+ dashboardConfigUpdateQueues.set(dashboardSlug, queuedUpdate);
48
+
49
+ await previousUpdate.catch(() => undefined);
50
+
51
+ try {
52
+ return await callback();
53
+ } finally {
54
+ releaseCurrentUpdate();
55
+
56
+ if (dashboardConfigUpdateQueues.get(dashboardSlug) === queuedUpdate) {
57
+ dashboardConfigUpdateQueues.delete(dashboardSlug);
58
+ }
59
+ }
60
+ }
61
+
29
62
  function normalizeDashboardOrder(config: DashboardConfig): DashboardConfig {
30
63
  const widgetsByGroupId = new Map<string, DashboardWidgetConfig[]>();
31
64
 
@@ -91,6 +124,36 @@ export async function persistDashboardConfig(
91
124
  };
92
125
  }
93
126
 
127
+ export async function updateDashboardConfig(
128
+ adminforth: IAdminForth,
129
+ dashboardConfigsResourceId: string,
130
+ slug: string,
131
+ mutateConfig: DashboardConfigMutator,
132
+ ): Promise<PersistedDashboardResponse | null> {
133
+ return runDashboardConfigUpdateQueued(slug, async () => {
134
+ const dashboard = await getDashboardRecord(adminforth, dashboardConfigsResourceId, slug);
135
+
136
+ if (!dashboard) {
137
+ return null;
138
+ }
139
+
140
+ const config = parseStoredDashboardConfig(dashboard.config);
141
+ const nextConfig = await mutateConfig(config, dashboard);
142
+
143
+ if (nextConfig === null) {
144
+ return {
145
+ id: dashboard.id,
146
+ slug: dashboard.slug,
147
+ label: dashboard.label,
148
+ revision: dashboard.revision,
149
+ config,
150
+ };
151
+ }
152
+
153
+ return persistDashboardConfig(adminforth, dashboardConfigsResourceId, dashboard, nextConfig);
154
+ });
155
+ }
156
+
94
157
  export type DashboardConfigService = {
95
158
  getDashboardRecord: (slug: string) => Promise<DashboardRecord | null>;
96
159
  parseStoredDashboardConfig: typeof parseStoredDashboardConfig;
@@ -98,6 +161,10 @@ export type DashboardConfigService = {
98
161
  dashboard: DashboardRecord,
99
162
  config: DashboardConfig,
100
163
  ) => Promise<PersistedDashboardResponse>;
164
+ updateDashboardConfig: (
165
+ slug: string,
166
+ mutateConfig: DashboardConfigMutator,
167
+ ) => Promise<PersistedDashboardResponse | null>;
101
168
  };
102
169
 
103
170
  export function createDashboardConfigService(
@@ -113,5 +180,11 @@ export function createDashboardConfigService(
113
180
  dashboard,
114
181
  config,
115
182
  ),
183
+ updateDashboardConfig: (slug, mutateConfig) => updateDashboardConfig(
184
+ adminforth,
185
+ dashboardConfigsResourceId,
186
+ slug,
187
+ mutateConfig,
188
+ ),
116
189
  };
117
190
  }