@trops/dash-core 0.1.662 → 0.1.664

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.js CHANGED
@@ -47222,6 +47222,14 @@ function _arrayLikeToArray$n(r, a) { (null == a || a > r.length) && (a = r.lengt
47222
47222
  * Pure: no React, no IPC.
47223
47223
  */
47224
47224
 
47225
+ /** Status dot colours shared by the Bots view and Dashboard Config › Bots. */
47226
+ var STATUS_DOT$2 = {
47227
+ Idle: "bg-gray-500",
47228
+ Running: "bg-indigo-400",
47229
+ Paused: "bg-gray-400",
47230
+ "Needs approval": "bg-amber-400",
47231
+ Failed: "bg-red-400"
47232
+ };
47225
47233
  var norm = function norm(id) {
47226
47234
  return id === undefined || id === null || id === "" ? null : String(id);
47227
47235
  };
@@ -55544,6 +55552,68 @@ var PrivacySecurityList = function PrivacySecurityList(_ref) {
55544
55552
  });
55545
55553
  };
55546
55554
 
55555
+ function useConfigTokens() {
55556
+ var _ref = React.useContext(DashReact.ThemeContext) || {},
55557
+ _ref$currentTheme = _ref.currentTheme,
55558
+ currentTheme = _ref$currentTheme === void 0 ? {} : _ref$currentTheme;
55559
+ return {
55560
+ muted: currentTheme["text-neutral-medium"] || "text-gray-400",
55561
+ strong: currentTheme["text-neutral-light"] || "text-gray-200",
55562
+ hairline: currentTheme["border-neutral-dark"] || "border-gray-700",
55563
+ selectedBg: currentTheme["bg-neutral-very-dark"] || "bg-gray-800",
55564
+ selectedBorder: currentTheme["border-primary-dark"] || "border-gray-600",
55565
+ fieldBg: currentTheme["bg-neutral-very-dark"] || "bg-gray-900"
55566
+ };
55567
+ }
55568
+
55569
+ /**
55570
+ * A row in one of the modal's left-hand lists (provider types, widgets,
55571
+ * event handlers) — styled like the Bots view's team list.
55572
+ *
55573
+ * @param {{ title: React.ReactNode, subtitle?: React.ReactNode,
55574
+ * meta?: React.ReactNode, badge?: React.ReactNode,
55575
+ * active?: boolean, mono?: boolean, onClick: () => void }} props
55576
+ * `subtitle` is a registry id (monospace); `meta` a muted count line.
55577
+ */
55578
+ var ConfigListRow = function ConfigListRow(_ref2) {
55579
+ var title = _ref2.title,
55580
+ _ref2$subtitle = _ref2.subtitle,
55581
+ subtitle = _ref2$subtitle === void 0 ? null : _ref2$subtitle,
55582
+ _ref2$meta = _ref2.meta,
55583
+ meta = _ref2$meta === void 0 ? null : _ref2$meta,
55584
+ _ref2$badge = _ref2.badge,
55585
+ badge = _ref2$badge === void 0 ? null : _ref2$badge,
55586
+ _ref2$active = _ref2.active,
55587
+ active = _ref2$active === void 0 ? false : _ref2$active,
55588
+ _ref2$mono = _ref2.mono,
55589
+ mono = _ref2$mono === void 0 ? false : _ref2$mono,
55590
+ onClick = _ref2.onClick;
55591
+ var _useConfigTokens = useConfigTokens(),
55592
+ muted = _useConfigTokens.muted,
55593
+ selectedBg = _useConfigTokens.selectedBg,
55594
+ selectedBorder = _useConfigTokens.selectedBorder;
55595
+ return /*#__PURE__*/jsxRuntime.jsxs("button", {
55596
+ type: "button",
55597
+ onClick: onClick,
55598
+ "aria-current": active ? "true" : undefined,
55599
+ className: "w-full text-left rounded-lg px-3 py-2 border ".concat(active ? "".concat(selectedBg, " ").concat(selectedBorder) : "border-transparent"),
55600
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
55601
+ className: "flex flex-row items-center justify-between gap-2 min-w-0",
55602
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
55603
+ className: "text-sm font-medium truncate ".concat(mono ? "font-mono" : ""),
55604
+ children: title
55605
+ }), badge]
55606
+ }), subtitle ? /*#__PURE__*/jsxRuntime.jsx("div", {
55607
+ className: "text-xs font-mono truncate mt-0.5 ".concat(muted),
55608
+ title: typeof subtitle === "string" ? subtitle : undefined,
55609
+ children: subtitle
55610
+ }) : null, meta ? /*#__PURE__*/jsxRuntime.jsx("div", {
55611
+ className: "text-xs mt-0.5 ".concat(muted),
55612
+ children: meta
55613
+ }) : null]
55614
+ });
55615
+ };
55616
+
55547
55617
  /**
55548
55618
  * grantStaleness
55549
55619
  *
@@ -55714,6 +55784,8 @@ var ToolToggleList = function ToolToggleList(_ref2) {
55714
55784
  serverName = _ref2.serverName,
55715
55785
  onToggleTool = _ref2.onToggleTool,
55716
55786
  hasAnyGrantOnServer = _ref2.hasAnyGrantOnServer;
55787
+ var _useConfigTokens = useConfigTokens(),
55788
+ muted = _useConfigTokens.muted;
55717
55789
  if (declaredTools.length === 0 && grantedTools.length === 0) return null;
55718
55790
  var grantedSet = new Set(grantedTools);
55719
55791
  var staleSet = computeStaleItems(declaredTools, grantedTools, true);
@@ -55721,7 +55793,7 @@ var ToolToggleList = function ToolToggleList(_ref2) {
55721
55793
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
55722
55794
  className: "flex flex-col space-y-1",
55723
55795
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
55724
- className: "text-xs opacity-50",
55796
+ className: "text-xs ".concat(muted),
55725
55797
  children: "Tools"
55726
55798
  }), all.map(function (tool) {
55727
55799
  var isGranted = grantedSet.has(tool);
@@ -55732,7 +55804,7 @@ var ToolToggleList = function ToolToggleList(_ref2) {
55732
55804
  // always allowed when the tool IS granted.
55733
55805
  var disabled = !isGranted && !hasAnyGrantOnServer;
55734
55806
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
55735
- className: "flex flex-row items-center justify-between gap-2 py-1 px-2 -mx-2 rounded hover:bg-gray-800 transition-colors",
55807
+ className: "flex flex-row items-center justify-between gap-2 py-1 px-2 -mx-2 rounded-lg",
55736
55808
  children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
55737
55809
  className: "text-xs font-mono break-all ".concat(isStale ? "text-amber-400" : isGranted ? "opacity-100" : "opacity-50"),
55738
55810
  children: [tool, isStale && /*#__PURE__*/jsxRuntime.jsx("span", {
@@ -55756,6 +55828,8 @@ var PermsList = function PermsList(_ref3) {
55756
55828
  grantedItems = _ref3.grantedItems,
55757
55829
  validatesStale = _ref3.validatesStale,
55758
55830
  onDeleteItem = _ref3.onDeleteItem;
55831
+ var _useConfigTokens2 = useConfigTokens(),
55832
+ muted = _useConfigTokens2.muted;
55759
55833
  if (declaredItems.length === 0 && grantedItems.length === 0) return null;
55760
55834
  var grantedSet = new Set(grantedItems);
55761
55835
  var staleSet = computeStaleItems(declaredItems, grantedItems, validatesStale);
@@ -55763,14 +55837,14 @@ var PermsList = function PermsList(_ref3) {
55763
55837
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
55764
55838
  className: "flex flex-col space-y-1",
55765
55839
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
55766
- className: "text-xs opacity-50",
55840
+ className: "text-xs ".concat(muted),
55767
55841
  children: label
55768
55842
  }), all.map(function (item) {
55769
55843
  var isGranted = grantedSet.has(item);
55770
55844
  var isStale = staleSet.has(item);
55771
55845
  var showTrash = isGranted && typeof onDeleteItem === "function";
55772
55846
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
55773
- className: "flex flex-row items-start justify-between gap-2 py-1 px-2 -mx-2 rounded hover:bg-gray-800 transition-colors",
55847
+ className: "flex flex-row items-start justify-between gap-2 py-1 px-2 -mx-2 rounded-lg",
55774
55848
  children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
55775
55849
  className: "text-xs font-mono break-all ".concat(isStale ? "text-amber-400" : isGranted ? "opacity-100" : "opacity-50 line-through"),
55776
55850
  children: [item, isStale && /*#__PURE__*/jsxRuntime.jsx("span", {
@@ -55806,23 +55880,26 @@ var RevokeConfirmInline = function RevokeConfirmInline(_ref4) {
55806
55880
  body = _ref4.body,
55807
55881
  onCancel = _ref4.onCancel,
55808
55882
  onConfirm = _ref4.onConfirm;
55883
+ var _useConfigTokens3 = useConfigTokens(),
55884
+ muted = _useConfigTokens3.muted,
55885
+ strong = _useConfigTokens3.strong;
55809
55886
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
55810
- className: "flex flex-col gap-2 border border-amber-500 rounded p-2 mt-1",
55887
+ className: "flex flex-col gap-2 border border-amber-500 rounded-lg p-2 mt-1",
55811
55888
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
55812
55889
  className: "flex flex-row items-center gap-2",
55813
55890
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
55814
55891
  icon: "triangle-exclamation",
55815
55892
  className: "h-3 w-3 text-amber-500"
55816
55893
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
55817
- className: "text-xs font-semibold text-gray-100",
55894
+ className: "text-xs font-semibold ".concat(strong),
55818
55895
  children: title
55819
55896
  })]
55820
55897
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
55821
- className: "text-xs text-gray-300 leading-relaxed",
55898
+ className: "text-xs leading-relaxed ".concat(muted),
55822
55899
  children: body
55823
55900
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
55824
55901
  className: "flex justify-end gap-2",
55825
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
55902
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
55826
55903
  title: "Cancel",
55827
55904
  onClick: onCancel,
55828
55905
  size: "sm"
@@ -55857,8 +55934,12 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
55857
55934
  pendingRevoke = _useState2[0],
55858
55935
  setPendingRevoke = _useState2[1];
55859
55936
  var widgetSummary = describeWidgetGrant(grantedServers);
55937
+ var _useConfigTokens4 = useConfigTokens(),
55938
+ muted = _useConfigTokens4.muted,
55939
+ hairline = _useConfigTokens4.hairline;
55860
55940
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
55861
- className: "flex flex-col space-y-3 border border-gray-700 rounded p-3",
55941
+ "data-testid": "widget-grant-row",
55942
+ className: "flex flex-col space-y-3 rounded-lg border px-3 py-2 ".concat(hairline),
55862
55943
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
55863
55944
  className: "flex flex-row items-center justify-between gap-2",
55864
55945
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -55874,11 +55955,11 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
55874
55955
  })]
55875
55956
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
55876
55957
  className: "flex flex-row gap-2",
55877
- children: [!hasManifest && !granted && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
55958
+ children: [!hasManifest && !granted && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
55878
55959
  title: "Grant manually",
55879
55960
  onClick: onGrantManually,
55880
55961
  size: "sm"
55881
- }), Object.keys(grantedServers).length > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
55962
+ }), Object.keys(grantedServers).length > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
55882
55963
  title: "Revoke all",
55883
55964
  onClick: function onClick() {
55884
55965
  return setPendingRevoke("widget");
@@ -55897,18 +55978,19 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
55897
55978
  onRevokeWidget && onRevokeWidget();
55898
55979
  }
