@richardmcquiston01/dashboard-widgets-toolkit 0.7.0 → 0.8.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 +155 -66
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +8 -1
- package/dist/react.d.ts +8 -1
- package/dist/react.js +155 -66
- 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/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -1570,6 +1570,45 @@ function ResolvedWidgetCard({
|
|
|
1570
1570
|
);
|
|
1571
1571
|
}
|
|
1572
1572
|
|
|
1573
|
+
// src/core/definition.ts
|
|
1574
|
+
var NOT_LOCKED = Object.freeze({
|
|
1575
|
+
move: false,
|
|
1576
|
+
hide: false,
|
|
1577
|
+
minimize: false
|
|
1578
|
+
});
|
|
1579
|
+
var FULLY_LOCKED = Object.freeze({
|
|
1580
|
+
move: true,
|
|
1581
|
+
hide: true,
|
|
1582
|
+
minimize: true
|
|
1583
|
+
});
|
|
1584
|
+
function resolveWidgetLock(definition) {
|
|
1585
|
+
const setting = definition.locked;
|
|
1586
|
+
if (setting === true) return FULLY_LOCKED;
|
|
1587
|
+
if (setting === void 0 || setting === false) return NOT_LOCKED;
|
|
1588
|
+
return {
|
|
1589
|
+
move: setting.move === true,
|
|
1590
|
+
hide: setting.hide === true,
|
|
1591
|
+
minimize: setting.minimize === true
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
function sortDefinitions(definitions) {
|
|
1595
|
+
return definitions.map((definition, index) => ({ definition, index })).sort(
|
|
1596
|
+
(a, b) => (a.definition.sortOrder ?? 0) - (b.definition.sortOrder ?? 0) || a.index - b.index
|
|
1597
|
+
).map(({ definition }) => definition);
|
|
1598
|
+
}
|
|
1599
|
+
function isWidgetVisibleTo(definition, roles) {
|
|
1600
|
+
if (definition.active === false) {
|
|
1601
|
+
return false;
|
|
1602
|
+
}
|
|
1603
|
+
if (definition.roles === void 0 || definition.roles.length === 0) {
|
|
1604
|
+
return true;
|
|
1605
|
+
}
|
|
1606
|
+
if (roles === void 0) {
|
|
1607
|
+
return false;
|
|
1608
|
+
}
|
|
1609
|
+
return definition.roles.some((role) => roles.includes(role));
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1573
1612
|
// src/core/layout.ts
|
|
1574
1613
|
var EMPTY_LAYOUT = Object.freeze({
|
|
1575
1614
|
order: Object.freeze([]),
|
|
@@ -1581,9 +1620,10 @@ function bySortOrder(items) {
|
|
|
1581
1620
|
(a, b) => (a.item.sortOrder ?? 0) - (b.item.sortOrder ?? 0) || a.index - b.index
|
|
1582
1621
|
).map(({ item }) => item);
|
|
1583
1622
|
}
|
|
1584
|
-
function
|
|
1585
|
-
|
|
1586
|
-
|
|
1623
|
+
function isPinned(item) {
|
|
1624
|
+
return resolveWidgetLock(item).move;
|
|
1625
|
+
}
|
|
1626
|
+
function viewerOrder(visible, layout) {
|
|
1587
1627
|
const byKey = new Map(visible.map((d) => [d.key, d]));
|
|
1588
1628
|
const ordered = [];
|
|
1589
1629
|
for (const key of layout.order) {
|
|
@@ -1598,34 +1638,62 @@ function visibleWidgets(definitions, layout) {
|
|
|
1598
1638
|
}
|
|
1599
1639
|
return ordered;
|
|
1600
1640
|
}
|
|
1641
|
+
function placeAroundPinned(visible, free) {
|
|
1642
|
+
const slots = bySortOrder(visible).map(
|
|
1643
|
+
(item) => isPinned(item) ? item : void 0
|
|
1644
|
+
);
|
|
1645
|
+
let next = 0;
|
|
1646
|
+
return slots.map((pinned) => pinned ?? free[next++]);
|
|
1647
|
+
}
|
|
1648
|
+
function visibleWidgets(definitions, layout) {
|
|
1649
|
+
const hidden = new Set(layout.hidden);
|
|
1650
|
+
const visible = definitions.filter((d) => !hidden.has(d.key));
|
|
1651
|
+
const ordered = viewerOrder(visible, layout);
|
|
1652
|
+
if (!visible.some(isPinned)) return ordered;
|
|
1653
|
+
return placeAroundPinned(
|
|
1654
|
+
visible,
|
|
1655
|
+
ordered.filter((item) => !isPinned(item))
|
|
1656
|
+
);
|
|
1657
|
+
}
|
|
1601
1658
|
function hiddenWidgets(definitions, layout) {
|
|
1602
1659
|
const hidden = new Set(layout.hidden);
|
|
1603
1660
|
return bySortOrder(definitions.filter((d) => hidden.has(d.key)));
|
|
1604
1661
|
}
|
|
1605
1662
|
function moveWidget(definitions, layout, key, toIndex) {
|
|
1606
|
-
const current = visibleWidgets(definitions, layout)
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
if (fromIndex === -1 || !Number.isInteger(toIndex) || toIndex < 0 || toIndex >= current.length || toIndex === fromIndex) {
|
|
1663
|
+
const current = visibleWidgets(definitions, layout);
|
|
1664
|
+
const fromIndex = current.findIndex((d) => d.key === key);
|
|
1665
|
+
const mover = current[fromIndex];
|
|
1666
|
+
if (mover === void 0 || !Number.isInteger(toIndex) || toIndex < 0 || toIndex >= current.length || toIndex === fromIndex || isPinned(mover) || isPinned(current[toIndex])) {
|
|
1611
1667
|
return layout;
|
|
1612
1668
|
}
|
|
1613
|
-
const
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1669
|
+
const freeSlots = freeSlotIndexes(current);
|
|
1670
|
+
const free = current.filter((item) => !isPinned(item));
|
|
1671
|
+
const fromFree = freeSlots.indexOf(fromIndex);
|
|
1672
|
+
const toFree = freeSlots.indexOf(toIndex);
|
|
1673
|
+
free.splice(fromFree, 1);
|
|
1674
|
+
free.splice(toFree, 0, mover);
|
|
1675
|
+
const next = placeAroundPinned(current, free);
|
|
1676
|
+
return { ...layout, order: next.map((d) => d.key) };
|
|
1677
|
+
}
|
|
1678
|
+
function freeSlotIndexes(ordered) {
|
|
1679
|
+
const slots = [];
|
|
1680
|
+
ordered.forEach((item, index) => {
|
|
1681
|
+
if (!isPinned(item)) slots.push(index);
|
|
1682
|
+
});
|
|
1683
|
+
return slots;
|
|
1617
1684
|
}
|
|
1618
1685
|
function moveWidgetBy(definitions, layout, key, offset) {
|
|
1619
|
-
const current = visibleWidgets(definitions, layout)
|
|
1620
|
-
|
|
1621
|
-
);
|
|
1622
|
-
const fromIndex = current.indexOf(key);
|
|
1686
|
+
const current = visibleWidgets(definitions, layout);
|
|
1687
|
+
const fromIndex = current.findIndex((d) => d.key === key);
|
|
1623
1688
|
if (fromIndex === -1) return layout;
|
|
1624
|
-
const
|
|
1689
|
+
const freeSlots = freeSlotIndexes(current);
|
|
1690
|
+
const fromFree = freeSlots.indexOf(fromIndex);
|
|
1691
|
+
if (fromFree === -1) return layout;
|
|
1692
|
+
const toFree = Math.max(
|
|
1625
1693
|
0,
|
|
1626
|
-
Math.min(
|
|
1694
|
+
Math.min(freeSlots.length - 1, fromFree + Math.trunc(offset))
|
|
1627
1695
|
);
|
|
1628
|
-
return moveWidget(definitions, layout, key,
|
|
1696
|
+
return moveWidget(definitions, layout, key, freeSlots[toFree]);
|
|
1629
1697
|
}
|
|
1630
1698
|
function isHidden(layout, key) {
|
|
1631
1699
|
return layout.hidden.includes(key);
|
|
@@ -1656,6 +1724,23 @@ function restoreWidget(layout, key) {
|
|
|
1656
1724
|
function toggleMinimized(layout, key) {
|
|
1657
1725
|
return isMinimized(layout, key) ? restoreWidget(layout, key) : minimizeWidget(layout, key);
|
|
1658
1726
|
}
|
|
1727
|
+
function enforceLocks(definitions, layout, options = {}) {
|
|
1728
|
+
if (options.overrideLocks === true) return layout;
|
|
1729
|
+
const noMove = /* @__PURE__ */ new Set();
|
|
1730
|
+
const noHide = /* @__PURE__ */ new Set();
|
|
1731
|
+
const noMinimize = /* @__PURE__ */ new Set();
|
|
1732
|
+
for (const definition of definitions) {
|
|
1733
|
+
const lock = resolveWidgetLock(definition);
|
|
1734
|
+
if (lock.move) noMove.add(definition.key);
|
|
1735
|
+
if (lock.hide) noHide.add(definition.key);
|
|
1736
|
+
if (lock.minimize) noMinimize.add(definition.key);
|
|
1737
|
+
}
|
|
1738
|
+
const without = (keys, drop) => keys.some((key) => drop.has(key)) ? keys.filter((key) => !drop.has(key)) : keys;
|
|
1739
|
+
const order = without(layout.order, noMove);
|
|
1740
|
+
const hidden = without(layout.hidden, noHide);
|
|
1741
|
+
const minimized = without(layout.minimized, noMinimize);
|
|
1742
|
+
return order === layout.order && hidden === layout.hidden && minimized === layout.minimized ? layout : { ...layout, order, hidden, minimized };
|
|
1743
|
+
}
|
|
1659
1744
|
function nextSort(current, column) {
|
|
1660
1745
|
if (current?.column !== column) return { column, direction: "asc" };
|
|
1661
1746
|
return current.direction === "asc" ? { column, direction: "desc" } : void 0;
|
|
@@ -2054,10 +2139,17 @@ function DetailHost({
|
|
|
2054
2139
|
}
|
|
2055
2140
|
) });
|
|
2056
2141
|
}
|
|
2142
|
+
function withoutLock(definition) {
|
|
2143
|
+
if (definition.locked === void 0) return definition;
|
|
2144
|
+
const copy = { ...definition };
|
|
2145
|
+
delete copy.locked;
|
|
2146
|
+
return copy;
|
|
2147
|
+
}
|
|
2057
2148
|
function DashboardInner({
|
|
2058
2149
|
widgets,
|
|
2059
|
-
layout = EMPTY_LAYOUT,
|
|
2150
|
+
layout: savedLayout = EMPTY_LAYOUT,
|
|
2060
2151
|
onLayoutChange,
|
|
2152
|
+
overrideLocks = false,
|
|
2061
2153
|
onRetry,
|
|
2062
2154
|
loadDetail,
|
|
2063
2155
|
onOpenDetail,
|
|
@@ -2066,7 +2158,10 @@ function DashboardInner({
|
|
|
2066
2158
|
}) {
|
|
2067
2159
|
const slot = useSlotClassName();
|
|
2068
2160
|
const { labels } = useWidgetSettings();
|
|
2069
|
-
const definitions = widgets.map(
|
|
2161
|
+
const definitions = widgets.map(
|
|
2162
|
+
(w) => overrideLocks ? withoutLock(w.definition) : w.definition
|
|
2163
|
+
);
|
|
2164
|
+
const layout = enforceLocks(definitions, savedLayout);
|
|
2070
2165
|
const byKey = new Map(
|
|
2071
2166
|
widgets.map((w) => [w.definition.key, w])
|
|
2072
2167
|
);
|
|
@@ -2139,32 +2234,45 @@ function DashboardInner({
|
|
|
2139
2234
|
if (widget === void 0) return null;
|
|
2140
2235
|
const key = definition.key;
|
|
2141
2236
|
const title = definition.title;
|
|
2237
|
+
const lock = resolveWidgetLock(definition);
|
|
2238
|
+
const canMoveEarlier = !lock.move && moveWidgetBy(definitions, layout, key, -1) !== layout;
|
|
2239
|
+
const canMoveLater = !lock.move && moveWidgetBy(definitions, layout, key, 1) !== layout;
|
|
2142
2240
|
const actions = editable ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2143
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2241
|
+
!lock.move && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2242
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2243
|
+
"button",
|
|
2244
|
+
{
|
|
2245
|
+
type: "button",
|
|
2246
|
+
className: slot(
|
|
2247
|
+
"button",
|
|
2248
|
+
"dwt-button",
|
|
2249
|
+
"dwt-icon-button"
|
|
2250
|
+
),
|
|
2251
|
+
"aria-label": labels.moveEarlier(title),
|
|
2252
|
+
title: labels.moveEarlier(title),
|
|
2253
|
+
disabled: index === 0 || !canMoveEarlier,
|
|
2254
|
+
onClick: () => change(moveWidgetBy(definitions, layout, key, -1)),
|
|
2255
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u2191" })
|
|
2256
|
+
}
|
|
2257
|
+
),
|
|
2258
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2259
|
+
"button",
|
|
2260
|
+
{
|
|
2261
|
+
type: "button",
|
|
2262
|
+
className: slot(
|
|
2263
|
+
"button",
|
|
2264
|
+
"dwt-button",
|
|
2265
|
+
"dwt-icon-button"
|
|
2266
|
+
),
|
|
2267
|
+
"aria-label": labels.moveLater(title),
|
|
2268
|
+
title: labels.moveLater(title),
|
|
2269
|
+
disabled: index === shown.length - 1 || !canMoveLater,
|
|
2270
|
+
onClick: () => change(moveWidgetBy(definitions, layout, key, 1)),
|
|
2271
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u2193" })
|
|
2272
|
+
}
|
|
2273
|
+
)
|
|
2274
|
+
] }),
|
|
2275
|
+
!lock.hide && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2168
2276
|
"button",
|
|
2169
2277
|
{
|
|
2170
2278
|
type: "button",
|
|
@@ -2188,7 +2296,7 @@ function DashboardInner({
|
|
|
2188
2296
|
...widthProps(twelve, definition),
|
|
2189
2297
|
minimized: isMinimized(layout, key),
|
|
2190
2298
|
...actions === void 0 ? {} : { actions },
|
|
2191
|
-
...editable ? {
|
|
2299
|
+
...editable && !lock.minimize ? {
|
|
2192
2300
|
onToggleMinimized: () => change(toggleMinimized(layout, key))
|
|
2193
2301
|
} : {},
|
|
2194
2302
|
...headingLevel === void 0 ? {} : { headingLevel },
|
|
@@ -2232,25 +2340,6 @@ function Dashboard({
|
|
|
2232
2340
|
);
|
|
2233
2341
|
}
|
|
2234
2342
|
|
|
2235
|
-
// src/core/definition.ts
|
|
2236
|
-
function sortDefinitions(definitions) {
|
|
2237
|
-
return definitions.map((definition, index) => ({ definition, index })).sort(
|
|
2238
|
-
(a, b) => (a.definition.sortOrder ?? 0) - (b.definition.sortOrder ?? 0) || a.index - b.index
|
|
2239
|
-
).map(({ definition }) => definition);
|
|
2240
|
-
}
|
|
2241
|
-
function isWidgetVisibleTo(definition, roles) {
|
|
2242
|
-
if (definition.active === false) {
|
|
2243
|
-
return false;
|
|
2244
|
-
}
|
|
2245
|
-
if (definition.roles === void 0 || definition.roles.length === 0) {
|
|
2246
|
-
return true;
|
|
2247
|
-
}
|
|
2248
|
-
if (roles === void 0) {
|
|
2249
|
-
return false;
|
|
2250
|
-
}
|
|
2251
|
-
return definition.roles.some((role) => roles.includes(role));
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
2343
|
// src/core/payload.ts
|
|
2255
2344
|
var WIDGET_KINDS = [
|
|
2256
2345
|
"TEXT",
|