@trops/dash-core 0.1.470 → 0.1.472

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/index.esm.js CHANGED
@@ -52874,11 +52874,12 @@ var EditField = function EditField(_ref7) {
52874
52874
 
52875
52875
  function ownKeys$h(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
52876
52876
  function _objectSpread$h(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$h(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$h(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
52877
+ var GLOBAL_KEY = "__global__";
52877
52878
  var NotificationsSection = function NotificationsSection(_ref) {
52878
52879
  var _ref$workspaces = _ref.workspaces,
52879
52880
  workspaces = _ref$workspaces === void 0 ? [] : _ref$workspaces;
52880
- var appContext = useContext(AppContext);
52881
- appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
52881
+ useContext(AppContext);
52882
+
52882
52883
  var _useState = useState(true),
52883
52884
  _useState2 = _slicedToArray(_useState, 2),
52884
52885
  globalEnabled = _useState2[0],
@@ -52895,6 +52896,22 @@ var NotificationsSection = function NotificationsSection(_ref) {
52895
52896
  _useState8 = _slicedToArray(_useState7, 2),
52896
52897
  loading = _useState8[0],
52897
52898
  setLoading = _useState8[1];
52899
+ var _useState9 = useState(""),
52900
+ _useState0 = _slicedToArray(_useState9, 2),
52901
+ searchQuery = _useState0[0],
52902
+ setSearchQuery = _useState0[1];
52903
+ var _useState1 = useState(GLOBAL_KEY),
52904
+ _useState10 = _slicedToArray(_useState1, 2),
52905
+ selectedKey = _useState10[0],
52906
+ setSelectedKey = _useState10[1];
52907
+ var _useState11 = useState("all"),
52908
+ _useState12 = _slicedToArray(_useState11, 2),
52909
+ filterDashboard = _useState12[0],
52910
+ setFilterDashboard = _useState12[1];
52911
+ var _useState13 = useState("all"),
52912
+ _useState14 = _slicedToArray(_useState13, 2),
52913
+ filterPackage = _useState14[0],
52914
+ setFilterPackage = _useState14[1];
52898
52915
 
52899
52916
  // Load preferences on mount
52900
52917
  useEffect(function () {
@@ -52911,38 +52928,79 @@ var NotificationsSection = function NotificationsSection(_ref) {
52911
52928
  });
52912
52929
  }, []);
52913
52930
 
52914
- // Collect all widget instances with notifications from workspaces.
52915
- // Route through `ComponentManager.resolve` so a legacy layout
52916
- // referencing a bare component name still finds its registered
52917
- // scoped form (post-v0.1.432). Direct `componentMap[item.component]`
52918
- // returns undefined for bare names after the migration.
52919
- var widgetInstances = [];
52920
- workspaces.forEach(function (ws) {
52921
- var items = flattenLayout(ws.layout);
52922
- items.forEach(function (item) {
52923
- var _config$notifications;
52924
- var config = ComponentManager.resolve(item.component, item);
52925
- if ((config === null || config === void 0 || (_config$notifications = config.notifications) === null || _config$notifications === void 0 ? void 0 : _config$notifications.length) > 0) {
52926
- var _item$userPrefs;
52927
- widgetInstances.push({
52928
- uuid: item.uuid || item.uuidString,
52929
- componentName: item.component,
52930
- title: ((_item$userPrefs = item.userPrefs) === null || _item$userPrefs === void 0 ? void 0 : _item$userPrefs.title) || config.displayName || item.component,
52931
- workspaceName: ws.name || ws.id,
52932
- notifications: config.notifications,
52933
- "package": config["package"]
52934
- });
52935
- }
52931
+ // Collect every widget instance with notifications, alphabetized
52932
+ // by display title. Route through `ComponentManager.resolve` so a
52933
+ // legacy layout referencing a bare component name still finds the
52934
+ // registered scoped form.
52935
+ var widgetInstances = useMemo(function () {
52936
+ var out = [];
52937
+ workspaces.forEach(function (ws) {
52938
+ var items = flattenLayout(ws.layout);
52939
+ items.forEach(function (item) {
52940
+ var _config$notifications;
52941
+ var config = ComponentManager.resolve(item.component, item);
52942
+ if ((config === null || config === void 0 || (_config$notifications = config.notifications) === null || _config$notifications === void 0 ? void 0 : _config$notifications.length) > 0) {
52943
+ var _item$userPrefs;
52944
+ out.push({
52945
+ uuid: item.uuid || item.uuidString,
52946
+ componentName: item.component,
52947
+ title: ((_item$userPrefs = item.userPrefs) === null || _item$userPrefs === void 0 ? void 0 : _item$userPrefs.title) || config.displayName || item.component,
52948
+ workspaceName: ws.name || ws.id,
52949
+ notifications: config.notifications,
52950
+ "package": config["package"] || "Other"
52951
+ });
52952
+ }
52953
+ });
52936
52954
  });
52937
- });
52955
+ return out.sort(function (a, b) {
52956
+ return String(a.title).localeCompare(String(b.title), undefined, {
52957
+ sensitivity: "base"
52958
+ });
52959
+ });
52960
+ }, [workspaces]);
52938
52961
 
52939
- // Group by package
52940
- var grouped = {};
52941
- widgetInstances.forEach(function (wi) {
52942
- var pkg = wi["package"] || "Other";
52943
- if (!grouped[pkg]) grouped[pkg] = [];
52944
- grouped[pkg].push(wi);
52945
- });
52962
+ // Derive dropdown option lists. Both sorted alphabetically so the
52963
+ // dropdowns don't shuffle as the underlying list changes order.
52964
+ var dashboardOptions = useMemo(function () {
52965
+ var set = new Set();
52966
+ widgetInstances.forEach(function (wi) {
52967
+ if (wi.workspaceName) set.add(wi.workspaceName);
52968
+ });
52969
+ return _toConsumableArray(set).sort(function (a, b) {
52970
+ return String(a).localeCompare(String(b), undefined, {
52971
+ sensitivity: "base"
52972
+ });
52973
+ });
52974
+ }, [widgetInstances]);
52975
+ var packageOptions = useMemo(function () {
52976
+ var set = new Set();
52977
+ widgetInstances.forEach(function (wi) {
52978
+ if (wi["package"]) set.add(wi["package"]);
52979
+ });
52980
+ return _toConsumableArray(set).sort(function (a, b) {
52981
+ return String(a).localeCompare(String(b), undefined, {
52982
+ sensitivity: "base"
52983
+ });
52984
+ });
52985
+ }, [widgetInstances]);
52986
+ var hasActiveFilters = searchQuery.trim() !== "" || filterDashboard !== "all" || filterPackage !== "all";
52987
+ var clearFilters = function clearFilters() {
52988
+ setSearchQuery("");
52989
+ setFilterDashboard("all");
52990
+ setFilterPackage("all");
52991
+ };
52992
+
52993
+ // Filter by search + dashboard + package (composed AND).
52994
+ var filteredInstances = useMemo(function () {
52995
+ var q = searchQuery.trim().toLowerCase();
52996
+ return widgetInstances.filter(function (wi) {
52997
+ if (filterDashboard !== "all" && wi.workspaceName !== filterDashboard) return false;
52998
+ if (filterPackage !== "all" && wi["package"] !== filterPackage) return false;
52999
+ if (!q) return true;
53000
+ var hay = [wi.title, wi["package"], wi.workspaceName, wi.componentName].filter(Boolean).join(" ").toLowerCase();
53001
+ return hay.includes(q);
53002
+ });
53003
+ }, [widgetInstances, searchQuery, filterDashboard, filterPackage]);
52946
53004
  function handleGlobalToggle(value) {
52947
53005
  var _window$mainApi2;
52948
53006
  setGlobalEnabled(value);
@@ -52976,16 +53034,126 @@ var NotificationsSection = function NotificationsSection(_ref) {
52976
53034
  children: "Loading notification preferences..."
52977
53035
  });
52978
53036
  }
52979
- return /*#__PURE__*/jsx("div", {
52980
- className: "flex-1 overflow-y-auto p-6",
52981
- children: /*#__PURE__*/jsxs("div", {
52982
- className: "flex flex-col space-y-6",
52983
- children: [/*#__PURE__*/jsxs("div", {
53037
+
53038
+ // ── Left list ──────────────────────────────────────────────────────
53039
+ var listContent = /*#__PURE__*/jsxs("div", {
53040
+ className: "flex flex-col h-full",
53041
+ children: [/*#__PURE__*/jsxs("div", {
53042
+ className: "flex flex-col gap-2 px-3 py-2 flex-shrink-0 border-b border-white/10",
53043
+ children: [/*#__PURE__*/jsx(SearchInput, {
53044
+ value: searchQuery,
53045
+ onChange: setSearchQuery,
53046
+ placeholder: "Search widgets...",
53047
+ inputClassName: "py-1.5 text-xs"
53048
+ }), /*#__PURE__*/jsxs("div", {
53049
+ className: "grid grid-cols-2 gap-1.5",
53050
+ children: [/*#__PURE__*/jsxs("select", {
53051
+ value: filterDashboard,
53052
+ onChange: function onChange(e) {
53053
+ return setFilterDashboard(e.target.value);
53054
+ },
53055
+ className: "w-full px-2 py-1 text-xs bg-gray-800/50 border border-white/10 rounded text-gray-200 focus:outline-none",
53056
+ children: [/*#__PURE__*/jsx("option", {
53057
+ value: "all",
53058
+ children: "All Dashboards"
53059
+ }), dashboardOptions.map(function (d) {
53060
+ return /*#__PURE__*/jsx("option", {
53061
+ value: d,
53062
+ children: d
53063
+ }, d);
53064
+ })]
53065
+ }), /*#__PURE__*/jsxs("select", {
53066
+ value: filterPackage,
53067
+ onChange: function onChange(e) {
53068
+ return setFilterPackage(e.target.value);
53069
+ },
53070
+ className: "w-full px-2 py-1 text-xs bg-gray-800/50 border border-white/10 rounded text-gray-200 focus:outline-none",
53071
+ children: [/*#__PURE__*/jsx("option", {
53072
+ value: "all",
53073
+ children: "All Packages"
53074
+ }), packageOptions.map(function (p) {
53075
+ return /*#__PURE__*/jsx("option", {
53076
+ value: p,
53077
+ children: p
53078
+ }, p);
53079
+ })]
53080
+ })]
53081
+ }), /*#__PURE__*/jsxs("div", {
53082
+ className: "flex items-center justify-between text-[10px] px-0.5",
53083
+ children: [/*#__PURE__*/jsx("span", {
53084
+ className: "opacity-50",
53085
+ children: hasActiveFilters ? "".concat(filteredInstances.length, " of ").concat(widgetInstances.length, " widgets") : "".concat(widgetInstances.length, " widget").concat(widgetInstances.length === 1 ? "" : "s")
53086
+ }), hasActiveFilters && /*#__PURE__*/jsx("button", {
53087
+ type: "button",
53088
+ onClick: clearFilters,
53089
+ className: "opacity-60 hover:opacity-100 transition-opacity text-gray-300 hover:bg-white/10 px-1.5 py-0.5 rounded",
53090
+ children: "Clear"
53091
+ })]
53092
+ })]
53093
+ }), /*#__PURE__*/jsxs(Sidebar.Content, {
53094
+ children: [/*#__PURE__*/jsx(Sidebar.Item, {
53095
+ icon: /*#__PURE__*/jsx(FontAwesomeIcon, {
53096
+ icon: globalEnabled ? "bell" : "bell-slash",
53097
+ className: "h-3.5 w-3.5"
53098
+ }),
53099
+ active: selectedKey === GLOBAL_KEY,
53100
+ onClick: function onClick() {
53101
+ return setSelectedKey(GLOBAL_KEY);
53102
+ },
53103
+ children: /*#__PURE__*/jsxs("span", {
53104
+ className: "flex flex-col",
53105
+ children: [/*#__PURE__*/jsx("span", {
53106
+ className: "font-medium",
53107
+ children: "Global"
53108
+ }), /*#__PURE__*/jsx("span", {
53109
+ className: "text-[10px] opacity-40",
53110
+ children: "Master switch + Do Not Disturb"
53111
+ })]
53112
+ })
53113
+ }), filteredInstances.length === 0 && widgetInstances.length === 0 && /*#__PURE__*/jsx("div", {
53114
+ className: "px-3 py-2 text-xs opacity-50",
53115
+ children: "No widgets with notification support found. Add widgets that declare notifications to see per-type controls here."
53116
+ }), filteredInstances.length === 0 && widgetInstances.length > 0 && /*#__PURE__*/jsxs("div", {
53117
+ className: "px-3 py-2 text-xs opacity-50",
53118
+ children: ["No widgets match \"", searchQuery, "\"."]
53119
+ }), filteredInstances.map(function (wi) {
53120
+ var isActive = selectedKey === wi.uuid;
53121
+ return /*#__PURE__*/jsx(Sidebar.Item, {
53122
+ icon: /*#__PURE__*/jsx(FontAwesomeIcon, {
53123
+ icon: "bell",
53124
+ className: "h-3.5 w-3.5"
53125
+ }),
53126
+ active: isActive,
53127
+ onClick: function onClick() {
53128
+ return setSelectedKey(wi.uuid);
53129
+ },
53130
+ className: isActive ? "bg-white/10 opacity-100" : "",
53131
+ children: /*#__PURE__*/jsxs("span", {
53132
+ className: "flex flex-col",
53133
+ children: [/*#__PURE__*/jsx("span", {
53134
+ className: "font-medium truncate",
53135
+ children: wi.title
53136
+ }), /*#__PURE__*/jsxs("span", {
53137
+ className: "text-[10px] opacity-40 truncate",
53138
+ children: [wi["package"], wi.workspaceName ? " \xB7 ".concat(wi.workspaceName) : ""]
53139
+ })]
53140
+ })
53141
+ }, wi.uuid);
53142
+ })]
53143
+ })]
53144
+ });
53145
+
53146
+ // ── Right detail ───────────────────────────────────────────────────
53147
+ var detailContent;
53148
+ if (selectedKey === GLOBAL_KEY) {
53149
+ detailContent = /*#__PURE__*/jsxs("div", {
53150
+ className: "flex flex-col p-6 space-y-6",
53151
+ children: [/*#__PURE__*/jsx(SubHeading3, {
53152
+ title: "Global",
53153
+ padding: false
53154
+ }), /*#__PURE__*/jsxs("div", {
52984
53155
  className: "flex flex-col space-y-3",
52985
- children: [/*#__PURE__*/jsx(SubHeading3, {
52986
- title: "Global",
52987
- padding: false
52988
- }), /*#__PURE__*/jsxs("div", {
53156
+ children: [/*#__PURE__*/jsxs("div", {
52989
53157
  className: "flex flex-row items-center justify-between py-2",
52990
53158
  children: [/*#__PURE__*/jsxs("div", {
52991
53159
  className: "flex flex-col",
@@ -53016,49 +53184,59 @@ var NotificationsSection = function NotificationsSection(_ref) {
53016
53184
  onChange: handleDndToggle
53017
53185
  })]
53018
53186
  })]
53019
- }), Object.keys(grouped).length > 0 ? Object.entries(grouped).map(function (_ref2) {
53020
- var _ref3 = _slicedToArray(_ref2, 2),
53021
- pkg = _ref3[0],
53022
- widgets = _ref3[1];
53023
- return /*#__PURE__*/jsxs("div", {
53024
- className: "flex flex-col space-y-3",
53187
+ })]
53188
+ });
53189
+ } else {
53190
+ var wi = widgetInstances.find(function (w) {
53191
+ return w.uuid === selectedKey;
53192
+ });
53193
+ if (!wi) {
53194
+ detailContent = /*#__PURE__*/jsx("div", {
53195
+ className: "flex-1 p-6 text-sm opacity-50",
53196
+ children: "Select a widget on the left to configure its notifications."
53197
+ });
53198
+ } else {
53199
+ detailContent = /*#__PURE__*/jsxs("div", {
53200
+ className: "flex flex-col p-6 space-y-4",
53201
+ children: [/*#__PURE__*/jsxs("div", {
53202
+ className: "flex flex-col space-y-1",
53025
53203
  children: [/*#__PURE__*/jsx(SubHeading3, {
53026
- title: pkg,
53204
+ title: wi.title,
53027
53205
  padding: false
53028
- }), widgets.map(function (wi) {
53206
+ }), /*#__PURE__*/jsxs("span", {
53207
+ className: "text-xs opacity-50",
53208
+ children: [wi["package"], wi.workspaceName ? " \xB7 ".concat(wi.workspaceName) : ""]
53209
+ })]
53210
+ }), /*#__PURE__*/jsx("div", {
53211
+ className: "flex flex-col space-y-3",
53212
+ children: wi.notifications.map(function (notif) {
53029
53213
  return /*#__PURE__*/jsxs("div", {
53030
- className: "flex flex-col space-y-2 pl-2 border-l-2 border-white/10",
53031
- children: [/*#__PURE__*/jsx("span", {
53032
- className: "text-sm font-medium opacity-80",
53033
- children: wi.title
53034
- }), wi.notifications.map(function (notif) {
53035
- return /*#__PURE__*/jsxs("div", {
53036
- className: "flex flex-row items-center justify-between py-1 pl-2",
53037
- children: [/*#__PURE__*/jsxs("div", {
53038
- className: "flex flex-col",
53039
- children: [/*#__PURE__*/jsx("span", {
53040
- className: "text-sm",
53041
- children: notif.displayName
53042
- }), notif.description && /*#__PURE__*/jsx("span", {
53043
- className: "text-xs opacity-50",
53044
- children: notif.description
53045
- })]
53046
- }), /*#__PURE__*/jsx(Switch, {
53047
- checked: getTypeEnabled(wi.uuid, notif.key, notif.defaultEnabled),
53048
- onChange: function onChange(value) {
53049
- return handleTypeToggle(wi.uuid, notif.key, value);
53050
- }
53051
- })]
53052
- }, notif.key);
53214
+ className: "flex flex-row items-center justify-between py-1",
53215
+ children: [/*#__PURE__*/jsxs("div", {
53216
+ className: "flex flex-col",
53217
+ children: [/*#__PURE__*/jsx("span", {
53218
+ className: "text-sm",
53219
+ children: notif.displayName
53220
+ }), notif.description && /*#__PURE__*/jsx("span", {
53221
+ className: "text-xs opacity-50",
53222
+ children: notif.description
53223
+ })]
53224
+ }), /*#__PURE__*/jsx(Switch, {
53225
+ checked: getTypeEnabled(wi.uuid, notif.key, notif.defaultEnabled),
53226
+ onChange: function onChange(value) {
53227
+ return handleTypeToggle(wi.uuid, notif.key, value);
53228
+ }
53053
53229
  })]
53054
- }, wi.uuid);
53055
- })]
53056
- }, pkg);
53057
- }) : /*#__PURE__*/jsx("div", {
53058
- className: "text-sm opacity-50",
53059
- children: "No widgets with notification support found. Add widgets that declare notifications to see per-type controls here."
53060
- })]
53061
- })
53230
+ }, notif.key);
53231
+ })
53232
+ })]
53233
+ });
53234
+ }
53235
+ }
53236
+ return /*#__PURE__*/jsx(SectionLayout, {
53237
+ listContent: listContent,
53238
+ detailContent: detailContent,
53239
+ emptyDetailMessage: "Select a widget to configure notifications"
53062
53240
  });
53063
53241
  };
53064
53242