55899
55980
  }), !declared && !granted && /*#__PURE__*/jsxRuntime.jsx("span", {
55900
- className: "text-xs opacity-50",
55981
+ className: "text-xs ".concat(muted),
55901
55982
  children: "This widget did not declare MCP permissions and the install-time scanner found nothing. Use Grant manually if you trust it."
55902
55983
  }), allServerNames.map(function (serverName) {
55903
55984
  var decl = declaredServers[serverName] || {};
55904
55985
  var grant = grantedServers[serverName];
55905
55986
  var allStale = isServerEntirelyStale(decl, grant);
55906
55987
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
55907
- className: "flex flex-col space-y-2 border-t border-gray-800 pt-2",
55988
+ "data-testid": "grant-server-".concat(serverName),
55989
+ className: "flex flex-col space-y-2 border-t pt-2 ".concat(hairline),
55908
55990
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
55909
55991
  className: "flex flex-row items-center justify-between gap-2",
55910
55992
  children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
55911
- className: "text-xs uppercase tracking-wider opacity-70",
55993
+ className: "text-xs uppercase tracking-wider ".concat(muted),
55912
55994
  children: [serverName, (grant === null || grant === void 0 ? void 0 : grant._labels) && grant._labels.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("span", {
55913
55995
  className: "ml-2 normal-case tracking-normal opacity-60",
55914
55996
  children: ["(", grant._labels.join(", "), ")"]
@@ -55921,7 +56003,7 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
55921
56003
  children: [(decl.tools || []).length > 0 && onToggleAllForServer && /*#__PURE__*/jsxRuntime.jsxs("div", {
55922
56004
  className: "flex flex-row items-center gap-2",
55923
56005
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
55924
- className: "text-xs opacity-60 normal-case tracking-normal",
56006
+ className: "text-xs normal-case tracking-normal ".concat(muted),
55925
56007
  children: "Allow all"
55926
56008
  }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Switch, {
55927
56009
  checked: (decl.tools || []).length > 0 && (decl.tools || []).every(function (t) {
@@ -55931,7 +56013,7 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
55931
56013
  return onToggleAllForServer(widgetId, serverName, next);
55932
56014
  }
55933
56015
  })]
55934
- }), grant && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
56016
+ }), grant && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
55935
56017
  title: "Revoke server",
55936
56018
  onClick: function onClick() {
55937
56019
  return setPendingRevoke({
@@ -55953,7 +56035,7 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
55953
56035
  onRevokeServer && onRevokeServer(serverName);
55954
56036
  }
55955
56037
  }), allStale && /*#__PURE__*/jsxRuntime.jsx("div", {
55956
- className: "text-xs text-amber-400 bg-amber-900 bg-opacity-20 border border-amber-700 rounded px-2 py-1.5",
56038
+ className: "text-xs text-amber-400 border border-amber-400 rounded-lg px-2 py-1.5",
55957
56039
  children: "All grants on this server are no longer in the manifest \u2014 the widget likely no longer uses this server. Consider revoking."
55958
56040
  }), /*#__PURE__*/jsxRuntime.jsx(ToolToggleList, {
55959
56041
  declaredTools: decl.tools || [],
@@ -55982,9 +56064,9 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
55982
56064
  })]
55983
56065
  }, serverName);
55984
56066
  }), (granted === null || granted === void 0 || (_granted$domains = granted.domains) === null || _granted$domains === void 0 ? void 0 : _granted$domains.fs) && ((granted.domains.fs.readPaths || []).length > 0 || (granted.domains.fs.writePaths || []).length > 0) && /*#__PURE__*/jsxRuntime.jsxs("div", {
55985
- className: "flex flex-col space-y-2 border-t border-gray-800 pt-2",
56067
+ className: "flex flex-col space-y-2 border-t pt-2 ".concat(hairline),
55986
56068
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
55987
- className: "text-xs uppercase tracking-wider opacity-70",
56069
+ className: "text-xs uppercase tracking-wider ".concat(muted),
55988
56070
  children: "filesystem"
55989
56071
  }), Array.isArray(granted.domains.fs.actions) && granted.domains.fs.actions.length > 0 && /*#__PURE__*/jsxRuntime.jsx(PermsList, {
55990
56072
  label: "Actions",
@@ -56012,9 +56094,9 @@ var WidgetGrantRow = function WidgetGrantRow(_ref5) {
56012
56094
  } : undefined
56013
56095
  })]
56014
56096
  }), (granted === null || granted === void 0 || (_granted$domains2 = granted.domains) === null || _granted$domains2 === void 0 ? void 0 : _granted$domains2.network) && (granted.domains.network.hosts || []).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
56015
- className: "flex flex-col space-y-2 border-t border-gray-800 pt-2",
56097
+ className: "flex flex-col space-y-2 border-t pt-2 ".concat(hairline),
56016
56098
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
56017
- className: "text-xs uppercase tracking-wider opacity-70",
56099
+ className: "text-xs uppercase tracking-wider ".concat(muted),
56018
56100
  children: "network"
56019
56101
  }), Array.isArray(granted.domains.network.actions) && granted.domains.network.actions.length > 0 && /*#__PURE__*/jsxRuntime.jsx(PermsList, {
56020
56102
  label: "Actions",
@@ -61241,6 +61323,9 @@ var WidgetsTab = function WidgetsTab(_ref) {
61241
61323
  stagedPrefs = _ref.stagedPrefs,
61242
61324
  stagePrefField = _ref.stagePrefField,
61243
61325
  stagePrefFieldForAll = _ref.stagePrefFieldForAll;
61326
+ var _useConfigTokens = useConfigTokens(),
61327
+ muted = _useConfigTokens.muted,
61328
+ hairline = _useConfigTokens.hairline;
61244
61329
  // Flatten every widget on the workspace, preserving which layout
61245
61330
  // section each came from (Main / Page N / Sidebar) so the left
61246
61331
  // column can group them cleanly. forEachWidget already dedupes.
@@ -61361,67 +61446,55 @@ var WidgetsTab = function WidgetsTab(_ref) {
61361
61446
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
61362
61447
  className: "flex h-full min-h-0",
61363
61448
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
61364
- className: "w-64 border-r border-white/10 overflow-y-auto flex-shrink-0",
61365
- children: [sharedFields.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("button", {
61366
- onClick: function onClick() {
61367
- return setSelectedId(ALL_WIDGETS_ID);
61368
- },
61369
- className: "w-full text-left px-4 py-3 border-b border-white/10 transition-colors ".concat(isAllMode ? "bg-indigo-600/20 text-indigo-200" : "hover:bg-white/5 text-gray-300"),
61370
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
61371
- className: "flex items-center gap-2",
61449
+ className: "w-64 border-r overflow-y-auto flex-shrink-0 p-3 flex flex-col gap-1 ".concat(hairline),
61450
+ children: [sharedFields.length > 0 && /*#__PURE__*/jsxRuntime.jsx(ConfigListRow, {
61451
+ title: /*#__PURE__*/jsxRuntime.jsxs("span", {
61452
+ className: "flex flex-row items-center gap-2",
61372
61453
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
61373
61454
  icon: "layer-group",
61374
61455
  className: "h-3.5 w-3.5"
61375
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
61376
- className: "font-semibold text-sm",
61377
- children: "All Widgets"
61378
- })]
61379
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
61380
- className: "text-[11px] text-gray-500 mt-0.5",
61381
- children: [sharedFields.length, " shared field", sharedFields.length === 1 ? "" : "s", " \xB7 bulk edit"]
61382
- })]
61456
+ }), "All Widgets"]
61457
+ }),
61458
+ meta: "".concat(sharedFields.length, " shared field").concat(sharedFields.length === 1 ? "" : "s", " \xB7 bulk edit"),
61459
+ active: isAllMode,
61460
+ onClick: function onClick() {
61461
+ return setSelectedId(ALL_WIDGETS_ID);
61462
+ }
61383
61463
  }), groupedWidgets.map(function (_ref2) {
61384
61464
  var _ref3 = _slicedToArray(_ref2, 2),
61385
61465
  section = _ref3[0],
61386
61466
  sectionWidgets = _ref3[1];
61387
61467
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
61388
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
61389
- className: "px-4 pt-3 pb-1 text-[10px] uppercase tracking-wider text-gray-600 font-semibold",
61468
+ className: "flex flex-col gap-1",
61469
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SectionLabel, {
61470
+ className: "px-3 pt-3 pb-1",
61390
61471
  children: section
61391
61472
  }), sectionWidgets.map(function (w) {
61392
61473
  var fieldCount = Object.keys(w.userConfig).length;
61393
61474
  var stagedForWidget = stagedPrefs !== null && stagedPrefs !== void 0 && stagedPrefs[w.id] ? Object.keys(stagedPrefs[w.id]).length : 0;
61394
- var isSel = selectedId === w.id;
61395
- return /*#__PURE__*/jsxRuntime.jsxs("button", {
61475
+ return /*#__PURE__*/jsxRuntime.jsx(ConfigListRow, {
61476
+ title: w.displayName,
61477
+ subtitle: w.widgetRef || null,
61478
+ meta: fieldCount === 0 ? "No configurable fields" : "".concat(fieldCount, " field").concat(fieldCount === 1 ? "" : "s"),
61479
+ badge: stagedForWidget > 0 ? /*#__PURE__*/jsxRuntime.jsxs("span", {
61480
+ className: "flex flex-row items-center gap-1.5 text-xs text-amber-400 flex-shrink-0",
61481
+ title: "Unsaved changes",
61482
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
61483
+ className: "inline-block h-1.5 w-1.5 rounded-full bg-amber-400"
61484
+ }), stagedForWidget]
61485
+ }) : null,
61486
+ active: selectedId === w.id,
61396
61487
  onClick: function onClick() {
61397
61488
  return setSelectedId(w.id);
61398
- },
61399
- className: "w-full text-left px-4 py-2 transition-colors ".concat(isSel ? "bg-indigo-600/20 text-indigo-200" : "hover:bg-white/5 text-gray-300"),
61400
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
61401
- className: "flex items-center justify-between",
61402
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
61403
- className: "text-sm truncate",
61404
- children: w.displayName
61405
- }), stagedForWidget > 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
61406
- className: "text-[10px] bg-amber-500/20 text-amber-300 px-1.5 rounded",
61407
- children: stagedForWidget
61408
- })]
61409
- }), w.widgetRef && /*#__PURE__*/jsxRuntime.jsx("div", {
61410
- className: "text-[10px] text-gray-500 font-mono truncate mt-0.5",
61411
- title: w.widgetRef,
61412
- children: w.widgetRef
61413
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
61414
- className: "text-[10px] text-gray-600 mt-0.5",
61415
- children: fieldCount === 0 ? "No configurable fields" : "".concat(fieldCount, " field").concat(fieldCount === 1 ? "" : "s")
61416
- })]
61489
+ }
61417
61490
  }, w.id);
61418
61491
  })]
61419
61492
  }, section);
61420
61493
  })]
