@tenorlab/react-dashboard 1.4.2 → 1.4.3

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/dist/core.d.ts CHANGED
@@ -5,7 +5,7 @@ export declare const blankDashboardConfig: IDashboardConfig;
5
5
  * Helper function to create dynamic entries
6
6
  * This helps keep the catalog registration clean
7
7
  */
8
- export declare const createDynamicEntry: (key: string, loader: TWidgetFactoryBase, metaData: TWidgetMetaInfoBase) => [string, IDynamicWidgetCatalogEntryBase];
8
+ export declare const createDynamicEntry: (key: string, loader: TWidgetFactoryBase, isRemote: boolean, metaData: TWidgetMetaInfoBase) => [string, IDynamicWidgetCatalogEntryBase];
9
9
 
10
10
  /**
11
11
  * @name createStaticEntry
@@ -185,6 +185,7 @@ export declare interface IDynamicWidgetCatalogEntryBase<TFrameworkElementType =
185
185
  key: TDashboardWidgetKey;
186
186
  title: string;
187
187
  isContainer?: boolean;
188
+ isRemote?: boolean;
188
189
  meta?: TWidgetMetaInfoBase<TFrameworkElementType>;
189
190
  component?: TFrameworkComponentType;
190
191
  loader?: TWidgetFactoryBase<TFrameworkComponentType>;
package/dist/core.es.js CHANGED
@@ -85,60 +85,60 @@ const w = [
85
85
  * @returns the update item
86
86
  */
87
87
  incrementOrDecrementValue: (e, t) => {
88
- const i = e.value.match(/([\d.]+)/), a = i ? parseFloat(i[1]) : 0, s = e.value.match(/([^\d.]+)/), n = s ? s[1] : e.defaultUnit, r = b(n, e.step) * t, c = `${Math.max(a + r, e.minValue).toFixed(1)}${n}`;
88
+ const a = e.value.match(/([\d.]+)/), i = a ? parseFloat(a[1]) : 0, s = e.value.match(/([^\d.]+)/), n = s ? s[1] : e.defaultUnit, r = b(n, e.step) * t, c = `${Math.max(i + r, e.minValue).toFixed(1)}${n}`;
89
89
  return {
90
90
  ...e,
91
91
  value: c
92
92
  };
93
93
  }
