@memberjunction/ng-dashboards 5.35.0 → 5.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.js +3 -3
  2. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  3. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts +22 -1
  4. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
  5. package/dist/AI/components/analytics/ai-analytics-resource.component.js +157 -137
  6. package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
  7. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +28 -0
  8. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  9. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +2075 -2068
  10. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  11. package/dist/AI/components/models/model-management.component.js +4 -4
  12. package/dist/AI/components/models/model-management.component.js.map +1 -1
  13. package/dist/AI/components/prompts/prompt-management.component.js +3 -3
  14. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  15. package/dist/AI/components/tags/tags-resource.component.d.ts +15 -0
  16. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  17. package/dist/AI/components/tags/tags-resource.component.js +1411 -1424
  18. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  19. package/dist/APIKeys/api-keys-resource.component.d.ts +12 -8
  20. package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
  21. package/dist/APIKeys/api-keys-resource.component.js +329 -371
  22. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  23. package/dist/Actions/components/actions-overview.component.js +137 -142
  24. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  25. package/dist/Actions/components/execution-monitoring.component.js +111 -116
  26. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  27. package/dist/Admin/admin-data-schema.component.js +13 -65
  28. package/dist/Admin/admin-data-schema.component.js.map +1 -1
  29. package/dist/Admin/admin-dev-tools-resource.component.js +13 -65
  30. package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
  31. package/dist/Admin/admin-identity-access.component.js +13 -65
  32. package/dist/Admin/admin-identity-access.component.js.map +1 -1
  33. package/dist/Admin/admin-monitoring.component.js +13 -65
  34. package/dist/Admin/admin-monitoring.component.js.map +1 -1
  35. package/dist/Admin/base-admin-container.component.d.ts +9 -7
  36. package/dist/Admin/base-admin-container.component.d.ts.map +1 -1
  37. package/dist/Admin/base-admin-container.component.js +26 -17
  38. package/dist/Admin/base-admin-container.component.js.map +1 -1
  39. package/dist/ApplicationRoles/application-roles-resource.component.js +74 -67
  40. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
  41. package/dist/Communication/communication-new-message-resource.component.d.ts +93 -0
  42. package/dist/Communication/communication-new-message-resource.component.d.ts.map +1 -0
  43. package/dist/Communication/communication-new-message-resource.component.js +661 -0
  44. package/dist/Communication/communication-new-message-resource.component.js.map +1 -0
  45. package/dist/Credentials/components/credentials-categories-resource.component.js +152 -159
  46. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  47. package/dist/Credentials/components/credentials-types-resource.component.js +151 -155
  48. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  49. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +20 -21
  50. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js.map +1 -1
  51. package/dist/DatabaseDesigner/components/entity-list.component.d.ts +2 -0
  52. package/dist/DatabaseDesigner/components/entity-list.component.d.ts.map +1 -1
  53. package/dist/DatabaseDesigner/components/entity-list.component.js +131 -125
  54. package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
  55. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +1 -1
  56. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
  57. package/dist/DatabaseDesigner/database-designer-dashboards.module.js +7 -1
  58. package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
  59. package/dist/DevTools/app-state-inspector.component.d.ts +5 -0
  60. package/dist/DevTools/app-state-inspector.component.d.ts.map +1 -1
  61. package/dist/DevTools/app-state-inspector.component.js +46 -72
  62. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  63. package/dist/DevTools/class-registry.component.js +88 -100
  64. package/dist/DevTools/class-registry.component.js.map +1 -1
  65. package/dist/DevTools/event-monitor.component.js +158 -168
  66. package/dist/DevTools/event-monitor.component.js.map +1 -1
  67. package/dist/DevTools/graphql-console.component.js +257 -264
  68. package/dist/DevTools/graphql-console.component.js.map +1 -1
  69. package/dist/DevTools/layout-inspector.component.d.ts +5 -0
  70. package/dist/DevTools/layout-inspector.component.d.ts.map +1 -1
  71. package/dist/DevTools/layout-inspector.component.js +46 -64
  72. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  73. package/dist/DevTools/lazy-module-status.component.js +75 -84
  74. package/dist/DevTools/lazy-module-status.component.js.map +1 -1
  75. package/dist/DevTools/settings-explorer.component.js +76 -85
  76. package/dist/DevTools/settings-explorer.component.js.map +1 -1
  77. package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts +2 -0
  78. package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts.map +1 -1
  79. package/dist/EntityAdmin/entity-admin-dashboard.component.js +7 -3
  80. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  81. package/dist/Integration/components/activity/activity.component.js +97 -99
  82. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  83. package/dist/Integration/components/connections/connections.component.js +842 -855
  84. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  85. package/dist/Integration/components/pipelines/pipelines.component.js +502 -517
  86. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  87. package/dist/Integration/components/schedules/schedules.component.js +78 -89
  88. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  89. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +5 -0
  90. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  91. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +1120 -1128
  92. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  93. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +11 -0
  94. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  95. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +606 -661
  96. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  97. package/dist/Lists/components/lists-browse-resource.component.d.ts +102 -0
  98. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  99. package/dist/Lists/components/lists-browse-resource.component.js +1179 -504
  100. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  101. package/dist/Lists/components/lists-operations-resource.component.d.ts +133 -3
  102. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  103. package/dist/Lists/components/lists-operations-resource.component.js +1527 -327
  104. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  105. package/dist/Lists/components/lists-shared-with-me-resource.component.d.ts +29 -0
  106. package/dist/Lists/components/lists-shared-with-me-resource.component.d.ts.map +1 -0
  107. package/dist/Lists/components/lists-shared-with-me-resource.component.js +77 -0
  108. package/dist/Lists/components/lists-shared-with-me-resource.component.js.map +1 -0
  109. package/dist/Lists/components/venn-diagram/venn-diagram.component.d.ts +6 -0
  110. package/dist/Lists/components/venn-diagram/venn-diagram.component.d.ts.map +1 -1
  111. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +35 -7
  112. package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
  113. package/dist/Lists/index.d.ts +1 -0
  114. package/dist/Lists/index.d.ts.map +1 -1
  115. package/dist/Lists/index.js +1 -0
  116. package/dist/Lists/index.js.map +1 -1
  117. package/dist/Lists/services/list-set-operations.service.d.ts +93 -2
  118. package/dist/Lists/services/list-set-operations.service.d.ts.map +1 -1
  119. package/dist/Lists/services/list-set-operations.service.js +236 -10
  120. package/dist/Lists/services/list-set-operations.service.js.map +1 -1
  121. package/dist/MCP/mcp-dashboard.component.js +19 -19
  122. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  123. package/dist/Scheduling/scheduling-dashboard.component.js +58 -60
  124. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  125. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +13 -3
  126. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  127. package/dist/SystemDiagnostics/system-diagnostics.component.js +1007 -1252
  128. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  129. package/dist/Testing/components/testing-explorer.component.d.ts +31 -6
  130. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  131. package/dist/Testing/components/testing-explorer.component.js +543 -629
  132. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  133. package/dist/Testing/testing-dashboard.component.js +50 -49
  134. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  135. package/dist/ai-dashboards.module.d.ts +1 -1
  136. package/dist/ai-dashboards.module.d.ts.map +1 -1
  137. package/dist/ai-dashboards.module.js +16 -1
  138. package/dist/ai-dashboards.module.js.map +1 -1
  139. package/dist/communication-dashboards.module.d.ts +9 -7
  140. package/dist/communication-dashboards.module.d.ts.map +1 -1
  141. package/dist/communication-dashboards.module.js +13 -4
  142. package/dist/communication-dashboards.module.js.map +1 -1
  143. package/dist/core-dashboards.module.d.ts +1 -1
  144. package/dist/core-dashboards.module.d.ts.map +1 -1
  145. package/dist/core-dashboards.module.js +16 -1
  146. package/dist/core-dashboards.module.js.map +1 -1
  147. package/dist/lists-dashboards.module.d.ts +10 -9
  148. package/dist/lists-dashboards.module.d.ts.map +1 -1
  149. package/dist/lists-dashboards.module.js +13 -2
  150. package/dist/lists-dashboards.module.js.map +1 -1
  151. package/dist/public-api.d.ts +1 -0
  152. package/dist/public-api.d.ts.map +1 -1
  153. package/dist/public-api.js +1 -0
  154. package/dist/public-api.js.map +1 -1
  155. package/dist/testing-dashboards.module.d.ts +1 -1
  156. package/dist/testing-dashboards.module.d.ts.map +1 -1
  157. package/dist/testing-dashboards.module.js +13 -1
  158. package/dist/testing-dashboards.module.js.map +1 -1
  159. package/package.json +53 -52