61421
61494
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
61422
- className: "flex-1 overflow-y-auto p-4 min-w-0",
61495
+ className: "flex-1 overflow-y-auto p-5 min-w-0",
61423
61496
  children: [!selectedId && /*#__PURE__*/jsxRuntime.jsx("div", {
61424
- className: "text-sm text-gray-500 italic",
61497
+ className: "text-sm italic ".concat(muted),
61425
61498
  children: "Select a widget from the list."
61426
61499
  }), isAllMode && /*#__PURE__*/jsxRuntime.jsx(BulkEditPane, {
61427
61500
  sharedFields: sharedFields,
@@ -61441,19 +61514,22 @@ function SingleWidgetPane(_ref4) {
61441
61514
  var widget = _ref4.widget,
61442
61515
  effectivePrefs = _ref4.effectivePrefs,
61443
61516
  onFieldChange = _ref4.onFieldChange;
61517
+ var _useConfigTokens2 = useConfigTokens(),
61518
+ muted = _useConfigTokens2.muted,
61519
+ strong = _useConfigTokens2.strong;
61444
61520
  var hasFields = Object.keys(widget.userConfig).length > 0;
61445
61521
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
61446
61522
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
61447
61523
  className: "mb-3",
61448
61524
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
61449
- className: "text-gray-200 font-semibold",
61525
+ className: "font-semibold ".concat(strong),
61450
61526
  children: widget.displayName
61451
61527
  }), widget.widgetRef && /*#__PURE__*/jsxRuntime.jsx("div", {
61452
- className: "text-xs text-gray-500 font-mono truncate mt-0.5",
61528
+ className: "text-xs font-mono truncate mt-0.5 ".concat(muted),
61453
61529
  title: widget.widgetRef,
61454
61530
  children: widget.widgetRef
61455
61531
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
61456
- className: "text-xs text-gray-600 mt-0.5",
61532
+ className: "text-xs mt-0.5 ".concat(muted),
61457
61533
  children: widget.section
61458
61534
  })]
61459
61535
  }), hasFields ? /*#__PURE__*/jsxRuntime.jsx(PanelEditForm, {
@@ -61461,7 +61537,7 @@ function SingleWidgetPane(_ref4) {
61461
61537
  userPrefs: effectivePrefs,
61462
61538
  onFieldChange: onFieldChange
61463
61539
  }) : /*#__PURE__*/jsxRuntime.jsx("div", {
61464
- className: "text-sm text-gray-500 italic",
61540
+ className: "text-sm italic ".concat(muted),
61465
61541
  children: "This widget has no configurable fields. It may be event-driven \u2014 pair it with a widget that publishes the events it listens for."
61466
61542
  })]
61467
61543
  });
@@ -61470,14 +61546,17 @@ function BulkEditPane(_ref5) {
61470
61546
  var sharedFields = _ref5.sharedFields,
61471
61547
  stagedPrefs = _ref5.stagedPrefs,
61472
61548
  onApplyAll = _ref5.onApplyAll;
61549
+ var _useConfigTokens3 = useConfigTokens(),
61550
+ muted = _useConfigTokens3.muted,
61551
+ strong = _useConfigTokens3.strong;
61473
61552
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
61474
61553
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
61475
61554
  className: "mb-3",
61476
61555
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
61477
- className: "text-gray-200 font-semibold",
61556
+ className: "font-semibold ".concat(strong),
61478
61557
  children: "All Widgets"
61479
61558
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
61480
- className: "text-xs text-gray-500",
61559
+ className: "text-xs ".concat(muted),
61481
61560
  children: "Fields declared by 2+ widgets on this dashboard. Apply once to update every matching widget."
61482
61561
  })]
61483
61562
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -61489,7 +61568,7 @@ function BulkEditPane(_ref5) {
61489
61568
  onApplyAll: onApplyAll
61490
61569
  }, "".concat(field.key, "::").concat(field.schema.type));
61491
61570
  }), sharedFields.length === 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
61492
- className: "text-sm text-gray-500 italic",
61571
+ className: "text-sm italic ".concat(muted),
61493
61572
  children: "No shared fields across widgets on this dashboard."
61494
61573
  })]
61495
61574
  })]
@@ -61516,32 +61595,38 @@ function SharedFieldRow(_ref6) {
61516
61595
  if (allSame) setDraft(distinctValues[0]);
61517
61596
  // eslint-disable-next-line react-hooks/exhaustive-deps
61518
61597
  }, [allSame, distinctValues[0]]);
61598
+ var _useConfigTokens4 = useConfigTokens(),
61599
+ muted = _useConfigTokens4.muted,
61600
+ strong = _useConfigTokens4.strong,
61601
+ hairline = _useConfigTokens4.hairline,
61602
+ fieldBg = _useConfigTokens4.fieldBg;
61603
+ var fieldClass = "w-full px-2 py-1.5 rounded-lg border text-sm ".concat(fieldBg, " ").concat(hairline, " ").concat(strong);
61519
61604
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
61520
- className: "border border-white/10 rounded p-3",
61605
+ className: "rounded-lg border p-3 ".concat(hairline),
61521
61606
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
61522
61607
  className: "flex items-start justify-between gap-3 mb-2",
61523
61608
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
61524
61609
  className: "flex-1 min-w-0",
61525
61610
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
61526
- className: "text-sm text-gray-200 font-semibold",
61611
+ className: "text-sm font-semibold ".concat(strong),
61527
61612
  children: field.schema.displayName || field.key
61528
61613
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
61529
- className: "text-[11px] text-gray-500",
61614
+ className: "text-xs ".concat(muted),
61530
61615
  children: ["Applies to ", field.widgets.length, " widgets", allSame ? "" : " \xB7 ".concat(distinctValues.length, " distinct values in use")]
61531
61616
  })]
61532
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
61617
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
61618
+ title: "Apply to all",
61619
+ size: "sm",
61533
61620
  onClick: function onClick() {
61534
61621
  return onApplyAll(field.widgets, field.key, draft);
61535
- },
61536
- className: "px-3 py-1 text-xs bg-indigo-600 hover:bg-indigo-500 text-white rounded transition-colors",
61537
- children: "Apply to all"
61622
+ }
61538
61623
  })]
61539
61624
  }), field.schema.type === "select" ? /*#__PURE__*/jsxRuntime.jsx("select", {
61540
61625
  value: draft,
61541
61626
  onChange: function onChange(e) {
61542
61627
  return setDraft(e.target.value);
61543
61628
  },
61544
- className: "w-full px-2 py-1.5 bg-gray-900 border border-white/10 rounded text-sm text-gray-200",
61629
+ className: fieldClass,
61545
61630
  children: (field.schema.options || []).map(function (opt) {
61546
61631
  return /*#__PURE__*/jsxRuntime.jsx("option", {
61547
61632
  value: opt.value,
@@ -61555,7 +61640,7 @@ function SharedFieldRow(_ref6) {
61555
61640
  return setDraft(e.target.value);
61556
61641
  },
61557
61642
  placeholder: allSame ? "" : "(multiple values — set one for all)",
61558
- className: "w-full px-2 py-1.5 bg-gray-900 border border-white/10 rounded text-sm text-gray-200"
61643
+ className: fieldClass
61559
61644
  })]
61560
61645
  });
61561
61646
  }
@@ -61583,6 +61668,13 @@ var PermissionsTab = function PermissionsTab(_ref) {
61583
61668
  _useState8 = _slicedToArray(_useState7, 2),
61584
61669
  busy = _useState8[0],
61585
61670
  setBusy = _useState8[1];
61671
+ var _useState9 = React.useState(false),
61672
+ _useState0 = _slicedToArray(_useState9, 2),
61673
+ confirmRevokeAll = _useState0[0],
61674
+ setConfirmRevokeAll = _useState0[1];
61675
+ var _useConfigTokens = useConfigTokens(),
61676
+ muted = _useConfigTokens.muted,
61677
+ hairline = _useConfigTokens.hairline;
61586
61678
 
61587
61679
  // Build the set of widget identifiers in this workspace. Walk every
61588
61680
  // layout location (main, pages, sidebar). `pickWidgetRef` returns
@@ -62111,7 +62203,7 @@ var PermissionsTab = function PermissionsTab(_ref) {
62111
62203
  }).length;
62112
62204
  if (loading) {
62113
62205
  return /*#__PURE__*/jsxRuntime.jsx("div", {
62114
- className: "text-sm opacity-60 p-4",
62206
+ className: "text-sm p-4 ".concat(muted),
62115
62207
  children: "Loading permissions\u2026"
62116
62208
  });
62117
62209
  }
@@ -62119,10 +62211,10 @@ var PermissionsTab = function PermissionsTab(_ref) {
62119
62211
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
62120
62212
  className: "flex flex-col gap-3 p-4",
62121
62213
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
62122
- className: "text-sm opacity-70",
62214
+ className: "text-sm",
62123
62215
  children: "No widgets in this dashboard request any MCP permissions."
62124
62216
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
62125
- className: "text-xs opacity-50",
62217
+ className: "text-xs ".concat(muted),
62126
62218
  children: "Permissions only show up here when a widget's published manifest (or local source) declares MCP tool usage."
62127
62219
  })]
62128
62220
  });
@@ -62130,32 +62222,66 @@ var PermissionsTab = function PermissionsTab(_ref) {
62130
62222
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
62131
62223
  className: "flex flex-col h-full min-h-0",
62132
62224
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
62133
- className: "flex-shrink-0 flex flex-row items-center justify-between gap-2 pb-3",
62225
+ className: "flex-shrink-0 flex flex-row items-center justify-between gap-2 pb-3 border-b ".concat(hairline),
62134
62226
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
62135
62227
  className: "flex flex-col",
62136
62228
  children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
62137
62229
  className: "text-sm font-medium",
62138
62230
  children: [filteredRows.length, " widget", filteredRows.length === 1 ? "" : "s", " with permissions in this dashboard"]
62139
62231
  }), /*#__PURE__*/jsxRuntime.jsxs("span", {
62140
- className: "text-xs opacity-60 mt-0.5",
62232
+ className: "text-xs mt-0.5 ".concat(muted),
62141
62233
  children: [totalGranted, " currently granted across ", totalDeclared, " declared server", totalDeclared === 1 ? "" : "s"]
62142
62234
  })]
62143
62235
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
62144
62236
  className: "flex flex-row gap-2",
62145
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
62237
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
62146
62238
  title: "Allow all declared",
62147
62239
  onClick: approveAllInDashboard,
62148
62240
  disabled: busy,
62149
62241
  size: "sm"
62242
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
62243
+ "data-testid": "permissions-revoke-all",
62244
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
62245
+ title: "Revoke all",
62246
+ onClick: function onClick() {
62247
+ return setConfirmRevokeAll(true);
62248
+ },
62249
+ disabled: busy || totalGranted === 0,
62250
+ size: "sm"
62251
+ })
62252
+ })]
62253
+ })]
62254
+ }), confirmRevokeAll && /*#__PURE__*/jsxRuntime.jsxs("div", {
62255
+ "data-testid": "permissions-revoke-all-confirm",
62256
+ className: "flex-shrink-0 flex flex-row items-center justify-between gap-3 rounded-lg border border-amber-400 px-3 py-2 mt-3",
62257
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
62258
+ className: "flex flex-col gap-0.5 min-w-0",
62259
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
62260
+ className: "text-sm font-medium",
62261
+ children: "Revoke all permissions for this dashboard?"
62262
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
62263
+ className: "text-xs ".concat(muted),
62264
+ children: "Every widget here will ask for consent again the next time it uses a tool."
62265
+ })]
62266
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
62267
+ className: "flex flex-row gap-2 flex-shrink-0",
62268
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
62269
+ title: "Cancel",
62270
+ size: "sm",
62271
+ onClick: function onClick() {
62272
+ return setConfirmRevokeAll(false);
62273
+ }
62150
62274
  }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
62151
- title: "Revoke all",
62152
- onClick: revokeAllInDashboard,
62153
- disabled: busy || totalGranted === 0,
62154
- size: "sm"
62275
+ title: "Revoke",
62276
+ size: "sm",
62277
+ onClick: function onClick() {
62278
+ setConfirmRevokeAll(false);
62279
+ revokeAllInDashboard();
62280
+ }
62155
62281
  })]
62156
62282
  })]