94
- }, f = (e, t) => `dashboards_${t}_${e}`, v = async (e, t, i, a) => {
94
+ }, f = (e, t) => `dashboards_${t}_${e}`, v = async (e, t, a, i) => {
95
95
  const s = localStorage.getItem(f(e, t));
96
96
  if (s)
97
97
  try {
98
98
  const n = JSON.parse(s);
99
- return n.length < 1 ? [a] : (n.forEach((r) => {
100
- r.dashboardId || (r.dashboardId = "default"), r.dashboardName || (r.dashboardName = `Dashboard ${r.dashboardId}`), r.responsiveGrid = r.responsiveGrid ?? !1, (r.widgets || []).length < 1 && (r.widgets = a.widgets);
99
+ return n.length < 1 ? [i] : (n.forEach((r) => {
100
+ r.dashboardId || (r.dashboardId = "default"), r.dashboardName || (r.dashboardName = `Dashboard ${r.dashboardId}`), r.responsiveGrid = r.responsiveGrid ?? !1, (r.widgets || []).length < 1 && (r.widgets = i.widgets);
101
101
  const c = (r.cssSettings || []).filter(
102
- (o) => a.cssSettings.some((d) => d.key === o.key)
102
+ (o) => i.cssSettings.some((d) => d.key === o.key)
103
103
  );
104
104
  if (c.length < 1)
105
- r.cssSettings = [...a.cssSettings];
105
+ r.cssSettings = [...i.cssSettings];
106
106
  else {
107
107
  c.forEach((d) => {
108
108
  d.value = (d.value || "").replace(/NaN/g, "");
109
- const l = a.cssSettings.find(
109
+ const l = i.cssSettings.find(
110
110
  (g) => g.key === d.key
111
111
  );
112
112
  l && (Object.keys(l).forEach((g) => {
113
113
  g in d || (d[g] = l[g]);
114
114
  }), d.step = l.step, d.minValue = l.minValue, d.defaultValue = l.defaultValue, d.defaultUnit = l.defaultUnit, /\d+/g.test(d.value) === !1 && (d.value = l ? l.value : "1.0rem"));
115
115
  });
116
- const o = a.cssSettings.filter((d) => !c.some(
116
+ const o = i.cssSettings.filter((d) => !c.some(
117
117
  (l) => l.key === d.key
118
118
  ));
119
119
  r.cssSettings = [...c, ...o];
120
120
  }
121
121
  r.widgets = r.widgets.filter(
122
- (o) => o.includes("WidgetContainer") || i.has(o)
122
+ (o) => o.includes("WidgetContainer") || a.has(o)
123
123
  ), r.childWidgetsConfig = r.childWidgetsConfig.filter(
124
- (o) => i.has(o.widgetKey)
124
+ (o) => a.has(o.widgetKey)
125
125
  ), r.zoomScale ? r.zoomScale < 0.7 && (r.zoomScale = 0.7) : r.zoomScale = 1;
126
126
  }), n);
127
127
  } catch (n) {
128
128
  console.warn("Error parsing saved dashboard config:", n);
129
129
  }
130
- return [a];
131
- }, C = async (e, t, i, a) => {
132
- i.forEach((n) => {
130
+ return [i];
131
+ }, C = async (e, t, a, i) => {
132
+ a.forEach((n) => {
133
133
  if (n.userID = e, n.clientAppKey = t, n.responsiveGrid = n.responsiveGrid ?? !1, typeof n != "object")
134
134
  throw new Error("Invalid dashboard configuration");
135
135
  n.widgets = n.widgets.filter(
136
- (r) => r.includes("WidgetContainer") || a.has(r)
136
+ (r) => r.includes("WidgetContainer") || i.has(r)
137
137
  ), n.childWidgetsConfig = n.childWidgetsConfig.filter(
138
- (r) => a.has(r.widgetKey)
138
+ (r) => i.has(r.widgetKey)
139
139
  ), n.zoomScale ? n.zoomScale < 0.7 && (n.zoomScale = 0.7) : n.zoomScale = 1;
140
140
  });
141
- const s = JSON.stringify(i);
141
+ const s = JSON.stringify(a);
142
142
  return localStorage.setItem(f(e, t), s), !0;
143
143
  }, W = {
144
144
  getSavedDashboards: v,
@@ -160,92 +160,94 @@ const w = [
160
160
  let t = Number(e || 0);
161
161
  return t < m && (t = m), t > p && (t = p), t;
162
162
  }, j = (e, t) => {
163
- let i = Number(Number((V * t).toFixed(2)).toFixed(2)), a = Number((Number(e) + i).toFixed(2));
164
- return D(a);
163
+ let a = Number(Number((V * t).toFixed(2)).toFixed(2)), i = Number((Number(e) + a).toFixed(2));
164
+ return D(i);
165
165
  }, N = (e) => {
166
166
  let t = {
167
167
  ...e
168
168
  };
169
- return t.widgets = t.widgets.filter((i) => {
170
- if (`${i}`.includes("WidgetContainer")) {
171
- const a = t.childWidgetsConfig.filter(
172
- (s) => s.parentWidgetKey === i
169
+ return t.widgets = t.widgets.filter((a) => {
170
+ if (`${a}`.includes("WidgetContainer")) {
171
+ const i = t.childWidgetsConfig.filter(
172
+ (s) => s.parentWidgetKey === a
173
173
  );
174
- if (!a || a.length === 0)
174
+ if (!i || i.length === 0)
175
175
  return t.widgets = t.widgets.filter(
176
- (s) => s !== i
176
+ (s) => s !== a
177
177
  ), !1;
178
178
  }
179
179
  return !0;
180
180
  }), t;
181
181
  }, x = (e) => {
182
182
  const t = e.widgets.filter(
183
- (a) => a.includes("WidgetContainer")
184
- ), i = {};
185
- return t.forEach((a, s) => {
186
- const n = `${a.split("_container")[0]}_container${s + 1}`;
187
- i[a] = n;
188
- }), e.widgets = e.widgets.map((a) => i[a] || a), e.childWidgetsConfig = e.childWidgetsConfig.map((a) => {
189
- const s = a.parentWidgetKey, n = i[s];
183
+ (i) => i.includes("WidgetContainer")
184
+ ), a = {};
185
+ return t.forEach((i, s) => {
186
+ const n = `${i.split("_container")[0]}_container${s + 1}`;
187
+ a[i] = n;
188
+ }), e.widgets = e.widgets.map((i) => a[i] || i), e.childWidgetsConfig = e.childWidgetsConfig.map((i) => {
189
+ const s = i.parentWidgetKey, n = a[s];
190
190
  return {
191
- ...a,
191
+ ...i,
192
192
  // If a new key exists, use it. If not, keep the original key.
193
193
  parentWidgetKey: n || s
194
194
  };
195
195
  }), e;
196
196
  }, u = (e, t) => {
197
- const i = `${e}`.includes("Container"), a = i ? ["Container"] : ["Widget"], s = t?.name || e, n = t?.description || (i ? "Container" : "Unknown");
197
+ const a = `${e}`.includes("Container"), i = a ? ["Container"] : ["Widget"], s = t?.name || e, n = t?.description || (a ? "Container" : "Unknown");
198
198
  return {
199
199
  name: s,
200
200
  description: n,
201
- categories: a,
201
+ categories: i,
202
202
  noDuplicatedWidgets: !0,
203
203
  icon: void 0,
204
204
  externalDependencies: []
205
205
  };
206
- }, I = (e, t, i) => t[e] || u(e, i), M = (e, t) => t.get(e)?.meta || u(e), k = (e, t, i) => {
207
- const a = i || u(e);
206
+ }, I = (e, t, a) => t[e] || u(e, a), M = (e, t) => t.get(e)?.meta || u(e), k = (e, t, a) => {
207
+ const i = a || u(e);
208
208
  return [
209
209
  e,
210
210
  {
211
211
  key: e,
212
- title: a.name,
212
+ title: i.name,
213
213
  isContainer: `${e}`.includes("Container"),
214
- meta: a,
214
+ isRemote: !1,
215
+ meta: i,
215
216
  component: t
216
217
  }
217
218
  ];
218
- }, h = (e, t, i) => {
219
- const a = i || u(e);
219
+ }, h = (e, t, a, i) => {
220
+ const s = i || u(e);
220
221
  return [
221
222
  e,
222
223
  {
223
224
  key: e,
224
- title: a.name,
225
+ title: s.name,
225
226
  isContainer: !1,
226
- meta: a,
227
+ isRemote: a,
228
+ meta: s,
227
229
  loader: t
228
230
  }
229
231
  ];
230
232
  }, F = (e) => {
231
233
  const t = e.match(/\/widget-([a-zA-Z0-9-]+)\/index\.ts$/);
232
234
  if (t && t[1]) {
233
- const i = t[1], a = i.split("-"), s = `Widget${a.map((r) => r.charAt(0).toUpperCase() + r.slice(1)).join("")}`, n = a.map((r) => r.charAt(0).toUpperCase() + r.slice(1)).join(" ");
235
+ const a = t[1], i = a.split("-"), s = `Widget${i.map((r) => r.charAt(0).toUpperCase() + r.slice(1)).join("")}`, n = i.map((r) => r.charAt(0).toUpperCase() + r.slice(1)).join(" ");
234
236
  return {
235
237
  key: s,
236
238
  title: n,
237
- folder: i
239
+ folder: a
238
240
  };
239
241
  }
240
242
  return null;
241
- }, $ = (e, t, i, a) => {
242
- const s = `${t}/widget-${i}/meta.ts`, n = e[s];
243
+ }, $ = (e, t, a, i) => {
244
+ const s = `${t}/widget-${a}/meta.ts`, n = e[s];
243
245
  if (!n)
244
246
  return;
245
- const r = `${a}Meta`;
247
+ const r = `${i}Meta`;
246
248
  return n[r] || void 0;
247
- }, A = async (e) => new Promise(async (t, i) => {
248
- const a = [];
249
+ }, A = async (e) => new Promise(async (t, a) => {
250
+ const i = [];
249
251
  try {
250
252
  const s = await (await fetch(`${e}?${Math.random()}`)).json();
251
253
  for (const n in s) {
@@ -261,32 +263,32 @@ const w = [
261
263
  // Or a logic to map a string name to a Lucide component
262
264
  externalDependencies: r.meta?.externalDependencies || []
263
265
  };
264
- a.push(h(n, c, o));
266
+ i.push(h(n, c, !0, o));
265
267
  }
266
268
  t({
267
- entries: a,
269
+ entries: i,
268
270
  message: "",
269
271
  details: ""
270
272
  });
271
273
  } catch (s) {
272
- console.error("Remote plugin discovery failed:", s), i({
274
+ console.error("Remote plugin discovery failed:", s), a({
273
275
  entries: [],
274
276
  message: "Remote plugin discovery failed:",
275
277
  details: typeof s == "object" ? JSON.stringify(s) : s
276
278
  });
277
279
  }
278
- }), K = (e, t, i, a = !0) => {
280
+ }), K = (e, t, a, i = !0) => {
279
281
  const s = [];
280
282
  for (const n in t) {
281
283
  const r = t[n], c = F(n);
282
284
  if (c && r) {
283
285
  const { key: o, title: d, folder: l } = c;
284
- let g = $(i, e, l, o);
286
+ let g = $(a, e, l, o);
285
287
  if (g || (g = u(o, {
286
- description: `Local ${a ? "dynamic" : "static"} widget`
287
- })), a)
288
+ description: `Local ${i ? "dynamic" : "static"} widget`
289
+ })), i)
288
290
  s.push(
289
- h(o, r, g)
291
+ h(o, r, !1, g)
290
292
  );
291
293
  else {
292
294
  const y = r.default || r;
@@ -295,13 +297,13 @@ const w = [
295
297
  }
296
298
  }
297
299
  return s;
298
- }, G = (e, t = "color") => {
300
+ }, R = (e, t = "color") => {
299
301
  if (typeof window > "u") return "#FFFFFF";
300
- const i = document.createElement("div");
301
- Array.isArray(e) ? e.forEach((s) => i.classList.add(s)) : e.split(" ").forEach((s) => i.classList.add(s)), i.style.display = "none", document.body.appendChild(i);
302
- const a = window.getComputedStyle(i)[t];
303
- return document.body.removeChild(i), a;
304
- }, R = {
302
+ const a = document.createElement("div");
303
+ Array.isArray(e) ? e.forEach((s) => a.classList.add(s)) : e.split(" ").forEach((s) => a.classList.add(s)), a.style.display = "none", document.body.appendChild(a);
304
+ const i = window.getComputedStyle(a)[t];
305
+ return document.body.removeChild(a), i;
306
+ }, G = {
305
307
  /**
306
308
  * @name getCssVariableValue
307
309
  * @description Return the value of a CSS custom property from the current HTML document
@@ -330,8 +332,8 @@ const w = [
330
332
  */
331
333
  restoreCssVarsFromSettings: (e) => {
332
334
  const t = document.documentElement;
333
- e.forEach((i) => {
334
- t.style.setProperty(i.cssProperty, i.value);
335
+ e.forEach((a) => {
336
+ t.style.setProperty(a.cssProperty, a.value);
335
337
  });
336
338
  }
337
339
  }, Z = (e, ...t) => [
@@ -347,7 +349,7 @@ export {
347
349
  h as createDynamicEntry,
348
350
  k as createStaticEntry,
349
351
  w as cssSettingsCatalog,
350
- R as cssVarsUtils,
352
+ G as cssVarsUtils,
351
353
  E as dashboardSettingsUtils,
352
354
  x as ensureContainersSequence,
353
355
  D as ensureZoomScaleIsWithinRange,
@@ -362,6 +364,6 @@ export {
362
364
  F as parseKeyAndTitleFromFilePath,
363
365
  A as remoteWidgetDiscovery,
364
366
  N as removeEmptyContainers,
365
- G as resolveColorFromClass,
367
+ R as resolveColorFromClass,
366
368
  P as useDashboardStorageService
367
369
  };
@@ -169,6 +169,7 @@ export declare interface IDynamicWidgetCatalogEntryBase<TFrameworkElementType =
169
169
  key: TDashboardWidgetKey;
170
170
  title: string;
171
171
  isContainer?: boolean;
172
+ isRemote?: boolean;
172
173
  meta?: TWidgetMetaInfoBase<TFrameworkElementType>;
173
174
  component?: TFrameworkComponentType;
174
175
  loader?: TWidgetFactoryBase<TFrameworkComponentType>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenorlab/react-dashboard",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "Foundation components for creating user-configurable dashboards in React",
5
5
  "author": "Damiano Fusco",
6
6
  "type": "module",
@@ -54,7 +54,7 @@
54
54
  "zustand": "^5.0.0 || ^5.0.9"
55
55
  },
56
56
  "devDependencies": {
57
- "@tenorlab/dashboard-core": "^1.4.1",
57
+ "@tenorlab/dashboard-core": "^1.4.2",
58
58
  "@types/node": "^24.10.1",
59
59
  "@types/react": "19.2.3",
60
60
  "@types/react-dom": "19.2.3",