@memberjunction/ng-explorer-core 3.0.0 → 3.1.1

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 (179) hide show
  1. package/dist/app-routing.module.d.ts.map +1 -1
  2. package/dist/app-routing.module.js +213 -0
  3. package/dist/app-routing.module.js.map +1 -1
  4. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +1 -1
  5. package/dist/lib/generic/form-toolbar.js +1 -1
  6. package/dist/lib/generic/resource-container-component.js +1 -1
  7. package/dist/lib/resource-wrappers/artifact-resource.component.js +1 -1
  8. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +1 -1
  9. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
  10. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +15 -15
  11. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  12. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +1 -1
  13. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  14. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +15 -15
  15. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  16. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +4 -3
  17. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
  18. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +19 -20
  19. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
  20. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +57 -4
  21. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  22. package/dist/lib/resource-wrappers/dashboard-resource.component.js +385 -46
  23. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  24. package/dist/lib/resource-wrappers/list-detail-resource.component.js +1 -1
  25. package/dist/lib/resource-wrappers/notifications-resource.component.js +1 -1
  26. package/dist/lib/resource-wrappers/query-resource.component.js +1 -1
  27. package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
  28. package/dist/lib/resource-wrappers/record-resource.component.js +15 -17
  29. package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
  30. package/dist/lib/resource-wrappers/resource-wrappers-loader.d.ts.map +1 -1
  31. package/dist/lib/resource-wrappers/resource-wrappers-loader.js +3 -1
  32. package/dist/lib/resource-wrappers/resource-wrappers-loader.js.map +1 -1
  33. package/dist/lib/resource-wrappers/search-results-resource.component.js +1 -1
  34. package/dist/lib/resource-wrappers/view-resource.component.js +1 -1
  35. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +1 -1
  36. package/dist/lib/shell/components/header/app-nav.component.d.ts +4 -1
  37. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
  38. package/dist/lib/shell/components/header/app-nav.component.js +31 -11
  39. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  40. package/dist/lib/shell/components/header/app-switcher.component.js +1 -1
  41. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  42. package/dist/lib/shell/components/tabs/tab-container.component.js +4 -1
  43. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  44. package/dist/lib/shell/shell.component.d.ts +5 -1
  45. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  46. package/dist/lib/shell/shell.component.js +354 -44
  47. package/dist/lib/shell/shell.component.js.map +1 -1
  48. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +1 -1
  49. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +1 -1
  50. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +1 -1
  51. package/dist/lib/single-dashboard/single-dashboard.component.js +1 -1
  52. package/dist/lib/single-list-detail/single-list-detail.component.js +1 -1
  53. package/dist/lib/single-query/single-query.component.js +1 -1
  54. package/dist/lib/single-record/single-record.component.js +1 -1
  55. package/dist/lib/single-search-result/single-search-result.component.js +1 -1
  56. package/dist/lib/system-validation/system-validation-banner.component.js +1 -1
  57. package/dist/lib/user-notifications/user-notifications.component.js +1 -1
  58. package/dist/lib/user-profile/user-profile.component.js +1 -1
  59. package/dist/module.d.ts +18 -17
  60. package/dist/module.d.ts.map +1 -1
  61. package/dist/module.js +4 -0
  62. package/dist/module.js.map +1 -1
  63. package/package.json +37 -36
  64. package/dist/generic/Events.types.d.ts +0 -174
  65. package/dist/generic/Events.types.d.ts.map +0 -1
  66. package/dist/generic/Events.types.js +0 -220
  67. package/dist/generic/Events.types.js.map +0 -1
  68. package/dist/lib/app-view/application-view.component.d.ts +0 -65
  69. package/dist/lib/app-view/application-view.component.d.ts.map +0 -1
  70. package/dist/lib/app-view/application-view.component.js +0 -611
  71. package/dist/lib/app-view/application-view.component.js.map +0 -1
  72. package/dist/lib/auth-button/auth-button.component.d.ts +0 -13
  73. package/dist/lib/auth-button/auth-button.component.d.ts.map +0 -1
  74. package/dist/lib/auth-button/auth-button.component.js +0 -36
  75. package/dist/lib/auth-button/auth-button.component.js.map +0 -1
  76. package/dist/lib/base-browser-component/base-browser-component.d.ts +0 -44
  77. package/dist/lib/base-browser-component/base-browser-component.d.ts.map +0 -1
  78. package/dist/lib/base-browser-component/base-browser-component.js +0 -195
  79. package/dist/lib/base-browser-component/base-browser-component.js.map +0 -1
  80. package/dist/lib/chat-wrapper/chat-wrapper.component.d.ts +0 -54
  81. package/dist/lib/chat-wrapper/chat-wrapper.component.d.ts.map +0 -1
  82. package/dist/lib/chat-wrapper/chat-wrapper.component.js +0 -257
  83. package/dist/lib/chat-wrapper/chat-wrapper.component.js.map +0 -1
  84. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts +0 -32
  85. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts.map +0 -1
  86. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js +0 -244
  87. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js.map +0 -1
  88. package/dist/lib/data-browser-component/data-browser.component.d.ts +0 -23
  89. package/dist/lib/data-browser-component/data-browser.component.d.ts.map +0 -1
  90. package/dist/lib/data-browser-component/data-browser.component.js +0 -267
  91. package/dist/lib/data-browser-component/data-browser.component.js.map +0 -1
  92. package/dist/lib/expansion-panel-component/expansion-panel-component.d.ts +0 -21
  93. package/dist/lib/expansion-panel-component/expansion-panel-component.d.ts.map +0 -1
  94. package/dist/lib/expansion-panel-component/expansion-panel-component.js +0 -158
  95. package/dist/lib/expansion-panel-component/expansion-panel-component.js.map +0 -1
  96. package/dist/lib/favorites/favorites.component.d.ts +0 -15
  97. package/dist/lib/favorites/favorites.component.d.ts.map +0 -1
  98. package/dist/lib/favorites/favorites.component.js +0 -135
  99. package/dist/lib/favorites/favorites.component.js.map +0 -1
  100. package/dist/lib/files/files.component.d.ts +0 -10
  101. package/dist/lib/files/files.component.d.ts.map +0 -1
  102. package/dist/lib/files/files.component.js +0 -41
  103. package/dist/lib/files/files.component.js.map +0 -1
  104. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts +0 -30
  105. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts.map +0 -1
  106. package/dist/lib/generic-browse-list/generic-browse-list.component.js +0 -171
  107. package/dist/lib/generic-browse-list/generic-browse-list.component.js.map +0 -1
  108. package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts +0 -120
  109. package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts.map +0 -1
  110. package/dist/lib/generic-browser-list/generic-browser-list.component.js +0 -1093
  111. package/dist/lib/generic-browser-list/generic-browser-list.component.js.map +0 -1
  112. package/dist/lib/header/MSFT_UserImageService.d.ts +0 -12
  113. package/dist/lib/header/MSFT_UserImageService.d.ts.map +0 -1
  114. package/dist/lib/header/MSFT_UserImageService.js +0 -25
  115. package/dist/lib/header/MSFT_UserImageService.js.map +0 -1
  116. package/dist/lib/header/header.component.d.ts +0 -69
  117. package/dist/lib/header/header.component.d.ts.map +0 -1
  118. package/dist/lib/header/header.component.js +0 -342
  119. package/dist/lib/header/header.component.js.map +0 -1
  120. package/dist/lib/home-component/home.component.d.ts +0 -22
  121. package/dist/lib/home-component/home.component.d.ts.map +0 -1
  122. package/dist/lib/home-component/home.component.js +0 -194
  123. package/dist/lib/home-component/home.component.js.map +0 -1
  124. package/dist/lib/home-wrapper/home-wrapper.component.d.ts +0 -7
  125. package/dist/lib/home-wrapper/home-wrapper.component.d.ts.map +0 -1
  126. package/dist/lib/home-wrapper/home-wrapper.component.js +0 -30
  127. package/dist/lib/home-wrapper/home-wrapper.component.js.map +0 -1
  128. package/dist/lib/list-view/list-view.component.d.ts +0 -45
  129. package/dist/lib/list-view/list-view.component.d.ts.map +0 -1
  130. package/dist/lib/list-view/list-view.component.js +0 -329
  131. package/dist/lib/list-view/list-view.component.js.map +0 -1
  132. package/dist/lib/navigation/navigation.component.d.ts +0 -142
  133. package/dist/lib/navigation/navigation.component.d.ts.map +0 -1
  134. package/dist/lib/navigation/navigation.component.js +0 -1212
  135. package/dist/lib/navigation/navigation.component.js.map +0 -1
  136. package/dist/lib/query-browser-component/query-browser.component.d.ts +0 -75
  137. package/dist/lib/query-browser-component/query-browser.component.d.ts.map +0 -1
  138. package/dist/lib/query-browser-component/query-browser.component.js +0 -908
  139. package/dist/lib/query-browser-component/query-browser.component.js.map +0 -1
  140. package/dist/lib/report-browser-component/report-browser.component.d.ts +0 -22
  141. package/dist/lib/report-browser-component/report-browser.component.d.ts.map +0 -1
  142. package/dist/lib/report-browser-component/report-browser.component.js +0 -80
  143. package/dist/lib/report-browser-component/report-browser.component.js.map +0 -1
  144. package/dist/lib/resource-browser/resource-browser.component.d.ts +0 -178
  145. package/dist/lib/resource-browser/resource-browser.component.d.ts.map +0 -1
  146. package/dist/lib/resource-browser/resource-browser.component.js +0 -1012
  147. package/dist/lib/resource-browser/resource-browser.component.js.map +0 -1
  148. package/dist/lib/resource-wrappers/report-resource.component.d.ts +0 -13
  149. package/dist/lib/resource-wrappers/report-resource.component.d.ts.map +0 -1
  150. package/dist/lib/resource-wrappers/report-resource.component.js +0 -49
  151. package/dist/lib/resource-wrappers/report-resource.component.js.map +0 -1
  152. package/dist/lib/shared/custom-icon/custom-icon.component.d.ts +0 -11
  153. package/dist/lib/shared/custom-icon/custom-icon.component.d.ts.map +0 -1
  154. package/dist/lib/shared/custom-icon/custom-icon.component.js +0 -44
  155. package/dist/lib/shared/custom-icon/custom-icon.component.js.map +0 -1
  156. package/dist/lib/single-application/single-application.component.d.ts +0 -24
  157. package/dist/lib/single-application/single-application.component.d.ts.map +0 -1
  158. package/dist/lib/single-application/single-application.component.js +0 -122
  159. package/dist/lib/single-application/single-application.component.js.map +0 -1
  160. package/dist/lib/single-entity/single-entity.component.d.ts +0 -34
  161. package/dist/lib/single-entity/single-entity.component.d.ts.map +0 -1
  162. package/dist/lib/single-entity/single-entity.component.js +0 -245
  163. package/dist/lib/single-entity/single-entity.component.js.map +0 -1
  164. package/dist/lib/single-report/single-report.component.d.ts +0 -17
  165. package/dist/lib/single-report/single-report.component.d.ts.map +0 -1
  166. package/dist/lib/single-report/single-report.component.js +0 -55
  167. package/dist/lib/single-report/single-report.component.js.map +0 -1
  168. package/dist/lib/single-view/single-view.component.d.ts +0 -43
  169. package/dist/lib/single-view/single-view.component.d.ts.map +0 -1
  170. package/dist/lib/single-view/single-view.component.js +0 -207
  171. package/dist/lib/single-view/single-view.component.js.map +0 -1
  172. package/dist/lib/style-guide-test/style-guide-test.component.d.ts +0 -70
  173. package/dist/lib/style-guide-test/style-guide-test.component.d.ts.map +0 -1
  174. package/dist/lib/style-guide-test/style-guide-test.component.js +0 -1024
  175. package/dist/lib/style-guide-test/style-guide-test.component.js.map +0 -1
  176. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts +0 -46
  177. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.d.ts.map +0 -1
  178. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js +0 -547
  179. package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js.map +0 -1