62157
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), error && /*#__PURE__*/jsxRuntime.jsx("div", {
62158
- className: "flex-shrink-0 text-xs text-red-400 bg-red-900/20 border border-red-700 rounded p-2 mt-3",
62283
+ }), error && /*#__PURE__*/jsxRuntime.jsx("div", {
62284
+ className: "flex-shrink-0 text-xs text-red-400 mt-3",
62159
62285
  children: error
62160
62286
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
62161
62287
  className: "flex-1 min-h-0 overflow-y-auto pt-3 space-y-3",
@@ -62745,15 +62871,38 @@ function useTeamBots(workspaceId) {
62745
62871
  }, [bots, running, paused, approvals, lastRunByBot, loading, approve, refresh, loadLastRun, drafts, dismissDraft]);
62746
62872
  }
62747
62873
 
62748
- var BotsTab = function BotsTab(_ref) {
62749
- var workspace = _ref.workspace,
62750
- _ref$onOpenBotsView = _ref.onOpenBotsView,
62751
- onOpenBotsView = _ref$onOpenBotsView === void 0 ? null : _ref$onOpenBotsView;
62874
+ var StatusDot = function StatusDot(_ref) {
62875
+ var status = _ref.status,
62876
+ muted = _ref.muted;
62877
+ var dot = STATUS_DOT$2[status] || STATUS_DOT$2.Idle;
62878
+ return /*#__PURE__*/jsxRuntime.jsxs("span", {
62879
+ "data-testid": "bot-status",
62880
+ className: "flex flex-row items-center gap-1.5 text-xs flex-shrink-0 ".concat(muted),
62881
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
62882
+ "data-testid": "bot-status-dot",
62883
+ className: "inline-block h-2 w-2 rounded-full ".concat(dot)
62884
+ }), status]
62885
+ });
62886
+ };
62887
+
62888
+ /**
62889
+ * BotsTab — Dashboard Config › Bots: a read-only summary of this dashboard's
62890
+ * team (bot-teams PRD TEAM-011). Managing bots — adding, editing, talking to
62891
+ * them — happens in the Bots view; "Open in Bots view" goes there.
62892
+ */
62893
+ var BotsTab = function BotsTab(_ref2) {
62894
+ var workspace = _ref2.workspace,
62895
+ _ref2$onOpenBotsView = _ref2.onOpenBotsView,
62896
+ onOpenBotsView = _ref2$onOpenBotsView === void 0 ? null : _ref2$onOpenBotsView;
62752
62897
  var team = useTeamBots(workspace ? workspace.id : null);
62753
62898
  var lead = team.lead,
62754
62899
  members = team.members,
62755
62900
  attention = team.attention,
62756
62901
  loading = team.loading;
62902
+ var _useConfigTokens = useConfigTokens(),
62903
+ muted = _useConfigTokens.muted,
62904
+ hairline = _useConfigTokens.hairline;
62905
+ var card = "rounded-lg border px-3 py-2 flex flex-row items-center justify-between gap-3 ".concat(hairline);
62757
62906
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
62758
62907
  className: "flex flex-col gap-4 h-full min-h-0",
62759
62908
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -62763,7 +62912,7 @@ var BotsTab = function BotsTab(_ref) {
62763
62912
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SectionLabel, {
62764
62913
  text: "This dashboard's team"
62765
62914
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
62766
- className: "text-xs opacity-60",
62915
+ className: "text-xs ".concat(muted),
62767
62916
  children: ["".concat(members.length, " bot").concat(members.length === 1 ? "" : "s"), lead ? "led by ".concat(lead.name) : "no team lead", attention > 0 ? "".concat(attention, " need").concat(attention === 1 ? "s" : "", " attention") : null].filter(Boolean).join(" · ")
62768
62917
  })]
62769
62918
  }), onOpenBotsView ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
@@ -62772,12 +62921,25 @@ var BotsTab = function BotsTab(_ref) {
62772
62921
  onClick: onOpenBotsView
62773
62922
  }) : null]
62774
62923
  }), lead ? /*#__PURE__*/jsxRuntime.jsxs("div", {
62775
- className: "flex flex-row items-center gap-2 text-sm",
62776
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
62777
- className: "font-medium",
62778
- children: lead.name
62779
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
62780
- text: "Lead"
62924
+ className: card,
62925
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
62926
+ className: "flex flex-col gap-0.5 min-w-0",
62927
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
62928
+ className: "flex flex-row items-center gap-2 text-sm",
62929
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
62930
+ className: "font-medium truncate",
62931
+ children: lead.name
62932
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
62933
+ className: "text-xs uppercase tracking-wider font-semibold ".concat(muted),
62934
+ children: "Lead"
62935
+ })]
62936
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
62937
+ className: "text-xs truncate ".concat(muted),
62938
+ children: "Answers questions about this team"
62939
+ })]
62940
+ }), /*#__PURE__*/jsxRuntime.jsx(StatusDot, {
62941
+ status: team.statusOf(lead.id),
62942
+ muted: muted
62781
62943
  })]
62782
62944
  }) : null, !loading && !members.length ? /*#__PURE__*/jsxRuntime.jsx(DashReact.EmptyState, {
62783
62945
  icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
@@ -62787,21 +62949,22 @@ var BotsTab = function BotsTab(_ref) {
62787
62949
  title: "No bots on this dashboard yet",
62788
62950
  description: "Add bots, talk to them and change their settings in the Bots view."
62789
62951
  }) : /*#__PURE__*/jsxRuntime.jsx("div", {
62790
- className: "flex flex-col gap-1 overflow-y-auto min-h-0",
62952
+ className: "flex flex-col gap-2 overflow-y-auto min-h-0",
62791
62953
  children: members.map(function (bot) {
62792
62954
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
62793
- className: "flex flex-row items-center justify-between gap-3 py-2 border-b",
62955
+ className: card,
62794
62956
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
62795
- className: "flex flex-col gap-1 min-w-0",
62957
+ className: "flex flex-col gap-0.5 min-w-0",
62796
62958
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
62797
62959
  className: "text-sm font-medium truncate",
62798
62960
  children: bot.name
62799
62961
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
62800
- className: "text-xs opacity-60",
62962
+ className: "text-xs truncate ".concat(muted),
62801
62963
  children: triggerSummary(bot)
62802
62964
  })]
62803
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
62804
- text: team.statusOf(bot.id)
62965
+ }), /*#__PURE__*/jsxRuntime.jsx(StatusDot, {
62966
+ status: team.statusOf(bot.id),
62967
+ muted: muted
62805
62968
  })]
62806
62969
  }, bot.id);
62807
62970
  })
@@ -62814,30 +62977,88 @@ function _unsupportedIterableToArray$9(r, a) { if (r) { if ("string" == typeof r
62814
62977
  function _arrayLikeToArray$9(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
62815
62978
  function ownKeys$e(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; }
62816
62979
  function _objectSpread$e(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$e(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$e(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
62817
- var DashboardConfigModal = function DashboardConfigModal(_ref) {
62818
- var isOpen = _ref.isOpen,
62819
- setIsOpen = _ref.setIsOpen,
62820
- workspace = _ref.workspace;
62821
- _ref.workspaces;
62822
- var appProviders = _ref.appProviders,
62823
- getWidgetRequirements = _ref.getWidgetRequirements,
62824
- _ref$getWidgetConfig = _ref.getWidgetConfig,
62825
- getWidgetConfig = _ref$getWidgetConfig === void 0 ? null : _ref$getWidgetConfig,
62826
- onSaveBindings = _ref.onSaveBindings,
62827
- onSaveListeners = _ref.onSaveListeners,
62828
- _ref$onSaveUserPrefs = _ref.onSaveUserPrefs,
62829
- onSaveUserPrefs = _ref$onSaveUserPrefs === void 0 ? null : _ref$onSaveUserPrefs,
62830
- _ref$onSkip = _ref.onSkip,
62831
- onSkip = _ref$onSkip === void 0 ? null : _ref$onSkip,
62832
- _ref$initialTab = _ref.initialTab,
62833
- initialTab = _ref$initialTab === void 0 ? "providers" : _ref$initialTab,
62834
- _ref$onOpenBotsView = _ref.onOpenBotsView,
62835
- onOpenBotsView = _ref$onOpenBotsView === void 0 ? null : _ref$onOpenBotsView;
62980
+ var ConfigTab = function ConfigTab(_ref) {
62981
+ var active = _ref.active,
62982
+ onClick = _ref.onClick,
62983
+ children = _ref.children;
62984
+ var _useConfigTokens = useConfigTokens(),
62985
+ muted = _useConfigTokens.muted;
62986
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
62987
+ type: "button",
62988
+ role: "tab",
62989
+ "aria-selected": active,
62990
+ onClick: onClick,
62991
+ className: "py-2.5 text-sm font-medium -mb-px border-b-2 ".concat(active ? "border-indigo-400" : "border-transparent ".concat(muted)),
62992
+ children: children
62993
+ });
62994
+ };
62995
+
62996
+ /**
62997
+ * DashboardConfigModal
62998
+ *
62999
+ * Workspace-scoped wiring panel. Lets a user assign providers to every
63000
+ * widget in the current workspace from one place instead of opening each
63001
+ * widget's settings individually. v1 ships the Providers tab; Listeners
63002
+ * tab lands in a follow-up PR (data model needs more exploration).
63003
+ *
63004
+ * Auto-opens on dashboard install when any required provider is still
63005
+ * unresolved after applying app-wide defaults. Also openable manually
63006
+ * via the dashboard toolbar's config button.
63007
+ *
63008
+ * @param {boolean} isOpen
63009
+ * @param {(open: boolean) => void} setIsOpen
63010
+ * @param {object} workspace Current workspace (layout/pages/sidebarLayout/selectedProviders).
63011
+ * @param {object|Array} appProviders Either a map keyed by provider name, or an array. Each entry has
63012
+ * at least { name?, type, providerClass, isDefaultForType }.
63013
+ * @param {(componentName: string) => Array} getWidgetRequirements
63014
+ * Called per widget instance. Should return the `providers: [...]`
63015
+ * array from the component's .dash.js. Usually backed by
63016
+ * ComponentManager.componentMap().
63017
+ * @param {(componentName: string) => object | null} getWidgetConfig
63018
+ * Called per widget instance. Returns the full ComponentManager
63019
+ * entry (events, eventHandlers, displayName, …). Used by the
63020
+ * Listeners tab to discover what each widget emits/handles.
63021
+ * @param {(changes: Array<{widgetId, providerType, providerName}>) => void} onSaveBindings
63022
+ * Called with the staged provider changes on Save. The parent persists
63023
+ * by forwarding to its existing `handleProviderSelect` /
63024
+ * `saveWorkspace` plumbing.
63025
+ * @param {(changes: {adds: Array, removes: Array}) => void} onSaveListeners
63026
+ * Called with the staged listener changes on Save. Each entry is
63027
+ * `{ receiverItemId, handlerName, sourceComponent, sourceItemId, eventName }`.
63028
+ * Parent uses `applyWiringChanges` + saveWorkspace.
63029
+ * @param {(changes: Array<{widgetId, key, value}>) => void} onSaveUserPrefs
63030
+ * Called with the staged widget userPrefs changes on Save. Parent
63031
+ * applies them to workspace + persists via saveWorkspace. Enables
63032
+ * bulk-edit of fields shared across widgets (e.g. basePath).
63033
+ * @param {"providers"|"listeners"|"widgets"} initialTab Which tab to focus when the modal opens.
63034
+ */
63035
+ var DashboardConfigModal = function DashboardConfigModal(_ref2) {
63036
+ var isOpen = _ref2.isOpen,
63037
+ setIsOpen = _ref2.setIsOpen,
63038
+ workspace = _ref2.workspace;
63039
+ _ref2.workspaces;
63040
+ var appProviders = _ref2.appProviders,
63041
+ getWidgetRequirements = _ref2.getWidgetRequirements,
63042
+ _ref2$getWidgetConfig = _ref2.getWidgetConfig,
63043
+ getWidgetConfig = _ref2$getWidgetConfig === void 0 ? null : _ref2$getWidgetConfig,
63044
+ onSaveBindings = _ref2.onSaveBindings,
63045
+ onSaveListeners = _ref2.onSaveListeners,
63046
+ _ref2$onSaveUserPrefs = _ref2.onSaveUserPrefs,
63047
+ onSaveUserPrefs = _ref2$onSaveUserPrefs === void 0 ? null : _ref2$onSaveUserPrefs,
63048
+ _ref2$onSkip = _ref2.onSkip,
63049
+ onSkip = _ref2$onSkip === void 0 ? null : _ref2$onSkip,
63050
+ _ref2$initialTab = _ref2.initialTab,
63051
+ initialTab = _ref2$initialTab === void 0 ? "providers" : _ref2$initialTab,
63052
+ _ref2$onOpenBotsView = _ref2.onOpenBotsView,
63053
+ onOpenBotsView = _ref2$onOpenBotsView === void 0 ? null : _ref2$onOpenBotsView;
62836
63054
  var _useContext = React.useContext(DashReact.ThemeContext),
62837
63055
  currentTheme = _useContext.currentTheme;
62838
63056
  var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
62839
63057
  grow: false
62840
63058
  });
63059
+ var _useConfigTokens2 = useConfigTokens(),
63060
+ muted = _useConfigTokens2.muted,
63061
+ hairline = _useConfigTokens2.hairline;
62841
63062
 
62842
63063
  // Active tab. Defaults to whatever the parent requested via
62843
63064
  // `initialTab`. Resets on each open via the modal's mount cycle.
@@ -63046,10 +63267,10 @@ var DashboardConfigModal = function DashboardConfigModal(_ref) {
63046
63267
  }
63047
63268
  return Array.from(byPackage.values()).map(function (e) {
63048
63269
  return _objectSpread$e(_objectSpread$e({}, e), {}, {
63049
- components: Array.from(e.components.entries()).map(function (_ref2) {
63050
- var _ref3 = _slicedToArray(_ref2, 2),
63051
- component = _ref3[0],
63052
- count = _ref3[1];
63270
+ components: Array.from(e.components.entries()).map(function (_ref3) {
63271
+ var _ref4 = _slicedToArray(_ref3, 2),
63272
+ component = _ref4[0],
63273
+ count = _ref4[1];
63053
63274
  return {
63054
63275
  component: component,
63055
63276
  count: count
@@ -63370,80 +63591,84 @@ var DashboardConfigModal = function DashboardConfigModal(_ref) {
63370
63591
  children: /*#__PURE__*/jsxRuntime.jsxs("div", {
63371
63592
  className: "flex flex-col h-full w-full rounded-lg overflow-clip border ".concat(panelStyles.backgroundColor || "", " ").concat(panelStyles.borderColor || "", " ").concat(panelStyles.textColor || ""),
63372
63593
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63373
- className: "flex-shrink-0 flex flex-row items-center justify-between p-4",
63594
+ className: "flex-shrink-0 flex flex-row items-start justify-between px-5 pt-4",
63374
63595
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63375
- className: "flex items-center gap-3",
63376
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
63377
- icon: "sliders",
63378
- className: "h-4 w-4 opacity-70"
63379
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
63380
- className: "text-lg font-semibold",
63381
- children: "Dashboard Config"
63382
- }), unresolvedCount > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag, {
63383
- text: "".concat(unresolvedCount, " unresolved"),
63384
- className: "bg-amber-900/40 text-amber-200"
63385
- })]
63596
+ className: "flex flex-col gap-0.5 min-w-0",
63597
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63598
+ className: "flex flex-row items-center gap-3",
63599
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
63600
+ icon: "sliders",
63601
+ className: "h-4 w-4 opacity-70"
63602
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
63603
+ className: "text-lg font-semibold",
63604
+ children: "Dashboard Config"
63605
+ }), unresolvedCount > 0 && /*#__PURE__*/jsxRuntime.jsxs("span", {
63606
+ "data-testid": "config-unresolved",
63607
+ className: "flex flex-row items-center gap-1.5 text-sm text-amber-400",
63608
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63609
+ className: "inline-block h-1.5 w-1.5 rounded-full bg-amber-400"
63610
+ }), unresolvedCount, " unresolved"]
63611
+ })]
63612
+ }), workspace !== null && workspace !== void 0 && workspace.name ? /*#__PURE__*/jsxRuntime.jsx("span", {
63613
+ className: "text-sm truncate ".concat(muted),
63614
+ children: workspace.name
63615
+ }) : null]
63386
63616
  }), /*#__PURE__*/jsxRuntime.jsx("button", {
63387
63617
  type: "button",
63388
63618
  onClick: handleCancel,
63619
+ "aria-label": "Close",
63389
63620
  className: "opacity-50 hover:opacity-100 transition-opacity cursor-pointer",
63390
63621
  children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
63391
63622
  icon: "xmark",
63392
63623
  className: "h-5 w-5"
63393
63624
  })
63394
63625
  })]