@@ -11,30 +11,8 @@ import { DevToolsPrefs } from './dev-tools-prefs';
11
11
  import * as i0 from "@angular/core";
12
12
  import * as i1 from "@memberjunction/ng-base-application";
13
13
  import * as i2 from "@angular/forms";
14
- import * as i3 from "@memberjunction/ng-code-editor";
15
- const _forTrack0 = ($index, $item) => $item.id;
16
- function LayoutInspectorComponent_For_22_Template(rf, ctx) { if (rf & 1) {
17
- const _r1 = i0.ɵɵgetCurrentView();
18
- i0.ɵɵelementStart(0, "button", 23);
19
- i0.ɵɵlistener("click", function LayoutInspectorComponent_For_22_Template_button_click_0_listener() { const section_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSectionClick(section_r2)); });
20
- i0.ɵɵelement(1, "i", 24);
21
- i0.ɵɵelementStart(2, "div", 25)(3, "div", 26);
22
- i0.ɵɵtext(4);
23
- i0.ɵɵelementEnd();
24
- i0.ɵɵelementStart(5, "div", 27);
25
- i0.ɵɵtext(6);
26
- i0.ɵɵelementEnd()()();
27
- } if (rf & 2) {
28
- const section_r2 = ctx.$implicit;
29
- const ctx_r2 = i0.ɵɵnextContext();
30
- i0.ɵɵclassProp("mj-inspector__nav-item--active", ctx_r2.ActiveSection === section_r2.id);
31
- i0.ɵɵadvance();
32
- i0.ɵɵclassMap(section_r2.icon);
33
- i0.ɵɵadvance(3);
34
- i0.ɵɵtextInterpolate(section_r2.label);
35
- i0.ɵɵadvance(2);
36
- i0.ɵɵtextInterpolate(section_r2.description);
37
- } }
14
+ import * as i3 from "@memberjunction/ng-ui-components";
15
+ import * as i4 from "@memberjunction/ng-code-editor";
38
16
  /**
39
17
  * Layout Inspector — read-only view of the current workspace + Golden Layout
40
18
  * configuration. Replaces the legacy "Log Layout (Debug)" user-menu item that
@@ -71,6 +49,21 @@ let LayoutInspectorComponent = class LayoutInspectorComponent extends BaseResour
71
49
  }
72
50
  async GetResourceDisplayName() { return 'Layout Inspector'; }
73
51
  async GetResourceIconClass() { return 'fa-solid fa-table-columns'; }
52
+ /** Sections rendered as horizontal tabs in the chrome's [toolbar] slot. */
53
+ get tabsConfig() {
54
+ return this.Sections.map(s => ({
55
+ key: s.id,
56
+ label: s.label,
57
+ icon: s.icon
58
+ }));
59
+ }
60
+ /** Adapter for `<mj-tab-nav>`'s string-typed `(TabChange)` output. */
61
+ onTabChange(key) {
62
+ const section = this.Sections.find(s => s.id === key);
63
+ if (section) {
64
+ this.OnSectionClick(section);
65
+ }
66
+ }
74
67
  OnSectionClick(section) {
75
68
  if (this.ActiveSection === section.id)
76
69
  return;
@@ -140,61 +133,50 @@ let LayoutInspectorComponent = class LayoutInspectorComponent extends BaseResour
140
133
  return value;
141
134
  }
