@trops/dash-core 0.1.434 → 0.1.435

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
@@ -14583,27 +14583,18 @@ var LayoutBuilderConfigModal = function LayoutBuilderConfigModal(_ref) {
14583
14583
  return s.key === activeSection;
14584
14584
  }) || sections[0];
14585
14585
 
14586
- // Scope/package label for the footer so the user can tell which
14587
- // package a widget comes from (ambiguous component names like
14588
- // `ProspectListColumn` can live under either `@ai-built/…` or
14589
- // `@trops/pipeline`). Same derivation order as WidgetCardHeader:
14590
- // widget config id → widget config package → layout item workspace.
14586
+ // Footer label: derive @scope/package straight from the layout
14587
+ // item's scoped component id. Strict no workspace fallback.
14591
14588
  var footerPackageLabel = function () {
14592
- if (!itemSelected) return "";
14593
- var cfg = ComponentManager.config(itemSelected.component, itemSelected);
14594
- var dropTrailingComponent = function dropTrailingComponent(s) {
14595
- if (typeof s !== "string") return "";
14596
- var lastDot = s.lastIndexOf(".");
14597
- return lastDot > 0 ? s.slice(0, lastDot) : s;
14598
- };
14599
- var fromId = dropTrailingComponent((cfg === null || cfg === void 0 ? void 0 : cfg.id) || "");
14600
- if (fromId) return fromId;
14601
- if (cfg !== null && cfg !== void 0 && cfg["package"]) return String(cfg["package"]);
14602
- var ws = itemSelected.workspace;
14603
- if (typeof ws === "string" && ws && ws !== "layout") {
14604
- return ws.startsWith("@") ? ws : "@".concat(ws);
14605
- }
14606
- return "";
14589
+ var scopedId = (itemSelected === null || itemSelected === void 0 ? void 0 : itemSelected.component) || "";
14590
+ if (typeof scopedId !== "string") return "";
14591
+ var parts = scopedId.split(".");
14592
+ if (parts.length !== 3) return "";
14593
+ var _parts = _slicedToArray(parts, 2),
14594
+ scope = _parts[0],
14595
+ pkg = _parts[1];
14596
+ if (!scope || !pkg) return "";
14597
+ return "@".concat(scope, "/").concat(pkg);
14607
14598
  }();
14608
14599
  var componentName = itemSelected ? itemSelected["component"] : "";