63395
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsxs("div", {
63396
- className: "flex-shrink-0 flex flex-row items-center gap-2 px-4 pt-3",
63397
- children: [/*#__PURE__*/jsxRuntime.jsxs("button", {
63398
- type: "button",
63626
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63627
+ role: "tablist",
63628
+ className: "flex-shrink-0 flex flex-row gap-6 px-5 mt-3 border-b ".concat(hairline),
63629
+ children: [/*#__PURE__*/jsxRuntime.jsxs(ConfigTab, {
63630
+ active: activeTab === "providers",
63399
63631
  onClick: function onClick() {
63400
63632
  return setActiveTab("providers");
63401
63633
  },
63402
- className: "px-3 py-1.5 text-sm font-medium -mb-px border-b-2 ".concat(activeTab === "providers" ? "border-indigo-400" : "border-transparent opacity-60 hover:opacity-100"),
63403
63634
  children: ["Providers", unresolvedCount > 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
63404
63635
  className: "ml-2 inline-block h-1.5 w-1.5 rounded-full bg-amber-400 align-middle"
63405
63636
  })]
63406
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
63407
- type: "button",
63637
+ }), /*#__PURE__*/jsxRuntime.jsx(ConfigTab, {
63638
+ active: activeTab === "listeners",
63408
63639
  onClick: function onClick() {
63409
63640
  return setActiveTab("listeners");
63410
63641
  },
63411
- className: "px-3 py-1.5 text-sm font-medium -mb-px border-b-2 ".concat(activeTab === "listeners" ? "border-indigo-400" : "border-transparent opacity-60 hover:opacity-100"),
63412
63642
  children: "Listeners"
63413
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
63414
- type: "button",
63643
+ }), /*#__PURE__*/jsxRuntime.jsx(ConfigTab, {
63644
+ active: activeTab === "notifications",
63415
63645
  onClick: function onClick() {
63416
63646
  return setActiveTab("notifications");
63417
63647
  },
63418
- className: "px-3 py-1.5 text-sm font-medium -mb-px border-b-2 ".concat(activeTab === "notifications" ? "border-indigo-400" : "border-transparent opacity-60 hover:opacity-100"),
63419
63648
  children: "Notifications"
63420
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
63421
- type: "button",
63649
+ }), /*#__PURE__*/jsxRuntime.jsx(ConfigTab, {
63650
+ active: activeTab === "widgets",
63422
63651
  onClick: function onClick() {
63423
63652
  return setActiveTab("widgets");
63424
63653
  },
63425
- className: "px-3 py-1.5 text-sm font-medium -mb-px border-b-2 ".concat(activeTab === "widgets" ? "border-indigo-400" : "border-transparent opacity-60 hover:opacity-100"),
63426
63654
  children: "Widgets"
63427
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
63428
- type: "button",
63655
+ }), /*#__PURE__*/jsxRuntime.jsx(ConfigTab, {
63656
+ active: activeTab === "permissions",
63429
63657
  onClick: function onClick() {
63430
63658
  return setActiveTab("permissions");
63431
63659
  },
63432
- className: "px-3 py-1.5 text-sm font-medium -mb-px border-b-2 ".concat(activeTab === "permissions" ? "border-indigo-400" : "border-transparent opacity-60 hover:opacity-100"),
63433
63660
  children: "Permissions"
63434
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
63435
- type: "button",
63661
+ }), /*#__PURE__*/jsxRuntime.jsx(ConfigTab, {
63662
+ active: activeTab === "bots",
63436
63663
  onClick: function onClick() {
63437
63664
  return setActiveTab("bots");
63438
63665
  },
63439
- className: "px-3 py-1.5 text-sm font-medium -mb-px border-b-2 ".concat(activeTab === "bots" ? "border-indigo-400" : "border-transparent opacity-60 hover:opacity-100"),
63440
63666
  children: "Bots"
63441
- }), /*#__PURE__*/jsxRuntime.jsxs("button", {
63442
- type: "button",
63667
+ }), /*#__PURE__*/jsxRuntime.jsxs(ConfigTab, {
63668
+ active: activeTab === "dependencies",
63443
63669
  onClick: function onClick() {
63444
63670
  return setActiveTab("dependencies");
63445
63671
  },
63446
- className: "px-3 py-1.5 text-sm font-medium -mb-px border-b-2 ".concat(activeTab === "dependencies" ? "border-indigo-400" : "border-transparent opacity-60 hover:opacity-100"),
63447
63672
  children: ["Dependencies", dependencyCount > 0 && /*#__PURE__*/jsxRuntime.jsxs(DashReact.Caption2, {
63448
63673
  className: "ml-2",
63449
63674
  children: ["(", dependencyCount, ")"]
@@ -63451,7 +63676,7 @@ var DashboardConfigModal = function DashboardConfigModal(_ref) {
63451
63676
  className: "ml-1 inline-block h-1.5 w-1.5 rounded-full bg-amber-400 align-middle"
63452
63677
  })]
63453
63678
  })]
63454
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsxs("div", {
63679
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63455
63680
  className: "flex-1 min-h-0 ".concat(activeTab === "widgets" ? "" : "p-5"),
63456
63681
  children: [activeTab === "listeners" && /*#__PURE__*/jsxRuntime.jsx(ListenersTab, {
63457
63682
  emitters: emitters,
@@ -63511,8 +63736,11 @@ var DashboardConfigModal = function DashboardConfigModal(_ref) {
63511
63736
  * write fails the user can re-toggle. No staging — the bulk modal
63512
63737
  * doesn't gate the user behind a Save button for boolean prefs.
63513
63738
  */
63514
- function NotificationsTab(_ref4) {
63515
- var workspace = _ref4.workspace;
63739
+ function NotificationsTab(_ref5) {
63740
+ var workspace = _ref5.workspace;
63741
+ var _useConfigTokens3 = useConfigTokens(),
63742
+ muted = _useConfigTokens3.muted,
63743
+ hairline = _useConfigTokens3.hairline;
63516
63744
  var _useState9 = React.useState(""),
63517
63745
  _useState0 = _slicedToArray(_useState9, 2),
63518
63746
  searchQuery = _useState0[0],
@@ -63654,13 +63882,13 @@ function NotificationsTab(_ref4) {
63654
63882
  };
63655
63883
  if (!loaded) {
63656
63884
  return /*#__PURE__*/jsxRuntime.jsx("div", {
63657
- className: "p-4 text-sm opacity-50",
63885
+ className: "p-4 text-sm ".concat(muted),
63658
63886
  children: "Loading\u2026"
63659
63887
  });
63660
63888
  }
63661
63889
  if (widgetInstances.length === 0) {
63662
63890
  return /*#__PURE__*/jsxRuntime.jsx("div", {
63663
- className: "p-4 text-sm opacity-50",
63891
+ className: "p-4 text-sm ".concat(muted),
63664
63892
  children: "No widgets in this dashboard declare notifications. Add widgets that declare notifications to see per-type controls here."
63665
63893
  });
63666
63894
  }
@@ -63676,71 +63904,70 @@ function NotificationsTab(_ref4) {
63676
63904
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63677
63905
  className: "flex flex-row items-center justify-between text-xs",
63678
63906
  children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
63679
- className: "opacity-50",
63907
+ className: muted,
63680
63908
  children: [filtered.length, " of ", widgetInstances.length, " widget", widgetInstances.length === 1 ? "" : "s"]
63681
63909
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63682
63910
  className: "flex flex-row items-center gap-2",
63683
- children: [/*#__PURE__*/jsxRuntime.jsx("button", {
63684
- type: "button",
63685
- onClick: function onClick() {
63686
- return setAllVisible(true);
63687
- },
63688
- className: "px-2 py-1 rounded bg-green-700 hover:bg-green-600 text-white text-xs font-medium transition-colors",
63911
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63689
63912
  "data-testid": "bulk-notifications-enable-all",
63690
- children: "Enable all"
63691
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
63692
- type: "button",
63693
- onClick: function onClick() {
63694
- return setAllVisible(false);
63695
- },
63696
- className: "px-2 py-1 rounded bg-gray-700 hover:bg-gray-600 text-gray-200 text-xs font-medium transition-colors",
63913
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
63914
+ title: "Enable all",
63915
+ size: "sm",
63916
+ onClick: function onClick() {
63917
+ return setAllVisible(true);
63918
+ }
63919
+ })
63920
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
63697
63921
  "data-testid": "bulk-notifications-disable-all",
63698
- children: "Disable all"
63922
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
63923
+ title: "Disable all",
63924
+ size: "sm",
63925
+ onClick: function onClick() {
63926
+ return setAllVisible(false);
63927
+ }
63928
+ })
63699
63929
  })]
63700
63930
  })]
63701
63931
  })]
63702
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsx("div", {
63703
- className: "flex-1 overflow-y-auto px-2 py-2 space-y-3",
63932
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
63933
+ className: "flex-1 overflow-y-auto px-2 py-3 flex flex-col gap-3 border-t ".concat(hairline),
63704
63934
  children: filtered.map(function (wi) {
63705
63935
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
63706
- className: "border border-white/10 rounded p-3 space-y-2",
63936
+ className: "rounded-lg border px-3 py-2 flex flex-col gap-2 ".concat(hairline),
63707
63937
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63708
- className: "flex flex-col",
63938
+ className: "flex flex-col gap-0.5",
63709
63939
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63710
63940
  className: "text-sm font-medium",
63711
63941
  children: wi.title
63712
- }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Caption, {
63713
- className: "font-mono",
63942
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
63943
+ className: "text-xs font-mono truncate ".concat(muted),
63714
63944
  children: [wi.component, wi.itemId != null ? " \xB7 #".concat(wi.itemId) : ""]
63715
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Caption3, {
63945
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
63946
+ className: "text-xs ".concat(muted),
63716
63947
  children: wi["package"]
63717
63948
  })]
63718
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63719
- className: "flex flex-row gap-2",
63720
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {
63721
- orientation: "vertical"
63722
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
63723
- className: "flex flex-col flex-1",
63724
- children: wi.notifications.map(function (notif) {
63725
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
63726
- className: "flex flex-row items-center justify-between gap-3 py-2 px-2 -mx-2 rounded hover:bg-gray-800 transition-colors",
63727
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63728
- className: "flex flex-col",
63729
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63730
- className: "text-xs",
63731
- children: notif.displayName
63732
- }), notif.description && /*#__PURE__*/jsxRuntime.jsx(DashReact.Caption, {
63733
- children: notif.description
63734
- })]
63735
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Switch, {
63736
- checked: isEnabled(wi.uuid, notif.key, notif.defaultEnabled),
63737
- onChange: function onChange(value) {
63738
- return setOne(wi.uuid, notif.key, value);
63739
- }
63949
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
63950
+ className: "flex flex-col border-t ".concat(hairline),
63951
+ children: wi.notifications.map(function (notif) {
63952
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
63953
+ className: "flex flex-row items-center justify-between gap-3 py-2",
63954
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63955
+ className: "flex flex-col gap-0.5",
63956
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63957
+ className: "text-sm",
63958
+ children: notif.displayName
63959
+ }), notif.description && /*#__PURE__*/jsxRuntime.jsx("span", {
63960
+ className: "text-xs ".concat(muted),
63961
+ children: notif.description
63740
63962
  })]
63741
- }, notif.key);
63742
- })
63743
- })]
63963
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Switch, {
63964
+ checked: isEnabled(wi.uuid, notif.key, notif.defaultEnabled),
63965
+ onChange: function onChange(value) {
63966
+ return setOne(wi.uuid, notif.key, value);
63967
+ }
63968
+ })]
63969
+ }, notif.key);
63970
+ })
63744
63971
  })]