142
135
  static ɵfac = function LayoutInspectorComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LayoutInspectorComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.WorkspaceStateManager), i0.ɵɵdirectiveInject(i1.GoldenLayoutManager)); };
143
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LayoutInspectorComponent, selectors: [["mj-layout-inspector"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 31, vars: 14, consts: [[1, "mj-inspector"], [1, "mj-inspector__header"], [1, "mj-inspector__header-icon"], [1, "fa-solid", "fa-table-columns"], [1, "mj-inspector__header-title"], [1, "mj-inspector__header-sub"], [1, "mj-inspector__header-spacer"], [1, "mj-inspector__header-actions"], ["type", "button", "title", "Refresh", 1, "mj-inspector__btn", 3, "click"], [1, "fa-solid", "fa-rotate"], ["type", "button", 1, "mj-inspector__btn", 3, "click", "title"], [1, "fa-solid"], ["type", "button", "title", "Download as JSON", 1, "mj-inspector__btn", 3, "click"], [1, "fa-solid", "fa-download"], [1, "mj-inspector__body"], [1, "mj-inspector__sidebar"], ["type", "button", 1, "mj-inspector__nav-item", 3, "mj-inspector__nav-item--active"], [1, "mj-inspector__content"], [1, "mj-inspector__content-head"], [1, "mj-inspector__content-title"], [1, "mj-inspector__content-meta"], [1, "mj-inspector__editor"], [3, "ngModelChange", "ngModel", "language", "readonly", "lineWrapping"], ["type", "button", 1, "mj-inspector__nav-item", 3, "click"], [1, "mj-inspector__nav-icon"], [1, "mj-inspector__nav-text"], [1, "mj-inspector__nav-label"], [1, "mj-inspector__nav-desc"]], template: function LayoutInspectorComponent_Template(rf, ctx) { if (rf & 1) {
144
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
145
- i0.ɵɵelement(3, "i", 3);
136
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LayoutInspectorComponent, selectors: [["mj-layout-inspector"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 19, vars: 16, consts: [[1, "mj-inspector", "mj-inspector--solo"], ["Role", "region", "AriaLabel", "Layout inspector", "Title", "Layout Inspector", "Subtitle", "Workspace + Golden Layout configuration"], ["actions", ""], [3, "Clicked", "Loading"], ["mjButton", "", "size", "sm", 3, "click", "variant", "title"], ["aria-hidden", "true", 1, "fa-solid"], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Download as JSON", "aria-label", "Download as JSON", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-download"], ["toolbar", ""], [3, "TabChange", "Tabs", "ActiveKey"], [1, "mj-inspector__content"], [1, "mj-inspector__content-head"], [1, "mj-inspector__content-title"], [1, "mj-inspector__content-meta"], [1, "mj-inspector__editor"], [3, "ngModelChange", "ngModel", "language", "readonly", "lineWrapping"]], template: function LayoutInspectorComponent_Template(rf, ctx) { if (rf & 1) {
137
+ i0.ɵɵelementStart(0, "div", 0)(1, "mj-page-header-interior", 1)(2, "div", 2)(3, "mj-refresh-button", 3);
138
+ i0.ɵɵlistener("Clicked", function LayoutInspectorComponent_Template_mj_refresh_button_Clicked_3_listener() { return ctx.refresh(); });
146
139
  i0.ɵɵelementEnd();
147
- i0.ɵɵelementStart(4, "div")(5, "h3", 4);
148
- i0.ɵɵtext(6, "Layout Inspector");
140
+ i0.ɵɵelementStart(4, "button", 4);
141
+ i0.ɵɵlistener("click", function LayoutInspectorComponent_Template_button_click_4_listener() { return ctx.OnCopy(); });
142
+ i0.ɵɵelement(5, "i", 5);
143
+ i0.ɵɵtext(6);
149
144
  i0.ɵɵelementEnd();
150
- i0.ɵɵelementStart(7, "div", 5);
151
- i0.ɵɵtext(8, "Workspace + Golden Layout configuration");
145
+ i0.ɵɵelementStart(7, "button", 6);
146
+ i0.ɵɵlistener("click", function LayoutInspectorComponent_Template_button_click_7_listener() { return ctx.OnDownload(); });
147
+ i0.ɵɵelement(8, "i", 7);
152
148
  i0.ɵɵelementEnd()();
153
- i0.ɵɵelement(9, "span", 6);
154
- i0.ɵɵelementStart(10, "div", 7)(11, "button", 8);
155
- i0.ɵɵlistener("click", function LayoutInspectorComponent_Template_button_click_11_listener() { return ctx.refresh(); });
156
- i0.ɵɵelement(12, "i", 9);
157
- i0.ɵɵtext(13, " Refresh ");
158
- i0.ɵɵelementEnd();
159
- i0.ɵɵelementStart(14, "button", 10);
160
- i0.ɵɵlistener("click", function LayoutInspectorComponent_Template_button_click_14_listener() { return ctx.OnCopy(); });
161
- i0.ɵɵelement(15, "i", 11);
162
- i0.ɵɵtext(16);
163
- i0.ɵɵelementEnd();
164
- i0.ɵɵelementStart(17, "button", 12);
165
- i0.ɵɵlistener("click", function LayoutInspectorComponent_Template_button_click_17_listener() { return ctx.OnDownload(); });
166
- i0.ɵɵelement(18, "i", 13);
149
+ i0.ɵɵelementStart(9, "div", 8)(10, "mj-tab-nav", 9);
150
+ i0.ɵɵlistener("TabChange", function LayoutInspectorComponent_Template_mj_tab_nav_TabChange_10_listener($event) { return ctx.onTabChange($event); });
167
151
  i0.ɵɵelementEnd()()();
168
- i0.ɵɵelementStart(19, "div", 14)(20, "aside", 15);
169
- i0.ɵɵrepeaterCreate(21, LayoutInspectorComponent_For_22_Template, 7, 6, "button", 16, _forTrack0);
170
- i0.ɵɵelementEnd();
171
- i0.ɵɵelementStart(23, "div", 17)(24, "div", 18)(25, "h4", 19);
172
- i0.ɵɵtext(26);
152
+ i0.ɵɵelementStart(11, "div", 10)(12, "div", 11)(13, "h4", 12);
153
+ i0.ɵɵtext(14);
173
154
  i0.ɵɵelementEnd();
174
- i0.ɵɵelementStart(27, "span", 20);
175
- i0.ɵɵtext(28);
155
+ i0.ɵɵelementStart(15, "span", 13);
156
+ i0.ɵɵtext(16);
176
157
  i0.ɵɵelementEnd()();
177
- i0.ɵɵelementStart(29, "div", 21)(30, "mj-code-editor", 22);
178
- i0.ɵɵtwoWayListener("ngModelChange", function LayoutInspectorComponent_Template_mj_code_editor_ngModelChange_30_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.LayoutJson, $event) || (ctx.LayoutJson = $event); return $event; });
179
- i0.ɵɵelementEnd()()()()();
158
+ i0.ɵɵelementStart(17, "div", 14)(18, "mj-code-editor", 15);
159
+ i0.ɵɵtwoWayListener("ngModelChange", function LayoutInspectorComponent_Template_mj_code_editor_ngModelChange_18_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.LayoutJson, $event) || (ctx.LayoutJson = $event); return $event; });
160
+ i0.ɵɵelementEnd()()()();
180
161
  } if (rf & 2) {
181
- i0.ɵɵadvance(14);
182
- i0.ɵɵclassProp("mj-inspector__btn--success", ctx.CopyConfirmed);
183
- i0.ɵɵproperty("title", ctx.CopyConfirmed ? "Copied" : "Copy JSON");
162
+ i0.ɵɵadvance(3);
163
+ i0.ɵɵproperty("Loading", false);
164
+ i0.ɵɵadvance();
165
+ i0.ɵɵproperty("variant", ctx.CopyConfirmed ? "success" : "secondary")("title", ctx.CopyConfirmed ? "Copied" : "Copy JSON");
184
166
  i0.ɵɵadvance();
185
167
  i0.ɵɵclassProp("fa-clipboard", !ctx.CopyConfirmed)("fa-check", ctx.CopyConfirmed);
186
168
  i0.ɵɵadvance();
187
169
  i0.ɵɵtextInterpolate1(" ", ctx.CopyConfirmed ? "Copied" : "Copy", " ");
188
- i0.ɵɵadvance(5);
189
- i0.ɵɵrepeater(ctx.Sections);
190
- i0.ɵɵadvance(5);
170
+ i0.ɵɵadvance(4);
171
+ i0.ɵɵproperty("Tabs", ctx.tabsConfig)("ActiveKey", ctx.ActiveSection);
172
+ i0.ɵɵadvance(4);
191
173
  i0.ɵɵtextInterpolate(ctx.SectionLabel);
192
174
  i0.ɵɵadvance(2);
193
175
  i0.ɵɵtextInterpolate1("Refreshed ", ctx.LastRefreshedLabel);
194
176
  i0.ɵɵadvance(2);
195
177
  i0.ɵɵtwoWayProperty("ngModel", ctx.LayoutJson);
196
178
  i0.ɵɵproperty("language", "json")("readonly", true)("lineWrapping", true);
197
- } }, dependencies: [i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent], styles: ["[_nghost-%COMP%] { display: block; height: 100%; }\n\n.mj-inspector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n\n\n.mj-inspector__header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.mj-inspector__header-icon[_ngcontent-%COMP%] {\n width: 36px; height: 36px;\n border-radius: 9px;\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: white;\n display: flex; align-items: center; justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n}\n.mj-inspector__header-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n letter-spacing: -0.2px;\n}\n.mj-inspector__header-sub[_ngcontent-%COMP%] {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n.mj-inspector__header-spacer[_ngcontent-%COMP%] { flex: 1; }\n.mj-inspector__header-actions[_ngcontent-%COMP%] {\n display: flex; gap: 6px;\n}\n.mj-inspector__btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: 7px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.15s;\n}\n.mj-inspector__btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__btn--success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-border-default));\n}\n\n\n\n.mj-inspector__body[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n.mj-inspector__sidebar[_ngcontent-%COMP%] {\n width: 220px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n overflow-y: auto;\n flex-shrink: 0;\n padding: 8px;\n}\n.mj-inspector__nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.12s;\n margin-bottom: 2px;\n font-family: inherit;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n text-align: left;\n width: 100%;\n}\n.mj-inspector__nav-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.mj-inspector__nav-item--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__nav-item--active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n}\n.mj-inspector__nav-icon[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n}\n.mj-inspector__nav-text[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n.mj-inspector__nav-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n}\n.mj-inspector__nav-desc[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n}\n.mj-inspector__nav-item--active[_ngcontent-%COMP%] .mj-inspector__nav-desc[_ngcontent-%COMP%] {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n}\n\n\n\n.mj-inspector__content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n.mj-inspector__content-head[_ngcontent-%COMP%] {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--mj-bg-surface-card);\n}\n.mj-inspector__content-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-inspector__content-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.mj-inspector__editor[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.mj-inspector__editor[_ngcontent-%COMP%] mj-code-editor[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: block;\n}\n\n\n\n.mj-inspector__empty[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n@media (max-width: 700px) {\n .mj-inspector__body[_ngcontent-%COMP%] { flex-direction: column; }\n .mj-inspector__sidebar[_ngcontent-%COMP%] {\n width: 100%;\n height: auto;\n max-height: 200px;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n .mj-inspector__nav-item[_ngcontent-%COMP%] { flex: 1 1 calc(50% - 8px); margin-bottom: 0; }\n .mj-inspector__nav-desc[_ngcontent-%COMP%] { display: none; }\n .mj-inspector__header[_ngcontent-%COMP%] { padding: 12px 14px; gap: 10px; }\n}"] });
179
+ } }, dependencies: [i2.NgControlStatus, i2.NgModel, i3.MJButtonDirective, i3.MJPageHeaderInteriorComponent, i3.MJRefreshButtonComponent, i3.MJTabNavComponent, i4.CodeEditorComponent], styles: ["[_nghost-%COMP%] { display: block; height: 100%; }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.mj-inspector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n\n\n.mj-inspector__content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n.mj-inspector__content-head[_ngcontent-%COMP%] {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--mj-bg-surface-card);\n}\n.mj-inspector__content-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-inspector__content-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.mj-inspector__editor[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.mj-inspector__editor[_ngcontent-%COMP%] mj-code-editor[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: block;\n}\n\n\n\n.mj-inspector__empty[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}"] });
198
180
  };
