@richardmcquiston01/dashboard-widgets-toolkit 0.13.0 → 0.14.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 +713 -383
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +697 -384
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +713 -383
- 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 +697 -384
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +836 -60
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +53 -4
- package/dist/react.d.ts +53 -4
- package/dist/react.js +836 -61
- package/dist/react.js.map +1 -1
- package/dist/{storage-DNB7gjvT.d.cts → storage-_Eb8Y98-.d.cts} +144 -3
- package/dist/{storage-DNB7gjvT.d.ts → storage-_Eb8Y98-.d.ts} +144 -3
- package/dist/styles.css +146 -0
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -827,6 +827,30 @@ var DEFAULT_LABELS = {
|
|
|
827
827
|
menuMoveEarlier: "Move earlier",
|
|
828
828
|
menuMoveLater: "Move later",
|
|
829
829
|
menuHide: "Hide",
|
|
830
|
+
menuOptions: "Options\u2026",
|
|
831
|
+
optionsFor: (title) => `Options for ${title}`,
|
|
832
|
+
optionsTitleField: "Title",
|
|
833
|
+
titleInUse: "Another widget already uses this title.",
|
|
834
|
+
optionsWidthField: "Width",
|
|
835
|
+
widthDefault: "Default",
|
|
836
|
+
widthOption: (width, share) => `${width} of 12 (${share})`,
|
|
837
|
+
optionsFlexible: "Grow to fill empty space in the row",
|
|
838
|
+
optionsDeclared: "Data",
|
|
839
|
+
apply: "Apply",
|
|
840
|
+
cancel: "Cancel",
|
|
841
|
+
resetToDefaults: "Reset to defaults",
|
|
842
|
+
revertToBeforeEditing: "Revert to before editing",
|
|
843
|
+
confirmApply: "Apply these changes?",
|
|
844
|
+
confirmDiscard: "Discard your changes?",
|
|
845
|
+
confirmResetOptions: "Reset these options to their defaults?",
|
|
846
|
+
confirmRevertOptions: "Revert these options to how they were before you started editing?",
|
|
847
|
+
optionsSaved: (title) => `Options saved for ${title}`,
|
|
848
|
+
sortDefault: "Default order",
|
|
849
|
+
sortAscending: "Ascending",
|
|
850
|
+
sortDescending: "Descending",
|
|
851
|
+
moveColumnUp: (column) => `Move ${column} up`,
|
|
852
|
+
moveColumnDown: (column) => `Move ${column} down`,
|
|
853
|
+
customRange: (value) => `Custom: ${value}`,
|
|
830
854
|
moveToPage: (title) => `Move ${title} to another page`,
|
|
831
855
|
moveToPagePlaceholder: "Move to page\u2026",
|
|
832
856
|
moveToPageOption: (title, rowsFree) => `${title} (${rowsFree} ${rowsFree === 1 ? "row" : "rows"} free)`,
|
|
@@ -1910,12 +1934,14 @@ function ResolvedWidgetCard({
|
|
|
1910
1934
|
var NOT_LOCKED = Object.freeze({
|
|
1911
1935
|
move: false,
|
|
1912
1936
|
hide: false,
|
|
1913
|
-
minimize: false
|
|
1937
|
+
minimize: false,
|
|
1938
|
+
options: false
|
|
1914
1939
|
});
|
|
1915
1940
|
var FULLY_LOCKED = Object.freeze({
|
|
1916
1941
|
move: true,
|
|
1917
1942
|
hide: true,
|
|
1918
|
-
minimize: true
|
|
1943
|
+
minimize: true,
|
|
1944
|
+
options: true
|
|
1919
1945
|
});
|
|
1920
1946
|
function resolveWidgetLock(definition) {
|
|
1921
1947
|
const setting = definition.locked;
|
|
@@ -1924,7 +1950,8 @@ function resolveWidgetLock(definition) {
|
|
|
1924
1950
|
return {
|
|
1925
1951
|
move: setting.move === true,
|
|
1926
1952
|
hide: setting.hide === true,
|
|
1927
|
-
minimize: setting.minimize === true
|
|
1953
|
+
minimize: setting.minimize === true,
|
|
1954
|
+
options: setting.options === true
|
|
1928
1955
|
};
|
|
1929
1956
|
}
|
|
1930
1957
|
function sortDefinitions(definitions) {
|
|
@@ -1945,6 +1972,151 @@ function isWidgetVisibleTo(definition, roles) {
|
|
|
1945
1972
|
return definition.roles.some((role) => roles.includes(role));
|
|
1946
1973
|
}
|
|
1947
1974
|
|
|
1975
|
+
// src/core/settings.ts
|
|
1976
|
+
var MAX_WIDGET_TITLE_LENGTH = 80;
|
|
1977
|
+
var MAX_COLUMN_LIST = 100;
|
|
1978
|
+
var MAX_VALUE_LENGTH = 500;
|
|
1979
|
+
function isRecord(value) {
|
|
1980
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1981
|
+
}
|
|
1982
|
+
function parseOptionValue(value) {
|
|
1983
|
+
if (typeof value === "string") {
|
|
1984
|
+
return value.length <= MAX_VALUE_LENGTH ? value : void 0;
|
|
1985
|
+
}
|
|
1986
|
+
if (typeof value === "number")
|
|
1987
|
+
return Number.isFinite(value) ? value : void 0;
|
|
1988
|
+
if (typeof value === "boolean") return value;
|
|
1989
|
+
if (Array.isArray(value) && value.length <= MAX_COLUMN_LIST) {
|
|
1990
|
+
return value.every(
|
|
1991
|
+
(entry) => typeof entry === "string" && entry.length <= MAX_VALUE_LENGTH
|
|
1992
|
+
) ? value : void 0;
|
|
1993
|
+
}
|
|
1994
|
+
return void 0;
|
|
1995
|
+
}
|
|
1996
|
+
function parseOne(raw) {
|
|
1997
|
+
if (!isRecord(raw)) return void 0;
|
|
1998
|
+
const title = raw["title"];
|
|
1999
|
+
const width = raw["width"];
|
|
2000
|
+
const flexible = raw["flexible"];
|
|
2001
|
+
const options = raw["options"];
|
|
2002
|
+
const cleanTitle = typeof title === "string" ? title.trim().slice(0, MAX_WIDGET_TITLE_LENGTH) : "";
|
|
2003
|
+
const chosen = {};
|
|
2004
|
+
if (isRecord(options)) {
|
|
2005
|
+
for (const [key, value] of Object.entries(options)) {
|
|
2006
|
+
const parsed = parseOptionValue(value);
|
|
2007
|
+
if (parsed !== void 0) chosen[key] = parsed;
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
const settings = {
|
|
2011
|
+
...cleanTitle === "" ? {} : { title: cleanTitle },
|
|
2012
|
+
...isWidgetWidth(width) ? { width } : {},
|
|
2013
|
+
...typeof flexible === "boolean" ? { flexible } : {},
|
|
2014
|
+
...Object.keys(chosen).length === 0 ? {} : { options: chosen }
|
|
2015
|
+
};
|
|
2016
|
+
return Object.keys(settings).length === 0 ? void 0 : settings;
|
|
2017
|
+
}
|
|
2018
|
+
function widthRange(item) {
|
|
2019
|
+
const min = isWidgetWidth(item.minWidth) ? item.minWidth : MIN_WIDGET_WIDTH;
|
|
2020
|
+
const max = isWidgetWidth(item.maxWidth) ? item.maxWidth : MAX_WIDGET_WIDTH;
|
|
2021
|
+
return { min, max: Math.max(min, max) };
|
|
2022
|
+
}
|
|
2023
|
+
var WIDTH_SHARES = {
|
|
2024
|
+
2: "1/6",
|
|
2025
|
+
3: "1/4",
|
|
2026
|
+
4: "1/3",
|
|
2027
|
+
5: "5/12",
|
|
2028
|
+
6: "1/2",
|
|
2029
|
+
7: "7/12",
|
|
2030
|
+
8: "2/3",
|
|
2031
|
+
9: "3/4",
|
|
2032
|
+
10: "5/6",
|
|
2033
|
+
11: "11/12",
|
|
2034
|
+
12: "Full"
|
|
2035
|
+
};
|
|
2036
|
+
function widthShareLabel(width) {
|
|
2037
|
+
return WIDTH_SHARES[width] ?? `${width}/12`;
|
|
2038
|
+
}
|
|
2039
|
+
function isOptionsLocked(item) {
|
|
2040
|
+
return resolveWidgetLock(item).options;
|
|
2041
|
+
}
|
|
2042
|
+
function fillWith(fill, flexible) {
|
|
2043
|
+
const heightToo = fill === "height" || fill === "both";
|
|
2044
|
+
if (flexible) return heightToo ? "both" : "width";
|
|
2045
|
+
return heightToo ? "height" : void 0;
|
|
2046
|
+
}
|
|
2047
|
+
function isFlexible(item, settings) {
|
|
2048
|
+
return item.fill === "width" || item.fill === "both";
|
|
2049
|
+
}
|
|
2050
|
+
function applySettings(definition, settings) {
|
|
2051
|
+
if (settings === void 0) return definition;
|
|
2052
|
+
const range = widthRange(definition);
|
|
2053
|
+
const width = settings.width === void 0 ? void 0 : Math.min(range.max, Math.max(range.min, settings.width));
|
|
2054
|
+
const title = settings.title === void 0 || settings.title.trim() === "" ? void 0 : settings.title;
|
|
2055
|
+
const flexibleChanged = settings.flexible !== void 0 && settings.flexible !== isFlexible(definition);
|
|
2056
|
+
if (title === void 0 && width === void 0 && !flexibleChanged) {
|
|
2057
|
+
return definition;
|
|
2058
|
+
}
|
|
2059
|
+
const next = { ...definition };
|
|
2060
|
+
if (title !== void 0) next.title = title;
|
|
2061
|
+
if (width !== void 0) next.width = width;
|
|
2062
|
+
if (flexibleChanged) {
|
|
2063
|
+
const fill = fillWith(
|
|
2064
|
+
definition.fill,
|
|
2065
|
+
settings.flexible === true
|
|
2066
|
+
);
|
|
2067
|
+
if (fill === void 0) {
|
|
2068
|
+
delete next.fill;
|
|
2069
|
+
} else {
|
|
2070
|
+
next.fill = fill;
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
return next;
|
|
2074
|
+
}
|
|
2075
|
+
function effectiveDefinitions(definitions, layout, options = {}) {
|
|
2076
|
+
return definitions.map(
|
|
2077
|
+
(definition) => options.overrideLocks !== true && isOptionsLocked(definition) ? definition : applySettings(definition, layout.settings?.[definition.key])
|
|
2078
|
+
);
|
|
2079
|
+
}
|
|
2080
|
+
function sameSettings(a, b) {
|
|
2081
|
+
if (a === b) return true;
|
|
2082
|
+
return a?.title === b?.title && a?.width === b?.width && a?.flexible === b?.flexible && sameOptionValues(a?.options ?? {}, b?.options ?? {});
|
|
2083
|
+
}
|
|
2084
|
+
function setWidgetSettings(layout, key, patch) {
|
|
2085
|
+
const before = layout.settings?.[key];
|
|
2086
|
+
const draft = { ...before };
|
|
2087
|
+
for (const field of ["title", "width", "flexible", "options"]) {
|
|
2088
|
+
if (!(field in patch)) continue;
|
|
2089
|
+
const value = patch[field];
|
|
2090
|
+
if (value === void 0) {
|
|
2091
|
+
delete draft[field];
|
|
2092
|
+
} else {
|
|
2093
|
+
draft[field] = value;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
const merged = parseOne(draft);
|
|
2097
|
+
if (sameSettings(before, merged)) return layout;
|
|
2098
|
+
const rest = { ...layout.settings };
|
|
2099
|
+
if (merged === void 0) {
|
|
2100
|
+
delete rest[key];
|
|
2101
|
+
} else {
|
|
2102
|
+
rest[key] = merged;
|
|
2103
|
+
}
|
|
2104
|
+
const { settings: _previous, ...others } = layout;
|
|
2105
|
+
return Object.keys(rest).length === 0 ? others : { ...others, settings: rest };
|
|
2106
|
+
}
|
|
2107
|
+
function normalizeTitle(title) {
|
|
2108
|
+
return title.normalize("NFKC").trim().toLowerCase();
|
|
2109
|
+
}
|
|
2110
|
+
function isTitleInUse(definitions, layout, key, title) {
|
|
2111
|
+
const wanted = normalizeTitle(title);
|
|
2112
|
+
if (wanted === "") return false;
|
|
2113
|
+
return effectiveDefinitions(definitions, layout, {
|
|
2114
|
+
overrideLocks: true
|
|
2115
|
+
}).some(
|
|
2116
|
+
(other) => other.key !== key && normalizeTitle(other.title ?? other.key) === wanted
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
|
|
1948
2120
|
// src/core/layout.ts
|
|
1949
2121
|
var MAX_PAGE_TITLE_LENGTH = 30;
|
|
1950
2122
|
var MAX_PARSED_PAGES = 50;
|
|
@@ -2422,6 +2594,57 @@ function moveWidgetToPage(definitions, layout, widgetKey, targetKey, options = {
|
|
|
2422
2594
|
}
|
|
2423
2595
|
return ok(moved);
|
|
2424
2596
|
}
|
|
2597
|
+
function InlineConfirm({
|
|
2598
|
+
message,
|
|
2599
|
+
onAnswer
|
|
2600
|
+
}) {
|
|
2601
|
+
const slot = useSlotClassName();
|
|
2602
|
+
const { labels } = useWidgetSettings();
|
|
2603
|
+
const noRef = useRef(null);
|
|
2604
|
+
useEffect(() => {
|
|
2605
|
+
noRef.current?.focus();
|
|
2606
|
+
}, []);
|
|
2607
|
+
return /* @__PURE__ */ jsxs(
|
|
2608
|
+
"span",
|
|
2609
|
+
{
|
|
2610
|
+
role: "group",
|
|
2611
|
+
"aria-label": message,
|
|
2612
|
+
className: "dwt-confirm",
|
|
2613
|
+
onKeyDown: (event) => {
|
|
2614
|
+
if (event.key === "Escape") {
|
|
2615
|
+
event.stopPropagation();
|
|
2616
|
+
onAnswer(false);
|
|
2617
|
+
}
|
|
2618
|
+
},
|
|
2619
|
+
children: [
|
|
2620
|
+
/* @__PURE__ */ jsx("span", { role: "alert", className: "dwt-confirm-message", children: message }),
|
|
2621
|
+
/* @__PURE__ */ jsx(
|
|
2622
|
+
"button",
|
|
2623
|
+
{
|
|
2624
|
+
type: "button",
|
|
2625
|
+
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
2626
|
+
"aria-label": labels.confirmYes,
|
|
2627
|
+
title: labels.confirmYes,
|
|
2628
|
+
onClick: () => onAnswer(true),
|
|
2629
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2713" })
|
|
2630
|
+
}
|
|
2631
|
+
),
|
|
2632
|
+
/* @__PURE__ */ jsx(
|
|
2633
|
+
"button",
|
|
2634
|
+
{
|
|
2635
|
+
ref: noRef,
|
|
2636
|
+
type: "button",
|
|
2637
|
+
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
2638
|
+
"aria-label": labels.confirmNo,
|
|
2639
|
+
title: labels.confirmNo,
|
|
2640
|
+
onClick: () => onAnswer(false),
|
|
2641
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2715" })
|
|
2642
|
+
}
|
|
2643
|
+
)
|
|
2644
|
+
]
|
|
2645
|
+
}
|
|
2646
|
+
);
|
|
2647
|
+
}
|
|
2425
2648
|
var EditMenuInitialOpenContext = createContext(false);
|
|
2426
2649
|
var ITEM_SELECTOR = '[role="menuitem"]:not(:disabled)';
|
|
2427
2650
|
function WidgetEditMenu({
|
|
@@ -2560,6 +2783,561 @@ function WidgetEditMenu({
|
|
|
2560
2783
|
}
|
|
2561
2784
|
);
|
|
2562
2785
|
}
|
|
2786
|
+
function draftFrom(settings) {
|
|
2787
|
+
return {
|
|
2788
|
+
title: settings?.title ?? "",
|
|
2789
|
+
width: settings?.width,
|
|
2790
|
+
flexible: settings?.flexible,
|
|
2791
|
+
options: settings?.options ?? {}
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
function storedDefault(option) {
|
|
2795
|
+
return option.type === "dateRange" ? option.default : defaultOptionValue(option);
|
|
2796
|
+
}
|
|
2797
|
+
function sameValue2(a, b) {
|
|
2798
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
2799
|
+
return a.length === b.length && a.every((item, i) => item === b[i]);
|
|
2800
|
+
}
|
|
2801
|
+
return a === b;
|
|
2802
|
+
}
|
|
2803
|
+
function patchFrom(definition, draft) {
|
|
2804
|
+
const title = draft.title.trim();
|
|
2805
|
+
const options = {};
|
|
2806
|
+
for (const option of definition.options ?? []) {
|
|
2807
|
+
const value = draft.options[option.key];
|
|
2808
|
+
if (value === void 0) continue;
|
|
2809
|
+
if (sameValue2(value, storedDefault(option))) continue;
|
|
2810
|
+
options[option.key] = value;
|
|
2811
|
+
}
|
|
2812
|
+
return {
|
|
2813
|
+
title: title === "" ? void 0 : title,
|
|
2814
|
+
width: draft.width,
|
|
2815
|
+
flexible: draft.flexible === void 0 || draft.flexible === isFlexible(definition) ? void 0 : draft.flexible,
|
|
2816
|
+
options: Object.keys(options).length === 0 ? void 0 : options
|
|
2817
|
+
};
|
|
2818
|
+
}
|
|
2819
|
+
function patchKey(patch) {
|
|
2820
|
+
const options = {};
|
|
2821
|
+
for (const key of Object.keys(patch.options ?? {}).sort()) {
|
|
2822
|
+
options[key] = patch.options[key];
|
|
2823
|
+
}
|
|
2824
|
+
return JSON.stringify([patch.title, patch.width, patch.flexible, options]);
|
|
2825
|
+
}
|
|
2826
|
+
var EMPTY_PATCH = {
|
|
2827
|
+
title: void 0,
|
|
2828
|
+
width: void 0,
|
|
2829
|
+
flexible: void 0,
|
|
2830
|
+
options: void 0
|
|
2831
|
+
};
|
|
2832
|
+
function WidgetOptionsDialog({
|
|
2833
|
+
definition,
|
|
2834
|
+
settings,
|
|
2835
|
+
baseline,
|
|
2836
|
+
isTitleInUse: isTitleInUse2,
|
|
2837
|
+
onApply,
|
|
2838
|
+
onClose
|
|
2839
|
+
}) {
|
|
2840
|
+
const slot = useSlotClassName();
|
|
2841
|
+
const { labels } = useWidgetSettings();
|
|
2842
|
+
const dialogRef = useRef(null);
|
|
2843
|
+
const headingId = useId();
|
|
2844
|
+
const baseId = useId();
|
|
2845
|
+
const [draft, setDraft] = useState(() => draftFrom(settings));
|
|
2846
|
+
const [confirming, setConfirming] = useState(
|
|
2847
|
+
void 0
|
|
2848
|
+
);
|
|
2849
|
+
useEffect(() => {
|
|
2850
|
+
const dialog = dialogRef.current;
|
|
2851
|
+
if (dialog === null) return void 0;
|
|
2852
|
+
const opener = document.activeElement;
|
|
2853
|
+
if (!dialog.open) dialog.showModal();
|
|
2854
|
+
return () => {
|
|
2855
|
+
if (dialog.open) dialog.close();
|
|
2856
|
+
if (opener instanceof HTMLElement) opener.focus();
|
|
2857
|
+
};
|
|
2858
|
+
}, []);
|
|
2859
|
+
const savedKey = patchKey(patchFrom(definition, draftFrom(settings)));
|
|
2860
|
+
const draftPatch = patchFrom(definition, draft);
|
|
2861
|
+
const dirty = patchKey(draftPatch) !== savedKey;
|
|
2862
|
+
const titleTaken = draft.title.trim() !== "" && isTitleInUse2?.(draft.title.trim()) === true;
|
|
2863
|
+
const canApply = dirty && !titleTaken;
|
|
2864
|
+
const baselineKey = baseline === void 0 ? void 0 : patchKey(patchFrom(definition, draftFrom(baseline.settings)));
|
|
2865
|
+
const canRevert = baselineKey !== void 0 && baselineKey !== savedKey;
|
|
2866
|
+
const canReset = savedKey !== patchKey(EMPTY_PATCH);
|
|
2867
|
+
const range = widthRange(definition);
|
|
2868
|
+
const effectiveFlexible = draft.flexible ?? isFlexible(definition);
|
|
2869
|
+
function requestClose() {
|
|
2870
|
+
if (confirming !== void 0) {
|
|
2871
|
+
setConfirming(void 0);
|
|
2872
|
+
} else if (dirty) {
|
|
2873
|
+
setConfirming("discard");
|
|
2874
|
+
} else {
|
|
2875
|
+
onClose();
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
function answer(yes) {
|
|
2879
|
+
const which = confirming;
|
|
2880
|
+
setConfirming(void 0);
|
|
2881
|
+
if (!yes || which === void 0) return;
|
|
2882
|
+
if (which === "discard") {
|
|
2883
|
+
onClose();
|
|
2884
|
+
} else if (which === "apply") {
|
|
2885
|
+
onApply(draftPatch);
|
|
2886
|
+
onClose();
|
|
2887
|
+
} else if (which === "reset") {
|
|
2888
|
+
onApply(EMPTY_PATCH);
|
|
2889
|
+
onClose();
|
|
2890
|
+
} else if (baseline !== void 0) {
|
|
2891
|
+
onApply(patchFrom(definition, draftFrom(baseline.settings)));
|
|
2892
|
+
onClose();
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
function setOption(key, value) {
|
|
2896
|
+
setDraft((current) => ({
|
|
2897
|
+
...current,
|
|
2898
|
+
options: { ...current.options, [key]: value }
|
|
2899
|
+
}));
|
|
2900
|
+
}
|
|
2901
|
+
const confirmMessage = {
|
|
2902
|
+
apply: labels.confirmApply,
|
|
2903
|
+
discard: labels.confirmDiscard,
|
|
2904
|
+
reset: labels.confirmResetOptions,
|
|
2905
|
+
revert: labels.confirmRevertOptions
|
|
2906
|
+
};
|
|
2907
|
+
const widths = [];
|
|
2908
|
+
for (let width = range.min; width <= range.max; width += 1)
|
|
2909
|
+
widths.push(width);
|
|
2910
|
+
return /* @__PURE__ */ jsx(
|
|
2911
|
+
"dialog",
|
|
2912
|
+
{
|
|
2913
|
+
ref: dialogRef,
|
|
2914
|
+
className: slot("dialog", "dwt-options-dialog"),
|
|
2915
|
+
"aria-labelledby": headingId,
|
|
2916
|
+
onCancel: (event) => {
|
|
2917
|
+
event.preventDefault();
|
|
2918
|
+
requestClose();
|
|
2919
|
+
},
|
|
2920
|
+
onClick: (event) => {
|
|
2921
|
+
if (event.target === dialogRef.current) requestClose();
|
|
2922
|
+
},
|
|
2923
|
+
children: /* @__PURE__ */ jsxs(
|
|
2924
|
+
"form",
|
|
2925
|
+
{
|
|
2926
|
+
className: "dwt-options",
|
|
2927
|
+
onSubmit: (event) => {
|
|
2928
|
+
event.preventDefault();
|
|
2929
|
+
if (canApply && confirming === void 0) setConfirming("apply");
|
|
2930
|
+
},
|
|
2931
|
+
children: [
|
|
2932
|
+
/* @__PURE__ */ jsx("h2", { id: headingId, className: "dwt-options-heading", children: labels.optionsFor(definition.title) }),
|
|
2933
|
+
/* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
2934
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${baseId}-title`, children: labels.optionsTitleField }),
|
|
2935
|
+
/* @__PURE__ */ jsx(
|
|
2936
|
+
"input",
|
|
2937
|
+
{
|
|
2938
|
+
id: `${baseId}-title`,
|
|
2939
|
+
type: "text",
|
|
2940
|
+
value: draft.title,
|
|
2941
|
+
maxLength: MAX_WIDGET_TITLE_LENGTH,
|
|
2942
|
+
placeholder: definition.title,
|
|
2943
|
+
"aria-invalid": titleTaken,
|
|
2944
|
+
...titleTaken ? { "aria-describedby": `${baseId}-title-error` } : {},
|
|
2945
|
+
onChange: (event) => setDraft((current) => ({ ...current, title: event.target.value }))
|
|
2946
|
+
}
|
|
2947
|
+
),
|
|
2948
|
+
titleTaken && /* @__PURE__ */ jsx(
|
|
2949
|
+
"p",
|
|
2950
|
+
{
|
|
2951
|
+
id: `${baseId}-title-error`,
|
|
2952
|
+
role: "alert",
|
|
2953
|
+
className: "dwt-options-error",
|
|
2954
|
+
children: labels.titleInUse
|
|
2955
|
+
}
|
|
2956
|
+
)
|
|
2957
|
+
] }),
|
|
2958
|
+
range.min < range.max && /* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
2959
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${baseId}-width`, children: labels.optionsWidthField }),
|
|
2960
|
+
/* @__PURE__ */ jsxs(
|
|
2961
|
+
"select",
|
|
2962
|
+
{
|
|
2963
|
+
id: `${baseId}-width`,
|
|
2964
|
+
value: draft.width === void 0 ? "" : String(draft.width),
|
|
2965
|
+
onChange: (event) => {
|
|
2966
|
+
const value = event.target.value;
|
|
2967
|
+
setDraft((current) => ({
|
|
2968
|
+
...current,
|
|
2969
|
+
width: value === "" ? void 0 : Number(value)
|
|
2970
|
+
}));
|
|
2971
|
+
},
|
|
2972
|
+
children: [
|
|
2973
|
+
/* @__PURE__ */ jsx("option", { value: "", children: labels.widthDefault }),
|
|
2974
|
+
widths.map((width) => /* @__PURE__ */ jsx("option", { value: String(width), children: labels.widthOption(width, widthShareLabel(width)) }, width))
|
|
2975
|
+
]
|
|
2976
|
+
}
|
|
2977
|
+
)
|
|
2978
|
+
] }),
|
|
2979
|
+
/* @__PURE__ */ jsxs("label", { className: "dwt-options-check", children: [
|
|
2980
|
+
/* @__PURE__ */ jsx(
|
|
2981
|
+
"input",
|
|
2982
|
+
{
|
|
2983
|
+
type: "checkbox",
|
|
2984
|
+
checked: effectiveFlexible,
|
|
2985
|
+
onChange: (event) => setDraft((current) => ({
|
|
2986
|
+
...current,
|
|
2987
|
+
flexible: event.target.checked
|
|
2988
|
+
}))
|
|
2989
|
+
}
|
|
2990
|
+
),
|
|
2991
|
+
labels.optionsFlexible
|
|
2992
|
+
] }),
|
|
2993
|
+
(definition.options?.length ?? 0) > 0 && /* @__PURE__ */ jsxs("fieldset", { className: "dwt-options-group", children: [
|
|
2994
|
+
/* @__PURE__ */ jsx("legend", { children: labels.optionsDeclared }),
|
|
2995
|
+
(definition.options ?? []).map((option) => /* @__PURE__ */ jsx(
|
|
2996
|
+
OptionField,
|
|
2997
|
+
{
|
|
2998
|
+
option,
|
|
2999
|
+
value: draft.options[option.key],
|
|
3000
|
+
id: `${baseId}-opt-${option.key}`,
|
|
3001
|
+
onChange: (value) => setOption(option.key, value)
|
|
3002
|
+
},
|
|
3003
|
+
option.key
|
|
3004
|
+
))
|
|
3005
|
+
] }),
|
|
3006
|
+
/* @__PURE__ */ jsx("div", { className: "dwt-options-actions", children: confirming === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3007
|
+
/* @__PURE__ */ jsx(
|
|
3008
|
+
"button",
|
|
3009
|
+
{
|
|
3010
|
+
type: "submit",
|
|
3011
|
+
className: slot("button", "dwt-button", "dwt-button-primary"),
|
|
3012
|
+
disabled: !canApply,
|
|
3013
|
+
children: labels.apply
|
|
3014
|
+
}
|
|
3015
|
+
),
|
|
3016
|
+
/* @__PURE__ */ jsx(
|
|
3017
|
+
"button",
|
|
3018
|
+
{
|
|
3019
|
+
type: "button",
|
|
3020
|
+
className: slot("button", "dwt-button"),
|
|
3021
|
+
onClick: requestClose,
|
|
3022
|
+
children: labels.cancel
|
|
3023
|
+
}
|
|
3024
|
+
),
|
|
3025
|
+
/* @__PURE__ */ jsx(
|
|
3026
|
+
"button",
|
|
3027
|
+
{
|
|
3028
|
+
type: "button",
|
|
3029
|
+
className: slot("button", "dwt-button"),
|
|
3030
|
+
disabled: !canReset,
|
|
3031
|
+
onClick: () => setConfirming("reset"),
|
|
3032
|
+
children: labels.resetToDefaults
|
|
3033
|
+
}
|
|
3034
|
+
),
|
|
3035
|
+
baseline !== void 0 && /* @__PURE__ */ jsx(
|
|
3036
|
+
"button",
|
|
3037
|
+
{
|
|
3038
|
+
type: "button",
|
|
3039
|
+
className: slot("button", "dwt-button"),
|
|
3040
|
+
disabled: !canRevert,
|
|
3041
|
+
onClick: () => setConfirming("revert"),
|
|
3042
|
+
children: labels.revertToBeforeEditing
|
|
3043
|
+
}
|
|
3044
|
+
)
|
|
3045
|
+
] }) : /* @__PURE__ */ jsx(
|
|
3046
|
+
InlineConfirm,
|
|
3047
|
+
{
|
|
3048
|
+
message: confirmMessage[confirming],
|
|
3049
|
+
onAnswer: answer
|
|
3050
|
+
}
|
|
3051
|
+
) })
|
|
3052
|
+
]
|
|
3053
|
+
}
|
|
3054
|
+
)
|
|
3055
|
+
}
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
function OptionField({
|
|
3059
|
+
option,
|
|
3060
|
+
value,
|
|
3061
|
+
id,
|
|
3062
|
+
onChange
|
|
3063
|
+
}) {
|
|
3064
|
+
const current = value ?? storedDefault(option);
|
|
3065
|
+
switch (option.type) {
|
|
3066
|
+
case "choice":
|
|
3067
|
+
return /* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
3068
|
+
/* @__PURE__ */ jsx("label", { htmlFor: id, children: option.label }),
|
|
3069
|
+
/* @__PURE__ */ jsx(
|
|
3070
|
+
"select",
|
|
3071
|
+
{
|
|
3072
|
+
id,
|
|
3073
|
+
value: String(current ?? option.default),
|
|
3074
|
+
onChange: (event) => onChange(event.target.value),
|
|
3075
|
+
children: option.choices.map((choice) => /* @__PURE__ */ jsx("option", { value: choice.value, children: choice.label }, choice.value))
|
|
3076
|
+
}
|
|
3077
|
+
)
|
|
3078
|
+
] });
|
|
3079
|
+
case "number":
|
|
3080
|
+
return /* @__PURE__ */ jsx(
|
|
3081
|
+
NumberField,
|
|
3082
|
+
{
|
|
3083
|
+
option,
|
|
3084
|
+
id,
|
|
3085
|
+
value: typeof current === "number" ? current : option.default,
|
|
3086
|
+
onChange
|
|
3087
|
+
}
|
|
3088
|
+
);
|
|
3089
|
+
case "boolean":
|
|
3090
|
+
return /* @__PURE__ */ jsxs("label", { className: "dwt-options-check", children: [
|
|
3091
|
+
/* @__PURE__ */ jsx(
|
|
3092
|
+
"input",
|
|
3093
|
+
{
|
|
3094
|
+
type: "checkbox",
|
|
3095
|
+
checked: current === true,
|
|
3096
|
+
onChange: (event) => onChange(event.target.checked)
|
|
3097
|
+
}
|
|
3098
|
+
),
|
|
3099
|
+
option.label
|
|
3100
|
+
] });
|
|
3101
|
+
case "text":
|
|
3102
|
+
return /* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
3103
|
+
/* @__PURE__ */ jsx("label", { htmlFor: id, children: option.label }),
|
|
3104
|
+
/* @__PURE__ */ jsx(
|
|
3105
|
+
"input",
|
|
3106
|
+
{
|
|
3107
|
+
id,
|
|
3108
|
+
type: "text",
|
|
3109
|
+
value: typeof current === "string" ? current : "",
|
|
3110
|
+
maxLength: option.maxLength,
|
|
3111
|
+
onChange: (event) => onChange(event.target.value)
|
|
3112
|
+
}
|
|
3113
|
+
)
|
|
3114
|
+
] });
|
|
3115
|
+
case "color":
|
|
3116
|
+
return /* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
3117
|
+
/* @__PURE__ */ jsx("label", { htmlFor: id, children: option.label }),
|
|
3118
|
+
/* @__PURE__ */ jsx(
|
|
3119
|
+
"input",
|
|
3120
|
+
{
|
|
3121
|
+
id,
|
|
3122
|
+
type: "color",
|
|
3123
|
+
value: typeof current === "string" ? current : option.default,
|
|
3124
|
+
onChange: (event) => onChange(event.target.value)
|
|
3125
|
+
}
|
|
3126
|
+
)
|
|
3127
|
+
] });
|
|
3128
|
+
case "dateRange":
|
|
3129
|
+
return /* @__PURE__ */ jsx(
|
|
3130
|
+
DateRangeField,
|
|
3131
|
+
{
|
|
3132
|
+
option,
|
|
3133
|
+
id,
|
|
3134
|
+
value: typeof current === "string" ? current : option.default,
|
|
3135
|
+
onChange
|
|
3136
|
+
}
|
|
3137
|
+
);
|
|
3138
|
+
case "sort":
|
|
3139
|
+
return /* @__PURE__ */ jsx(
|
|
3140
|
+
SortField,
|
|
3141
|
+
{
|
|
3142
|
+
option,
|
|
3143
|
+
id,
|
|
3144
|
+
value: typeof current === "string" ? current : void 0,
|
|
3145
|
+
onChange
|
|
3146
|
+
}
|
|
3147
|
+
);
|
|
3148
|
+
case "columns":
|
|
3149
|
+
return /* @__PURE__ */ jsx(
|
|
3150
|
+
ColumnsField,
|
|
3151
|
+
{
|
|
3152
|
+
option,
|
|
3153
|
+
value: Array.isArray(current) ? current : option.default,
|
|
3154
|
+
onChange
|
|
3155
|
+
}
|
|
3156
|
+
);
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
function NumberField({
|
|
3160
|
+
option,
|
|
3161
|
+
id,
|
|
3162
|
+
value,
|
|
3163
|
+
onChange
|
|
3164
|
+
}) {
|
|
3165
|
+
const [text, setText] = useState(String(value));
|
|
3166
|
+
useEffect(() => {
|
|
3167
|
+
setText((typed) => Number(typed) === value ? typed : String(value));
|
|
3168
|
+
}, [value]);
|
|
3169
|
+
return /* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
3170
|
+
/* @__PURE__ */ jsx("label", { htmlFor: id, children: option.label }),
|
|
3171
|
+
/* @__PURE__ */ jsx(
|
|
3172
|
+
"input",
|
|
3173
|
+
{
|
|
3174
|
+
id,
|
|
3175
|
+
type: "number",
|
|
3176
|
+
value: text,
|
|
3177
|
+
min: option.min,
|
|
3178
|
+
max: option.max,
|
|
3179
|
+
step: option.step ?? 1,
|
|
3180
|
+
onChange: (event) => {
|
|
3181
|
+
setText(event.target.value);
|
|
3182
|
+
const parsed = Number(event.target.value);
|
|
3183
|
+
if (event.target.value.trim() !== "" && coerceOptionValue(option, parsed) !== void 0) {
|
|
3184
|
+
onChange(parsed);
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
)
|
|
3189
|
+
] });
|
|
3190
|
+
}
|
|
3191
|
+
var PRESET_LABELS = {
|
|
3192
|
+
today: "Today",
|
|
3193
|
+
yesterday: "Yesterday",
|
|
3194
|
+
last7: "Last 7 days",
|
|
3195
|
+
last30: "Last 30 days",
|
|
3196
|
+
last90: "Last 90 days",
|
|
3197
|
+
thisMonth: "This month",
|
|
3198
|
+
lastMonth: "Last month",
|
|
3199
|
+
thisYear: "This year",
|
|
3200
|
+
lastYear: "Last year"
|
|
3201
|
+
};
|
|
3202
|
+
function DateRangeField({
|
|
3203
|
+
option,
|
|
3204
|
+
id,
|
|
3205
|
+
value,
|
|
3206
|
+
onChange
|
|
3207
|
+
}) {
|
|
3208
|
+
const { labels } = useWidgetSettings();
|
|
3209
|
+
const presets = option.presets ?? DATE_RANGE_PRESETS.map((preset) => ({
|
|
3210
|
+
value: preset,
|
|
3211
|
+
label: PRESET_LABELS[preset]
|
|
3212
|
+
}));
|
|
3213
|
+
const known = presets.some((preset) => preset.value === value);
|
|
3214
|
+
return /* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
3215
|
+
/* @__PURE__ */ jsx("label", { htmlFor: id, children: option.label }),
|
|
3216
|
+
/* @__PURE__ */ jsxs(
|
|
3217
|
+
"select",
|
|
3218
|
+
{
|
|
3219
|
+
id,
|
|
3220
|
+
value,
|
|
3221
|
+
onChange: (event) => onChange(event.target.value),
|
|
3222
|
+
children: [
|
|
3223
|
+
!known && /* @__PURE__ */ jsx("option", { value, children: labels.customRange(value) }),
|
|
3224
|
+
presets.map((preset) => /* @__PURE__ */ jsx("option", { value: preset.value, children: preset.label }, preset.value))
|
|
3225
|
+
]
|
|
3226
|
+
}
|
|
3227
|
+
)
|
|
3228
|
+
] });
|
|
3229
|
+
}
|
|
3230
|
+
function SortField({
|
|
3231
|
+
option,
|
|
3232
|
+
id,
|
|
3233
|
+
value,
|
|
3234
|
+
onChange
|
|
3235
|
+
}) {
|
|
3236
|
+
const { labels } = useWidgetSettings();
|
|
3237
|
+
const parsed = value === void 0 ? void 0 : parseSortValue(value);
|
|
3238
|
+
const column = parsed?.column ?? "";
|
|
3239
|
+
const direction = parsed?.direction ?? "desc";
|
|
3240
|
+
return /* @__PURE__ */ jsxs("div", { className: "dwt-options-field", children: [
|
|
3241
|
+
/* @__PURE__ */ jsx("label", { htmlFor: id, children: option.label }),
|
|
3242
|
+
/* @__PURE__ */ jsxs("span", { className: "dwt-options-pair", children: [
|
|
3243
|
+
/* @__PURE__ */ jsxs(
|
|
3244
|
+
"select",
|
|
3245
|
+
{
|
|
3246
|
+
id,
|
|
3247
|
+
value: column,
|
|
3248
|
+
onChange: (event) => onChange(`${event.target.value}:${direction}`),
|
|
3249
|
+
children: [
|
|
3250
|
+
option.default === void 0 && column === "" && /* @__PURE__ */ jsx("option", { value: "", children: labels.sortDefault }),
|
|
3251
|
+
option.columns.map((entry) => /* @__PURE__ */ jsx("option", { value: entry.key, children: entry.label }, entry.key))
|
|
3252
|
+
]
|
|
3253
|
+
}
|
|
3254
|
+
),
|
|
3255
|
+
/* @__PURE__ */ jsxs(
|
|
3256
|
+
"select",
|
|
3257
|
+
{
|
|
3258
|
+
"aria-label": option.label,
|
|
3259
|
+
value: direction,
|
|
3260
|
+
disabled: column === "",
|
|
3261
|
+
onChange: (event) => onChange(`${column}:${event.target.value}`),
|
|
3262
|
+
children: [
|
|
3263
|
+
/* @__PURE__ */ jsx("option", { value: "asc", children: labels.sortAscending }),
|
|
3264
|
+
/* @__PURE__ */ jsx("option", { value: "desc", children: labels.sortDescending })
|
|
3265
|
+
]
|
|
3266
|
+
}
|
|
3267
|
+
)
|
|
3268
|
+
] })
|
|
3269
|
+
] });
|
|
3270
|
+
}
|
|
3271
|
+
function ColumnsField({
|
|
3272
|
+
option,
|
|
3273
|
+
value,
|
|
3274
|
+
onChange
|
|
3275
|
+
}) {
|
|
3276
|
+
const { labels } = useWidgetSettings();
|
|
3277
|
+
const slot = useSlotClassName();
|
|
3278
|
+
const ordered = [
|
|
3279
|
+
...value,
|
|
3280
|
+
...option.columns.map((c) => c.key).filter((key) => !value.includes(key))
|
|
3281
|
+
];
|
|
3282
|
+
const labelOf = (key) => option.columns.find((c) => c.key === key)?.label ?? key;
|
|
3283
|
+
function move(key, by) {
|
|
3284
|
+
const next = [...value];
|
|
3285
|
+
const from = next.indexOf(key);
|
|
3286
|
+
const to = from + by;
|
|
3287
|
+
if (from === -1 || to < 0 || to >= next.length) return;
|
|
3288
|
+
[next[from], next[to]] = [next[to], next[from]];
|
|
3289
|
+
onChange(next);
|
|
3290
|
+
}
|
|
3291
|
+
return /* @__PURE__ */ jsxs("fieldset", { className: "dwt-options-columns", children: [
|
|
3292
|
+
/* @__PURE__ */ jsx("legend", { children: option.label }),
|
|
3293
|
+
/* @__PURE__ */ jsx("ul", { children: ordered.map((key) => {
|
|
3294
|
+
const shown = value.includes(key);
|
|
3295
|
+
const name = labelOf(key);
|
|
3296
|
+
return /* @__PURE__ */ jsxs("li", { children: [
|
|
3297
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
3298
|
+
/* @__PURE__ */ jsx(
|
|
3299
|
+
"input",
|
|
3300
|
+
{
|
|
3301
|
+
type: "checkbox",
|
|
3302
|
+
checked: shown,
|
|
3303
|
+
disabled: shown && value.length === 1,
|
|
3304
|
+
onChange: (event) => onChange(
|
|
3305
|
+
event.target.checked ? [...value, key] : value.filter((k) => k !== key)
|
|
3306
|
+
)
|
|
3307
|
+
}
|
|
3308
|
+
),
|
|
3309
|
+
name
|
|
3310
|
+
] }),
|
|
3311
|
+
shown && /* @__PURE__ */ jsxs("span", { className: "dwt-options-move", children: [
|
|
3312
|
+
/* @__PURE__ */ jsx(
|
|
3313
|
+
"button",
|
|
3314
|
+
{
|
|
3315
|
+
type: "button",
|
|
3316
|
+
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
3317
|
+
"aria-label": labels.moveColumnUp(name),
|
|
3318
|
+
title: labels.moveColumnUp(name),
|
|
3319
|
+
disabled: value.indexOf(key) === 0,
|
|
3320
|
+
onClick: () => move(key, -1),
|
|
3321
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2191" })
|
|
3322
|
+
}
|
|
3323
|
+
),
|
|
3324
|
+
/* @__PURE__ */ jsx(
|
|
3325
|
+
"button",
|
|
3326
|
+
{
|
|
3327
|
+
type: "button",
|
|
3328
|
+
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
3329
|
+
"aria-label": labels.moveColumnDown(name),
|
|
3330
|
+
title: labels.moveColumnDown(name),
|
|
3331
|
+
disabled: value.indexOf(key) === value.length - 1,
|
|
3332
|
+
onClick: () => move(key, 1),
|
|
3333
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2193" })
|
|
3334
|
+
}
|
|
3335
|
+
)
|
|
3336
|
+
] })
|
|
3337
|
+
] }, key);
|
|
3338
|
+
}) })
|
|
3339
|
+
] });
|
|
3340
|
+
}
|
|
2563
3341
|
function nextSort(current, column) {
|
|
2564
3342
|
if (current?.column !== column) return { column, direction: "asc" };
|
|
2565
3343
|
return current.direction === "asc" ? { column, direction: "desc" } : void 0;
|
|
@@ -2987,57 +3765,6 @@ function DetailHost({
|
|
|
2987
3765
|
}
|
|
2988
3766
|
) });
|
|
2989
3767
|
}
|
|
2990
|
-
function InlineConfirm({
|
|
2991
|
-
message,
|
|
2992
|
-
onAnswer
|
|
2993
|
-
}) {
|
|
2994
|
-
const slot = useSlotClassName();
|
|
2995
|
-
const { labels } = useWidgetSettings();
|
|
2996
|
-
const noRef = useRef(null);
|
|
2997
|
-
useEffect(() => {
|
|
2998
|
-
noRef.current?.focus();
|
|
2999
|
-
}, []);
|
|
3000
|
-
return /* @__PURE__ */ jsxs(
|
|
3001
|
-
"span",
|
|
3002
|
-
{
|
|
3003
|
-
role: "group",
|
|
3004
|
-
"aria-label": message,
|
|
3005
|
-
className: "dwt-confirm",
|
|
3006
|
-
onKeyDown: (event) => {
|
|
3007
|
-
if (event.key === "Escape") {
|
|
3008
|
-
event.stopPropagation();
|
|
3009
|
-
onAnswer(false);
|
|
3010
|
-
}
|
|
3011
|
-
},
|
|
3012
|
-
children: [
|
|
3013
|
-
/* @__PURE__ */ jsx("span", { role: "alert", className: "dwt-confirm-message", children: message }),
|
|
3014
|
-
/* @__PURE__ */ jsx(
|
|
3015
|
-
"button",
|
|
3016
|
-
{
|
|
3017
|
-
type: "button",
|
|
3018
|
-
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
3019
|
-
"aria-label": labels.confirmYes,
|
|
3020
|
-
title: labels.confirmYes,
|
|
3021
|
-
onClick: () => onAnswer(true),
|
|
3022
|
-
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2713" })
|
|
3023
|
-
}
|
|
3024
|
-
),
|
|
3025
|
-
/* @__PURE__ */ jsx(
|
|
3026
|
-
"button",
|
|
3027
|
-
{
|
|
3028
|
-
ref: noRef,
|
|
3029
|
-
type: "button",
|
|
3030
|
-
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
3031
|
-
"aria-label": labels.confirmNo,
|
|
3032
|
-
title: labels.confirmNo,
|
|
3033
|
-
onClick: () => onAnswer(false),
|
|
3034
|
-
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2715" })
|
|
3035
|
-
}
|
|
3036
|
-
)
|
|
3037
|
-
]
|
|
3038
|
-
}
|
|
3039
|
-
);
|
|
3040
|
-
}
|
|
3041
3768
|
function PageTabs({
|
|
3042
3769
|
pages,
|
|
3043
3770
|
activeKey,
|
|
@@ -3243,12 +3970,19 @@ function DashboardInner({
|
|
|
3243
3970
|
}) {
|
|
3244
3971
|
const slot = useSlotClassName();
|
|
3245
3972
|
const { labels } = useWidgetSettings();
|
|
3246
|
-
const
|
|
3973
|
+
const effectiveWidgets = widgets.map((w) => {
|
|
3974
|
+
const settings = savedLayout.settings?.[w.definition.key];
|
|
3975
|
+
return settings === void 0 || !overrideLocks && isOptionsLocked(w.definition) ? w : { ...w, definition: applySettings(w.definition, settings) };
|
|
3976
|
+
});
|
|
3977
|
+
const definitions = effectiveWidgets.map(
|
|
3247
3978
|
(w) => overrideLocks ? withoutLock(w.definition) : w.definition
|
|
3248
3979
|
);
|
|
3249
3980
|
const layout = enforceLocks(definitions, savedLayout);
|
|
3250
3981
|
const byKey = new Map(
|
|
3251
|
-
|
|
3982
|
+
effectiveWidgets.map((w) => [w.definition.key, w])
|
|
3983
|
+
);
|
|
3984
|
+
const authorDefinitions = new Map(
|
|
3985
|
+
widgets.map((w) => [w.definition.key, w.definition])
|
|
3252
3986
|
);
|
|
3253
3987
|
const pages = pageList(layout);
|
|
3254
3988
|
const paged = pages.length >= 2;
|
|
@@ -3293,6 +4027,7 @@ function DashboardInner({
|
|
|
3293
4027
|
const minimized = editable ? visible.filter((definition) => isMinimized(view, definition.key)) : [];
|
|
3294
4028
|
const shown = editable ? visible.filter((definition) => !isMinimized(view, definition.key)) : visible;
|
|
3295
4029
|
const [detailKey, setDetailKey] = useState(void 0);
|
|
4030
|
+
const [optionsKey, setOptionsKey] = useState(void 0);
|
|
3296
4031
|
const gridRef = useRef(null);
|
|
3297
4032
|
const twelve = usesWidthColumns(shown);
|
|
3298
4033
|
const spans = useFillSpans(
|
|
@@ -3432,7 +4167,14 @@ function DashboardInner({
|
|
|
3432
4167
|
const which = pending;
|
|
3433
4168
|
setConfirming(void 0);
|
|
3434
4169
|
if (yes && which === "reset") {
|
|
3435
|
-
|
|
4170
|
+
const arranged = enforceLocks(
|
|
4171
|
+
definitions,
|
|
4172
|
+
defaultLayout ?? EMPTY_LAYOUT
|
|
4173
|
+
);
|
|
4174
|
+
const { settings: _defaultSettings, ...arrangement } = arranged;
|
|
4175
|
+
change(
|
|
4176
|
+
layout.settings === void 0 ? arrangement : { ...arrangement, settings: layout.settings }
|
|
4177
|
+
);
|
|
3436
4178
|
} else if (yes && which === "revert" && snapshot !== void 0) {
|
|
3437
4179
|
change(snapshot);
|
|
3438
4180
|
}
|
|
@@ -3729,6 +4471,15 @@ function DashboardInner({
|
|
|
3729
4471
|
onSelect: () => changePage(moveWidgetBy(pageDefs, view, key, 1))
|
|
3730
4472
|
}
|
|
3731
4473
|
],
|
|
4474
|
+
...lock.options ? [] : [
|
|
4475
|
+
{
|
|
4476
|
+
kind: "action",
|
|
4477
|
+
key: "options",
|
|
4478
|
+
label: labels.menuOptions,
|
|
4479
|
+
ariaLabel: labels.optionsFor(title),
|
|
4480
|
+
onSelect: () => setOptionsKey(key)
|
|
4481
|
+
}
|
|
4482
|
+
],
|
|
3732
4483
|
...pageTargets,
|
|
3733
4484
|
...lock.hide ? [] : [
|
|
3734
4485
|
{
|
|
@@ -3817,6 +4568,30 @@ function DashboardInner({
|
|
|
3817
4568
|
]
|
|
3818
4569
|
}
|
|
3819
4570
|
),
|
|
4571
|
+
optionsKey !== void 0 && authorDefinitions.get(optionsKey) !== void 0 && /* @__PURE__ */ jsx(
|
|
4572
|
+
WidgetOptionsDialog,
|
|
4573
|
+
{
|
|
4574
|
+
definition: authorDefinitions.get(optionsKey),
|
|
4575
|
+
settings: layout.settings?.[optionsKey],
|
|
4576
|
+
...snapshot === void 0 ? {} : { baseline: { settings: snapshot.settings?.[optionsKey] } },
|
|
4577
|
+
isTitleInUse: (title) => isTitleInUse(
|
|
4578
|
+
widgets.map((w) => w.definition),
|
|
4579
|
+
layout,
|
|
4580
|
+
optionsKey,
|
|
4581
|
+
title
|
|
4582
|
+
),
|
|
4583
|
+
onApply: (patch) => {
|
|
4584
|
+
change(setWidgetSettings(layout, optionsKey, patch));
|
|
4585
|
+
setAnnouncement(
|
|
4586
|
+
labels.optionsSaved(
|
|
4587
|
+
authorDefinitions.get(optionsKey)?.title ?? optionsKey
|
|
4588
|
+
)
|
|
4589
|
+
);
|
|
4590
|
+
},
|
|
4591
|
+
onClose: () => setOptionsKey(void 0)
|
|
4592
|
+
},
|
|
4593
|
+
optionsKey
|
|
4594
|
+
),
|
|
3820
4595
|
detailKey !== void 0 && byKey.get(detailKey) !== void 0 && /* @__PURE__ */ jsx(
|
|
3821
4596
|
DetailHost,
|
|
3822
4597
|
{
|
|
@@ -4091,7 +4866,7 @@ function describeType2(value) {
|
|
|
4091
4866
|
}
|
|
4092
4867
|
return typeof value;
|
|
4093
4868
|
}
|
|
4094
|
-
function
|
|
4869
|
+
function isRecord2(value) {
|
|
4095
4870
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4096
4871
|
}
|
|
4097
4872
|
function join(path, field) {
|
|
@@ -4173,7 +4948,7 @@ function requireOneOf(record, field, options, path, problems) {
|
|
|
4173
4948
|
function eachRecord(items, path, problems, check) {
|
|
4174
4949
|
items.forEach((item, index) => {
|
|
4175
4950
|
const itemPath = `${path}[${index}]`;
|
|
4176
|
-
if (
|
|
4951
|
+
if (isRecord2(item)) {
|
|
4177
4952
|
check(item, itemPath);
|
|
4178
4953
|
} else {
|
|
4179
4954
|
problems.push(
|
|
@@ -4327,7 +5102,7 @@ function formatProblems(prefix, problems) {
|
|
|
4327
5102
|
}
|
|
4328
5103
|
function validateWidgetData(value, options = {}) {
|
|
4329
5104
|
const subject = options.widgetKey === void 0 ? "Widget data" : `Widget ${JSON.stringify(options.widgetKey)}`;
|
|
4330
|
-
if (!
|
|
5105
|
+
if (!isRecord2(value)) {
|
|
4331
5106
|
return err(`${subject}: must be an object, got ${describeType2(value)}.`);
|
|
4332
5107
|
}
|
|
4333
5108
|
if (value["empty"] === true) {
|
|
@@ -4772,6 +5547,6 @@ function useWidgets(definitions, providers, context, options = {}) {
|
|
|
4772
5547
|
return { widgets, refresh, setOptions, gridRef };
|
|
4773
5548
|
}
|
|
4774
5549
|
|
|
4775
|
-
export { AlertListWidget, BarListWidget, DEFAULT_LABELS, DEFAULT_SERIES_COLORS, Dashboard, GaugeWidget, GraphWidget, KpiWidget, ResolvedWidgetCard, TableWidget, TextWidget, Thumbnail, WidgetCard, WidgetContent, WidgetDetail, WidgetDetailDialog, WidgetGrid, WidgetLink, WidgetSettingsProvider, barPath, buildChartModel, describeChart, joinClassNames, seriesColor, useDetailData, useStoredLayout, useWidgetSettings, useWidgets, widgetTitle };
|
|
5550
|
+
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 };
|
|
4776
5551
|
//# sourceMappingURL=react.js.map
|
|
4777
5552
|
//# sourceMappingURL=react.js.map
|