63745
63972
  }, wi.uuid);
63746
63973
  })
@@ -63754,12 +63981,16 @@ function NotificationsTab(_ref4) {
63754
63981
  * dot per-type when any widget of that type is unresolved). Column 2
63755
63982
  * shows the selected type's bulk dropdown + per-widget dropdowns.
63756
63983
  */
63757
- function ProvidersTab(_ref5) {
63984
+ function ProvidersTab(_ref6) {
63758
63985
  var _typeEntries$, _selectedRows$;
63759
- var grouped = _ref5.grouped,
63760
- providersByType = _ref5.providersByType,
63761
- onBulk = _ref5.onBulk,
63762
- onPerWidget = _ref5.onPerWidget;
63986
+ var grouped = _ref6.grouped,
63987
+ providersByType = _ref6.providersByType,
63988
+ onBulk = _ref6.onBulk,
63989
+ onPerWidget = _ref6.onPerWidget;
63990
+ var _useConfigTokens4 = useConfigTokens(),
63991
+ muted = _useConfigTokens4.muted,
63992
+ hairline = _useConfigTokens4.hairline,
63993
+ fieldBg = _useConfigTokens4.fieldBg;
63763
63994
  var typeEntries = React.useMemo(function () {
63764
63995
  return Array.from(grouped.entries());
63765
63996
  }, [grouped]);
@@ -63790,73 +64021,66 @@ function ProvidersTab(_ref5) {
63790
64021
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
63791
64022
  className: "flex flex-row gap-3 h-full min-h-0",
63792
64023
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63793
- className: "w-56 flex-shrink-0 overflow-hidden flex flex-col border-r border-white/10",
63794
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
63795
- className: "px-3 py-2 text-xs font-semibold opacity-50 uppercase tracking-wider",
64024
+ className: "w-56 flex-shrink-0 overflow-hidden flex flex-col",
64025
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SectionLabel, {
64026
+ className: "px-3 mb-2",
63796
64027
  children: "Provider Types"
63797
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsx("div", {
63798
- className: "overflow-y-auto flex-1",
63799
- children: typeEntries.map(function (_ref6) {
63800
- var _ref7 = _slicedToArray(_ref6, 2),
63801
- providerType = _ref7[0],
63802
- rows = _ref7[1];
63803
- var isActive = selectedType === providerType;
64028
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
64029
+ className: "overflow-y-auto flex-1 flex flex-col gap-1",
64030
+ children: typeEntries.map(function (_ref7) {
64031
+ var _ref8 = _slicedToArray(_ref7, 2),
64032
+ providerType = _ref8[0],
64033
+ rows = _ref8[1];
63804
64034
  var unresolvedHere = rows.filter(function (r) {
63805
64035
  return r.required && !r.resolvedProviderName;
63806
64036
  }).length;
63807
- return /*#__PURE__*/jsxRuntime.jsxs("button", {
63808
- type: "button",
64037
+ return /*#__PURE__*/jsxRuntime.jsx(ConfigListRow, {
64038
+ title: providerType,
64039
+ active: selectedType === providerType,
63809
64040
  onClick: function onClick() {
63810
64041
  return setSelectedType(providerType);
63811
64042
  },
63812
- className: "w-full text-left px-3 py-2 border-l-2 ".concat(isActive ? "bg-indigo-900/30 border-indigo-400" : "border-transparent hover:bg-white/5"),
63813
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63814
- className: "flex items-center gap-2",
64043
+ meta: "".concat(rows.length, " widget").concat(rows.length === 1 ? "" : "s"),
64044
+ badge: unresolvedHere > 0 ? /*#__PURE__*/jsxRuntime.jsxs("span", {
64045
+ className: "flex flex-row items-center gap-1.5 text-xs text-amber-400 flex-shrink-0",
63815
64046
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63816
- className: "text-sm font-medium truncate",
63817
- children: providerType
63818
- }), unresolvedHere > 0 && /*#__PURE__*/jsxRuntime.jsxs("span", {
63819
- className: "text-[10px] text-amber-300 flex items-center gap-1",
63820
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
63821
- icon: "triangle-exclamation",
63822
- className: "h-2.5 w-2.5"
63823
- }), unresolvedHere]
63824
- })]
63825
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63826
- className: "text-xs opacity-50 mt-0.5",
63827
- children: [rows.length, " widget", rows.length === 1 ? "" : "s"]
63828
- })]
64047
+ className: "inline-block h-1.5 w-1.5 rounded-full bg-amber-400"
64048
+ }), unresolvedHere]
64049
+ }) : null
63829
64050
  }, providerType);
63830
64051
  })
63831
64052
  })]
64053
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
64054
+ "aria-hidden": true,
64055
+ className: "flex-shrink-0 border-r ".concat(hairline)
63832
64056
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
63833
64057
  className: "flex-1 min-w-0 overflow-hidden flex flex-col",
63834
64058
  children: selectedType ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
63835
64059
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63836
- className: "px-4 py-3 flex-shrink-0",
64060
+ className: "px-4 pb-3 flex-shrink-0 border-b ".concat(hairline),
63837
64061
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63838
64062
  className: "text-sm font-semibold",
63839
64063
  children: [selectedType, " ", /*#__PURE__*/jsxRuntime.jsx("span", {
63840
- className: "opacity-60 font-normal",
64064
+ className: "font-normal ".concat(muted),
63841
64065
  children: "provider"
63842
64066
  })]
63843
64067
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
63844
- className: "text-xs opacity-60 mt-1",
64068
+ className: "text-xs mt-1 ".concat(muted),
63845
64069
  children: "Apply one provider to every widget of this type, or adjust per-widget below."
63846
64070
  })]
63847
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsxs("div", {
64071
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63848
64072
  className: "flex-1 overflow-y-auto p-4 space-y-4",
63849
64073
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63850
64074
  className: "flex items-center gap-3",
63851
64075
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63852
- className: "text-xs opacity-60 flex-shrink-0 w-20",
64076
+ className: "text-xs flex-shrink-0 w-20 ".concat(muted),
63853
64077
  children: "Bulk assign"
63854
64078
  }), /*#__PURE__*/jsxRuntime.jsxs("select", {
63855
64079
  value: topValue,
63856
64080
  onChange: function onChange(e) {
63857
64081
  return onBulk(selectedType, e.target.value);
63858
64082
  },
63859
- className: "flex-1 bg-gray-800 border border-white/10 rounded px-3 py-1.5 text-sm",
64083
+ className: "flex-1 rounded-lg border px-3 py-1.5 text-sm ".concat(fieldBg, " ").concat(hairline),
63860
64084
  children: [/*#__PURE__*/jsxRuntime.jsx("option", {
63861
64085
  value: "",
63862
64086
  children: "\u2014 Select provider \u2014"
@@ -63868,10 +64092,11 @@ function ProvidersTab(_ref5) {
63868
64092
  })]
63869
64093
  })]