199
181
  LayoutInspectorComponent = __decorate([
200
182
  RegisterClass(BaseResourceComponent, 'LayoutInspector')
@@ -202,7 +184,7 @@ LayoutInspectorComponent = __decorate([
202
184
  export { LayoutInspectorComponent };
203
185
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LayoutInspectorComponent, [{
204
186
  type: Component,
205
- args: [{ standalone: false, selector: 'mj-layout-inspector', template: "<div class=\"mj-inspector\">\n <div class=\"mj-inspector__header\">\n <div class=\"mj-inspector__header-icon\"><i class=\"fa-solid fa-table-columns\"></i></div>\n <div>\n <h3 class=\"mj-inspector__header-title\">Layout Inspector</h3>\n <div class=\"mj-inspector__header-sub\">Workspace + Golden Layout configuration</div>\n </div>\n <span class=\"mj-inspector__header-spacer\"></span>\n <div class=\"mj-inspector__header-actions\">\n <button class=\"mj-inspector__btn\" type=\"button\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\"></i> Refresh\n </button>\n <button class=\"mj-inspector__btn\"\n [class.mj-inspector__btn--success]=\"CopyConfirmed\"\n type=\"button\" (click)=\"OnCopy()\"\n [title]=\"CopyConfirmed ? 'Copied' : 'Copy JSON'\">\n <i class=\"fa-solid\" [class.fa-clipboard]=\"!CopyConfirmed\" [class.fa-check]=\"CopyConfirmed\"></i>\n {{ CopyConfirmed ? 'Copied' : 'Copy' }}\n </button>\n <button class=\"mj-inspector__btn\" type=\"button\" (click)=\"OnDownload()\" title=\"Download as JSON\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n </div>\n </div>\n\n <div class=\"mj-inspector__body\">\n <aside class=\"mj-inspector__sidebar\">\n @for (section of Sections; track section.id) {\n <button type=\"button\"\n class=\"mj-inspector__nav-item\"\n [class.mj-inspector__nav-item--active]=\"ActiveSection === section.id\"\n (click)=\"OnSectionClick(section)\">\n <i class=\"mj-inspector__nav-icon\" [class]=\"section.icon\"></i>\n <div class=\"mj-inspector__nav-text\">\n <div class=\"mj-inspector__nav-label\">{{ section.label }}</div>\n <div class=\"mj-inspector__nav-desc\">{{ section.description }}</div>\n </div>\n </button>\n }\n </aside>\n\n <div class=\"mj-inspector__content\">\n <div class=\"mj-inspector__content-head\">\n <h4 class=\"mj-inspector__content-title\">{{ SectionLabel }}</h4>\n <span class=\"mj-inspector__content-meta\">Refreshed {{ LastRefreshedLabel }}</span>\n </div>\n <div class=\"mj-inspector__editor\">\n <mj-code-editor\n [(ngModel)]=\"LayoutJson\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host { display: block; height: 100%; }\n\n.mj-inspector {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n/* Header */\n.mj-inspector__header {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.mj-inspector__header-icon {\n width: 36px; height: 36px;\n border-radius: 9px;\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: white;\n display: flex; align-items: center; justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n}\n.mj-inspector__header-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n letter-spacing: -0.2px;\n}\n.mj-inspector__header-sub {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n.mj-inspector__header-spacer { flex: 1; }\n.mj-inspector__header-actions {\n display: flex; gap: 6px;\n}\n.mj-inspector__btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: 7px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.15s;\n}\n.mj-inspector__btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__btn--success {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-border-default));\n}\n\n/* Layout: sidebar + content */\n.mj-inspector__body {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n.mj-inspector__sidebar {\n width: 220px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n overflow-y: auto;\n flex-shrink: 0;\n padding: 8px;\n}\n.mj-inspector__nav-item {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.12s;\n margin-bottom: 2px;\n font-family: inherit;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n text-align: left;\n width: 100%;\n}\n.mj-inspector__nav-item:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.mj-inspector__nav-item--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__nav-item--active:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n}\n.mj-inspector__nav-icon {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n}\n.mj-inspector__nav-text { flex: 1; min-width: 0; }\n.mj-inspector__nav-label {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n}\n.mj-inspector__nav-desc {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n}\n.mj-inspector__nav-item--active .mj-inspector__nav-desc {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n}\n\n/* Content area */\n.mj-inspector__content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n.mj-inspector__content-head {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--mj-bg-surface-card);\n}\n.mj-inspector__content-title {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-inspector__content-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.mj-inspector__editor {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.mj-inspector__editor mj-code-editor {\n flex: 1;\n min-height: 0;\n display: block;\n}\n\n/* Empty state */\n.mj-inspector__empty {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n@media (max-width: 700px) {\n .mj-inspector__body { flex-direction: column; }\n .mj-inspector__sidebar {\n width: 100%;\n height: auto;\n max-height: 200px;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n .mj-inspector__nav-item { flex: 1 1 calc(50% - 8px); margin-bottom: 0; }\n .mj-inspector__nav-desc { display: none; }\n .mj-inspector__header { padding: 12px 14px; gap: 10px; }\n}\n"] }]
187
+ args: [{ standalone: false, selector: 'mj-layout-inspector', template: "<div class=\"mj-inspector mj-inspector--solo\">\n <mj-page-header-interior\n Role=\"region\"\n AriaLabel=\"Layout inspector\"\n Title=\"Layout Inspector\"\n Subtitle=\"Workspace + Golden Layout configuration\">\n <div actions>\n <mj-refresh-button [Loading]=\"false\" (Clicked)=\"refresh()\"></mj-refresh-button>\n <button mjButton\n [variant]=\"CopyConfirmed ? 'success' : 'secondary'\"\n size=\"sm\"\n (click)=\"OnCopy()\"\n [title]=\"CopyConfirmed ? 'Copied' : 'Copy JSON'\">\n <i class=\"fa-solid\" [class.fa-clipboard]=\"!CopyConfirmed\" [class.fa-check]=\"CopyConfirmed\" aria-hidden=\"true\"></i>\n {{ CopyConfirmed ? 'Copied' : 'Copy' }}\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnDownload()\" title=\"Download as JSON\" aria-label=\"Download as JSON\">\n <i class=\"fa-solid fa-download\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div toolbar>\n <mj-tab-nav\n [Tabs]=\"tabsConfig\"\n [ActiveKey]=\"ActiveSection\"\n (TabChange)=\"onTabChange($event)\">\n </mj-tab-nav>\n </div>\n </mj-page-header-interior>\n\n <div class=\"mj-inspector__content\">\n <div class=\"mj-inspector__content-head\">\n <h4 class=\"mj-inspector__content-title\">{{ SectionLabel }}</h4>\n <span class=\"mj-inspector__content-meta\">Refreshed {{ LastRefreshedLabel }}</span>\n </div>\n <div class=\"mj-inspector__editor\">\n <mj-code-editor\n [(ngModel)]=\"LayoutJson\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n</div>\n", styles: [":host { display: block; height: 100%; }\n\n/*\n Inspector shell \u2014 each Dev Tools sub-page wraps its body in .mj-inspector. The\n chrome (title icon, title, subtitle, action buttons) was previously rendered\n via .mj-inspector__header*, but that's been replaced by <mj-page-header-interior>\n in every inspector template. Action buttons now use the mjButton directive\n (variant=\"secondary\" / \"success\") so they inherit global button styling. App\n State + Layout inspectors used to carry an inner left rail (.mj-inspector__body\n + __sidebar + __nav-item) for L2 sections; that rail was retired 2026-05-19 in\n favor of <mj-tab-nav> projected into the chrome's [toolbar] slot, matching\n SystemDiagnostics and the API Keys tab strip. All inspectors are now \"solo\"\n mode (no sidebar).\n*/\n.mj-inspector {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n/* Content area */\n.mj-inspector__content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n.mj-inspector__content-head {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--mj-bg-surface-card);\n}\n.mj-inspector__content-title {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-inspector__content-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.mj-inspector__editor {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.mj-inspector__editor mj-code-editor {\n flex: 1;\n min-height: 0;\n display: block;\n}\n\n/* Empty state */\n.mj-inspector__empty {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n"] }]
206
188
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.WorkspaceStateManager }, { type: i1.GoldenLayoutManager }], null); })();
207
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LayoutInspectorComponent, { className: "LayoutInspectorComponent", filePath: "src/DevTools/layout-inspector.component.ts", lineNumber: 26 }); })();
189
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LayoutInspectorComponent, { className: "LayoutInspectorComponent", filePath: "src/DevTools/layout-inspector.component.ts", lineNumber: 27 }); })();
208
190
  //# sourceMappingURL=layout-inspector.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-inspector.component.js","sourceRoot":"","sources":["../../src/DevTools/layout-inspector.component.ts","../../src/DevTools/layout-inspector.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RegisterClass } from '@memberjunction/global';\nimport { WorkspaceStateManager, GoldenLayoutManager } from '@memberjunction/ng-base-application';\nimport { DevToolsPrefs } from './dev-tools-prefs';\n\ninterface LayoutSection {\n id: 'workspace' | 'golden';\n label: string;\n icon: string;\n description: string;\n}\n\n/**\n * Layout Inspector — read-only view of the current workspace + Golden Layout\n * configuration. Replaces the legacy \"Log Layout (Debug)\" user-menu item that\n * only printed to console.\n */\n@RegisterClass(BaseResourceComponent, 'LayoutInspector')\n@Component({\n standalone: false,\n selector: 'mj-layout-inspector',\n templateUrl: './layout-inspector.component.html',\n styleUrls: ['./inspector-shared.css']\n})\nexport class LayoutInspectorComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n\n public Sections: LayoutSection[] = [\n { id: 'workspace', label: 'Workspace State', icon: 'fa-solid fa-table-columns', description: 'Tabs, active tab, app state' },\n { id: 'golden', label: 'Golden Layout', icon: 'fa-solid fa-window-restore', description: 'Active layout JSON config' }\n ];\n\n public ActiveSection: 'workspace' | 'golden' = 'workspace';\n public LayoutJson = '{}';\n public CopyConfirmed = false;\n public LastRefreshed = new Date();\n\n constructor(\n private cdr: ChangeDetectorRef,\n private workspace: WorkspaceStateManager,\n private layout: GoldenLayoutManager\n ) {\n super();\n }\n\n public ngOnInit(): void {\n const p = DevToolsPrefs.Get<{ activeSection?: 'workspace' | 'golden' }>('layoutInspector');\n if (p?.activeSection) this.ActiveSection = p.activeSection;\n this.refresh();\n this.NotifyLoadComplete();\n }\n\n public override ngOnDestroy(): void {\n DevToolsPrefs.Save('layoutInspector', { activeSection: this.ActiveSection });\n super.ngOnDestroy();\n }\n\n public override async GetResourceDisplayName(): Promise<string> { return 'Layout Inspector'; }\n public override async GetResourceIconClass(): Promise<string> { return 'fa-solid fa-table-columns'; }\n\n public OnSectionClick(section: LayoutSection): void {\n if (this.ActiveSection === section.id) return;\n this.ActiveSection = section.id;\n DevToolsPrefs.Save('layoutInspector', { activeSection: this.ActiveSection });\n this.refresh();\n }\n\n public refresh(): void {\n this.LayoutJson = JSON.stringify(this.computeData(), this.jsonReplacer, 2);\n this.LastRefreshed = new Date();\n this.cdr.markForCheck();\n }\n\n public async OnCopy(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.LayoutJson);\n this.CopyConfirmed = true;\n this.cdr.markForCheck();\n setTimeout(() => {\n this.CopyConfirmed = false;\n this.cdr.markForCheck();\n }, 1800);\n } catch {\n // clipboard unavailable\n }\n }\n\n public OnDownload(): void {\n const blob = new Blob([this.LayoutJson], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n const stamp = new Date().toISOString().replace(/[:.]/g, '-');\n a.download = `mj-layout-${this.ActiveSection}-${stamp}.json`;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n public get LastRefreshedLabel(): string {\n return this.LastRefreshed.toLocaleTimeString();\n }\n\n public get SectionLabel(): string {\n return this.Sections.find(s => s.id === this.ActiveSection)?.label ?? '';\n }\n\n // ---------- private ----------\n\n private computeData(): unknown {\n if (this.ActiveSection === 'workspace') {\n return this.workspace.GetConfiguration();\n }\n // Golden Layout: GoldenLayoutManager exposes its raw config when active\n const layoutAny = this.layout as unknown as { GetCurrentLayoutConfig?: () => unknown; CurrentConfig?: unknown };\n if (typeof layoutAny.GetCurrentLayoutConfig === 'function') {\n return layoutAny.GetCurrentLayoutConfig();\n }\n if (layoutAny.CurrentConfig !== undefined) {\n return layoutAny.CurrentConfig;\n }\n return { note: 'Golden Layout config is not currently exposed by GoldenLayoutManager.' };\n }\n\n private jsonReplacer(_key: string, value: unknown): unknown {\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Map) return Object.fromEntries(value.entries());\n if (value instanceof Set) return Array.from(value);\n if (typeof value === 'function') return `[Function ${(value as { name: string }).name || 'anonymous'}]`;\n return value;\n }\n}\n","<div class=\"mj-inspector\">\n <div class=\"mj-inspector__header\">\n <div class=\"mj-inspector__header-icon\"><i class=\"fa-solid fa-table-columns\"></i></div>\n <div>\n <h3 class=\"mj-inspector__header-title\">Layout Inspector</h3>\n <div class=\"mj-inspector__header-sub\">Workspace + Golden Layout configuration</div>\n </div>\n <span class=\"mj-inspector__header-spacer\"></span>\n <div class=\"mj-inspector__header-actions\">\n <button class=\"mj-inspector__btn\" type=\"button\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\"></i> Refresh\n </button>\n <button class=\"mj-inspector__btn\"\n [class.mj-inspector__btn--success]=\"CopyConfirmed\"\n type=\"button\" (click)=\"OnCopy()\"\n [title]=\"CopyConfirmed ? 'Copied' : 'Copy JSON'\">\n <i class=\"fa-solid\" [class.fa-clipboard]=\"!CopyConfirmed\" [class.fa-check]=\"CopyConfirmed\"></i>\n {{ CopyConfirmed ? 'Copied' : 'Copy' }}\n </button>\n <button class=\"mj-inspector__btn\" type=\"button\" (click)=\"OnDownload()\" title=\"Download as JSON\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n </div>\n </div>\n\n <div class=\"mj-inspector__body\">\n <aside class=\"mj-inspector__sidebar\">\n @for (section of Sections; track section.id) {\n <button type=\"button\"\n class=\"mj-inspector__nav-item\"\n [class.mj-inspector__nav-item--active]=\"ActiveSection === section.id\"\n (click)=\"OnSectionClick(section)\">\n <i class=\"mj-inspector__nav-icon\" [class]=\"section.icon\"></i>\n <div class=\"mj-inspector__nav-text\">\n <div class=\"mj-inspector__nav-label\">{{ section.label }}</div>\n <div class=\"mj-inspector__nav-desc\">{{ section.description }}</div>\n </div>\n </button>\n }\n </aside>\n\n <div class=\"mj-inspector__content\">\n <div class=\"mj-inspector__content-head\">\n <h4 class=\"mj-inspector__content-title\">{{ SectionLabel }}</h4>\n <span class=\"mj-inspector__content-meta\">Refreshed {{ LastRefreshedLabel }}</span>\n </div>\n <div class=\"mj-inspector__editor\">\n <mj-code-editor\n [(ngModel)]=\"LayoutJson\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"layout-inspector.component.js","sourceRoot":"","sources":["../../src/DevTools/layout-inspector.component.ts","../../src/DevTools/layout-inspector.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RegisterClass } from '@memberjunction/global';\nimport { TabConfig } from '@memberjunction/ng-ui-components';\nimport { WorkspaceStateManager, GoldenLayoutManager } from '@memberjunction/ng-base-application';\nimport { DevToolsPrefs } from './dev-tools-prefs';\n\ninterface LayoutSection {\n id: 'workspace' | 'golden';\n label: string;\n icon: string;\n description: string;\n}\n\n/**\n * Layout Inspector — read-only view of the current workspace + Golden Layout\n * configuration. Replaces the legacy \"Log Layout (Debug)\" user-menu item that\n * only printed to console.\n */\n@RegisterClass(BaseResourceComponent, 'LayoutInspector')\n@Component({\n standalone: false,\n selector: 'mj-layout-inspector',\n templateUrl: './layout-inspector.component.html',\n styleUrls: ['./inspector-shared.css']\n})\nexport class LayoutInspectorComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n\n public Sections: LayoutSection[] = [\n { id: 'workspace', label: 'Workspace State', icon: 'fa-solid fa-table-columns', description: 'Tabs, active tab, app state' },\n { id: 'golden', label: 'Golden Layout', icon: 'fa-solid fa-window-restore', description: 'Active layout JSON config' }\n ];\n\n public ActiveSection: 'workspace' | 'golden' = 'workspace';\n public LayoutJson = '{}';\n public CopyConfirmed = false;\n public LastRefreshed = new Date();\n\n constructor(\n private cdr: ChangeDetectorRef,\n private workspace: WorkspaceStateManager,\n private layout: GoldenLayoutManager\n ) {\n super();\n }\n\n public ngOnInit(): void {\n const p = DevToolsPrefs.Get<{ activeSection?: 'workspace' | 'golden' }>('layoutInspector');\n if (p?.activeSection) this.ActiveSection = p.activeSection;\n this.refresh();\n this.NotifyLoadComplete();\n }\n\n public override ngOnDestroy(): void {\n DevToolsPrefs.Save('layoutInspector', { activeSection: this.ActiveSection });\n super.ngOnDestroy();\n }\n\n public override async GetResourceDisplayName(): Promise<string> { return 'Layout Inspector'; }\n public override async GetResourceIconClass(): Promise<string> { return 'fa-solid fa-table-columns'; }\n\n /** Sections rendered as horizontal tabs in the chrome's [toolbar] slot. */\n public get tabsConfig(): TabConfig[] {\n return this.Sections.map(s => ({\n key: s.id,\n label: s.label,\n icon: s.icon\n }));\n }\n\n /** Adapter for `<mj-tab-nav>`'s string-typed `(TabChange)` output. */\n public onTabChange(key: string): void {\n const section = this.Sections.find(s => s.id === key);\n if (section) {\n this.OnSectionClick(section);\n }\n }\n\n public OnSectionClick(section: LayoutSection): void {\n if (this.ActiveSection === section.id) return;\n this.ActiveSection = section.id;\n DevToolsPrefs.Save('layoutInspector', { activeSection: this.ActiveSection });\n this.refresh();\n }\n\n public refresh(): void {\n this.LayoutJson = JSON.stringify(this.computeData(), this.jsonReplacer, 2);\n this.LastRefreshed = new Date();\n this.cdr.markForCheck();\n }\n\n public async OnCopy(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.LayoutJson);\n this.CopyConfirmed = true;\n this.cdr.markForCheck();\n setTimeout(() => {\n this.CopyConfirmed = false;\n this.cdr.markForCheck();\n }, 1800);\n } catch {\n // clipboard unavailable\n }\n }\n\n public OnDownload(): void {\n const blob = new Blob([this.LayoutJson], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n const stamp = new Date().toISOString().replace(/[:.]/g, '-');\n a.download = `mj-layout-${this.ActiveSection}-${stamp}.json`;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n public get LastRefreshedLabel(): string {\n return this.LastRefreshed.toLocaleTimeString();\n }\n\n public get SectionLabel(): string {\n return this.Sections.find(s => s.id === this.ActiveSection)?.label ?? '';\n }\n\n // ---------- private ----------\n\n private computeData(): unknown {\n if (this.ActiveSection === 'workspace') {\n return this.workspace.GetConfiguration();\n }\n // Golden Layout: GoldenLayoutManager exposes its raw config when active\n const layoutAny = this.layout as unknown as { GetCurrentLayoutConfig?: () => unknown; CurrentConfig?: unknown };\n if (typeof layoutAny.GetCurrentLayoutConfig === 'function') {\n return layoutAny.GetCurrentLayoutConfig();\n }\n if (layoutAny.CurrentConfig !== undefined) {\n return layoutAny.CurrentConfig;\n }\n return { note: 'Golden Layout config is not currently exposed by GoldenLayoutManager.' };\n }\n\n private jsonReplacer(_key: string, value: unknown): unknown {\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Map) return Object.fromEntries(value.entries());\n if (value instanceof Set) return Array.from(value);\n if (typeof value === 'function') return `[Function ${(value as { name: string }).name || 'anonymous'}]`;\n return value;\n }\n}\n","<div class=\"mj-inspector mj-inspector--solo\">\n <mj-page-header-interior\n Role=\"region\"\n AriaLabel=\"Layout inspector\"\n Title=\"Layout Inspector\"\n Subtitle=\"Workspace + Golden Layout configuration\">\n <div actions>\n <mj-refresh-button [Loading]=\"false\" (Clicked)=\"refresh()\"></mj-refresh-button>\n <button mjButton\n [variant]=\"CopyConfirmed ? 'success' : 'secondary'\"\n size=\"sm\"\n (click)=\"OnCopy()\"\n [title]=\"CopyConfirmed ? 'Copied' : 'Copy JSON'\">\n <i class=\"fa-solid\" [class.fa-clipboard]=\"!CopyConfirmed\" [class.fa-check]=\"CopyConfirmed\" aria-hidden=\"true\"></i>\n {{ CopyConfirmed ? 'Copied' : 'Copy' }}\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnDownload()\" title=\"Download as JSON\" aria-label=\"Download as JSON\">\n <i class=\"fa-solid fa-download\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div toolbar>\n <mj-tab-nav\n [Tabs]=\"tabsConfig\"\n [ActiveKey]=\"ActiveSection\"\n (TabChange)=\"onTabChange($event)\">\n </mj-tab-nav>\n </div>\n </mj-page-header-interior>\n\n <div class=\"mj-inspector__content\">\n <div class=\"mj-inspector__content-head\">\n <h4 class=\"mj-inspector__content-title\">{{ SectionLabel }}</h4>\n <span class=\"mj-inspector__content-meta\">Refreshed {{ LastRefreshedLabel }}</span>\n </div>\n <div class=\"mj-inspector__editor\">\n <mj-code-editor\n [(ngModel)]=\"LayoutJson\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n</div>\n"]}