@richardmcquiston01/dashboard-widgets-toolkit 0.7.0 → 0.9.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 +100 -19
- 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 +99 -20
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +100 -19
- 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 +99 -20
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +458 -153
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +50 -3
- package/dist/react.d.ts +50 -3
- package/dist/react.js +458 -153
- package/dist/react.js.map +1 -1
- package/dist/{scale-W60sXwlI.d.cts → scale-CrXxawQn.d.cts} +57 -5
- package/dist/{scale-W60sXwlI.d.ts → scale-CrXxawQn.d.ts} +57 -5
- package/dist/styles.css +35 -0
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -522,6 +522,19 @@ var DEFAULT_LABELS = {
|
|
|
522
522
|
moveLater: (title) => `Move ${title} later`,
|
|
523
523
|
hiddenWidgets: "Hidden:",
|
|
524
524
|
minimizedWidgets: "Minimized:",
|
|
525
|
+
customize: "Customize",
|
|
526
|
+
done: "Done",
|
|
527
|
+
reset: "Reset layout",
|
|
528
|
+
revertChanges: "Revert changes",
|
|
529
|
+
confirmReset: "Reset the layout to the default?",
|
|
530
|
+
confirmRevert: "Revert to how this looked before you started editing?",
|
|
531
|
+
confirmYes: "Yes",
|
|
532
|
+
confirmNo: "No",
|
|
533
|
+
editingOn: "Editing dashboard. Use the buttons on each card to reorder or hide it.",
|
|
534
|
+
editingOff: "Finished editing.",
|
|
535
|
+
dashboardControls: "Dashboard controls",
|
|
536
|
+
locked: (title) => `${title} is locked`,
|
|
537
|
+
lockedForViewers: (title) => `${title} is locked for viewers`,
|
|
525
538
|
opensInNewTab: "(opens in a new tab)",
|
|
526
539
|
view: (title) => `View ${title}`,
|
|
527
540
|
close: "Close",
|
|
@@ -1392,6 +1405,7 @@ function WidgetCard({
|
|
|
1392
1405
|
columnSpan,
|
|
1393
1406
|
width,
|
|
1394
1407
|
widgetKey,
|
|
1408
|
+
editing = false,
|
|
1395
1409
|
headingLevel = 2,
|
|
1396
1410
|
className,
|
|
1397
1411
|
children
|
|
@@ -1436,6 +1450,7 @@ function WidgetCard({
|
|
|
1436
1450
|
"dwt-card",
|
|
1437
1451
|
`dwt-card--${status}`,
|
|
1438
1452
|
minimized && "dwt-card--minimized",
|
|
1453
|
+
editing && "dwt-card--editing",
|
|
1439
1454
|
size !== void 0 && `dwt-card--size-${size}`,
|
|
1440
1455
|
fillsHeight(fill) && "dwt-card--fill-height",
|
|
1441
1456
|
fillsWidth(fill) && "dwt-card--fill-width",
|
|
@@ -1568,6 +1583,45 @@ function ResolvedWidgetCard({
|
|
|
1568
1583
|
);
|
|
1569
1584
|
}
|
|
1570
1585
|
|
|
1586
|
+
// src/core/definition.ts
|
|
1587
|
+
var NOT_LOCKED = Object.freeze({
|
|
1588
|
+
move: false,
|
|
1589
|
+
hide: false,
|
|
1590
|
+
minimize: false
|
|
1591
|
+
});
|
|
1592
|
+
var FULLY_LOCKED = Object.freeze({
|
|
1593
|
+
move: true,
|
|
1594
|
+
hide: true,
|
|
1595
|
+
minimize: true
|
|
1596
|
+
});
|
|
1597
|
+
function resolveWidgetLock(definition) {
|
|
1598
|
+
const setting = definition.locked;
|
|
1599
|
+
if (setting === true) return FULLY_LOCKED;
|
|
1600
|
+
if (setting === void 0 || setting === false) return NOT_LOCKED;
|
|
1601
|
+
return {
|
|
1602
|
+
move: setting.move === true,
|
|
1603
|
+
hide: setting.hide === true,
|
|
1604
|
+
minimize: setting.minimize === true
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
function sortDefinitions(definitions) {
|
|
1608
|
+
return definitions.map((definition, index) => ({ definition, index })).sort(
|
|
1609
|
+
(a, b) => (a.definition.sortOrder ?? 0) - (b.definition.sortOrder ?? 0) || a.index - b.index
|
|
1610
|
+
).map(({ definition }) => definition);
|
|
1611
|
+
}
|
|
1612
|
+
function isWidgetVisibleTo(definition, roles) {
|
|
1613
|
+
if (definition.active === false) {
|
|
1614
|
+
return false;
|
|
1615
|
+
}
|
|
1616
|
+
if (definition.roles === void 0 || definition.roles.length === 0) {
|
|
1617
|
+
return true;
|
|
1618
|
+
}
|
|
1619
|
+
if (roles === void 0) {
|
|
1620
|
+
return false;
|
|
1621
|
+
}
|
|
1622
|
+
return definition.roles.some((role) => roles.includes(role));
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1571
1625
|
// src/core/layout.ts
|
|
1572
1626
|
var EMPTY_LAYOUT = Object.freeze({
|
|
1573
1627
|
order: Object.freeze([]),
|
|
@@ -1579,9 +1633,10 @@ function bySortOrder(items) {
|
|
|
1579
1633
|
(a, b) => (a.item.sortOrder ?? 0) - (b.item.sortOrder ?? 0) || a.index - b.index
|
|
1580
1634
|
).map(({ item }) => item);
|
|
1581
1635
|
}
|
|
1582
|
-
function
|
|
1583
|
-
|
|
1584
|
-
|
|
1636
|
+
function isPinned(item) {
|
|
1637
|
+
return resolveWidgetLock(item).move;
|
|
1638
|
+
}
|
|
1639
|
+
function viewerOrder(visible, layout) {
|
|
1585
1640
|
const byKey = new Map(visible.map((d) => [d.key, d]));
|
|
1586
1641
|
const ordered = [];
|
|
1587
1642
|
for (const key of layout.order) {
|
|
@@ -1596,34 +1651,62 @@ function visibleWidgets(definitions, layout) {
|
|
|
1596
1651
|
}
|
|
1597
1652
|
return ordered;
|
|
1598
1653
|
}
|
|
1654
|
+
function placeAroundPinned(visible, free) {
|
|
1655
|
+
const slots = bySortOrder(visible).map(
|
|
1656
|
+
(item) => isPinned(item) ? item : void 0
|
|
1657
|
+
);
|
|
1658
|
+
let next = 0;
|
|
1659
|
+
return slots.map((pinned) => pinned ?? free[next++]);
|
|
1660
|
+
}
|
|
1661
|
+
function visibleWidgets(definitions, layout) {
|
|
1662
|
+
const hidden = new Set(layout.hidden);
|
|
1663
|
+
const visible = definitions.filter((d) => !hidden.has(d.key));
|
|
1664
|
+
const ordered = viewerOrder(visible, layout);
|
|
1665
|
+
if (!visible.some(isPinned)) return ordered;
|
|
1666
|
+
return placeAroundPinned(
|
|
1667
|
+
visible,
|
|
1668
|
+
ordered.filter((item) => !isPinned(item))
|
|
1669
|
+
);
|
|
1670
|
+
}
|
|
1599
1671
|
function hiddenWidgets(definitions, layout) {
|
|
1600
1672
|
const hidden = new Set(layout.hidden);
|
|
1601
1673
|
return bySortOrder(definitions.filter((d) => hidden.has(d.key)));
|
|
1602
1674
|
}
|
|
1603
1675
|
function moveWidget(definitions, layout, key, toIndex) {
|
|
1604
|
-
const current = visibleWidgets(definitions, layout)
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
if (fromIndex === -1 || !Number.isInteger(toIndex) || toIndex < 0 || toIndex >= current.length || toIndex === fromIndex) {
|
|
1676
|
+
const current = visibleWidgets(definitions, layout);
|
|
1677
|
+
const fromIndex = current.findIndex((d) => d.key === key);
|
|
1678
|
+
const mover = current[fromIndex];
|
|
1679
|
+
if (mover === void 0 || !Number.isInteger(toIndex) || toIndex < 0 || toIndex >= current.length || toIndex === fromIndex || isPinned(mover) || isPinned(current[toIndex])) {
|
|
1609
1680
|
return layout;
|
|
1610
1681
|
}
|
|
1611
|
-
const
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1682
|
+
const freeSlots = freeSlotIndexes(current);
|
|
1683
|
+
const free = current.filter((item) => !isPinned(item));
|
|
1684
|
+
const fromFree = freeSlots.indexOf(fromIndex);
|
|
1685
|
+
const toFree = freeSlots.indexOf(toIndex);
|
|
1686
|
+
free.splice(fromFree, 1);
|
|
1687
|
+
free.splice(toFree, 0, mover);
|
|
1688
|
+
const next = placeAroundPinned(current, free);
|
|
1689
|
+
return { ...layout, order: next.map((d) => d.key) };
|
|
1690
|
+
}
|
|
1691
|
+
function freeSlotIndexes(ordered) {
|
|
1692
|
+
const slots = [];
|
|
1693
|
+
ordered.forEach((item, index) => {
|
|
1694
|
+
if (!isPinned(item)) slots.push(index);
|
|
1695
|
+
});
|
|
1696
|
+
return slots;
|
|
1615
1697
|
}
|
|
1616
1698
|
function moveWidgetBy(definitions, layout, key, offset) {
|
|
1617
|
-
const current = visibleWidgets(definitions, layout)
|
|
1618
|
-
|
|
1619
|
-
);
|
|
1620
|
-
const fromIndex = current.indexOf(key);
|
|
1699
|
+
const current = visibleWidgets(definitions, layout);
|
|
1700
|
+
const fromIndex = current.findIndex((d) => d.key === key);
|
|
1621
1701
|
if (fromIndex === -1) return layout;
|
|
1622
|
-
const
|
|
1702
|
+
const freeSlots = freeSlotIndexes(current);
|
|
1703
|
+
const fromFree = freeSlots.indexOf(fromIndex);
|
|
1704
|
+
if (fromFree === -1) return layout;
|
|
1705
|
+
const toFree = Math.max(
|
|
1623
1706
|
0,
|
|
1624
|
-
Math.min(
|
|
1707
|
+
Math.min(freeSlots.length - 1, fromFree + Math.trunc(offset))
|
|
1625
1708
|
);
|
|
1626
|
-
return moveWidget(definitions, layout, key,
|
|
1709
|
+
return moveWidget(definitions, layout, key, freeSlots[toFree]);
|
|
1627
1710
|
}
|
|
1628
1711
|
function isHidden(layout, key) {
|
|
1629
1712
|
return layout.hidden.includes(key);
|
|
@@ -1654,6 +1737,23 @@ function restoreWidget(layout, key) {
|
|
|
1654
1737
|
function toggleMinimized(layout, key) {
|
|
1655
1738
|
return isMinimized(layout, key) ? restoreWidget(layout, key) : minimizeWidget(layout, key);
|
|
1656
1739
|
}
|
|
1740
|
+
function enforceLocks(definitions, layout, options = {}) {
|
|
1741
|
+
if (options.overrideLocks === true) return layout;
|
|
1742
|
+
const noMove = /* @__PURE__ */ new Set();
|
|
1743
|
+
const noHide = /* @__PURE__ */ new Set();
|
|
1744
|
+
const noMinimize = /* @__PURE__ */ new Set();
|
|
1745
|
+
for (const definition of definitions) {
|
|
1746
|
+
const lock = resolveWidgetLock(definition);
|
|
1747
|
+
if (lock.move) noMove.add(definition.key);
|
|
1748
|
+
if (lock.hide) noHide.add(definition.key);
|
|
1749
|
+
if (lock.minimize) noMinimize.add(definition.key);
|
|
1750
|
+
}
|
|
1751
|
+
const without = (keys, drop) => keys.some((key) => drop.has(key)) ? keys.filter((key) => !drop.has(key)) : keys;
|
|
1752
|
+
const order = without(layout.order, noMove);
|
|
1753
|
+
const hidden = without(layout.hidden, noHide);
|
|
1754
|
+
const minimized = without(layout.minimized, noMinimize);
|
|
1755
|
+
return order === layout.order && hidden === layout.hidden && minimized === layout.minimized ? layout : { ...layout, order, hidden, minimized };
|
|
1756
|
+
}
|
|
1657
1757
|
function nextSort(current, column) {
|
|
1658
1758
|
if (current?.column !== column) return { column, direction: "asc" };
|
|
1659
1759
|
return current.direction === "asc" ? { column, direction: "desc" } : void 0;
|
|
@@ -2052,10 +2152,74 @@ function DetailHost({
|
|
|
2052
2152
|
}
|
|
2053
2153
|
) });
|
|
2054
2154
|
}
|
|
2155
|
+
function InlineConfirm({
|
|
2156
|
+
message,
|
|
2157
|
+
onAnswer
|
|
2158
|
+
}) {
|
|
2159
|
+
const slot = useSlotClassName();
|
|
2160
|
+
const { labels } = useWidgetSettings();
|
|
2161
|
+
const noRef = useRef(null);
|
|
2162
|
+
useEffect(() => {
|
|
2163
|
+
noRef.current?.focus();
|
|
2164
|
+
}, []);
|
|
2165
|
+
return /* @__PURE__ */ jsxs(
|
|
2166
|
+
"span",
|
|
2167
|
+
{
|
|
2168
|
+
role: "group",
|
|
2169
|
+
"aria-label": message,
|
|
2170
|
+
className: "dwt-confirm",
|
|
2171
|
+
onKeyDown: (event) => {
|
|
2172
|
+
if (event.key === "Escape") {
|
|
2173
|
+
event.stopPropagation();
|
|
2174
|
+
onAnswer(false);
|
|
2175
|
+
}
|
|
2176
|
+
},
|
|
2177
|
+
children: [
|
|
2178
|
+
/* @__PURE__ */ jsx("span", { role: "alert", className: "dwt-confirm-message", children: message }),
|
|
2179
|
+
/* @__PURE__ */ jsx(
|
|
2180
|
+
"button",
|
|
2181
|
+
{
|
|
2182
|
+
type: "button",
|
|
2183
|
+
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
2184
|
+
"aria-label": labels.confirmYes,
|
|
2185
|
+
title: labels.confirmYes,
|
|
2186
|
+
onClick: () => onAnswer(true),
|
|
2187
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2713" })
|
|
2188
|
+
}
|
|
2189
|
+
),
|
|
2190
|
+
/* @__PURE__ */ jsx(
|
|
2191
|
+
"button",
|
|
2192
|
+
{
|
|
2193
|
+
ref: noRef,
|
|
2194
|
+
type: "button",
|
|
2195
|
+
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
2196
|
+
"aria-label": labels.confirmNo,
|
|
2197
|
+
title: labels.confirmNo,
|
|
2198
|
+
onClick: () => onAnswer(false),
|
|
2199
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2715" })
|
|
2200
|
+
}
|
|
2201
|
+
)
|
|
2202
|
+
]
|
|
2203
|
+
}
|
|
2204
|
+
);
|
|
2205
|
+
}
|
|
2206
|
+
function withoutLock(definition) {
|
|
2207
|
+
if (definition.locked === void 0) return definition;
|
|
2208
|
+
const copy = { ...definition };
|
|
2209
|
+
delete copy.locked;
|
|
2210
|
+
return copy;
|
|
2211
|
+
}
|
|
2055
2212
|
function DashboardInner({
|
|
2056
2213
|
widgets,
|
|
2057
|
-
layout = EMPTY_LAYOUT,
|
|
2214
|
+
layout: savedLayout = EMPTY_LAYOUT,
|
|
2058
2215
|
onLayoutChange,
|
|
2216
|
+
overrideLocks = false,
|
|
2217
|
+
editMode = "always",
|
|
2218
|
+
editing: editingProp,
|
|
2219
|
+
defaultEditing = false,
|
|
2220
|
+
onEditingChange,
|
|
2221
|
+
defaultLayout,
|
|
2222
|
+
toolbar = true,
|
|
2059
2223
|
onRetry,
|
|
2060
2224
|
loadDetail,
|
|
2061
2225
|
onOpenDetail,
|
|
@@ -2064,13 +2228,35 @@ function DashboardInner({
|
|
|
2064
2228
|
}) {
|
|
2065
2229
|
const slot = useSlotClassName();
|
|
2066
2230
|
const { labels } = useWidgetSettings();
|
|
2067
|
-
const definitions = widgets.map(
|
|
2231
|
+
const definitions = widgets.map(
|
|
2232
|
+
(w) => overrideLocks ? withoutLock(w.definition) : w.definition
|
|
2233
|
+
);
|
|
2234
|
+
const layout = enforceLocks(definitions, savedLayout);
|
|
2068
2235
|
const byKey = new Map(
|
|
2069
2236
|
widgets.map((w) => [w.definition.key, w])
|
|
2070
2237
|
);
|
|
2071
2238
|
const visible = visibleWidgets(definitions, layout);
|
|
2072
2239
|
const hidden = hiddenWidgets(definitions, layout);
|
|
2073
2240
|
const editable = onLayoutChange !== void 0;
|
|
2241
|
+
const toggleMode = editMode === "toggle";
|
|
2242
|
+
const [editingState, setEditingState] = useState(defaultEditing);
|
|
2243
|
+
const editing = editingProp ?? editingState;
|
|
2244
|
+
const controlsShown = editable && (!toggleMode || editing);
|
|
2245
|
+
const [snapshot, setSnapshot] = useState(
|
|
2246
|
+
void 0
|
|
2247
|
+
);
|
|
2248
|
+
if (toggleMode && editable && editing) {
|
|
2249
|
+
if (snapshot === void 0) setSnapshot(savedLayout);
|
|
2250
|
+
} else if (snapshot !== void 0) {
|
|
2251
|
+
setSnapshot(void 0);
|
|
2252
|
+
}
|
|
2253
|
+
const [confirming, setConfirming] = useState(
|
|
2254
|
+
void 0
|
|
2255
|
+
);
|
|
2256
|
+
const pending = editing ? confirming : void 0;
|
|
2257
|
+
const [announcement, setAnnouncement] = useState("");
|
|
2258
|
+
const toggleRef = useRef(null);
|
|
2259
|
+
const resetRef = useRef(null);
|
|
2074
2260
|
const minimized = editable ? visible.filter((definition) => isMinimized(layout, definition.key)) : [];
|
|
2075
2261
|
const shown = editable ? visible.filter((definition) => !isMinimized(layout, definition.key)) : visible;
|
|
2076
2262
|
const [detailKey, setDetailKey] = useState(void 0);
|
|
@@ -2084,129 +2270,267 @@ function DashboardInner({
|
|
|
2084
2270
|
function change(next) {
|
|
2085
2271
|
if (next !== layout) onLayoutChange?.(next);
|
|
2086
2272
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2273
|
+
function setEditing(next) {
|
|
2274
|
+
if (editingProp === void 0) setEditingState(next);
|
|
2275
|
+
onEditingChange?.(next);
|
|
2276
|
+
setAnnouncement(next ? labels.editingOn : labels.editingOff);
|
|
2277
|
+
setConfirming(void 0);
|
|
2278
|
+
}
|
|
2279
|
+
function answerConfirmation(yes) {
|
|
2280
|
+
const which = pending;
|
|
2281
|
+
setConfirming(void 0);
|
|
2282
|
+
if (yes && which === "reset") {
|
|
2283
|
+
change(enforceLocks(definitions, defaultLayout ?? EMPTY_LAYOUT));
|
|
2284
|
+
} else if (yes && which === "revert" && snapshot !== void 0) {
|
|
2285
|
+
change(snapshot);
|
|
2286
|
+
}
|
|
2287
|
+
(which === "revert" ? toggleRef : resetRef).current?.focus();
|
|
2288
|
+
}
|
|
2289
|
+
return /* @__PURE__ */ jsxs(
|
|
2290
|
+
"div",
|
|
2291
|
+
{
|
|
2292
|
+
className: slot(
|
|
2293
|
+
"dashboard",
|
|
2294
|
+
"dwt-dashboard",
|
|
2295
|
+
toggleMode && controlsShown && "dwt-dashboard--editing",
|
|
2296
|
+
className
|
|
2297
|
+
),
|
|
2298
|
+
children: [
|
|
2299
|
+
editable && toggleMode && toolbar && /* @__PURE__ */ jsxs(
|
|
2300
|
+
"div",
|
|
2301
|
+
{
|
|
2302
|
+
role: "group",
|
|
2303
|
+
"aria-label": labels.dashboardControls,
|
|
2304
|
+
className: slot("toolbar", "dwt-toolbar"),
|
|
2305
|
+
children: [
|
|
2306
|
+
/* @__PURE__ */ jsx(
|
|
2307
|
+
"button",
|
|
2308
|
+
{
|
|
2309
|
+
ref: toggleRef,
|
|
2310
|
+
type: "button",
|
|
2311
|
+
"aria-pressed": editing,
|
|
2312
|
+
className: slot("button", "dwt-button", "dwt-toolbar-toggle"),
|
|
2313
|
+
onClick: () => setEditing(!editing),
|
|
2314
|
+
children: editing ? labels.done : labels.customize
|
|
2315
|
+
}
|
|
2316
|
+
),
|
|
2317
|
+
editing && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2318
|
+
/* @__PURE__ */ jsx(
|
|
2319
|
+
"button",
|
|
2320
|
+
{
|
|
2321
|
+
ref: resetRef,
|
|
2322
|
+
type: "button",
|
|
2323
|
+
className: slot("button", "dwt-button"),
|
|
2324
|
+
onClick: () => setConfirming("reset"),
|
|
2325
|
+
children: labels.reset
|
|
2326
|
+
}
|
|
2327
|
+
),
|
|
2328
|
+
/* @__PURE__ */ jsx(
|
|
2329
|
+
"button",
|
|
2330
|
+
{
|
|
2331
|
+
type: "button",
|
|
2332
|
+
className: slot("button", "dwt-button"),
|
|
2333
|
+
disabled: snapshot === void 0 || savedLayout === snapshot,
|
|
2334
|
+
onClick: () => setConfirming("revert"),
|
|
2335
|
+
children: labels.revertChanges
|
|
2336
|
+
}
|
|
2337
|
+
)
|
|
2338
|
+
] }),
|
|
2339
|
+
pending !== void 0 && /* @__PURE__ */ jsx(
|
|
2340
|
+
InlineConfirm,
|
|
2341
|
+
{
|
|
2342
|
+
message: pending === "reset" ? labels.confirmReset : labels.confirmRevert,
|
|
2343
|
+
onAnswer: answerConfirmation
|
|
2344
|
+
}
|
|
2345
|
+
),
|
|
2346
|
+
/* @__PURE__ */ jsx("span", { className: "dwt-visually-hidden", "aria-live": "polite", children: announcement })
|
|
2347
|
+
]
|
|
2348
|
+
}
|
|
2349
|
+
),
|
|
2350
|
+
controlsShown && hidden.length > 0 && /* @__PURE__ */ jsxs("div", { className: slot("hiddenBar", "dwt-hidden-bar"), children: [
|
|
2351
|
+
/* @__PURE__ */ jsx("span", { className: "dwt-hidden-label", children: labels.hiddenWidgets }),
|
|
2352
|
+
hidden.map((definition) => /* @__PURE__ */ jsxs(
|
|
2112
2353
|
"button",
|
|
2113
2354
|
{
|
|
2114
2355
|
type: "button",
|
|
2115
2356
|
className: slot("button", "dwt-button", "dwt-show-button"),
|
|
2116
|
-
"aria-label": labels.
|
|
2117
|
-
onClick: () => change(
|
|
2357
|
+
"aria-label": labels.show(definition.title),
|
|
2358
|
+
onClick: () => change(showWidget(layout, definition.key)),
|
|
2118
2359
|
children: [
|
|
2119
|
-
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "
|
|
2360
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "+ " }),
|
|
2120
2361
|
definition.title
|
|
2121
2362
|
]
|
|
2122
2363
|
},
|
|
2123
2364
|
definition.key
|
|
2124
2365
|
))
|
|
2125
|
-
]
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2366
|
+
] }),
|
|
2367
|
+
minimized.length > 0 && /* @__PURE__ */ jsxs(
|
|
2368
|
+
"div",
|
|
2369
|
+
{
|
|
2370
|
+
className: slot("hiddenBar", "dwt-hidden-bar", "dwt-minimized-bar"),
|
|
2371
|
+
children: [
|
|
2372
|
+
/* @__PURE__ */ jsx("span", { className: "dwt-hidden-label", children: labels.minimizedWidgets }),
|
|
2373
|
+
minimized.map((definition) => /* @__PURE__ */ jsxs(
|
|
2374
|
+
"button",
|
|
2375
|
+
{
|
|
2376
|
+
type: "button",
|
|
2377
|
+
className: slot("button", "dwt-button", "dwt-show-button"),
|
|
2378
|
+
"aria-label": labels.expand(definition.title),
|
|
2379
|
+
onClick: () => change(toggleMinimized(layout, definition.key)),
|
|
2380
|
+
children: [
|
|
2381
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u25B8 " }),
|
|
2382
|
+
definition.title
|
|
2383
|
+
]
|
|
2384
|
+
},
|
|
2385
|
+
definition.key
|
|
2386
|
+
))
|
|
2387
|
+
]
|
|
2388
|
+
}
|
|
2389
|
+
),
|
|
2390
|
+
visible.length === 0 ? /* @__PURE__ */ jsx("p", { className: slot("empty", "dwt-empty", "dwt-dashboard-empty"), children: definitions.length === 0 ? labels.noWidgets : labels.allHidden }) : shown.length === 0 ? null : /* @__PURE__ */ jsx(
|
|
2391
|
+
"div",
|
|
2392
|
+
{
|
|
2393
|
+
ref: gridRef,
|
|
2394
|
+
className: slot("grid", "dwt-grid", twelve && "dwt-grid--twelve"),
|
|
2395
|
+
children: shown.map((definition, index) => {
|
|
2396
|
+
const widget = byKey.get(
|
|
2397
|
+
definition.key
|
|
2398
|
+
);
|
|
2399
|
+
if (widget === void 0) return null;
|
|
2400
|
+
const key = definition.key;
|
|
2401
|
+
const title = definition.title;
|
|
2402
|
+
const lock = resolveWidgetLock(definition);
|
|
2403
|
+
const ownLock = resolveWidgetLock(
|
|
2404
|
+
widget.definition
|
|
2405
|
+
);
|
|
2406
|
+
const isLocked = ownLock.move || ownLock.hide || ownLock.minimize;
|
|
2407
|
+
const lockLabel = overrideLocks ? labels.lockedForViewers(title) : labels.locked(title);
|
|
2408
|
+
const canMoveEarlier = !lock.move && moveWidgetBy(definitions, layout, key, -1) !== layout;
|
|
2409
|
+
const canMoveLater = !lock.move && moveWidgetBy(definitions, layout, key, 1) !== layout;
|
|
2410
|
+
const actions = controlsShown ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2411
|
+
isLocked && /* @__PURE__ */ jsx(
|
|
2412
|
+
"span",
|
|
2413
|
+
{
|
|
2414
|
+
role: "img",
|
|
2415
|
+
className: "dwt-lock",
|
|
2416
|
+
"aria-label": lockLabel,
|
|
2417
|
+
title: lockLabel,
|
|
2418
|
+
children: /* @__PURE__ */ jsxs(
|
|
2419
|
+
"svg",
|
|
2420
|
+
{
|
|
2421
|
+
viewBox: "0 0 16 16",
|
|
2422
|
+
width: "14",
|
|
2423
|
+
height: "14",
|
|
2424
|
+
"aria-hidden": "true",
|
|
2425
|
+
focusable: "false",
|
|
2426
|
+
children: [
|
|
2427
|
+
/* @__PURE__ */ jsx(
|
|
2428
|
+
"rect",
|
|
2429
|
+
{
|
|
2430
|
+
x: "3",
|
|
2431
|
+
y: "7",
|
|
2432
|
+
width: "10",
|
|
2433
|
+
height: "7",
|
|
2434
|
+
rx: "1.5",
|
|
2435
|
+
fill: "currentColor"
|
|
2436
|
+
}
|
|
2437
|
+
),
|
|
2438
|
+
/* @__PURE__ */ jsx(
|
|
2439
|
+
"path",
|
|
2440
|
+
{
|
|
2441
|
+
d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2",
|
|
2442
|
+
fill: "none",
|
|
2443
|
+
stroke: "currentColor",
|
|
2444
|
+
strokeWidth: "1.4"
|
|
2445
|
+
}
|
|
2446
|
+
)
|
|
2447
|
+
]
|
|
2448
|
+
}
|
|
2449
|
+
)
|
|
2450
|
+
}
|
|
2451
|
+
),
|
|
2452
|
+
!lock.move && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2453
|
+
/* @__PURE__ */ jsx(
|
|
2454
|
+
"button",
|
|
2455
|
+
{
|
|
2456
|
+
type: "button",
|
|
2457
|
+
className: slot(
|
|
2458
|
+
"button",
|
|
2459
|
+
"dwt-button",
|
|
2460
|
+
"dwt-icon-button"
|
|
2461
|
+
),
|
|
2462
|
+
"aria-label": labels.moveEarlier(title),
|
|
2463
|
+
title: labels.moveEarlier(title),
|
|
2464
|
+
disabled: index === 0 || !canMoveEarlier,
|
|
2465
|
+
onClick: () => change(moveWidgetBy(definitions, layout, key, -1)),
|
|
2466
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2191" })
|
|
2467
|
+
}
|
|
2468
|
+
),
|
|
2469
|
+
/* @__PURE__ */ jsx(
|
|
2470
|
+
"button",
|
|
2471
|
+
{
|
|
2472
|
+
type: "button",
|
|
2473
|
+
className: slot(
|
|
2474
|
+
"button",
|
|
2475
|
+
"dwt-button",
|
|
2476
|
+
"dwt-icon-button"
|
|
2477
|
+
),
|
|
2478
|
+
"aria-label": labels.moveLater(title),
|
|
2479
|
+
title: labels.moveLater(title),
|
|
2480
|
+
disabled: index === shown.length - 1 || !canMoveLater,
|
|
2481
|
+
onClick: () => change(moveWidgetBy(definitions, layout, key, 1)),
|
|
2482
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2193" })
|
|
2483
|
+
}
|
|
2484
|
+
)
|
|
2485
|
+
] }),
|
|
2486
|
+
!lock.hide && /* @__PURE__ */ jsx(
|
|
2487
|
+
"button",
|
|
2488
|
+
{
|
|
2489
|
+
type: "button",
|
|
2490
|
+
className: slot("button", "dwt-button", "dwt-icon-button"),
|
|
2491
|
+
"aria-label": labels.hide(title),
|
|
2492
|
+
title: labels.hide(title),
|
|
2493
|
+
onClick: () => change(hideWidget(layout, key)),
|
|
2494
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xD7" })
|
|
2495
|
+
}
|
|
2496
|
+
)
|
|
2497
|
+
] }) : void 0;
|
|
2498
|
+
const viewable = resolveDetailOptions(definition) !== void 0 && (onOpenDetail !== void 0 || loadDetail !== void 0 || widget.status === "ok" && deriveDetailData(widget.data) !== void 0);
|
|
2499
|
+
return /* @__PURE__ */ jsx(
|
|
2500
|
+
ResolvedWidgetCard,
|
|
2501
|
+
{
|
|
2502
|
+
widget,
|
|
2503
|
+
...viewable ? {
|
|
2504
|
+
onView: () => onOpenDetail === void 0 ? setDetailKey(key) : onOpenDetail(key)
|
|
2505
|
+
} : {},
|
|
2506
|
+
...spanProps(spans, key),
|
|
2507
|
+
...widthProps(twelve, definition),
|
|
2508
|
+
minimized: isMinimized(layout, key),
|
|
2509
|
+
editing: toggleMode && controlsShown,
|
|
2510
|
+
...actions === void 0 ? {} : { actions },
|
|
2511
|
+
...editable && !lock.minimize ? {
|
|
2512
|
+
onToggleMinimized: () => change(toggleMinimized(layout, key))
|
|
2513
|
+
} : {},
|
|
2514
|
+
...headingLevel === void 0 ? {} : { headingLevel },
|
|
2515
|
+
...onRetry === void 0 || widget.status !== "error" ? {} : { onRetry: () => onRetry(key) }
|
|
2516
|
+
},
|
|
2517
|
+
key
|
|
2518
|
+
);
|
|
2519
|
+
})
|
|
2520
|
+
}
|
|
2521
|
+
),
|
|
2522
|
+
detailKey !== void 0 && byKey.get(detailKey) !== void 0 && /* @__PURE__ */ jsx(
|
|
2523
|
+
DetailHost,
|
|
2524
|
+
{
|
|
2525
|
+
widget: byKey.get(detailKey),
|
|
2526
|
+
loadDetail,
|
|
2527
|
+
onClose: () => setDetailKey(void 0)
|
|
2528
|
+
},
|
|
2529
|
+
detailKey
|
|
2530
|
+
)
|
|
2531
|
+
]
|
|
2532
|
+
}
|
|
2533
|
+
);
|
|
2210
2534
|
}
|
|
2211
2535
|
function Dashboard({
|
|
2212
2536
|
locale,
|
|
@@ -2230,25 +2554,6 @@ function Dashboard({
|
|
|
2230
2554
|
);
|
|
2231
2555
|
}
|
|
2232
2556
|
|
|
2233
|
-
// src/core/definition.ts
|
|
2234
|
-
function sortDefinitions(definitions) {
|
|
2235
|
-
return definitions.map((definition, index) => ({ definition, index })).sort(
|
|
2236
|
-
(a, b) => (a.definition.sortOrder ?? 0) - (b.definition.sortOrder ?? 0) || a.index - b.index
|
|
2237
|
-
).map(({ definition }) => definition);
|
|
2238
|
-
}
|
|
2239
|
-
function isWidgetVisibleTo(definition, roles) {
|
|
2240
|
-
if (definition.active === false) {
|
|
2241
|
-
return false;
|
|
2242
|
-
}
|
|
2243
|
-
if (definition.roles === void 0 || definition.roles.length === 0) {
|
|
2244
|
-
return true;
|
|
2245
|
-
}
|
|
2246
|
-
if (roles === void 0) {
|
|
2247
|
-
return false;
|
|
2248
|
-
}
|
|
2249
|
-
return definition.roles.some((role) => roles.includes(role));
|
|
2250
|
-
}
|
|
2251
|
-
|
|
2252
2557
|
// src/core/payload.ts
|
|
2253
2558
|
var WIDGET_KINDS = [
|
|
2254
2559
|
"TEXT",
|