63870
64094
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63871
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
63872
- className: "text-xs font-semibold opacity-50 uppercase tracking-wider mb-2",
64095
+ className: "flex flex-col gap-2",
64096
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SectionLabel, {
63873
64097
  children: "Per-widget"
63874
64098
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
64099
+ className: "flex flex-col gap-2",
63875
64100
  children: selectedRows.map(function (row) {
63876
64101
  var _row$layoutItem;
63877
64102
  var hasExplicitOverride = !!((_row$layoutItem = row.layoutItem) !== null && _row$layoutItem !== void 0 && (_row$layoutItem = _row$layoutItem.selectedProviders) !== null && _row$layoutItem !== void 0 && _row$layoutItem[selectedType]);
@@ -63879,35 +64104,29 @@ function ProvidersTab(_ref5) {
63879
64104
  var isMissing = !row.resolvedProviderName;
63880
64105
  var needsAttention = isRequired && isMissing;
63881
64106
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
63882
- className: "flex flex-row items-center gap-3 py-2 px-2 rounded border-l-2 transition-colors ".concat(needsAttention ? "bg-red-900 border-red-500" : "border-transparent hover:bg-gray-800"),
64107
+ "data-testid": "provider-row",
64108
+ className: "flex flex-row items-center gap-3 rounded-lg border px-3 py-2 ".concat(hairline),
63883
64109
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63884
64110
  className: "flex-1 min-w-0",
63885
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63886
- className: "text-sm truncate flex items-center gap-1.5 ".concat(needsAttention ? "font-semibold text-red-100" : "font-medium"),
63887
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63888
- className: "truncate",
63889
- children: row.label || row.component || "widget"
63890
- }), isRequired && /*#__PURE__*/jsxRuntime.jsx("span", {
63891
- className: needsAttention ? "text-red-300" : "text-indigo-300",
63892
- title: "Required provider",
63893
- "aria-label": "required",
63894
- children: "*"
63895
- })]
63896
- }), (row.widgetRef || row.component) && /*#__PURE__*/jsxRuntime.jsx(DashReact.Caption, {
63897
- block: true,
63898
- className: "font-mono truncate mt-0.5",
64111
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
64112
+ className: "text-sm font-medium truncate",
64113
+ children: row.label || row.component || "widget"
64114
+ }), (row.widgetRef || row.component) && /*#__PURE__*/jsxRuntime.jsx("div", {
64115
+ className: "text-xs font-mono truncate mt-0.5 ".concat(muted),
63899
64116
  title: row.widgetRef || row.component,
63900
64117
  children: row.widgetRef || row.component
63901
64118
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63902
- className: "flex items-center gap-1.5 mt-1 text-xs",
63903
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63904
- className: "uppercase tracking-wide px-1.5 py-0.5 rounded font-semibold ".concat(needsAttention ? "bg-red-600 text-white" : isRequired ? "bg-indigo-800 text-indigo-100" : "bg-gray-700 text-gray-300"),
63905
- children: isRequired ? "required" : "optional"
64119
+ className: "flex flex-row items-center gap-3 mt-1 text-xs",
64120
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
64121
+ className: "flex flex-row items-center gap-1.5 uppercase tracking-wider font-semibold ".concat(needsAttention ? "text-amber-400" : muted),
64122
+ children: [needsAttention && /*#__PURE__*/jsxRuntime.jsx("span", {
64123
+ className: "inline-block h-1.5 w-1.5 rounded-full bg-amber-400"
64124
+ }), isRequired ? "Required" : "Optional"]
63906
64125
  }), hasExplicitOverride && /*#__PURE__*/jsxRuntime.jsx("span", {
63907
- className: "uppercase tracking-wide px-1.5 py-0.5 rounded font-semibold bg-indigo-900 text-indigo-200",
63908
- children: "override"
64126
+ className: "uppercase tracking-wider font-semibold ".concat(muted),
64127
+ children: "Override"
63909
64128
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
63910
- className: "opacity-40 truncate ml-1",
64129
+ className: "font-mono truncate ".concat(muted),
63911
64130
  children: (row.widgetId || "").slice(0, 8)
63912
64131
  })]
63913
64132
  })]
@@ -63916,7 +64135,7 @@ function ProvidersTab(_ref5) {
63916
64135
  onChange: function onChange(e) {
63917
64136
  return onPerWidget(row.widgetId, selectedType, e.target.value);
63918
64137
  },
63919
- className: "bg-gray-800 border rounded px-2 py-1 text-xs min-w-[12rem] ".concat(needsAttention ? "border-red-400" : "border-gray-700"),
64138
+ className: "w-48 flex-shrink-0 rounded-lg border px-2 py-1 text-xs ".concat(fieldBg, " ").concat(needsAttention ? "border-amber-400" : hairline),
63920
64139
  children: [/*#__PURE__*/jsxRuntime.jsx("option", {
63921
64140
  value: "",
63922
64141
  children: "\u2014 none \u2014"
@@ -63933,7 +64152,7 @@ function ProvidersTab(_ref5) {
63933
64152
  })]
63934
64153
  })]
63935
64154
  }) : /*#__PURE__*/jsxRuntime.jsx("div", {
63936
- className: "flex-1 flex items-center justify-center text-sm opacity-60",
64155
+ className: "flex-1 flex items-center justify-center text-sm ".concat(muted),
63937
64156
  children: "Pick a provider type to bulk-assign or adjust per widget."
63938
64157
  })
63939
64158
  })]
@@ -63954,11 +64173,14 @@ function ProvidersTab(_ref5) {
63954
64173
  * package (no `config.id` / `config.package` / item.workspace hint).
63955
64174
  * Usually this is a stale layout item whose widget got uninstalled.
63956
64175
  */
63957
- function DependenciesTab(_ref9) {
63958
- var dependencies = _ref9.dependencies;
64176
+ function DependenciesTab(_ref0) {
64177
+ var dependencies = _ref0.dependencies;
64178
+ var _useConfigTokens5 = useConfigTokens(),
64179
+ muted = _useConfigTokens5.muted,
64180
+ hairline = _useConfigTokens5.hairline;
63959
64181
  if (!dependencies || dependencies.length === 0) {
63960
64182
  return /*#__PURE__*/jsxRuntime.jsx("div", {
63961
- className: "flex items-center justify-center h-full text-sm opacity-60 text-center",
64183
+ className: "flex items-center justify-center h-full text-sm text-center ".concat(muted),
63962
64184
  children: /*#__PURE__*/jsxRuntime.jsx("div", {
63963
64185
  children: "No widget packages referenced by this dashboard."
63964
64186
  })
@@ -63967,37 +64189,38 @@ function DependenciesTab(_ref9) {
63967
64189
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
63968
64190
  className: "flex flex-col h-full min-h-0 overflow-y-auto gap-3",
63969
64191
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
63970
- className: "text-xs opacity-60",
64192
+ className: "text-xs ".concat(muted),
63971
64193
  children: "Every widget instance in this workspace, grouped by the package it belongs to. Locations show where each package is referenced."
63972
64194
  }), dependencies.map(function (dep) {
63973
64195
  var isUnknown = dep.packageLabel === "(unknown)";
63974
64196
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
63975
- className: "border rounded-lg px-4 py-3 ".concat(isUnknown ? "bg-amber-900/10 border-amber-700/40" : "bg-white/5 border-white/10"),
64197
+ className: "border rounded-lg px-3 py-2 ".concat(isUnknown ? "border-amber-400" : hairline),
63976
64198
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63977
64199
  className: "flex items-center gap-2 flex-wrap",
63978
64200
  children: [/*#__PURE__*/jsxRuntime.jsx("code", {
63979
- className: "text-sm font-semibold ".concat(isUnknown ? "text-amber-200" : ""),
64201
+ className: "text-sm font-semibold",
63980
64202
  children: dep.packageLabel
63981
64203
  }), /*#__PURE__*/jsxRuntime.jsxs("span", {
63982
- className: "text-xs opacity-60",
64204
+ className: "text-xs ".concat(muted),
63983
64205
  children: [dep.total, " instance", dep.total === 1 ? "" : "s"]
63984
- }), isUnknown && /*#__PURE__*/jsxRuntime.jsx("span", {
63985
- className: "text-[10px] text-amber-300 uppercase tracking-wide",
63986
- children: "no package mapping"
64206
+ }), isUnknown && /*#__PURE__*/jsxRuntime.jsxs("span", {
64207
+ className: "flex flex-row items-center gap-1.5 text-xs text-amber-400 uppercase tracking-wider font-semibold",
64208
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
64209
+ className: "inline-block h-1.5 w-1.5 rounded-full bg-amber-400"
64210
+ }), "No package mapping"]
63987
64211
  })]
63988
64212
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63989
- className: "mt-2 text-xs opacity-70",
64213
+ className: "mt-2 text-xs flex flex-col gap-1",
63990
64214
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
63991
64215
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
63992
- className: "opacity-60 mr-1",
64216
+ className: "mr-1 ".concat(muted),
63993
64217
  children: "Widgets:"
63994
64218
  }), dep.components.map(function (c) {
63995
64219
  return "".concat(c.component).concat(c.count > 1 ? " \xD7".concat(c.count) : "");
63996
64220
  }).join(", ")]
63997
64221
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
63998
- className: "mt-1",
63999
64222
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
64000
- className: "opacity-60 mr-1",
64223
+ className: "mr-1 ".concat(muted),
64001
64224
  children: "Locations:"
64002
64225
  }), dep.locations.join(", ")]
64003
64226
  })]
@@ -64028,13 +64251,16 @@ function sameWiringEntry(a, b) {
64028
64251
  * adjusts wiring per handler from a single dropdown of all emitters'
64029
64252
  * (widget × event) pairs.
64030
64253
  */
64031
- function ListenersTab(_ref0) {
64254
+ function ListenersTab(_ref1) {
64032
64255
  var _receivers$;
64033
- var emitters = _ref0.emitters,
64034
- receivers = _ref0.receivers,
64035
- wiring = _ref0.wiring,
64036
- onAdd = _ref0.onAdd,
64037
- onRemove = _ref0.onRemove;
64256
+ var emitters = _ref1.emitters,
64257
+ receivers = _ref1.receivers,
64258
+ wiring = _ref1.wiring,
64259
+ onAdd = _ref1.onAdd,
64260
+ onRemove = _ref1.onRemove;
64261
+ var _useConfigTokens6 = useConfigTokens(),
64262
+ muted = _useConfigTokens6.muted,
64263
+ hairline = _useConfigTokens6.hairline;
64038
64264
  var _useState17 = React.useState(((_receivers$ = receivers[0]) === null || _receivers$ === void 0 ? void 0 : _receivers$.key) || null),
64039
64265
  _useState18 = _slicedToArray(_useState17, 2),
64040
64266
  selectedReceiverKey = _useState18[0],
@@ -64090,31 +64316,25 @@ function ListenersTab(_ref0) {
64090
64316
  className: "flex flex-row gap-3 flex-1 min-h-0",
64091
64317
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
64092
64318
  className: "w-56 flex-shrink-0 overflow-hidden flex flex-col",
64093
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
64094
- className: "px-3 py-2 text-xs font-semibold opacity-50 uppercase tracking-wider",
64319
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SectionLabel, {
64320
+ className: "px-3 mb-2",
64095
64321
  children: "Widgets"
64096
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsx("div", {
64097
- className: "overflow-y-auto flex-1",
64322
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
64323
+ className: "overflow-y-auto flex-1 flex flex-col gap-1",
64098
64324
  children: receivers.map(function (r) {
64099
- var isActive = r.key === selectedReceiverKey;
64100
- return /*#__PURE__*/jsxRuntime.jsxs("button", {
64101
- type: "button",
64325
+ return /*#__PURE__*/jsxRuntime.jsx(ConfigListRow, {
64326
+ title: r.label,
64327
+ subtitle: r.widgetRef || null,
64328
+ active: r.key === selectedReceiverKey,
64102
64329
  onClick: function onClick() {
64103
64330
  return setSelectedReceiverKey(r.key);
64104
- },
64105
- className: "w-full text-left px-3 py-2 border-l-2 ".concat(isActive ? "bg-indigo-900/30 border-indigo-400" : "border-transparent hover:bg-white/5"),
64106
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
64107
- className: "text-sm font-medium truncate",
64108
- children: r.label
64109
- }), r.widgetRef && /*#__PURE__*/jsxRuntime.jsx(DashReact.Caption, {
64110
- block: true,
64111
- className: "font-mono truncate mt-0.5",
64112
- title: r.widgetRef,
64113
- children: r.widgetRef
64114
- })]
64331
+ }
64115
64332
  }, r.key);
64116
64333
  })
64117
64334
  })]
64335
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
64336
+ "aria-hidden": true,
64337
+ className: "flex-shrink-0 border-r ".concat(hairline)
64118
64338
  }), selectedReceiver ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