@@ -6,16 +6,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { Component, ViewChild } from '@angular/core';
8
8
  import { BaseResourceComponent, BaseDashboard } from '@memberjunction/ng-shared';
9
- import { ResourceData, DashboardEngine } from '@memberjunction/core-entities';
9
+ import { DashboardEngine } from '@memberjunction/core-entities';
10
10
  import { RegisterClass, MJGlobal, SafeJSONParse } from '@memberjunction/global';
11
11
  import { Metadata, CompositeKey, LogError } from '@memberjunction/core';
12
- import { SingleDashboardComponent } from '../single-dashboard/single-dashboard.component';
13
12
  import { DataExplorerDashboardComponent } from '@memberjunction/ng-dashboards';
13
+ import { DashboardViewerComponent } from '@memberjunction/ng-dashboard-viewer';
14
14
  import * as i0 from "@angular/core";
15
15
  import * as i1 from "@memberjunction/ng-shared";
16
+ import * as i2 from "@angular/forms";
17
+ import * as i3 from "@memberjunction/ng-dashboards";
16
18
  const _c0 = ["container"];
17
- function DashboardResource_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelementStart(0, "details", 7)(1, "summary");
19
+ function DashboardResource_Conditional_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
20
+ i0.ɵɵelementStart(0, "details", 11)(1, "summary");
19
21
  i0.ɵɵtext(2, "Technical Details");
