@richardmcquiston01/dashboard-widgets-toolkit 0.16.0 → 0.17.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/dist/core.cjs +103 -15
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +10 -2
- package/dist/core.d.ts +10 -2
- package/dist/core.js +100 -16
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +103 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +100 -16
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +105 -12
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +10 -1
- package/dist/react.d.ts +10 -1
- package/dist/react.js +105 -12
- package/dist/react.js.map +1 -1
- package/dist/{storage-oivwB7al.d.cts → storage-CRBfjiVZ.d.cts} +59 -8
- package/dist/{storage-oivwB7al.d.ts → storage-CRBfjiVZ.d.ts} +59 -8
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement, RefObject } from 'react';
|
|
2
|
-
import { D as DashboardWidget, W as WidgetSize, a as WidgetFill, G as GraphWidgetData, N as NiceDomain, b as WidgetDefinition, c as DetailProviderOptions, d as DetailData, e as DetailQuery, O as OptionValues, L as Locale, f as DashboardLayout, g as WidgetViewerSettings, h as WidgetSettingsPatch, A as AlertListWidgetData, B as BarListWidgetData, i as GaugeWidgetData, K as KpiWidgetData, T as TableWidgetData, R as ResolvedTableControls, j as DetailSort, k as TextWidgetData, l as WidgetData, m as LayoutPersistence, S as StoreScope, P as PageItem, n as NormalizeOptions, o as ResolveOptions, p as WidgetContext, q as WidgetProviders } from './storage-
|
|
2
|
+
import { D as DashboardWidget, W as WidgetSize, a as WidgetFill, G as GraphWidgetData, N as NiceDomain, b as WidgetDefinition, c as DetailProviderOptions, d as DetailData, e as DetailQuery, O as OptionValues, L as Locale, f as DashboardLayout, g as WidgetViewerSettings, h as WidgetSettingsPatch, A as AlertListWidgetData, B as BarListWidgetData, i as GaugeWidgetData, K as KpiWidgetData, T as TableWidgetData, R as ResolvedTableControls, j as DetailSort, k as TextWidgetData, l as WidgetData, m as LayoutPersistence, S as StoreScope, P as PageItem, n as NormalizeOptions, o as ResolveOptions, p as WidgetContext, q as WidgetProviders } from './storage-CRBfjiVZ.cjs';
|
|
3
3
|
|
|
4
4
|
interface WidgetCardProps {
|
|
5
5
|
readonly title: string;
|
|
@@ -566,6 +566,13 @@ interface UseWidgetsOptions extends ResolveOptions {
|
|
|
566
566
|
* fresh object each render.
|
|
567
567
|
*/
|
|
568
568
|
readonly optionValues?: Readonly<Record<string, Readonly<Record<string, unknown>> | undefined>>;
|
|
569
|
+
/**
|
|
570
|
+
* The view each widget shows, by widget key (see `viewValuesFromLayout`).
|
|
571
|
+
* Only views the provider supplies matter: choosing one loads it (the
|
|
572
|
+
* provider is called with `options.view`), and the card shows loading until
|
|
573
|
+
* it arrives. It may be a fresh object each render.
|
|
574
|
+
*/
|
|
575
|
+
readonly viewValues?: Readonly<Record<string, string | undefined>>;
|
|
569
576
|
}
|
|
570
577
|
interface UseWidgetsResult {
|
|
571
578
|
/** Pass to `Dashboard` or `WidgetGrid`: placeholders first, then results. */
|
|
@@ -574,6 +581,8 @@ interface UseWidgetsResult {
|
|
|
574
581
|
readonly refresh: (key?: string) => void;
|
|
575
582
|
/** Choose option values for one widget; same effect as `optionValues`. */
|
|
576
583
|
readonly setOptions: (key: string, chosen: Readonly<Record<string, unknown>>) => void;
|
|
584
|
+
/** Choose a widget's view; same effect as `viewValues`. */
|
|
585
|
+
readonly setView: (key: string, view: string | undefined) => void;
|
|
577
586
|
/**
|
|
578
587
|
* For `loadWhen: 'visible'`: attach to any element that contains the cards,
|
|
579
588
|
* for example a wrapper `<div ref={gridRef}>` around `Dashboard`.
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement, RefObject } from 'react';
|
|
2
|
-
import { D as DashboardWidget, W as WidgetSize, a as WidgetFill, G as GraphWidgetData, N as NiceDomain, b as WidgetDefinition, c as DetailProviderOptions, d as DetailData, e as DetailQuery, O as OptionValues, L as Locale, f as DashboardLayout, g as WidgetViewerSettings, h as WidgetSettingsPatch, A as AlertListWidgetData, B as BarListWidgetData, i as GaugeWidgetData, K as KpiWidgetData, T as TableWidgetData, R as ResolvedTableControls, j as DetailSort, k as TextWidgetData, l as WidgetData, m as LayoutPersistence, S as StoreScope, P as PageItem, n as NormalizeOptions, o as ResolveOptions, p as WidgetContext, q as WidgetProviders } from './storage-
|
|
2
|
+
import { D as DashboardWidget, W as WidgetSize, a as WidgetFill, G as GraphWidgetData, N as NiceDomain, b as WidgetDefinition, c as DetailProviderOptions, d as DetailData, e as DetailQuery, O as OptionValues, L as Locale, f as DashboardLayout, g as WidgetViewerSettings, h as WidgetSettingsPatch, A as AlertListWidgetData, B as BarListWidgetData, i as GaugeWidgetData, K as KpiWidgetData, T as TableWidgetData, R as ResolvedTableControls, j as DetailSort, k as TextWidgetData, l as WidgetData, m as LayoutPersistence, S as StoreScope, P as PageItem, n as NormalizeOptions, o as ResolveOptions, p as WidgetContext, q as WidgetProviders } from './storage-CRBfjiVZ.js';
|
|
3
3
|
|
|
4
4
|
interface WidgetCardProps {
|
|
5
5
|
readonly title: string;
|
|
@@ -566,6 +566,13 @@ interface UseWidgetsOptions extends ResolveOptions {
|
|
|
566
566
|
* fresh object each render.
|
|
567
567
|
*/
|
|
568
568
|
readonly optionValues?: Readonly<Record<string, Readonly<Record<string, unknown>> | undefined>>;
|
|
569
|
+
/**
|
|
570
|
+
* The view each widget shows, by widget key (see `viewValuesFromLayout`).
|
|
571
|
+
* Only views the provider supplies matter: choosing one loads it (the
|
|
572
|
+
* provider is called with `options.view`), and the card shows loading until
|
|
573
|
+
* it arrives. It may be a fresh object each render.
|
|
574
|
+
*/
|
|
575
|
+
readonly viewValues?: Readonly<Record<string, string | undefined>>;
|
|
569
576
|
}
|
|
570
577
|
interface UseWidgetsResult {
|
|
571
578
|
/** Pass to `Dashboard` or `WidgetGrid`: placeholders first, then results. */
|
|
@@ -574,6 +581,8 @@ interface UseWidgetsResult {
|
|
|
574
581
|
readonly refresh: (key?: string) => void;
|
|
575
582
|
/** Choose option values for one widget; same effect as `optionValues`. */
|
|
576
583
|
readonly setOptions: (key: string, chosen: Readonly<Record<string, unknown>>) => void;
|
|
584
|
+
/** Choose a widget's view; same effect as `viewValues`. */
|
|
585
|
+
readonly setView: (key: string, view: string | undefined) => void;
|
|
577
586
|
/**
|
|
578
587
|
* For `loadWhen: 'visible'`: attach to any element that contains the cards,
|
|
579
588
|
* for example a wrapper `<div ref={gridRef}>` around `Dashboard`.
|
package/dist/react.js
CHANGED
|
@@ -2066,6 +2066,9 @@ function viewChoices(item) {
|
|
|
2066
2066
|
}))
|
|
2067
2067
|
];
|
|
2068
2068
|
}
|
|
2069
|
+
function isProviderView(view) {
|
|
2070
|
+
return view.convert === void 0;
|
|
2071
|
+
}
|
|
2069
2072
|
function isKnownView(item, key) {
|
|
2070
2073
|
return key !== void 0 && (key === BASE_VIEW_KEY || findView(item, key) !== void 0);
|
|
2071
2074
|
}
|
|
@@ -2075,6 +2078,14 @@ function effectiveViewKey(item, chosen) {
|
|
|
2075
2078
|
if (isKnownView(item, item.defaultView)) return item.defaultView;
|
|
2076
2079
|
return BASE_VIEW_KEY;
|
|
2077
2080
|
}
|
|
2081
|
+
function loadViewKey(item, chosen) {
|
|
2082
|
+
const key = effectiveViewKey(item, chosen);
|
|
2083
|
+
const view = findView(item, key);
|
|
2084
|
+
return view !== void 0 && isProviderView(view) ? key : BASE_VIEW_KEY;
|
|
2085
|
+
}
|
|
2086
|
+
function loadViewKind(item, chosen) {
|
|
2087
|
+
return findView(item, loadViewKey(item, chosen))?.kind ?? item.kind;
|
|
2088
|
+
}
|
|
2078
2089
|
function cellValue2(cell) {
|
|
2079
2090
|
const value = cell?.value;
|
|
2080
2091
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
@@ -2209,6 +2220,11 @@ function convertView(widgetKey, view, data, options = {}) {
|
|
|
2209
2220
|
where: `Widget ${JSON.stringify(widgetKey)} view ${JSON.stringify(view.key)}`,
|
|
2210
2221
|
...options.locale === void 0 ? {} : { locale: options.locale }
|
|
2211
2222
|
};
|
|
2223
|
+
if (conversion === void 0) {
|
|
2224
|
+
return err(
|
|
2225
|
+
`${context.where}: the provider supplies this view, so there is nothing to convert.`
|
|
2226
|
+
);
|
|
2227
|
+
}
|
|
2212
2228
|
const expected = VIEW_CONVERSIONS[conversion.type]?.from;
|
|
2213
2229
|
if (expected === void 0) {
|
|
2214
2230
|
return err(
|
|
@@ -2236,14 +2252,29 @@ function convertView(widgetKey, view, data, options = {}) {
|
|
|
2236
2252
|
function applyView(widget, chosen, options = {}) {
|
|
2237
2253
|
const key = effectiveViewKey(widget.definition, chosen);
|
|
2238
2254
|
const view = findView(widget.definition, key);
|
|
2239
|
-
|
|
2255
|
+
const wanted = loadViewKey(widget.definition, chosen);
|
|
2256
|
+
const loaded = widget.status === "ok" ? widget.view ?? BASE_VIEW_KEY : void 0;
|
|
2257
|
+
const mismatched = loaded !== void 0 && loaded !== wanted;
|
|
2258
|
+
if (view === void 0) {
|
|
2259
|
+
return mismatched ? {
|
|
2260
|
+
definition: widget.definition,
|
|
2261
|
+
status: "loading",
|
|
2262
|
+
...widget.options === void 0 ? {} : { options: widget.options }
|
|
2263
|
+
} : widget;
|
|
2264
|
+
}
|
|
2240
2265
|
const definition = {
|
|
2241
2266
|
...widget.definition,
|
|
2242
2267
|
kind: view.kind
|
|
2243
2268
|
};
|
|
2244
|
-
if (widget.status
|
|
2245
|
-
if (
|
|
2246
|
-
|
|
2269
|
+
if (widget.status !== "ok") return { ...widget, definition };
|
|
2270
|
+
if (mismatched) {
|
|
2271
|
+
return {
|
|
2272
|
+
definition,
|
|
2273
|
+
status: "loading",
|
|
2274
|
+
...widget.options === void 0 ? {} : { options: widget.options }
|
|
2275
|
+
};
|
|
2276
|
+
}
|
|
2277
|
+
if (isProviderView(view)) return { ...widget, definition };
|
|
2247
2278
|
const converted = convertView(
|
|
2248
2279
|
widget.definition.key,
|
|
2249
2280
|
view,
|
|
@@ -5677,7 +5708,10 @@ function resolvePayload(definition, payload, options = {}) {
|
|
|
5677
5708
|
} else {
|
|
5678
5709
|
const result = validateWidgetData(payload, {
|
|
5679
5710
|
widgetKey: definition.key,
|
|
5680
|
-
expectedKind:
|
|
5711
|
+
expectedKind: loadViewKind(
|
|
5712
|
+
definition,
|
|
5713
|
+
options.viewValues?.[definition.key]
|
|
5714
|
+
)
|
|
5681
5715
|
});
|
|
5682
5716
|
if (!result.ok) {
|
|
5683
5717
|
return { definition, status: "error", error: result.error };
|
|
@@ -5688,7 +5722,14 @@ function resolvePayload(definition, payload, options = {}) {
|
|
|
5688
5722
|
if (emptyText !== null) {
|
|
5689
5723
|
return { definition, status: "empty", emptyText };
|
|
5690
5724
|
}
|
|
5691
|
-
return {
|
|
5725
|
+
return {
|
|
5726
|
+
definition,
|
|
5727
|
+
status: "ok",
|
|
5728
|
+
data: checked,
|
|
5729
|
+
...hasViews(definition) ? {
|
|
5730
|
+
view: loadViewKey(definition, options.viewValues?.[definition.key])
|
|
5731
|
+
} : {}
|
|
5732
|
+
};
|
|
5692
5733
|
}
|
|
5693
5734
|
function failedWidget(definition, error) {
|
|
5694
5735
|
return { definition, status: "error", error };
|
|
@@ -5698,7 +5739,14 @@ function loadingWidgets(definitions) {
|
|
|
5698
5739
|
}
|
|
5699
5740
|
function cacheKeyFor(definition, options, values) {
|
|
5700
5741
|
const base = options.cacheKey === void 0 ? definition.sourceKey ?? definition.key : options.cacheKey(definition);
|
|
5701
|
-
|
|
5742
|
+
const view = loadViewKey(
|
|
5743
|
+
definition,
|
|
5744
|
+
options.viewValues?.[definition.key]
|
|
5745
|
+
);
|
|
5746
|
+
const viewPart = view === BASE_VIEW_KEY ? "" : `view=${encodeURIComponent(view)}`;
|
|
5747
|
+
const optionPart = values === void 0 ? "" : optionsCacheSuffix(definition, values, options);
|
|
5748
|
+
if (viewPart === "") return `${base}${optionPart}`;
|
|
5749
|
+
return optionPart === "" ? `${base}?${viewPart}` : `${base}?${viewPart}&${optionPart.slice(1)}`;
|
|
5702
5750
|
}
|
|
5703
5751
|
function optionValuesFor(definition, options) {
|
|
5704
5752
|
return resolveOptionValues(
|
|
@@ -5709,6 +5757,9 @@ function optionValuesFor(definition, options) {
|
|
|
5709
5757
|
}
|
|
5710
5758
|
function finalizeWidget(widget, values) {
|
|
5711
5759
|
if (Object.keys(values).length === 0) return widget;
|
|
5760
|
+
if (widget.status === "ok" && widget.view !== void 0 && widget.view !== BASE_VIEW_KEY) {
|
|
5761
|
+
return { ...widget, options: values };
|
|
5762
|
+
}
|
|
5712
5763
|
if (widget.status === "ok") {
|
|
5713
5764
|
const data = applyClientOptions(
|
|
5714
5765
|
widget.definition,
|
|
@@ -5759,7 +5810,8 @@ async function resolveWidgetUnapplied(definition, provider, context, options = {
|
|
|
5759
5810
|
if (controller.signal.aborted) throw new LoadInterruption();
|
|
5760
5811
|
return provider(context, definition, {
|
|
5761
5812
|
signal: controller.signal,
|
|
5762
|
-
options: values
|
|
5813
|
+
options: values,
|
|
5814
|
+
view: loadViewKey(definition, options.viewValues?.[definition.key])
|
|
5763
5815
|
});
|
|
5764
5816
|
}),
|
|
5765
5817
|
interrupted
|
|
@@ -5807,9 +5859,18 @@ function createWidgetLoader(options) {
|
|
|
5807
5859
|
([key, values]) => values === void 0 ? [] : [[key, values]]
|
|
5808
5860
|
)
|
|
5809
5861
|
);
|
|
5862
|
+
const chosenViews = new Map(
|
|
5863
|
+
Object.entries(baseOptions.viewValues ?? {}).flatMap(
|
|
5864
|
+
([key, view]) => view === void 0 ? [] : [[key, view]]
|
|
5865
|
+
)
|
|
5866
|
+
);
|
|
5810
5867
|
const resolveOptions = baseOptions;
|
|
5811
5868
|
function currentOptions() {
|
|
5812
|
-
return {
|
|
5869
|
+
return {
|
|
5870
|
+
...resolveOptions,
|
|
5871
|
+
optionValues: Object.fromEntries(chosen),
|
|
5872
|
+
viewValues: Object.fromEntries(chosenViews)
|
|
5873
|
+
};
|
|
5813
5874
|
}
|
|
5814
5875
|
const unapplied = /* @__PURE__ */ new Map();
|
|
5815
5876
|
const visible = widgetsFor(definitions, context.roles);
|
|
@@ -5942,6 +6003,23 @@ function createWidgetLoader(options) {
|
|
|
5942
6003
|
}
|
|
5943
6004
|
start(definition, true);
|
|
5944
6005
|
}
|
|
6006
|
+
function setView(key, view) {
|
|
6007
|
+
if (disposed) return;
|
|
6008
|
+
const definition = definitionFor(key);
|
|
6009
|
+
if (definition === void 0) return;
|
|
6010
|
+
const before = loadViewKey(definition, chosenViews.get(key));
|
|
6011
|
+
if (view === void 0 || view === "") chosenViews.delete(key);
|
|
6012
|
+
else chosenViews.set(key, view);
|
|
6013
|
+
const after = loadViewKey(definition, chosenViews.get(key));
|
|
6014
|
+
if (before === after || !started.has(key)) return;
|
|
6015
|
+
const current = snapshot.find(
|
|
6016
|
+
(widget) => widget.definition.key === key
|
|
6017
|
+
);
|
|
6018
|
+
if (current !== void 0 && current.status !== "loading") {
|
|
6019
|
+
replace(key, { definition, status: "loading" });
|
|
6020
|
+
}
|
|
6021
|
+
start(definition, true);
|
|
6022
|
+
}
|
|
5945
6023
|
function dispose() {
|
|
5946
6024
|
disposed = true;
|
|
5947
6025
|
abortAll(new Error("The widget loader was disposed."));
|
|
@@ -5960,6 +6038,7 @@ function createWidgetLoader(options) {
|
|
|
5960
6038
|
loadAll,
|
|
5961
6039
|
refresh,
|
|
5962
6040
|
setOptions,
|
|
6041
|
+
setView,
|
|
5963
6042
|
dispose
|
|
5964
6043
|
};
|
|
5965
6044
|
}
|
|
@@ -5975,7 +6054,8 @@ function useWidgets(definitions, providers, context, options = {}) {
|
|
|
5975
6054
|
signal,
|
|
5976
6055
|
cache,
|
|
5977
6056
|
cacheKey,
|
|
5978
|
-
optionValues
|
|
6057
|
+
optionValues,
|
|
6058
|
+
viewValues
|
|
5979
6059
|
} = options;
|
|
5980
6060
|
const placeholders = useMemo(
|
|
5981
6061
|
() => loadingWidgets(widgetsFor(definitions, context.roles)),
|
|
@@ -5987,6 +6067,8 @@ function useWidgets(definitions, providers, context, options = {}) {
|
|
|
5987
6067
|
const gridRef = useRef(null);
|
|
5988
6068
|
const optionValuesRef = useRef(optionValues);
|
|
5989
6069
|
optionValuesRef.current = optionValues;
|
|
6070
|
+
const viewValuesRef = useRef(viewValues);
|
|
6071
|
+
viewValuesRef.current = viewValues;
|
|
5990
6072
|
useEffect(() => {
|
|
5991
6073
|
const created = createWidgetLoader({
|
|
5992
6074
|
definitions,
|
|
@@ -5997,7 +6079,8 @@ function useWidgets(definitions, providers, context, options = {}) {
|
|
|
5997
6079
|
...signal === void 0 ? {} : { signal },
|
|
5998
6080
|
...cache === void 0 ? {} : { cache },
|
|
5999
6081
|
...cacheKey === void 0 ? {} : { cacheKey },
|
|
6000
|
-
...optionValuesRef.current === void 0 ? {} : { optionValues: optionValuesRef.current }
|
|
6082
|
+
...optionValuesRef.current === void 0 ? {} : { optionValues: optionValuesRef.current },
|
|
6083
|
+
...viewValuesRef.current === void 0 ? {} : { viewValues: viewValuesRef.current }
|
|
6001
6084
|
});
|
|
6002
6085
|
loaderRef.current = created;
|
|
6003
6086
|
setWidgets(created.getSnapshot());
|
|
@@ -6076,6 +6159,16 @@ function useWidgets(definitions, providers, context, options = {}) {
|
|
|
6076
6159
|
if (chosen !== void 0) loader.setOptions(key, chosen);
|
|
6077
6160
|
}
|
|
6078
6161
|
}, [loader, optionSignature]);
|
|
6162
|
+
const viewSignature = JSON.stringify(viewValues ?? {});
|
|
6163
|
+
useEffect(() => {
|
|
6164
|
+
if (loader === null) return;
|
|
6165
|
+
for (const [key, view] of Object.entries(viewValuesRef.current ?? {})) {
|
|
6166
|
+
loader.setView(key, view);
|
|
6167
|
+
}
|
|
6168
|
+
}, [loader, viewSignature]);
|
|
6169
|
+
const setView = useCallback((key, view) => {
|
|
6170
|
+
loaderRef.current?.setView(key, view);
|
|
6171
|
+
}, []);
|
|
6079
6172
|
const setOptions = useCallback(
|
|
6080
6173
|
(key, chosen) => {
|
|
6081
6174
|
loaderRef.current?.setOptions(key, chosen);
|
|
@@ -6085,7 +6178,7 @@ function useWidgets(definitions, providers, context, options = {}) {
|
|
|
6085
6178
|
const refresh = useCallback((key) => {
|
|
6086
6179
|
loaderRef.current?.refresh(key);
|
|
6087
6180
|
}, []);
|
|
6088
|
-
return { widgets, refresh, setOptions, gridRef };
|
|
6181
|
+
return { widgets, refresh, setOptions, setView, gridRef };
|
|
6089
6182
|
}
|
|
6090
6183
|
|
|
6091
6184
|
export { AlertListWidget, BarListWidget, DEFAULT_LABELS, DEFAULT_SERIES_COLORS, Dashboard, GaugeWidget, GraphWidget, KpiWidget, ResolvedWidgetCard, TableWidget, TextWidget, Thumbnail, WidgetCard, WidgetContent, WidgetDetail, WidgetDetailDialog, WidgetGrid, WidgetLink, WidgetOptionsDialog, WidgetSettingsProvider, barPath, buildChartModel, describeChart, joinClassNames, seriesColor, useDetailData, useStoredLayout, useWidgetSettings, useWidgets, widgetTitle };
|