64119
64339
  children: [/*#__PURE__*/jsxRuntime.jsx(HandlersColumn, {
64120
64340
  receiver: selectedReceiver,
@@ -64134,7 +64354,7 @@ function ListenersTab(_ref0) {
64134
64354
  onRemove: onRemove
64135
64355
  })]
64136
64356
  }) : /*#__PURE__*/jsxRuntime.jsx("div", {
64137
- className: "flex-1 min-w-0 flex items-center justify-center text-sm opacity-60",
64357
+ className: "flex-1 min-w-0 flex items-center justify-center text-sm ".concat(muted),
64138
64358
  children: "Pick a widget on the left to wire its handlers."
64139
64359
  })]
64140
64360
  })
@@ -64147,11 +64367,11 @@ function ListenersTab(_ref0) {
64147
64367
  * third column. Matches the left-column look from
64148
64368
  * PanelEditItemHandlers.
64149
64369
  */
64150
- function HandlersColumn(_ref10) {
64151
- var receiver = _ref10.receiver,
64152
- myWiring = _ref10.myWiring,
64153
- selectedHandler = _ref10.selectedHandler,
64154
- onSelectHandler = _ref10.onSelectHandler;
64370
+ function HandlersColumn(_ref11) {
64371
+ var receiver = _ref11.receiver,
64372
+ myWiring = _ref11.myWiring,
64373
+ selectedHandler = _ref11.selectedHandler,
64374
+ onSelectHandler = _ref11.onSelectHandler;
64155
64375
  var countsByHandler = React.useMemo(function () {
64156
64376
  var m = new Map();
64157
64377
  var _iterator9 = _createForOfIteratorHelper$9(myWiring),
@@ -64168,44 +64388,43 @@ function HandlersColumn(_ref10) {
64168
64388
  }
64169
64389
  return m;
64170
64390
  }, [myWiring]);
64391
+ var _useConfigTokens7 = useConfigTokens(),
64392
+ muted = _useConfigTokens7.muted,
64393
+ hairline = _useConfigTokens7.hairline;
64171
64394
  return (
64172
64395
  /*#__PURE__*/
64173
64396
  // Plain <div> wrapper — Card2 reads as washed-out against the
64174
64397
  // modal's dark chrome. See ListenersTab + ProvidersTab fix.
64175
- jsxRuntime.jsxs("div", {
64176
- className: "w-56 flex-shrink-0 overflow-hidden flex flex-col",
64177
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
64178
- className: "px-3 py-2 text-xs font-semibold opacity-50 uppercase tracking-wider",
64179
- children: "Event Handlers"
64180
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsx("div", {
64181
- className: "overflow-y-auto flex-1",
64182
- children: receiver.eventHandlers.length === 0 ? /*#__PURE__*/jsxRuntime.jsx("div", {
64183
- className: "text-xs opacity-50 text-center py-6 px-3",
64184
- children: "This widget declares no event handlers."
64185
- }) : receiver.eventHandlers.map(function (h) {
64186
- var isActive = h === selectedHandler;
64187
- var count = countsByHandler.get(h) || 0;
64188
- return /*#__PURE__*/jsxRuntime.jsxs("button", {
64189
- type: "button",
64190
- onClick: function onClick() {
64191
- return onSelectHandler(h);
64192
- },
64193
- className: "w-full text-left px-3 py-2 text-sm flex items-center justify-between gap-2 border-l-2 ".concat(isActive ? "bg-indigo-900/30 border-indigo-400" : "border-transparent hover:bg-white/5"),
64194
- children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
64195
- className: "flex items-center gap-2 min-w-0",
64196
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
64197
- icon: "bolt",
64198
- className: "h-3 w-3 opacity-60 flex-shrink-0"
64199
- }), /*#__PURE__*/jsxRuntime.jsx("code", {
64200
- className: "truncate",
64201
- children: h
64202
- })]
64203
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
64204
- className: "text-xs opacity-60 flex-shrink-0",
64205
- children: count
64206
- })]
64207
- }, h);
64208
- })
64398
+ jsxRuntime.jsxs(jsxRuntime.Fragment, {
64399
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
64400
+ className: "w-56 flex-shrink-0 overflow-hidden flex flex-col",
64401
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SectionLabel, {
64402
+ className: "px-3 mb-2",
64403
+ children: "Event Handlers"
64404
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
64405
+ className: "overflow-y-auto flex-1 flex flex-col gap-1",
64406
+ children: receiver.eventHandlers.length === 0 ? /*#__PURE__*/jsxRuntime.jsx("div", {
64407
+ className: "text-xs text-center py-6 px-3 ".concat(muted),
64408
+ children: "This widget declares no event handlers."
64409
+ }) : receiver.eventHandlers.map(function (h) {
64410
+ var count = countsByHandler.get(h) || 0;
64411
+ return /*#__PURE__*/jsxRuntime.jsx(ConfigListRow, {
64412
+ title: h,
64413
+ mono: true,
64414
+ active: h === selectedHandler,
64415
+ onClick: function onClick() {
64416
+ return onSelectHandler(h);
64417
+ },
64418
+ badge: /*#__PURE__*/jsxRuntime.jsx("span", {
64419
+ className: "text-xs flex-shrink-0 ".concat(muted),
64420
+ children: count
64421
+ })
64422
+ }, h);
64423
+ })
64424
+ })]
64425
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
64426
+ "aria-hidden": true,
64427
+ className: "flex-shrink-0 border-r ".concat(hairline)
64209
64428
  })]
64210
64429
  })
64211
64430
  );
@@ -64217,13 +64436,16 @@ function HandlersColumn(_ref10) {
64217
64436
  * Checked = wired; toggling commits an add/remove. Mirrors the
64218
64437
  * right-column UX of PanelEditItemHandlers.
64219
64438
  */
64220
- function EventsColumn(_ref11) {
64221
- var receiver = _ref11.receiver,
64222
- handlerName = _ref11.handlerName,
64223
- myWiring = _ref11.myWiring,
64224
- emitters = _ref11.emitters,
64225
- onAdd = _ref11.onAdd,
64226
- onRemove = _ref11.onRemove;
64439
+ function EventsColumn(_ref12) {
64440
+ var receiver = _ref12.receiver,
64441
+ handlerName = _ref12.handlerName,
64442
+ myWiring = _ref12.myWiring,
64443
+ emitters = _ref12.emitters,
64444
+ onAdd = _ref12.onAdd,
64445
+ onRemove = _ref12.onRemove;
64446
+ var _useConfigTokens8 = useConfigTokens(),
64447
+ muted = _useConfigTokens8.muted,
64448
+ hairline = _useConfigTokens8.hairline;
64227
64449
  // Wired-for-this-handler: dedupe defensively (legacy workspaces
64228
64450
  // occasionally contain duplicate entries under the same handler).
64229
64451
  var wiredHere = React.useMemo(function () {
@@ -64260,7 +64482,7 @@ function EventsColumn(_ref11) {
64260
64482
  });
64261
64483
  if (!handlerName) {
64262
64484
  return /*#__PURE__*/jsxRuntime.jsx("div", {
64263
- className: "flex-1 min-w-0 flex items-center justify-center text-sm opacity-60",
64485
+ className: "flex-1 min-w-0 flex items-center justify-center text-sm ".concat(muted),
64264
64486
  children: "Select a handler to view available events."
64265
64487
  });
64266
64488
  }
@@ -64294,7 +64516,7 @@ function EventsColumn(_ref11) {
64294
64516
  jsxRuntime.jsxs("div", {
64295
64517
  className: "flex-1 min-w-0 overflow-hidden flex flex-col",
64296
64518
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
64297
- className: "flex-shrink-0 px-4 py-2 text-xs opacity-60",
64519
+ className: "flex-shrink-0 px-4 pb-3 text-xs border-b ".concat(muted, " ").concat(hairline),
64298
64520
  children: ["Check an event to fire ", /*#__PURE__*/jsxRuntime.jsx("code", {
64299
64521
  className: "text-xs",
64300
64522
  children: handlerName
@@ -64302,22 +64524,21 @@ function EventsColumn(_ref11) {
64302
64524
  className: "font-medium",
64303
64525
  children: receiver.label
64304
64526
  }), "."]
64305
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Divider, {}), /*#__PURE__*/jsxRuntime.jsx("div", {
64306
- className: "flex-1 overflow-y-auto p-4 space-y-5",
64527
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
64528
+ className: "flex-1 overflow-y-auto p-4 flex flex-col gap-3",
64307
64529
  children: emittersForList.length === 0 ? /*#__PURE__*/jsxRuntime.jsx("div", {
64308
- className: "text-sm opacity-60",
64530
+ className: "text-sm ".concat(muted),
64309
64531
  children: "No other widgets in this dashboard emit events."
64310
64532
  }) : emittersForList.map(function (e) {
64311
64533
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
64312
- className: "space-y-1",
64534
+ className: "rounded-lg border px-3 py-2 flex flex-col gap-1 ".concat(hairline),
64313
64535
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
64314
64536
  className: "flex flex-col gap-0.5 mb-1",
64315
64537
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
64316
64538
  className: "text-sm font-semibold",
64317
64539
  children: e.label
64318
- }), (e.widgetRef || e.component) && /*#__PURE__*/jsxRuntime.jsx(DashReact.Caption, {
64319
- block: true,
64320
- className: "font-mono truncate",
64540
+ }), (e.widgetRef || e.component) && /*#__PURE__*/jsxRuntime.jsx("div", {
64541
+ className: "text-xs font-mono truncate ".concat(muted),
64321
64542
  children: (e.widgetRef || e.component) + (e.itemId != null ? "[".concat(e.itemId, "]") : "")
64322
64543
  })]
64323
64544
  }), e.events.map(function (eventName) {
@@ -65165,13 +65386,7 @@ var isDraftId = function isDraftId(id) {
65165
65386
  return typeof id === "string" && id.startsWith(DRAFT_PREFIX);
65166
65387
  };
65167
65388
  var NARROW_PX = 900;
65168
- var DOT = {
65169
- Idle: "bg-gray-500",
65170
- Running: "bg-indigo-400",
65171
- Paused: "bg-gray-400",
65172
- "Needs approval": "bg-amber-400",
65173
- Failed: "bg-red-400"
65174
- };
65389
+ var DOT = STATUS_DOT$2;
65175
65390
  var getWidgetConfig$1 = function getWidgetConfig(name) {
65176
65391
  return name && ComponentManager.config(name) || null;
65177
65392
  };