20
22
  i0.ɵɵelementEnd();
21
23
  i0.ɵɵelementStart(3, "pre");
@@ -26,17 +28,17 @@ function DashboardResource_Conditional_2_Conditional_7_Template(rf, ctx) { if (r
26
28
  i0.ɵɵadvance(4);
27
29
  i0.ɵɵtextInterpolate(ctx_r0.errorDetails);
28
30
  } }
29
- function DashboardResource_Conditional_2_Template(rf, ctx) { if (rf & 1) {
30
- i0.ɵɵelementStart(0, "div", 2)(1, "div", 3);
31
- i0.ɵɵelement(2, "i", 4);
31
+ function DashboardResource_Conditional_1_Template(rf, ctx) { if (rf & 1) {
32
+ i0.ɵɵelementStart(0, "div", 2)(1, "div", 7);
33
+ i0.ɵɵelement(2, "i", 8);
32
34
  i0.ɵɵelementEnd();
33
- i0.ɵɵelementStart(3, "h2", 5);
35
+ i0.ɵɵelementStart(3, "h2", 9);
34
36
  i0.ɵɵtext(4, "Unable to Load Dashboard");
35
37
  i0.ɵɵelementEnd();
36
- i0.ɵɵelementStart(5, "p", 6);
38
+ i0.ɵɵelementStart(5, "p", 10);
37
39
  i0.ɵɵtext(6);
38
40
  i0.ɵɵelementEnd();
39
- i0.ɵɵtemplate(7, DashboardResource_Conditional_2_Conditional_7_Template, 5, 1, "details", 7);
41
+ i0.ɵɵtemplate(7, DashboardResource_Conditional_1_Conditional_7_Template, 5, 1, "details", 11);
40
42
  i0.ɵɵelementEnd();
41
43
  } if (rf & 2) {
42
44
  const ctx_r0 = i0.ɵɵnextContext();
@@ -45,6 +47,85 @@ function DashboardResource_Conditional_2_Template(rf, ctx) { if (rf & 1) {
45
47
  i0.ɵɵadvance();
46
48
  i0.ɵɵconditional(ctx_r0.errorDetails ? 7 : -1);
47
49
  } }
50
+ function DashboardResource_Conditional_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
51
+ i0.ɵɵelementStart(0, "span", 15);
52
+ i0.ɵɵelement(1, "i", 19);
53
+ i0.ɵɵelementEnd();
54
+ } }
55
+ function DashboardResource_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
56
+ const _r2 = i0.ɵɵgetCurrentView();
57
+ i0.ɵɵelementStart(0, "button", 20);
58
+ i0.ɵɵlistener("click", function DashboardResource_Conditional_2_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openShareDialog()); });
59
+ i0.ɵɵelement(1, "i", 19);
60
+ i0.ɵɵelementEnd();
61
+ } }
62
+ function DashboardResource_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
63
+ const _r3 = i0.ɵɵgetCurrentView();
64
+ i0.ɵɵelementStart(0, "button", 21);
65
+ i0.ɵɵlistener("click", function DashboardResource_Conditional_2_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleEditMode()); });
66
+ i0.ɵɵelement(1, "i", 22);
67
+ i0.ɵɵelementEnd();
68
+ } }
69
+ function DashboardResource_Conditional_2_Template(rf, ctx) { if (rf & 1) {
70
+ i0.ɵɵelementStart(0, "div", 3)(1, "div", 12)(2, "span", 13);
71
+ i0.ɵɵelement(3, "i", 14);
72
+ i0.ɵɵtext(4);
73
+ i0.ɵɵelementEnd();
74
+ i0.ɵɵtemplate(5, DashboardResource_Conditional_2_Conditional_5_Template, 2, 0, "span", 15);
75
+ i0.ɵɵelementEnd();
76
+ i0.ɵɵelementStart(6, "div", 16);
77
+ i0.ɵɵtemplate(7, DashboardResource_Conditional_2_Conditional_7_Template, 2, 0, "button", 17)(8, DashboardResource_Conditional_2_Conditional_8_Template, 2, 0, "button", 18);
78
+ i0.ɵɵelementEnd()();
79
+ } if (rf & 2) {
80
+ const ctx_r0 = i0.ɵɵnextContext();
81
+ i0.ɵɵadvance(4);
82
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.configDashboard.Name, " ");
83
+ i0.ɵɵadvance();
84
+ i0.ɵɵconditional(!ctx_r0.dashboardPermissions.IsOwner && ctx_r0.dashboardPermissions.PermissionSource !== "none" ? 5 : -1);
85
+ i0.ɵɵadvance(2);
86
+ i0.ɵɵconditional(ctx_r0.dashboardPermissions.CanShare ? 7 : -1);
87
+ i0.ɵɵadvance();
88
+ i0.ɵɵconditional(ctx_r0.dashboardPermissions.CanEdit ? 8 : -1);
89
+ } }
90
+ function DashboardResource_Conditional_3_Template(rf, ctx) { if (rf & 1) {
91
+ const _r4 = i0.ɵɵgetCurrentView();
92
+ i0.ɵɵelementStart(0, "div", 4)(1, "div", 23)(2, "button", 24);
93
+ i0.ɵɵlistener("click", function DashboardResource_Conditional_3_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.openAddPartDialog()); });
94
+ i0.ɵɵelement(3, "i", 25);
95
+ i0.ɵɵtext(4, " Add Part ");
96
+ i0.ɵɵelementEnd();
97
+ i0.ɵɵelement(5, "div", 26);
98
+ i0.ɵɵelementStart(6, "div", 27)(7, "input", 28);
99
+ i0.ɵɵtwoWayListener("ngModelChange", function DashboardResource_Conditional_3_Template_input_ngModelChange_7_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.editingName, $event) || (ctx_r0.editingName = $event); return i0.ɵɵresetView($event); });
100
+ i0.ɵɵelementEnd();
101
+ i0.ɵɵelementStart(8, "input", 29);
102
+ i0.ɵɵtwoWayListener("ngModelChange", function DashboardResource_Conditional_3_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.editingDescription, $event) || (ctx_r0.editingDescription = $event); return i0.ɵɵresetView($event); });
103
+ i0.ɵɵelementEnd()()();
104
+ i0.ɵɵelementStart(9, "div", 30)(10, "button", 31);
105
+ i0.ɵɵlistener("click", function DashboardResource_Conditional_3_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.saveDashboard()); });
106
+ i0.ɵɵelement(11, "i", 32);
107
+ i0.ɵɵtext(12, " Save ");
108
+ i0.ɵɵelementEnd();
109
+ i0.ɵɵelementStart(13, "button", 33);
110
+ i0.ɵɵlistener("click", function DashboardResource_Conditional_3_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.cancelEdit()); });
111
+ i0.ɵɵtext(14, " Cancel ");
112
+ i0.ɵɵelementEnd()()();
113
+ } if (rf & 2) {
114
+ const ctx_r0 = i0.ɵɵnextContext();
115
+ i0.ɵɵadvance(7);
116
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.editingName);
117
+ i0.ɵɵadvance();
118
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.editingDescription);
119
+ } }
120
+ function DashboardResource_Conditional_6_Template(rf, ctx) { if (rf & 1) {
121
+ const _r5 = i0.ɵɵgetCurrentView();
122
+ i0.ɵɵelementStart(0, "mj-dashboard-share-dialog", 34);
123
+ i0.ɵɵlistener("Result", function DashboardResource_Conditional_6_Template_mj_dashboard_share_dialog_Result_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onShareDialogResult($event)); });
124
+ i0.ɵɵelementEnd();
125
+ } if (rf & 2) {
126
+ const ctx_r0 = i0.ɵɵnextContext();
127
+ i0.ɵɵproperty("Visible", ctx_r0.showShareDialog)("Dashboard", ctx_r0.configDashboard);
128
+ } }
48
129
  export function LoadDashboardResource() {
49
130
  }