14609
14600
  var footerLeftContent = footerPackageLabel ? /*#__PURE__*/jsxRuntime.jsxs("span", {
@@ -18909,29 +18900,21 @@ var WidgetCardHeader = function WidgetCardHeader(_ref) {
18909
18900
  // Get widget name from config or item
18910
18901
  var widgetName = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.displayName) || (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.name) || (widgetItem === null || widgetItem === void 0 ? void 0 : widgetItem.name) || (widgetItem === null || widgetItem === void 0 ? void 0 : widgetItem.component);
18911
18902
 
18912
- // Build a scope/package subtitle so ambiguous component names like
18913
- // `ProspectListColumn` (which might come from `@ai-built/…` or
18914
- // `@trops/pipeline`) are disambiguated in the layout builder. Derives
18915
- // from whatever identity the config / layout item carries:
18916
- // - widgetConfig.id: e.g. "@ai-built/prospectlistcolumn.ProspectListColumn"
18917
- // - widgetConfig.package: e.g. "@ai-built/prospectlistcolumn"
18918
- // - widgetItem.workspace: fallback hint ("ai-built" / "@trops/pipeline")
18919
- // Falls back to empty string so we can skip rendering if we have
18920
- // nothing meaningful beyond the component name itself.
18903
+ // Derive the "@scope/package" label from the layout item's scoped
18904
+ // component id (`scope.package.Component`). Strict the layout item
18905
+ // is the source of truth. If the item isn't scoped (a legacy layout
18906
+ // that LayoutModel couldn't migrate, or a missing widget) the label
18907
+ // is empty rather than guessed from the workspace category.
18921
18908
  var packageLabel = function () {
18922
- var dropTrailingComponent = function dropTrailingComponent(s) {
18923
- if (typeof s !== "string") return "";
18924
- var lastDot = s.lastIndexOf(".");
18925
- return lastDot > 0 ? s.slice(0, lastDot) : s;
18926
- };
18927
- var fromId = dropTrailingComponent((widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.id) || "");
18928
- if (fromId) return fromId;
18929
- if (widgetConfig !== null && widgetConfig !== void 0 && widgetConfig["package"]) return String(widgetConfig["package"]);
18930
- var wsHint = widgetItem === null || widgetItem === void 0 ? void 0 : widgetItem.workspace;
18931
- if (typeof wsHint === "string" && wsHint && wsHint !== "layout") {
18932
- return wsHint.startsWith("@") ? wsHint : "@".concat(wsHint);
18933
- }
18934
- return "";
18909
+ var scopedId = (widgetItem === null || widgetItem === void 0 ? void 0 : widgetItem.component) || (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.id) || "";
18910
+ if (typeof scopedId !== "string") return "";
18911
+ var parts = scopedId.split(".");
18912
+ if (parts.length !== 3) return "";
18913
+ var _parts = _slicedToArray(parts, 2),
18914
+ scope = _parts[0],
18915
+ pkg = _parts[1];
18916
+ if (!scope || !pkg) return "";
18917
+ return "@".concat(scope, "/").concat(pkg);
18935
18918
  }();
18936
18919
 
18937
18920
  // Get provider requirements from widget config (not from item directly)
@@ -27515,10 +27498,10 @@ function addChildToLayoutItem(childComponent, layoutItem, workspace) {
27515
27498
  * widgets share the same bare name
27516
27499
  * @returns {boolean} true if the widget can be rendered
27517
27500
  */
27518
- function isWidgetResolvable(componentKey, data) {
27501
+ function isWidgetResolvable(componentKey) {
27519
27502
  // Layout containers are always resolvable (handled specially by WidgetFactory)
27520
27503
  if (ComponentManager.isLayoutContainer(componentKey)) return true;
27521
- var config = ComponentManager.resolve(componentKey, data);
27504
+ var config = ComponentManager.resolve(componentKey);
27522
27505
  return !!(config && typeof config.component === "function");
27523
27506
  }
27524
27507
 
@@ -27548,6 +27531,52 @@ function isWidgetResolvable(componentKey, data) {
27548
27531
  // isMinOrderForItem
27549
27532
  // }
27550
27533
 
27534
+ /**
27535
+ * One-shot legacy bare-name → canonical scoped-id migration.
27536
+ *
27537
+ * Pre-v0.1.435 dashboards stored layout items with bare component
27538
+ * names (`component: "PipelineKanban"`). Post-v0.1.435 the registry
27539
+ * is keyed strictly by scoped ids (`scope.package.Component`) and
27540
+ * `resolveComponentKey` does no fallback scanning. This helper
27541
+ * bridges the two: at workspace-load time, walk the registry once
27542
+ * and rewrite any bare name that maps unambiguously to a scoped
27543
+ * registration.
27544
+ *
27545
+ * Behavior (deliberately strict):
27546
+ * - Already-scoped (3 dot-separated parts) → return verbatim.
27547
+ * - Bare name with exactly one matching registry key ending in
27548
+ * `.${bareName}` → return the scoped key.
27549
+ * - Zero matches OR multiple matches → return verbatim. The
27550
+ * renderer surfaces `WidgetNotFound` rather than guessing wrong;
27551
+ * the user can resave or republish to fix the layout.
27552
+ *
27553
+ * Should be called once per layout item on workspace load. After the
27554
+ * workspace is saved, every item carries a scoped id and this helper
27555
+ * is a no-op.
27556
+ *
27557
+ * @param {Object} componentMap - The live registry map keyed by scoped ids
27558
+ * @param {string} component - The layout item's `component` field
27559
+ * @returns {string} - The canonical scoped id, or the input unchanged
27560
+ */
27561
+ function migrateBareComponentName(componentMap, component) {
27562
+ if (!componentMap || typeof component !== "string" || !component) {
27563
+ return component;
27564
+ }
27565
+ // Already scoped — fast path. Three dot-separated parts is the
27566
+ // canonical shape (`scope.package.Component`); anything else
27567
+ // (bare names, two-part forms, four-part typos) goes through the
27568
+ // suffix scan.
27569
+ if (component.split(".").length === 3) return component;
27570
+ // Already in the registry under its current key — also a fast path.
27571
+ if (component in componentMap) return component;
27572
+ var suffix = ".".concat(component);
27573
+ var matches = Object.keys(componentMap).filter(function (k) {
27574
+ return k.endsWith(suffix);
27575
+ });
27576
+ if (matches.length === 1) return matches[0];
27577
+ return component;
27578
+ }
27579
+
27551
27580
  function ownKeys$C(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; }
27552
27581
  function _objectSpread$C(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$C(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$C(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
27553
27582
  function _createForOfIteratorHelper$k(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$k(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
@@ -27625,6 +27654,14 @@ var LayoutModel = function LayoutModel(layoutItem, workspaceLayout, dashboardId)
27625
27654
  layout.component = obj["componentName"];
27626
27655
  }
27627
27656
 
27657
+ // Legacy bare-name migration. Pre-v0.1.435 layouts stored
27658
+ // `component: "PipelineKanban"`; the registry is now strictly
27659
+ // keyed by `scope.package.Component`. If the layout item still
27660
+ // carries a bare name AND the registry has exactly one matching
27661
+ // scoped key, rewrite to the scoped form. The next save persists
27662
+ // the migration. Idempotent — already-scoped names pass through.
27663
+ layout.component = migrateBareComponentName(ComponentManager.componentMap(), layout.component);
27664
+
27628
27665
  /**
27629
27666
  * @param {String} direction Layout direction (row|col)
27630
27667
  * @deprecated Use grid layout instead of flexbox direction
@@ -27686,7 +27723,10 @@ var LayoutModel = function LayoutModel(layoutItem, workspaceLayout, dashboardId)
27686
27723
 
27687
27724
  layout.uuid = dashboardId !== undefined ? "".concat(dashboardId, "-").concat(layout["component"], "-").concat(layout.id) : "".concat(layout["component"], "-").concat(layout.id);
27688
27725
 
27689
- /// widget configuration
27726
+ // Resolve widget configuration — strict scoped lookup. By this
27727
+ // point `layout.component` has already been migrated from any
27728
+ // legacy bare name above, so config() either returns the live
27729
+ // entry or null (renderer shows WidgetNotFound).
27690
27730
  var widgetConfig = ComponentManager.config(layout["component"], obj);
27691
27731
  layout.userPrefs = {};
27692
27732
  layout.widgetConfig = widgetConfig;
@@ -27701,16 +27741,6 @@ var LayoutModel = function LayoutModel(layoutItem, workspaceLayout, dashboardId)
27701
27741
  if (Array.isArray(widgetConfig.eventHandlers)) {
27702
27742
  layout.eventHandlers = widgetConfig.eventHandlers;
27703
27743
  }
27704
- // Migrate legacy bare `component` references to the canonical
27705
- // scoped form (`scope.package.Component`). ComponentManager.config
27706
- // returns the resolved scoped key on `widgetConfig.component`, so
27707
- // we just lift it. Idempotent: items already scoped pass through
27708
- // unchanged because resolveComponentKey returns the input verbatim
27709
- // when it's already in the map. Persisted on next save — no
27710
- // separate migration step needed.
27711
- if (typeof widgetConfig.component === "string" && widgetConfig.component && widgetConfig.component !== layout.component) {
27712
- layout.component = widgetConfig.component;
27713
- }
27714
27744
  }
27715
27745
 
27716
27746
  // Merge user-entered config values (from EnhancedWidgetDropdown) into userPrefs
@@ -31396,6 +31426,34 @@ var ContextModel = /*#__PURE__*/function () {
31396
31426
  }]);
31397
31427
  }();
31398
31428
 
31429
+ /**
31430
+ * Resolve a component reference to its registry key.
31431
+ *
31432
+ * Strict exact-match lookup. Layout items carry the canonical scoped
31433
+ * id (`scope.package.Component`); the registry stores entries under
31434
+ * the same key. If the layout item's `component` doesn't match a
31435
+ * registered key exactly, the renderer shows `WidgetNotFound` — there
31436
+ * is no suffix-scan fallback and no `packageId` hint, because both
31437
+ * could silently resolve a typo / legacy bare name to the wrong widget.
31438
+ *
31439
+ * Legacy dashboards that still carry a bare `component` (pre-scope
31440
+ * migration) are handled in `LayoutModel`, which performs a one-shot
31441
+ * suffix-scan rewrite on load. By the time `resolveComponentKey` is
31442
+ * called, every layout item is expected to have a fully scoped id.
31443
+ *
31444
+ * Pure function. No side effects. Stays outside ComponentManager so
31445
+ * it can be tested in isolation without the Models/Layout import chain.
31446
+ *
31447
+ * @param {Object} componentMap - The registry map keyed by scoped ids
31448
+ * @param {string} component - The scoped id from the layout item
31449
+ * @returns {string|null} The matching registry key, or null
31450
+ */
31451
+ function resolveComponentKey(componentMap, component) {
31452
+ if (!componentMap || !component) return null;
31453
+ if (typeof component !== "string") return null;
31454
+ return component in componentMap ? component : null;
31455
+ }
31456
+
31399
31457
  /**
31400
31458
  * scopedComponentId.js
31401
31459
  *
@@ -31462,57 +31520,48 @@ function bareComponentName(idOrName) {
31462
31520
  return parts[parts.length - 1] || "";
31463
31521
  }
31464
31522
 
31523
+ var _componentMap = {};
31524
+ var _containerComponent = null;
31525
+ var _gridContainerComponent = null;
31526
+
31465
31527
  /**
31466
- * Resolve a component name to a registry key. Returns null if no
31467
- * match exists.
31528
+ * Compute the canonical `scope.package.Component` id for a widget
31529
+ * config. Throws if the config doesn't carry enough origin metadata
31530
+ * to derive an id.
31468
31531
  *
31469
- * Pure function — depends only on the passed-in `componentMap` and
31470
- * `data`. Lives outside ComponentManager so it can be tested without
31471
- * pulling in the full Component/Layout import chain (and so other
31472
- * call sites can route through it without circular deps).
31532
+ * Order of precedence:
31533
+ * - `config.id` already scoped (3 dot-separated parts, no leading "@")
31534
+ * - `config.scope` + `config.packageName` + (`config.name` |
31535
+ * `config.component?.displayName` | `config.component?.name`)
31536
+ * - Otherwise throw — the config is missing origin info and would
31537
+ * register under an ambiguous key.
31473
31538
  *
31474
- * Lookup order (the LAYOUT ITEM is the source of truth):
31475
- * 1. EXACT match on `component` covers the new scoped form
31476
- * (`scope.package.X`) and any legacy `.dash.js` that already
31477
- * set `config.id` to a scoped value.
31478
- * 2. If `component` is bare (no dots) AND we have a packageId hint
31479
- * on the layout item, build the scoped id and try that.
31480
- * 3. Bare-name fallback: scan the map for any key ending in
31481
- * `.${component}`. If exactly one matches, use it. If multiple
31482
- * match (the collision case), prefer the one matching the
31483
- * layout item's `packageId` / `_sourcePackage`; otherwise fall
31484
- * through to the first match (deterministic, but also logs a
31485
- * warning so callers can spot the ambiguity).
31486
- *
31487
- * Step (3) is the back-compat path for layouts authored before
31488
- * scoped registration landed. New layouts ALWAYS resolve via step (1).
31539
+ * The `widgetKey` is consulted ONLY when both above paths fail and
31540
+ * the key itself is already a scoped id; this preserves compat with
31541
+ * callers that pass a fully-qualified registration key.
31489
31542
  */
31490
- function resolveComponentKey(componentMap, component, data) {
31491
- if (!componentMap || !component) return null;
31492
- if (component in componentMap) return component;
31493
- if (typeof component !== "string") return null;
31494
- if (component.includes(".")) return null;
31495
- var packageId = (data === null || data === void 0 ? void 0 : data.packageId) || (data === null || data === void 0 ? void 0 : data._sourcePackage) || (data === null || data === void 0 ? void 0 : data.packageName) || null;
31496
- if (packageId) {
31497
- var scoped = makeScopedComponentId(packageId, component);
31498
- if (scoped in componentMap) return scoped;
31499
- }
31500
- var suffix = ".".concat(component);
31501
- var matches = Object.keys(componentMap).filter(function (k) {
31502
- return k.endsWith(suffix);
31503
- });
31504
- if (matches.length === 0) return null;
31505
- if (matches.length === 1) return matches[0];
31506
- if (packageId) {
31507
- var target = makeScopedComponentId(packageId, component);
31508
- if (matches.includes(target)) return target;
31509
- }
31510
- return matches[0];
31543
+ function canonicalScopedId(config, widgetKey) {
31544
+ var looksScoped = function looksScoped(s) {
31545
+ return typeof s === "string" && s.split(".").length === 3 && !s.includes("/");
31546
+ };
31547
+ if (looksScoped(config === null || config === void 0 ? void 0 : config.id)) return config.id;
31548
+ if (looksScoped(widgetKey)) return widgetKey;
31549
+ if (config !== null && config !== void 0 && config.scope && config !== null && config !== void 0 && config.packageName) {
31550
+ var _config$component, _config$component2;
31551
+ var componentName = config.name || ((_config$component = config.component) === null || _config$component === void 0 ? void 0 : _config$component.displayName) || ((_config$component2 = config.component) === null || _config$component2 === void 0 ? void 0 : _config$component2.name) || null;
31552
+ if (componentName) {
31553
+ return makeScopedComponentId("".concat(String(config.scope).replace(/^@/, ""), "/").concat(config.packageName), componentName);
31554
+ }
31555
+ }
31556
+ var dump = JSON.stringify({
31557
+ id: config === null || config === void 0 ? void 0 : config.id,
31558
+ scope: config === null || config === void 0 ? void 0 : config.scope,
31559
+ packageName: config === null || config === void 0 ? void 0 : config.packageName,
31560
+ name: config === null || config === void 0 ? void 0 : config.name,
31561
+ widgetKey: widgetKey
31562
+ });
31563
+ throw new Error("[ComponentManager] Cannot register widget \u2014 missing origin metadata. " + "Need either a scoped `id` (scope.package.Component) or " + "`scope` + `packageName` + `name`. Got: ".concat(dump));
31511
31564
  }
31512
-
31513
- var _componentMap = {};
31514
- var _containerComponent = null;
31515
- var _gridContainerComponent = null;
31516
31565
  var ComponentManager = {
31517
31566
  // _componentMap: {},
31518
31567
 
@@ -31547,39 +31596,50 @@ var ComponentManager = {
31547
31596
  return _componentMap;
31548
31597
  },
31549
31598
  /**
31550
- * Resolve a component name to its registered config — single source
31551
- * of truth for every render-path lookup. Routes through
31552
- * `resolveComponentKey` so legacy bare names (`"ProspectWorkspace"`)
31553
- * still find their registered scoped counterpart
31554
- * (`"ai-built.pipeline.ProspectWorkspace"`). Returns null when the
31555
- * widget isn't registered. Pass the layout item as `data` to use
31556
- * its `packageId` / `_sourcePackage` for disambiguation.
31599
+ * Resolve a component reference to its registered config. Strict
31600
+ * exact-match lookup against the registry. Layout items are
31601
+ * expected to carry the canonical scoped id
31602
+ * (`scope.package.Component`); `LayoutModel` migrates legacy bare
31603
+ * names to the scoped form on dashboard load.
31557
31604
  *
31558
- * @param {string} component
31559
- * @param {object} [data]
31605
+ * Returns null when the widget isn't registered — the renderer then
31606
+ * shows `WidgetNotFound`. There is no fallback.
31607
+ *
31608
+ * @param {string} component - The scoped widget id
31560
31609
  * @returns {object|null} the live registered config, or null
31561
31610
  */
31562
- resolve: function resolve(component, data) {
31611
+ resolve: function resolve(component) {
31563
31612
  var m = _componentMap;
31564
31613
  if (!m) return null;
31565
- var key = resolveComponentKey(m, component, data);
31614
+ var key = resolveComponentKey(m, component);
31566
31615
  return key ? m[key] || null : null;
31567
31616
  },
31568
31617
  /**
31569
- * The method for registering the widget into the Dashboard application
31570
- * This is a requirement for the widget to be included into the Dash
31618
+ * Register a widget config under its canonical scoped id.
31619
+ *
31620
+ * Every widget that enters the registry MUST have a scope.package
31621
+ * .Component id. The id is determined in this order:
31622
+ * 1. `config.id` already in scoped form → trust it.
31623
+ * 2. `config.scope` + `config.packageName` + `config.name` → derive.
31624
+ * 3. Otherwise → throw. Silent fallbacks here are how layouts end
31625
+ * up referencing widgets that were registered under the wrong
31626
+ * key, so we fail loudly at registration instead of producing
31627
+ * a corrupt registry.
31571
31628
  *
31572
- * @param {Object} widgetConfig the widget configuration script created by the developer
31573
- * @param {*} widgetKey the unique id for the widget
31629
+ * `widgetKey` is kept for backwards compatibility with callers that
31630
+ * pass a string key; it is consulted ONLY as a tiebreak when the
31631
+ * config is otherwise complete.
31632
+ *
31633
+ * @param {Object} widgetConfig the widget configuration script
31634
+ * @param {string} [widgetKey] legacy fallback key (informational only)
31635
+ * @throws if origin metadata is missing
31574
31636
  */
31575
31637
  registerWidget: function registerWidget(widgetConfig, widgetKey) {
31576
31638
  var tempComponentMap = this.componentMap();
31577
- // Handle both module exports (widgetConfig.default) and direct config objects
31578
31639
  var config = widgetConfig["default"] || widgetConfig;
31579
- // Register under a single canonical key: config.id (scoped widget ID) if
31580
- // available, otherwise the provided widgetKey. No aliases — one widget, one key.
31581
- var registrationKey = config.id || widgetKey;
31582
- tempComponentMap[registrationKey] = ComponentConfigModel(config);
31640
+ var id = canonicalScopedId(config, widgetKey);
31641
+ config.id = id;
31642
+ tempComponentMap[id] = ComponentConfigModel(config);
31583
31643
  this.setComponentMap(tempComponentMap);
31584
31644
  },
31585
31645
  /**
@@ -31633,15 +31693,14 @@ var ComponentManager = {
31633
31693
  * @returns {Widget} the Widget in the component map
31634
31694
  */
31635
31695
  getComponent: function getComponent(component) {
31636
- var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
31637
31696
  try {
31638
- // console.log("get component");
31639
31697
  if (component && this.componentMap()) {
31640
31698
  if (ComponentManager.isLayoutContainer(component) === false) {
31641
31699
  var m = this.componentMap();
31642
- // Resolve through the scoped/bare lookup pipeline so layouts
31643
- // authored under either format land at the same registry key.
31644
- var resolvedKey = resolveComponentKey(m, component, data);
31700
+ // Strict scoped-id lookup. If the layout item didn't carry
31701
+ // a scoped id, LayoutModel should have migrated it before
31702
+ // we get here.
31703
+ var resolvedKey = resolveComponentKey(m, component);
31645
31704
  var cmp = resolvedKey ? m[resolvedKey] : null;
31646
31705
  if (cmp !== null && cmp !== undefined) {
31647
31706
  cmp["componentName"] = resolvedKey;
@@ -31804,7 +31863,6 @@ var ComponentManager = {
31804
31863
  var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
31805
31864
  try {
31806
31865
  if (component) {
31807
- // console.log("config");
31808
31866
  var requiredFields = {
31809
31867
  type: {
31810
31868
  value: "text"
@@ -31819,35 +31877,19 @@ var ComponentManager = {
31819
31877
  value: ""
31820
31878
  }
31821
31879
  };
31822
-
31823
- // get the component configuration from the map
31824
31880
  var components = this.map();
31825
- var resolvedKey = resolveComponentKey(components, component, data);
31881
+ var resolvedKey = resolveComponentKey(components, component);
31826
31882
  if (resolvedKey && resolvedKey in components) {
31827
- // let c = deepCopy(components['component']);
31828
-
31829
- // we have to make sure that we remove the component if this is a context
31830
-
31831
31883
  var tempComponent = components[resolvedKey];
31832
31884
  delete tempComponent["component"];
31833
31885
  var c = JSON.parse(JSON.stringify(tempComponent));
31834
-
31835
- // Carry the canonical scoped id forward so callers (LayoutModel,
31836
- // ComponentManager.getComponent) can rewrite layout items'
31837
- // `component` to the scoped form on first load.
31838
31886
  c["component"] = resolvedKey;
31839
-
31840
- // if no userConfig key. let's add it for the next step
31841
31887
  if ("userConfig" in c === false) {
31842
31888
  c["userConfig"] = {};
31843
31889
  }
31844
-
31845
- // if (isLayout === false) {
31846
31890
  var userPrefs = {};
31847
- // now we can make sure the configuration is "complete"
31848
31891
  if ("userConfig" in c) {
31849
31892
  Object.keys(c["userConfig"]).forEach(function (key) {
31850
- // check the required fields!
31851
31893
  Object.keys(requiredFields).forEach(function (k) {
31852
31894
  if (k in c["userConfig"][key]) {
31853
31895
  if (k in c["userConfig"][key] === false) {
@@ -31855,16 +31897,21 @@ var ComponentManager = {
31855
31897
  }
31856
31898
  }
31857
31899
  });
31858
- // set the user preferences
31859
31900
  userPrefs[key] = ComponentManager.userPrefsForItem("userPrefs" in data ? data : c, key, c["userConfig"][key]);
31860
31901
  });
31861
31902
  }
31862
-
31863
- // set the user preferences here
31864
31903
  c["userPrefs"] = userPrefs;
31904
+
31905
+ // Identity fields (id/package/scope/...) are forwarded so
31906
+ // consumers can derive the package label without reading
31907
+ // the live registry directly. Without these, callers fall
31908
+ // back to `item.workspace` which is a category, not a
31909
+ // package, and produce labels like `@DashSamples-workspace`.
31865
31910
  return {
31911
+ id: resolvedKey,
31866
31912
  type: c["type"],
31867
31913
  name: c["name"],
31914
+ displayName: c["displayName"],
31868
31915
  workspace: c["workspace"],
31869
31916
  canHaveChildren: c["canHaveChildren"],
31870
31917
  userPrefs: c["userPrefs"],
@@ -31875,7 +31922,13 @@ var ComponentManager = {
31875
31922
  providers: "providers" in c ? c["providers"] : [],
31876
31923
  notifications: "notifications" in c ? c["notifications"] : [],
31877
31924
  scheduledTasks: "scheduledTasks" in c ? c["scheduledTasks"] : [],
31878
- icon: "icon" in c ? c["icon"] : null
31925
+ icon: "icon" in c ? c["icon"] : null,
31926
+ scope: c["scope"],
31927
+ packageName: c["packageName"],
31928
+ "package": c["package"],
31929
+ author: c["author"],
31930
+ version: c["version"],
31931
+ _sourcePackage: c["_sourcePackage"]
31879
31932
  };
31880
31933
  }
31881
31934
  return null;
@@ -55554,26 +55607,23 @@ var DashboardConfigModal = function DashboardConfigModal(_ref) {
55554
55607
  // footer so the same package label shows in every surface.
55555
55608
  var dependencies = React.useMemo(function () {
55556
55609
  var byPackage = new Map();
55557
- var stripTrailingComponent = function stripTrailingComponent(s) {
55558
- if (typeof s !== "string") return "";
55559
- var lastDot = s.lastIndexOf(".");
55560
- return lastDot > 0 ? s.slice(0, lastDot) : s;
55561
- };
55610
+ // Derive the @scope/package label from the layout item's scoped
55611
+ // component id. Layout items are always scoped post-v0.1.435
55612
+ // (LayoutModel migrates legacy bare names on load), so this is
55613
+ // the single source of truth — no config lookup, no workspace
55614
+ // fallback, no heuristics.
55562
55615
  var derivePackage = function derivePackage(item) {
55563
- // The layout item records the exact source package id when the
55564
- // widget was added. If present, trust it — no heuristics. This
55565
- // matches the publish flow's attribution, so the Dependencies
55566
- // tab and the Publish modal always agree.
55616
+ var scopedId = typeof (item === null || item === void 0 ? void 0 : item.component) === "string" ? item.component : "";
55617
+ var parts = scopedId.split(".");
55618
+ if (parts.length === 3) {
55619
+ var _parts = _slicedToArray(parts, 2),
55620
+ scope = _parts[0],
55621
+ pkg = _parts[1];
55622
+ if (scope && pkg) return "@".concat(scope, "/").concat(pkg);
55623
+ }
55624
+ // Defensive: an explicit packageId on the item still wins for
55625
+ // legacy items the migration couldn't auto-resolve.
55567
55626
  if (item !== null && item !== void 0 && item.packageId) return String(item.packageId);
55568
- var cfg = typeof getWidgetConfig === "function" ? getWidgetConfig(item.component) : null;
55569
- if (cfg !== null && cfg !== void 0 && cfg._sourcePackage) return String(cfg._sourcePackage);
55570
- var fromId = stripTrailingComponent((cfg === null || cfg === void 0 ? void 0 : cfg.id) || "");
55571
- if (fromId) return fromId;
55572
- if (cfg !== null && cfg !== void 0 && cfg["package"]) return String(cfg["package"]);
55573
- var ws = item === null || item === void 0 ? void 0 : item.workspace;
55574
- if (typeof ws === "string" && ws && ws !== "layout") {
55575
- return ws.startsWith("@") ? ws : "@".concat(ws);
55576
- }
55577
55627
  return "(unknown)";
55578
55628
  };
55579
55629