50
131
  /**
@@ -55,6 +136,7 @@ export function LoadDashboardResource() {
55
136
  let DashboardResource = class DashboardResource extends BaseResourceComponent {
56
137
  viewContainer;
57
138
  navigationService;
139
+ cdr;
58
140
  componentRef = null;
59
141
  dataLoaded = false;
60
142
  containerElement;
@@ -62,6 +144,29 @@ let DashboardResource = class DashboardResource extends BaseResourceComponent {
62
144
  errorMessage = null;
63
145
  /** Technical error details (shown in expandable section) */
64
146
  errorDetails = null;
147
+ /** Cached dashboard categories for breadcrumb navigation */
148
+ categories = [];
149
+ /** Reference to the dashboard viewer component (for config-based dashboards) */
150
+ viewerInstance = null;
151
+ /** The config-based dashboard entity (null for code-based dashboards) */
152
+ configDashboard = null;
153
+ /** Whether we're in edit mode */
154
+ isEditMode = false;
155
+ /** Editing fields */
156
+ editingName = '';
157
+ editingDescription = '';
158
+ /** Current user's permissions for this dashboard */
159
+ dashboardPermissions = {
160
+ DashboardID: '',
161
+ CanRead: true,
162
+ CanEdit: true,
163
+ CanDelete: true,
164
+ CanShare: true,
165
+ IsOwner: true,
166
+ PermissionSource: 'owner'
167
+ };
168
+ /** Whether the share dialog is visible */
169
+ showShareDialog = false;
65
170
  /**
66
171
  * Sets the error state with a user-friendly message and optional technical details
67
172
  */
@@ -84,10 +189,11 @@ let DashboardResource = class DashboardResource extends BaseResourceComponent {
84
189
  this.errorMessage = null;
85
190
  this.errorDetails = null;
86
191
  }
87
- constructor(viewContainer, navigationService) {
192
+ constructor(viewContainer, navigationService, cdr) {
88
193
  super();
89
194
  this.viewContainer = viewContainer;
90
195
  this.navigationService = navigationService;
196
+ this.cdr = cdr;
91
197
  }
92
198
  set Data(value) {
93
199
  super.Data = value;
@@ -105,6 +211,102 @@ let DashboardResource = class DashboardResource extends BaseResourceComponent {
105
211
  this.componentRef.destroy();
106
212
  }
107
213
  }
214
+ // ========================================
215
+ // Edit Mode Methods
216
+ // ========================================
217
+ /**
218
+ * Toggle between view and edit mode
219
+ */
220
+ toggleEditMode() {
221
+ if (this.isEditMode) {
222
+ this.cancelEdit();
223
+ }
224
+ else {
225
+ this.enterEditMode();
226
+ }
227
+ }
228
+ /**
229
+ * Enter edit mode
230
+ */
231
+ enterEditMode() {
232
+ if (!this.configDashboard)
233
+ return;
234
+ this.isEditMode = true;
235
+ this.editingName = this.configDashboard.Name;
236
+ this.editingDescription = this.configDashboard.Description || '';
237
+ // Tell the viewer to enter edit mode
238
+ if (this.viewerInstance) {
239
+ this.viewerInstance.isEditing = true;
240
+ }
241
+ this.cdr.detectChanges();
242
+ }
243
+ /**
244
+ * Cancel edit mode and discard changes
245
+ */
246
+ cancelEdit() {
247
+ this.isEditMode = false;
248
+ // Tell the viewer to exit edit mode
249
+ if (this.viewerInstance) {
250
+ this.viewerInstance.isEditing = false;
251
+ }
252
+ this.cdr.detectChanges();
253
+ }
254
+ /**
255
+ * Save dashboard changes
256
+ */
257
+ async saveDashboard() {
258
+ if (!this.configDashboard || !this.viewerInstance)
259
+ return;
260
+ try {
261
+ // Update dashboard name and description
262
+ this.configDashboard.Name = this.editingName;
263
+ this.configDashboard.Description = this.editingDescription;
264
+ // Save via the viewer (which handles layout saving)
265
+ await this.viewerInstance.save();
266
+ // Exit edit mode
267
+ this.isEditMode = false;
268
+ this.viewerInstance.isEditing = false;
269
+ this.cdr.detectChanges();
270
+ }
271
+ catch (error) {
272
+ console.error('Error saving dashboard:', error);
273
+ }
274
+ }
275
+ /**
276
+ * Open the add panel dialog
277
+ */
278
+ openAddPartDialog() {
279
+ if (this.viewerInstance) {
280
+ // Trigger the viewer's add panel flow
281
+ this.viewerInstance.onAddPanelClick();
282
+ }
283
+ }
284
+ /**
285
+ * Open the share dialog for this dashboard
286
+ */
287
+ openShareDialog() {
288
+ this.showShareDialog = true;
289
+ this.cdr.detectChanges();
290
+ }
291
+ /**
292
+ * Close the share dialog
293
+ */
294
+ closeShareDialog() {
295
+ this.showShareDialog = false;
296
+ this.cdr.detectChanges();
297
+ }
298
+ /**
299
+ * Handle share dialog result
300
+ */
301
+ onShareDialogResult(result) {
302
+ this.showShareDialog = false;
303
+ if (result.Action === 'save' && this.configDashboard) {
304
+ // Recompute permissions after sharing changes
305
+ const md = new Metadata();
306
+ this.dashboardPermissions = DashboardEngine.Instance.GetDashboardPermissions(this.configDashboard.ID, md.CurrentUser.ID);
307
+ }
308
+ this.cdr.detectChanges();
309
+ }
108
310
  /**
109
311
  * Load the appropriate dashboard component based on dashboard type
110
312
  * Routes between code-based dashboards (registered classes) and config-based dashboards
@@ -283,40 +485,58 @@ let DashboardResource = class DashboardResource extends BaseResourceComponent {
283
485
  return stateObject;
284
486
  }
285
487
  /**
286
- * Load a config-based dashboard using the generic SingleDashboardComponent
488
+ * Load a config-based dashboard using the new DashboardViewerComponent (Golden Layout)
287
489
  */
288
490
  async loadConfigBasedDashboard(dashboard) {
289
491
  try {
290
492
  this.containerElement.nativeElement.innerHTML = '';
291
- this.componentRef = this.viewContainer.createComponent(SingleDashboardComponent);
292
- const instance = this.componentRef.instance;
493
+ const componentRef = this.viewContainer.createComponent(DashboardViewerComponent);
494
+ this.componentRef = componentRef;
495
+ const instance = componentRef.instance;
496
+ // Store references for external toolbar control
497
+ this.viewerInstance = instance;
498
+ this.configDashboard = dashboard;
499
+ // Compute user permissions for this dashboard
500
+ const md = new Metadata();
501
+ this.dashboardPermissions = DashboardEngine.Instance.GetDashboardPermissions(dashboard.ID, md.CurrentUser.ID);
293
502
  // Manually append the component's native element inside the div
294
503
  const nativeElement = this.componentRef.hostView.rootNodes[0];
295
504
  nativeElement.style.width = '100%';
296
505
  nativeElement.style.height = '100%';
297
506
  this.containerElement.nativeElement.appendChild(nativeElement);
298
- // Initialize with dashboard data
299
- const baseData = this.Data;
300
- const resourceData = new ResourceData({
301
- ResourceRecordID: baseData.ResourceRecordID,
302
- Configuration: baseData.Configuration || {}
303
- });
304
- instance.ResourceData = resourceData;
305
- // Wire up events if they exist
306
- if (instance.loadComplete) {
307
- instance.loadComplete.subscribe(() => {
308
- this.NotifyLoadComplete();
309
- });
310
- }
311
- else {
312
- // Fallback if event emitter not available
313
- setTimeout(() => this.NotifyLoadComplete(), 100);
314
- }
315
- if (instance.dashboardSaved) {
316
- instance.dashboardSaved.subscribe((entity) => {
317
- this.ResourceRecordSaved(entity);
318
- });
507
+ // Load categories for breadcrumb navigation (if not already loaded)
508
+ if (this.categories.length === 0) {
509
+ this.categories = DashboardEngine.Instance.DashboardCategories;
319
510
  }
511
+ // Set the dashboard entity directly on the viewer
512
+ // We provide our own external toolbar, so disable the viewer's internal toolbar
513
+ instance.dashboard = dashboard;
514
+ instance.showToolbar = false; // We provide external toolbar
515
+ instance.showBreadcrumb = false; // Already in its own tab, no breadcrumb needed
516
+ instance.showOpenInTabButton = false; // Already in its own tab
517
+ instance.showEditButton = false; // External toolbar handles edit
518
+ instance.Categories = this.categories;
519
+ // Wire up navigation events - handle navigation requests from the dashboard
520
+ instance.navigationRequested.subscribe((event) => {
521
+ this.handleNavigationRequest(event);
522
+ });
523
+ // Wire up "Open in Tab" button click
524
+ instance.openInTab.subscribe((event) => {
525
+ this.navigationService.OpenDashboard(event.dashboardId, event.dashboardName);
526
+ });
527
+ // Wire up dashboard saved event
528
+ instance.dashboardSaved.subscribe((savedDashboard) => {
529
+ this.ResourceRecordSaved(savedDashboard);
530
+ });
531
+ // Wire up error events
532
+ instance.error.subscribe((errorEvent) => {
533
+ console.error('Dashboard error:', errorEvent.message, errorEvent.error);
534
+ });
535
+ // Notify load complete after a brief delay to let Golden Layout initialize
536
+ setTimeout(() => {
537
+ this.NotifyLoadComplete();
538
+ this.cdr.detectChanges();
539
+ }, 150);
320
540
  }
321
541
  catch (error) {
322
542
  console.error('Error loading config-based dashboard:', error);
@@ -324,6 +544,35 @@ let DashboardResource = class DashboardResource extends BaseResourceComponent {
324
544
  this.NotifyLoadComplete();
325
545
  }
326
546
  }
547
+ /**
548
+ * Handle navigation requests from the dashboard viewer
549
+ */
550
+ handleNavigationRequest(event) {
551
+ const request = event.request;
552
+ switch (request.type) {
553
+ case 'OpenEntityRecord': {
554
+ const entityRequest = request;
555
+ const pkey = new CompositeKey([{ FieldName: 'ID', Value: entityRequest.recordId }]);
556
+ this.navigationService.OpenEntityRecord(entityRequest.entityName, pkey);
557
+ break;
558
+ }
559
+ case 'OpenDashboard': {
560
+ const dashRequest = request;
561
+ // Load dashboard name from engine cache
562
+ const targetDashboard = DashboardEngine.Instance.Dashboards.find(d => d.ID === dashRequest.dashboardId);
563
+ const name = targetDashboard?.Name || 'Dashboard';
564
+ this.navigationService.OpenDashboard(dashRequest.dashboardId, name);
565
+ break;
566
+ }
567
+ case 'OpenQuery': {
568
+ const queryRequest = request;
569
+ this.navigationService.OpenQuery(queryRequest.queryId, 'Query');
570
+ break;
571
+ }
572
+ default:
573
+ console.warn('Unhandled navigation request type:', request.type);
574
+ }
575
+ }
327
576
  /**
328
577
  * Get the display name for a dashboard resource
329
578
  * Loads the actual dashboard name from the database if available
@@ -352,20 +601,28 @@ let DashboardResource = class DashboardResource extends BaseResourceComponent {
352
601
  async GetResourceIconClass(data) {
353
602
  return 'fa-solid fa-table-columns';
354
603
  }
355
- static ɵfac = function DashboardResource_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || DashboardResource)(i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i1.NavigationService)); };
604
+ static ɵfac = function DashboardResource_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || DashboardResource)(i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i1.NavigationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
356
605
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DashboardResource, selectors: [["mj-dashboard-resource"]], viewQuery: function DashboardResource_Query(rf, ctx) { if (rf & 1) {
357
606
  i0.ɵɵviewQuery(_c0, 7);
358
607
  } if (rf & 2) {
359
608
  let _t;
360
609
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.containerElement = _t.first);
361
- } }, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 1, consts: [["container", ""], [1, "dashboard-resource-container"], [1, "error-state"], [1, "error-icon"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "error-title"], [1, "error-message"], [1, "error-details"]], template: function DashboardResource_Template(rf, ctx) { if (rf & 1) {
362
- i0.ɵɵelementStart(0, "div", 1, 0);
363
- i0.ɵɵtemplate(2, DashboardResource_Conditional_2_Template, 8, 2, "div", 2);
610
+ } }, features: [i0.ɵɵInheritDefinitionFeature], decls: 7, vars: 4, consts: [["container", ""], [1, "dashboard-resource-wrapper"], [1, "error-state"], [1, "viewer-toolbar"], [1, "viewer-header", "editing"], [1, "dashboard-resource-container"], [3, "Visible", "Dashboard"], [1, "error-icon"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "error-title"], [1, "error-message"], [1, "error-details"], [1, "toolbar-left"], [1, "dashboard-title"], [1, "fa-solid", "fa-chart-line"], ["title", "Shared with you", 1, "shared-indicator"], [1, "toolbar-actions"], ["title", "Share Dashboard", 1, "btn-icon"], ["title", "Edit Dashboard", 1, "btn-icon"], [1, "fa-solid", "fa-share-nodes"], ["title", "Share Dashboard", 1, "btn-icon", 3, "click"], ["title", "Edit Dashboard", 1, "btn-icon", 3, "click"], [1, "fa-solid", "fa-edit"], [1, "header-left"], [1, "btn-add-part", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "header-separator"], [1, "dashboard-info-edit"], ["type", "text", "placeholder", "Dashboard name", 1, "dashboard-name-input", 3, "ngModelChange", "ngModel"], ["type", "text", "placeholder", "Add a description...", 1, "dashboard-description-input", 3, "ngModelChange", "ngModel"], [1, "header-right"], [1, "btn-primary", 3, "click"], [1, "fa-solid", "fa-save"], [1, "btn-cancel", 3, "click"], [3, "Result", "Visible", "Dashboard"]], template: function DashboardResource_Template(rf, ctx) { if (rf & 1) {
611
+ i0.ɵɵelementStart(0, "div", 1);
612
+ i0.ɵɵtemplate(1, DashboardResource_Conditional_1_Template, 8, 2, "div", 2)(2, DashboardResource_Conditional_2_Template, 9, 4, "div", 3)(3, DashboardResource_Conditional_3_Template, 15, 2, "div", 4);
613
+ i0.ɵɵelement(4, "div", 5, 0);
614
+ i0.ɵɵtemplate(6, DashboardResource_Conditional_6_Template, 1, 2, "mj-dashboard-share-dialog", 6);
364
615
  i0.ɵɵelementEnd();
365
616
  } if (rf & 2) {
366
- i0.ɵɵadvance(2);
367
- i0.ɵɵconditional(ctx.errorMessage ? 2 : -1);
368
- } }, styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .dashboard-resource-container[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: auto;\n }\n .error-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 40px;\n text-align: center;\n color: #424242;\n }\n .error-icon[_ngcontent-%COMP%] {\n font-size: 64px;\n color: #f44336;\n margin-bottom: 24px;\n opacity: 0.8;\n }\n .error-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 500;\n margin: 0 0 12px 0;\n color: #212121;\n }\n .error-message[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #616161;\n margin: 0 0 24px 0;\n max-width: 500px;\n line-height: 1.5;\n }\n .error-details[_ngcontent-%COMP%] {\n background: #f5f5f5;\n border-radius: 8px;\n padding: 12px 16px;\n max-width: 600px;\n text-align: left;\n font-size: 13px;\n }\n .error-details[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] {\n cursor: pointer;\n font-weight: 500;\n color: #757575;\n margin-bottom: 8px;\n }\n .error-details[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n color: #d32f2f;\n font-family: 'Consolas', 'Monaco', monospace;\n font-size: 12px;\n }"] });
617
+ i0.ɵɵadvance();
618
+ i0.ɵɵconditional(ctx.errorMessage ? 1 : -1);
619
+ i0.ɵɵadvance();
620
+ i0.ɵɵconditional(ctx.configDashboard && !ctx.isEditMode && !ctx.errorMessage ? 2 : -1);
621
+ i0.ɵɵadvance();
622
+ i0.ɵɵconditional(ctx.configDashboard && ctx.isEditMode && !ctx.errorMessage ? 3 : -1);
623
+ i0.ɵɵadvance(3);
624
+ i0.ɵɵconditional(ctx.configDashboard ? 6 : -1);
625
+ } }, dependencies: [i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.DashboardShareDialogComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .dashboard-resource-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: #f5f5f5;\n }\n .dashboard-resource-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n }\n\n \n\n .viewer-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n gap: 16px;\n }\n .viewer-toolbar[_ngcontent-%COMP%] .toolbar-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .viewer-toolbar[_ngcontent-%COMP%] .dashboard-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .viewer-toolbar[_ngcontent-%COMP%] .dashboard-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #5c6bc0;\n }\n .shared-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: #e3f2fd;\n color: #1976d2;\n font-size: 11px;\n }\n .viewer-toolbar[_ngcontent-%COMP%] .toolbar-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n \n\n .viewer-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n transition: background 0.2s, border-color 0.2s;\n }\n .viewer-header.editing[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #e8eaf6 0%, #c5cae9 100%);\n border-bottom: 2px solid #5c6bc0;\n }\n .viewer-header[_ngcontent-%COMP%] .header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n }\n .viewer-header[_ngcontent-%COMP%] .header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n \n\n .btn-add-part[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: #5c6bc0;\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s, transform 0.1s;\n box-shadow: 0 2px 4px rgba(92, 107, 192, 0.3);\n }\n .btn-add-part[_ngcontent-%COMP%]:hover {\n background: #3f51b5;\n transform: translateY(-1px);\n box-shadow: 0 3px 6px rgba(92, 107, 192, 0.4);\n }\n .btn-add-part[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 12px; }\n\n \n\n .header-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 28px;\n background: rgba(92, 107, 192, 0.3);\n margin: 0 4px;\n }\n\n \n\n .btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: none;\n border-radius: 6px;\n background: #5c6bc0;\n color: #fff;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n }\n .btn-primary[_ngcontent-%COMP%]:hover { background: #3f51b5; }\n\n .btn-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: #fff;\n color: #666;\n cursor: pointer;\n transition: all 0.2s;\n }\n .btn-icon[_ngcontent-%COMP%]:hover { background: #f5f5f5; }\n\n .btn-cancel[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: 1px solid #d0d0d0;\n border-radius: 6px;\n background: #fff;\n color: #666;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n }\n .btn-cancel[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n border-color: #bbb;\n color: #333;\n }\n\n \n\n .dashboard-info-edit[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex: 1;\n }\n .dashboard-name-input[_ngcontent-%COMP%] {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n background: rgba(255, 255, 255, 0.7);\n outline: none;\n min-width: 200px;\n max-width: 300px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n }\n .dashboard-name-input[_ngcontent-%COMP%]:hover { background: rgba(255, 255, 255, 0.9); }\n .dashboard-name-input[_ngcontent-%COMP%]:focus {\n background: #fff;\n border-color: #5c6bc0;\n box-shadow: 0 0 0 2px rgba(92, 107, 192, 0.2);\n }\n .dashboard-description-input[_ngcontent-%COMP%] {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: #555;\n background: rgba(255, 255, 255, 0.5);\n outline: none;\n flex: 1;\n min-width: 150px;\n max-width: 400px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n }\n .dashboard-description-input[_ngcontent-%COMP%]:hover { background: rgba(255, 255, 255, 0.8); }\n .dashboard-description-input[_ngcontent-%COMP%]:focus {\n background: #fff;\n border-color: #5c6bc0;\n box-shadow: 0 0 0 2px rgba(92, 107, 192, 0.2);\n }\n .dashboard-description-input[_ngcontent-%COMP%]::placeholder {\n color: #888;\n font-style: normal;\n }\n\n \n\n .error-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 40px;\n text-align: center;\n color: #424242;\n }\n .error-icon[_ngcontent-%COMP%] {\n font-size: 64px;\n color: #f44336;\n margin-bottom: 24px;\n opacity: 0.8;\n }\n .error-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 500;\n margin: 0 0 12px 0;\n color: #212121;\n }\n .error-message[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #616161;\n margin: 0 0 24px 0;\n max-width: 500px;\n line-height: 1.5;\n }\n .error-details[_ngcontent-%COMP%] {\n background: #f5f5f5;\n border-radius: 8px;\n padding: 12px 16px;\n max-width: 600px;\n text-align: left;\n font-size: 13px;\n }\n .error-details[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] {\n cursor: pointer;\n font-weight: 500;\n color: #757575;\n margin-bottom: 8px;\n }\n .error-details[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n color: #d32f2f;\n font-family: 'Consolas', 'Monaco', monospace;\n font-size: 12px;\n }\n\n \n\n @media (max-width: 768px) {\n .viewer-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n .viewer-header[_ngcontent-%COMP%] .header-left[_ngcontent-%COMP%] { flex-wrap: wrap; }\n .dashboard-info-edit[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n .dashboard-name-input[_ngcontent-%COMP%], \n .dashboard-description-input[_ngcontent-%COMP%] { max-width: none; }\n }"] });
369
626
  };
370
627
  DashboardResource = __decorate([
371
628
  RegisterClass(BaseResourceComponent, 'DashboardResource')
@@ -374,7 +631,8 @@ export { DashboardResource };
374
631
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DashboardResource, [{
375
632
  type: Component,
376
633
  args: [{ selector: 'mj-dashboard-resource', template: `
377
- <div #container class="dashboard-resource-container">
634
+ <div class="dashboard-resource-wrapper">
635
+ <!-- Error State -->
378
636
  @if (errorMessage) {
379
637
  <div class="error-state">
380
638
  <div class="error-icon">
@@ -390,11 +648,92 @@ export { DashboardResource };
390
648
  }
391
649
  </div>
392
650
  }
651
+
652
+ <!-- View Mode Toolbar -->
653
+ @if (configDashboard && !isEditMode && !errorMessage) {
654
+ <div class="viewer-toolbar">
655
+ <div class="toolbar-left">
656
+ <span class="dashboard-title">
657
+ <i class="fa-solid fa-chart-line"></i>
658
+ {{ configDashboard.Name }}
659
+ </span>
660
+ @if (!dashboardPermissions.IsOwner && dashboardPermissions.PermissionSource !== 'none') {
661
+ <span class="shared-indicator" title="Shared with you">
662
+ <i class="fa-solid fa-share-nodes"></i>
663
+ </span>
664
+ }
665
+ </div>
666
+ <div class="toolbar-actions">
667
+ @if (dashboardPermissions.CanShare) {
668
+ <button
669
+ class="btn-icon"
670
+ title="Share Dashboard"
671
+ (click)="openShareDialog()">
672
+ <i class="fa-solid fa-share-nodes"></i>
673
+ </button>
674
+ }
675
+ @if (dashboardPermissions.CanEdit) {
676
+ <button
677
+ class="btn-icon"
678
+ title="Edit Dashboard"
679
+ (click)="toggleEditMode()">
680
+ <i class="fa-solid fa-edit"></i>
681
+ </button>
682
+ }
683
+ </div>
684
+ </div>
685
+ }
686
+
687
+ <!-- Edit Mode Toolbar -->
688
+ @if (configDashboard && isEditMode && !errorMessage) {
689
+ <div class="viewer-header editing">
690
+ <div class="header-left">
691
+ <button class="btn-add-part" (click)="openAddPartDialog()">
692
+ <i class="fa-solid fa-plus"></i>
693
+ Add Part
694
+ </button>
695
+ <div class="header-separator"></div>
696
+ <div class="dashboard-info-edit">
697
+ <input
698
+ type="text"
699
+ class="dashboard-name-input"
700
+ [(ngModel)]="editingName"
701
+ placeholder="Dashboard name">
702
+ <input
703
+ type="text"
704
+ class="dashboard-description-input"
705
+ [(ngModel)]="editingDescription"
706
+ placeholder="Add a description...">
707
+ </div>
708
+ </div>
709
+ <div class="header-right">
710
+ <button class="btn-primary" (click)="saveDashboard()">
711
+ <i class="fa-solid fa-save"></i>
712
+ Save
713
+ </button>
714
+ <button class="btn-cancel" (click)="cancelEdit()">
715
+ Cancel
716
+ </button>
717
+ </div>
718
+ </div>
719
+ }
720
+
721
+ <!-- Dashboard Content Container -->
722
+ <div #container class="dashboard-resource-container"></div>
723
+
724
+ <!-- Share Dashboard Dialog -->
725
+ @if (configDashboard) {
726
+ <mj-dashboard-share-dialog
727
+ [Visible]="showShareDialog"
728
+ [Dashboard]="configDashboard"
729
+ (Result)="onShareDialogResult($event)">
730
+ </mj-dashboard-share-dialog>
731
+ }
393
732
  </div>
394
- `, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .dashboard-resource-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: auto;\n }\n .error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 40px;\n text-align: center;\n color: #424242;\n }\n .error-icon {\n font-size: 64px;\n color: #f44336;\n margin-bottom: 24px;\n opacity: 0.8;\n }\n .error-title {\n font-size: 24px;\n font-weight: 500;\n margin: 0 0 12px 0;\n color: #212121;\n }\n .error-message {\n font-size: 16px;\n color: #616161;\n margin: 0 0 24px 0;\n max-width: 500px;\n line-height: 1.5;\n }\n .error-details {\n background: #f5f5f5;\n border-radius: 8px;\n padding: 12px 16px;\n max-width: 600px;\n text-align: left;\n font-size: 13px;\n }\n .error-details summary {\n cursor: pointer;\n font-weight: 500;\n color: #757575;\n margin-bottom: 8px;\n }\n .error-details pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n color: #d32f2f;\n font-family: 'Consolas', 'Monaco', monospace;\n font-size: 12px;\n }\n "] }]
395
- }], () => [{ type: i0.ViewContainerRef }, { type: i1.NavigationService }], { containerElement: [{
733
+ `, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n }\n .dashboard-resource-wrapper {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: #f5f5f5;\n }\n .dashboard-resource-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n }\n\n /* View Mode Toolbar */\n .viewer-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n gap: 16px;\n }\n .viewer-toolbar .toolbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .viewer-toolbar .dashboard-title {\n font-size: 16px;\n font-weight: 500;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .viewer-toolbar .dashboard-title i {\n color: #5c6bc0;\n }\n .shared-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: #e3f2fd;\n color: #1976d2;\n font-size: 11px;\n }\n .viewer-toolbar .toolbar-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n /* Edit Mode Header */\n .viewer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 24px;\n background: #fff;\n border-bottom: 1px solid #e0e0e0;\n transition: background 0.2s, border-color 0.2s;\n }\n .viewer-header.editing {\n background: linear-gradient(135deg, #e8eaf6 0%, #c5cae9 100%);\n border-bottom: 2px solid #5c6bc0;\n }\n .viewer-header .header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n }\n .viewer-header .header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n /* Add Part button */\n .btn-add-part {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n background: #5c6bc0;\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s, transform 0.1s;\n box-shadow: 0 2px 4px rgba(92, 107, 192, 0.3);\n }\n .btn-add-part:hover {\n background: #3f51b5;\n transform: translateY(-1px);\n box-shadow: 0 3px 6px rgba(92, 107, 192, 0.4);\n }\n .btn-add-part i { font-size: 12px; }\n\n /* Header separator */\n .header-separator {\n width: 1px;\n height: 28px;\n background: rgba(92, 107, 192, 0.3);\n margin: 0 4px;\n }\n\n /* Buttons */\n .btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: none;\n border-radius: 6px;\n background: #5c6bc0;\n color: #fff;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n }\n .btn-primary:hover { background: #3f51b5; }\n\n .btn-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: #fff;\n color: #666;\n cursor: pointer;\n transition: all 0.2s;\n }\n .btn-icon:hover { background: #f5f5f5; }\n\n .btn-cancel {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: 1px solid #d0d0d0;\n border-radius: 6px;\n background: #fff;\n color: #666;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n }\n .btn-cancel:hover {\n background: #f5f5f5;\n border-color: #bbb;\n color: #333;\n }\n\n /* Dashboard info inputs */\n .dashboard-info-edit {\n display: flex;\n align-items: center;\n gap: 16px;\n flex: 1;\n }\n .dashboard-name-input {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n background: rgba(255, 255, 255, 0.7);\n outline: none;\n min-width: 200px;\n max-width: 300px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n }\n .dashboard-name-input:hover { background: rgba(255, 255, 255, 0.9); }\n .dashboard-name-input:focus {\n background: #fff;\n border-color: #5c6bc0;\n box-shadow: 0 0 0 2px rgba(92, 107, 192, 0.2);\n }\n .dashboard-description-input {\n border: 1px solid transparent;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: #555;\n background: rgba(255, 255, 255, 0.5);\n outline: none;\n flex: 1;\n min-width: 150px;\n max-width: 400px;\n transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n }\n .dashboard-description-input:hover { background: rgba(255, 255, 255, 0.8); }\n .dashboard-description-input:focus {\n background: #fff;\n border-color: #5c6bc0;\n box-shadow: 0 0 0 2px rgba(92, 107, 192, 0.2);\n }\n .dashboard-description-input::placeholder {\n color: #888;\n font-style: normal;\n }\n\n /* Error state */\n .error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 40px;\n text-align: center;\n color: #424242;\n }\n .error-icon {\n font-size: 64px;\n color: #f44336;\n margin-bottom: 24px;\n opacity: 0.8;\n }\n .error-title {\n font-size: 24px;\n font-weight: 500;\n margin: 0 0 12px 0;\n color: #212121;\n }\n .error-message {\n font-size: 16px;\n color: #616161;\n margin: 0 0 24px 0;\n max-width: 500px;\n line-height: 1.5;\n }\n .error-details {\n background: #f5f5f5;\n border-radius: 8px;\n padding: 12px 16px;\n max-width: 600px;\n text-align: left;\n font-size: 13px;\n }\n .error-details summary {\n cursor: pointer;\n font-weight: 500;\n color: #757575;\n margin-bottom: 8px;\n }\n .error-details pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n color: #d32f2f;\n font-family: 'Consolas', 'Monaco', monospace;\n font-size: 12px;\n }\n\n /* Responsive */\n @media (max-width: 768px) {\n .viewer-header {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n .viewer-header .header-left { flex-wrap: wrap; }\n .dashboard-info-edit {\n flex-direction: column;\n align-items: stretch;\n }\n .dashboard-name-input,\n .dashboard-description-input { max-width: none; }\n }\n "] }]
734
+ }], () => [{ type: i0.ViewContainerRef }, { type: i1.NavigationService }, { type: i0.ChangeDetectorRef }], { containerElement: [{
396
735
  type: ViewChild,
397
736
  args: ['container', { static: true }]
398
737
  }] }); })();
399
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(DashboardResource, { className: "DashboardResource" }); })();
738
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(DashboardResource, { className: "DashboardResource", filePath: "src/lib/resource-wrappers/dashboard-resource.component.ts", lineNumber: 413 }); })();
400
739
  //# sourceMappingURL=dashboard-resource.component.js.map