@memberjunction/ng-explorer-core 0.9.2

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 (97) hide show
  1. package/dist/lib/ask-skip/ask-skip.component.d.ts +83 -0
  2. package/dist/lib/ask-skip/ask-skip.component.js +591 -0
  3. package/dist/lib/ask-skip/skip-dynamic-report-wrapper.d.ts +12 -0
  4. package/dist/lib/ask-skip/skip-dynamic-report-wrapper.js +49 -0
  5. package/dist/lib/auth-button/auth-button.component.d.ts +12 -0
  6. package/dist/lib/auth-button/auth-button.component.js +43 -0
  7. package/dist/lib/dashboard-browser-component/dashboard-browser.component.d.ts +14 -0
  8. package/dist/lib/dashboard-browser-component/dashboard-browser.component.js +55 -0
  9. package/dist/lib/data-browser-component/data-browser.component.d.ts +14 -0
  10. package/dist/lib/data-browser-component/data-browser.component.js +91 -0
  11. package/dist/lib/favorites/favorites.component.d.ts +13 -0
  12. package/dist/lib/favorites/favorites.component.js +100 -0
  13. package/dist/lib/generic/base-form-component.d.ts +76 -0
  14. package/dist/lib/generic/base-form-component.js +436 -0
  15. package/dist/lib/generic/base-form-section-component.d.ts +6 -0
  16. package/dist/lib/generic/base-form-section-component.js +10 -0
  17. package/dist/lib/generic/base-record-component.d.ts +6 -0
  18. package/dist/lib/generic/base-record-component.js +13 -0
  19. package/dist/lib/generic/base-resource-component.d.ts +34 -0
  20. package/dist/lib/generic/base-resource-component.js +75 -0
  21. package/dist/lib/generic/dynamic-chart.d.ts +26 -0
  22. package/dist/lib/generic/dynamic-chart.js +180 -0
  23. package/dist/lib/generic/dynamic-grid.d.ts +24 -0
  24. package/dist/lib/generic/dynamic-grid.js +135 -0
  25. package/dist/lib/generic/dynamic-report.d.ts +38 -0
  26. package/dist/lib/generic/dynamic-report.js +399 -0
  27. package/dist/lib/generic/form-toolbar.d.ts +7 -0
  28. package/dist/lib/generic/form-toolbar.js +98 -0
  29. package/dist/lib/generic/resource-container-component.d.ts +25 -0
  30. package/dist/lib/generic/resource-container-component.js +103 -0
  31. package/dist/lib/generic/section-loader-component.d.ts +17 -0
  32. package/dist/lib/generic/section-loader-component.js +65 -0
  33. package/dist/lib/generic-browse-list/generic-browse-list.component.d.ts +16 -0
  34. package/dist/lib/generic-browse-list/generic-browse-list.component.js +91 -0
  35. package/dist/lib/guards/auth-guard.service.d.ts +11 -0
  36. package/dist/lib/guards/auth-guard.service.js +24 -0
  37. package/dist/lib/guards/entities.guard.d.ts +3 -0
  38. package/dist/lib/guards/entities.guard.js +38 -0
  39. package/dist/lib/header/MSFT_UserImageService.d.ts +11 -0
  40. package/dist/lib/header/MSFT_UserImageService.js +23 -0
  41. package/dist/lib/header/header.component.d.ts +51 -0
  42. package/dist/lib/header/header.component.js +208 -0
  43. package/dist/lib/home-component/home.component.d.ts +9 -0
  44. package/dist/lib/home-component/home.component.js +54 -0
  45. package/dist/lib/join-grid/join-grid.component.d.ts +30 -0
  46. package/dist/lib/join-grid/join-grid.component.js +225 -0
  47. package/dist/lib/navigation/navigation.component.d.ts +102 -0
  48. package/dist/lib/navigation/navigation.component.js +970 -0
  49. package/dist/lib/report-browser-component/report-browser.component.d.ts +14 -0
  50. package/dist/lib/report-browser-component/report-browser.component.js +55 -0
  51. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +8 -0
  52. package/dist/lib/resource-wrappers/dashboard-resource.component.js +49 -0
  53. package/dist/lib/resource-wrappers/record-resource.component.d.ts +8 -0
  54. package/dist/lib/resource-wrappers/record-resource.component.js +55 -0
  55. package/dist/lib/resource-wrappers/report-resource.component.d.ts +10 -0
  56. package/dist/lib/resource-wrappers/report-resource.component.js +53 -0
  57. package/dist/lib/resource-wrappers/resource-wrappers-loader.d.ts +1 -0
  58. package/dist/lib/resource-wrappers/resource-wrappers-loader.js +12 -0
  59. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +10 -0
  60. package/dist/lib/resource-wrappers/search-results-resource.component.js +50 -0
  61. package/dist/lib/resource-wrappers/view-resource.component.d.ts +8 -0
  62. package/dist/lib/resource-wrappers/view-resource.component.js +51 -0
  63. package/dist/lib/settings/settings.component.d.ts +5 -0
  64. package/dist/lib/settings/settings.component.js +14 -0
  65. package/dist/lib/shared/shared.service.d.ts +87 -0
  66. package/dist/lib/shared/shared.service.js +302 -0
  67. package/dist/lib/shared/urlPipe.d.ts +7 -0
  68. package/dist/lib/shared/urlPipe.js +16 -0
  69. package/dist/lib/single-application/single-application.component.d.ts +21 -0
  70. package/dist/lib/single-application/single-application.component.js +132 -0
  71. package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +28 -0
  72. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +212 -0
  73. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts +26 -0
  74. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +169 -0
  75. package/dist/lib/single-dashboard/single-dashboard.component.d.ts +55 -0
  76. package/dist/lib/single-dashboard/single-dashboard.component.js +266 -0
  77. package/dist/lib/single-entity/single-entity.component.d.ts +33 -0
  78. package/dist/lib/single-entity/single-entity.component.js +252 -0
  79. package/dist/lib/single-record/single-record.component.d.ts +20 -0
  80. package/dist/lib/single-record/single-record.component.js +95 -0
  81. package/dist/lib/single-report/single-report.component.d.ts +22 -0
  82. package/dist/lib/single-report/single-report.component.js +87 -0
  83. package/dist/lib/single-search-result/single-search-result.component.d.ts +15 -0
  84. package/dist/lib/single-search-result/single-search-result.component.js +60 -0
  85. package/dist/lib/single-view/single-view.component.d.ts +34 -0
  86. package/dist/lib/single-view/single-view.component.js +154 -0
  87. package/dist/lib/user-notifications/user-notifications.component.d.ts +32 -0
  88. package/dist/lib/user-notifications/user-notifications.component.js +282 -0
  89. package/dist/lib/user-profile/user-profile.component.d.ts +10 -0
  90. package/dist/lib/user-profile/user-profile.component.js +41 -0
  91. package/dist/lib/user-view-properties/view-properties-dialog.component.d.ts +70 -0
  92. package/dist/lib/user-view-properties/view-properties-dialog.component.js +568 -0
  93. package/dist/module.d.ts +64 -0
  94. package/dist/module.js +332 -0
  95. package/dist/public-api.d.ts +47 -0
  96. package/dist/public-api.js +50 -0
  97. package/package.json +39 -0
@@ -0,0 +1,970 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Component, ElementRef, ViewChild, HostListener, HostBinding, Input } from '@angular/core';
11
+ import { NavigationEnd, NavigationSkipped } from '@angular/router';
12
+ import { DrawerComponent } from "@progress/kendo-angular-layout";
13
+ import { Metadata, RunView, LogError } from '@memberjunction/core';
14
+ import { MJEventType, MJGlobal } from '@memberjunction/global';
15
+ import { EventCodes } from '../shared/shared.service';
16
+ import { BaseResourceComponent, ResourceData } from '../generic/base-resource-component';
17
+ import * as i0 from "@angular/core";
18
+ import * as i1 from "@angular/router";
19
+ import * as i2 from "../shared/shared.service";
20
+ import * as i3 from "@angular/common";
21
+ import * as i4 from "@angular/platform-browser";
22
+ import * as i5 from "@progress/kendo-angular-indicators";
23
+ import * as i6 from "@progress/kendo-angular-layout";
24
+ import * as i7 from "@progress/kendo-angular-icons";
25
+ import * as i8 from "@memberjunction/ng-container-directives";
26
+ import * as i9 from "../generic/resource-container-component";
27
+ const _c0 = ["drawerWrapper"];
28
+ const _c1 = ["tabstrip"];
29
+ const _c2 = ["container"];
30
+ function NavigationComponent_kendo_loader_2_Template(rf, ctx) { if (rf & 1) {
31
+ i0.ɵɵelement(0, "kendo-loader", 5);
32
+ } }
33
+ function NavigationComponent_kendo_drawer_container_3_ng_template_7_Template(rf, ctx) { if (rf & 1) {
34
+ const _r10 = i0.ɵɵgetCurrentView();
35
+ i0.ɵɵelementStart(0, "kendo-icon", 15);
36
+ i0.ɵɵlistener("contextmenu", function NavigationComponent_kendo_drawer_container_3_ng_template_7_Template_kendo_icon_contextmenu_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r9 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r9.onTabContextMenu($event, 0)); });
37
+ i0.ɵɵelementEnd();
38
+ i0.ɵɵelementStart(1, "span", 16);
39
+ i0.ɵɵlistener("contextmenu", function NavigationComponent_kendo_drawer_container_3_ng_template_7_Template_span_contextmenu_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r11 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r11.onTabContextMenu($event, 0)); });
40
+ i0.ɵɵtext(2, "Home");
41
+ i0.ɵɵelementEnd();
42
+ } }
43
+ function NavigationComponent_kendo_drawer_container_3_ng_template_8_Template(rf, ctx) { if (rf & 1) {
44
+ i0.ɵɵelement(0, "router-outlet");
45
+ } }
46
+ function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_1_Template(rf, ctx) { if (rf & 1) {
47
+ const _r18 = i0.ɵɵgetCurrentView();
48
+ i0.ɵɵelementStart(0, "kendo-icon", 17);
49
+ i0.ɵɵlistener("contextmenu", function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_1_Template_kendo_icon_contextmenu_0_listener($event) { i0.ɵɵrestoreView(_r18); const i_r13 = i0.ɵɵnextContext().index; const ctx_r16 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r16.onTabContextMenu($event, i_r13)); });
50
+ i0.ɵɵelementEnd();
51
+ i0.ɵɵelementStart(1, "kendo-icon", 18);
52
+ i0.ɵɵlistener("contextmenu", function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_1_Template_kendo_icon_contextmenu_1_listener($event) { i0.ɵɵrestoreView(_r18); const i_r13 = i0.ɵɵnextContext().index; const ctx_r19 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r19.onTabContextMenu($event, i_r13)); });
53
+ i0.ɵɵelementEnd();
54
+ i0.ɵɵelementStart(2, "span", 16);
55
+ i0.ɵɵlistener("contextmenu", function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_1_Template_span_contextmenu_2_listener($event) { i0.ɵɵrestoreView(_r18); const i_r13 = i0.ɵɵnextContext().index; const ctx_r21 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r21.onTabContextMenu($event, i_r13)); });
56
+ i0.ɵɵtext(3);
57
+ i0.ɵɵelementEnd();
58
+ } if (rf & 2) {
59
+ const tab_r12 = i0.ɵɵnextContext().$implicit;
60
+ i0.ɵɵstyleProp("display", (tab_r12 == null ? null : tab_r12.contentLoading) ? "inline" : "none");
61
+ i0.ɵɵadvance(1);
62
+ i0.ɵɵstyleProp("display", !(tab_r12 == null ? null : tab_r12.contentLoading) && (tab_r12 == null ? null : tab_r12.icon) ? "inline" : "none");
63
+ i0.ɵɵproperty("name", tab_r12.icon);
64
+ i0.ɵɵadvance(2);
65
+ i0.ɵɵtextInterpolate(tab_r12.labelLoading ? "Loading..." : tab_r12.label);
66
+ } }
67
+ function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_2_Template(rf, ctx) { if (rf & 1) {
68
+ const _r26 = i0.ɵɵgetCurrentView();
69
+ i0.ɵɵelementStart(0, "app-resource", 19);
70
+ i0.ɵɵlistener("ResourceRecordSaved", function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_2_Template_app_resource_ResourceRecordSaved_0_listener() { i0.ɵɵrestoreView(_r26); const tab_r12 = i0.ɵɵnextContext().$implicit; const ctx_r24 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r24.SaveSingleWorkspaceItem(tab_r12)); })("ContentLoadingStarted", function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_2_Template_app_resource_ContentLoadingStarted_0_listener() { i0.ɵɵrestoreView(_r26); const tab_r12 = i0.ɵɵnextContext().$implicit; const ctx_r27 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r27.setTabContentLoadingStatus(tab_r12, true)); })("ContentLoadingComplete", function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_2_Template_app_resource_ContentLoadingComplete_0_listener() { i0.ɵɵrestoreView(_r26); const tab_r12 = i0.ɵɵnextContext().$implicit; const ctx_r29 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r29.setTabContentLoadingStatus(tab_r12, false)); });
71
+ i0.ɵɵelementEnd();
72
+ } if (rf & 2) {
73
+ const tab_r12 = i0.ɵɵnextContext().$implicit;
74
+ const ctx_r15 = i0.ɵɵnextContext(2);
75
+ i0.ɵɵproperty("Data", tab_r12.data)("isVisible", (tab_r12 == null ? null : tab_r12.id) === ctx_r15.getActiveTabId());
76
+ } }
77
+ function NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_Template(rf, ctx) { if (rf & 1) {
78
+ i0.ɵɵelementStart(0, "kendo-tabstrip-tab", 11);
79
+ i0.ɵɵtemplate(1, NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_1_Template, 4, 6, "ng-template", 12);
80
+ i0.ɵɵtemplate(2, NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_ng_template_2_Template, 1, 2, "ng-template", 13);
81
+ i0.ɵɵelementEnd();
82
+ } if (rf & 2) {
83
+ const tab_r12 = ctx.$implicit;
84
+ const ctx_r8 = i0.ɵɵnextContext(2);
85
+ i0.ɵɵproperty("selected", ctx_r8.isTabActive(tab_r12.id))("closable", true);
86
+ } }
87
+ function NavigationComponent_kendo_drawer_container_3_Template(rf, ctx) { if (rf & 1) {
88
+ const _r33 = i0.ɵɵgetCurrentView();
89
+ i0.ɵɵelementStart(0, "kendo-drawer-container")(1, "kendo-drawer", 6, 7);
90
+ i0.ɵɵlistener("select", function NavigationComponent_kendo_drawer_container_3_Template_kendo_drawer_select_1_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r32 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r32.onDrawerSelect($event)); });
91
+ i0.ɵɵelementEnd();
92
+ i0.ɵɵelementStart(3, "kendo-drawer-content", 8)(4, "kendo-tabstrip", 9, 10);
93
+ i0.ɵɵlistener("tabClose", function NavigationComponent_kendo_drawer_container_3_Template_kendo_tabstrip_tabClose_4_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r34 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r34.onClose($event)); })("tabSelect", function NavigationComponent_kendo_drawer_container_3_Template_kendo_tabstrip_tabSelect_4_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r35 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r35.onTabSelect($event)); });
94
+ i0.ɵɵelementStart(6, "kendo-tabstrip-tab", 11);
95
+ i0.ɵɵtemplate(7, NavigationComponent_kendo_drawer_container_3_ng_template_7_Template, 3, 0, "ng-template", 12);
96
+ i0.ɵɵtemplate(8, NavigationComponent_kendo_drawer_container_3_ng_template_8_Template, 1, 0, "ng-template", 13);
97
+ i0.ɵɵelementEnd();
98
+ i0.ɵɵtemplate(9, NavigationComponent_kendo_drawer_container_3_kendo_tabstrip_tab_9_Template, 3, 2, "kendo-tabstrip-tab", 14);
99
+ i0.ɵɵelementEnd()()();
100
+ } if (rf & 2) {
101
+ const ctx_r2 = i0.ɵɵnextContext();
102
+ i0.ɵɵadvance(1);
103
+ i0.ɵɵproperty("items", ctx_r2.drawerItems)("mode", ctx_r2.mode)("mini", ctx_r2.mini)("animation", false)("autoCollapse", false);
104
+ i0.ɵɵadvance(3);
105
+ i0.ɵɵproperty("scrollable", true)("keepTabContent", true)("animate", false);
106
+ i0.ɵɵadvance(2);
107
+ i0.ɵɵproperty("selected", ctx_r2.activeTabIndex === 0)("closable", false);
108
+ i0.ɵɵadvance(3);
109
+ i0.ɵɵproperty("ngForOf", ctx_r2.tabs);
110
+ } }
111
+ function NavigationComponent_div_4_Template(rf, ctx) { if (rf & 1) {
112
+ const _r37 = i0.ɵɵgetCurrentView();
113
+ i0.ɵɵelementStart(0, "div", 20)(1, "div", 21);
114
+ i0.ɵɵlistener("click", function NavigationComponent_div_4_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r37); const ctx_r36 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r36.handleContextMenuOption(1)); });
115
+ i0.ɵɵtext(2, "Close All");
116
+ i0.ɵɵelementEnd();
117
+ i0.ɵɵelementStart(3, "div", 21);
118
+ i0.ɵɵlistener("click", function NavigationComponent_div_4_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r37); const ctx_r38 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r38.handleContextMenuOption(2)); });
119
+ i0.ɵɵtext(4, "Close Others");
120
+ i0.ɵɵelementEnd();
121
+ i0.ɵɵelementStart(5, "div", 21);
122
+ i0.ɵɵlistener("click", function NavigationComponent_div_4_Template_div_click_5_listener() { i0.ɵɵrestoreView(_r37); const ctx_r39 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r39.handleContextMenuOption(3)); });
123
+ i0.ɵɵtext(6, "Close Tabs to the Right");
124
+ i0.ɵɵelementEnd()();
125
+ } if (rf & 2) {
126
+ const ctx_r3 = i0.ɵɵnextContext();
127
+ i0.ɵɵproperty("ngStyle", ctx_r3.contextMenuStyle);
128
+ } }
129
+ const _c3 = function (a0) { return { "waiting": a0 }; };
130
+ export class NavigationComponent {
131
+ onWindowResize() {
132
+ clearTimeout(this.resizeTimeout);
133
+ this.resizeTimeout = setTimeout(() => {
134
+ this.checkViewportSize();
135
+ }, 200); // Adjust the debounce time as needed
136
+ }
137
+ onClick() {
138
+ this.contextMenuVisible = false;
139
+ }
140
+ // Inject the authentication service into your component through the constructor
141
+ constructor(router, route, sharedService, location, renderer, titleService) {
142
+ this.router = router;
143
+ this.route = route;
144
+ this.sharedService = sharedService;
145
+ this.location = location;
146
+ this.renderer = renderer;
147
+ this.titleService = titleService;
148
+ this.drawerItems = [{
149
+ text: 'Loading...',
150
+ icon: 'k-i-apps',
151
+ }];
152
+ this.mode = 'push';
153
+ this.mini = true;
154
+ this.viewsList = [];
155
+ this.selectedDrawerItem = null;
156
+ this.selectedApp = null;
157
+ this.selectedEntity = null;
158
+ this.selectedView = null;
159
+ this.loading = true;
160
+ this.loader = false;
161
+ this.tabs = [];
162
+ this.closedTabs = []; // should always be empty after using it
163
+ this.tabQueryParams = {};
164
+ this.activeTabIndex = 0;
165
+ this.selectedTabIndex = 0;
166
+ this.workSpace = {};
167
+ this.workSpaceItems = [];
168
+ this.routeSub = null;
169
+ this.isMobileScreen = false;
170
+ this.contextMenuStyle = {};
171
+ this.contextMenuVisible = false;
172
+ this._loggedIn = false;
173
+ this._earlyEvents = [];
174
+ this.gotFirstNav = false;
175
+ this._mostRecentURL = '';
176
+ this.tabs = [];
177
+ }
178
+ onTabContextMenu(event, tab) {
179
+ event.preventDefault();
180
+ this.selectedTabIndex = tab;
181
+ const mouseEvent = event;
182
+ const mouseX = mouseEvent.clientX;
183
+ const mouseY = mouseEvent.clientY;
184
+ this.contextMenuStyle = {
185
+ top: mouseY + 'px',
186
+ left: mouseX + 'px'
187
+ };
188
+ this.contextMenuVisible = true;
189
+ }
190
+ handleContextMenuOption(option) {
191
+ return __awaiter(this, void 0, void 0, function* () {
192
+ this.closedTabs = [];
193
+ switch (option) {
194
+ case 1:
195
+ // Close All
196
+ this.closedTabs = this.closedTabs.concat(this.tabs);
197
+ this.tabs = [];
198
+ break;
199
+ case 2:
200
+ // Close Others
201
+ this.closedTabs = this.tabs.filter((tab, id) => id !== this.selectedTabIndex);
202
+ this.tabs = [this.tabs[this.selectedTabIndex]];
203
+ if (this.activeTabIndex > 1)
204
+ this.activeTabIndex = 1;
205
+ break;
206
+ case 3:
207
+ // Close Tabs to the Right
208
+ this.activeTabIndex = this.selectedTabIndex + 1;
209
+ this.closedTabs = this.closedTabs.concat(this.tabs.slice(this.activeTabIndex));
210
+ this.tabs = this.tabs.slice(0, this.selectedTabIndex + 1);
211
+ break;
212
+ default:
213
+ // Handle other options if needed
214
+ break;
215
+ }
216
+ this.contextMenuVisible = false;
217
+ for (let i = 0; i < this.closedTabs.length; ++i) {
218
+ const tab = this.closedTabs[i];
219
+ yield this.removeWorkspaceItem(tab);
220
+ }
221
+ this.activeTabIndex = 0;
222
+ this.tabstrip.selectTab(this.activeTabIndex);
223
+ // in this situation we have the home tab showing, so we need to update the URL path based on what's selected in the drawer
224
+ let url = this.selectedDrawerItem ? this.selectedDrawerItem.path : '/home';
225
+ this.router.navigate([url]);
226
+ //this.location.go(url); // update the browser URL if needed
227
+ this._mostRecentURL = url;
228
+ });
229
+ }
230
+ checkViewportSize() {
231
+ this.isMobileScreen = window.innerWidth <= 840;
232
+ }
233
+ ngAfterViewInit() {
234
+ MJGlobal.Instance.GetEventListener(true) // true gets us replay of past events so we can "catch up" as needed
235
+ .subscribe(event => {
236
+ this.handleEvent(event, event.args);
237
+ });
238
+ this.route.queryParams.subscribe(params => {
239
+ // what we want to do here is CACHE the params for the CURRENT tab so we have them
240
+ // to throw back in the URL whenever the tab gets clicked on again in the future
241
+ this.tabQueryParams['tab_' + this.activeTabIndex] = params;
242
+ });
243
+ }
244
+ handleEvent(event, args) {
245
+ return __awaiter(this, void 0, void 0, function* () {
246
+ // event handler
247
+ switch (event.event) {
248
+ case MJEventType.LoggedIn:
249
+ yield this.loadApp();
250
+ yield this.getWorkspace();
251
+ this._loggedIn = true;
252
+ // check for early events and replay them now that we're logged in
253
+ for (let i = 0; i < this._earlyEvents.length; ++i) {
254
+ const e = this._earlyEvents[i];
255
+ this.handleEvent(e.event, e.args); // recursve call to handle the event
256
+ }
257
+ this._earlyEvents.length = 0; // clear the array
258
+ // resize everything after a short delay
259
+ setTimeout(() => {
260
+ this.sharedService.InvokeManualResize();
261
+ }, 100);
262
+ this.checkForBaseURL();
263
+ break;
264
+ case MJEventType.ComponentEvent:
265
+ if (!this._loggedIn) {
266
+ // we're not logged in yet, so queue up the event to be handled later
267
+ this._earlyEvents.push({ event, args });
268
+ }
269
+ else {
270
+ // we're logged in so go ahead and handle normally
271
+ switch (event.eventCode) {
272
+ case EventCodes.ViewNotifications:
273
+ this.setActiveTabToHome();
274
+ break;
275
+ case EventCodes.ViewCreated:
276
+ case EventCodes.AddDashboard:
277
+ case EventCodes.AddReport:
278
+ case EventCodes.EntityRecordClicked:
279
+ case EventCodes.ViewClicked:
280
+ case EventCodes.ViewClicked:
281
+ case EventCodes.RunSearch:
282
+ // another component requested that we add something to our tab structure
283
+ this.AddOrSelectTab(event.args);
284
+ break;
285
+ default:
286
+ break;
287
+ }
288
+ }
289
+ break;
290
+ default:
291
+ break;
292
+ }
293
+ });
294
+ }
295
+ ngOnInit() {
296
+ this.checkViewportSize();
297
+ // Subscribe to route changes
298
+ this.routeSub = this.router.events.pipe().subscribe((args) => {
299
+ if (args instanceof NavigationEnd || args instanceof PopStateEvent) {
300
+ const trigger = args.navigationTrigger;
301
+ switch (trigger) {
302
+ case 'imperative':
303
+ // this is a programmatic navigation, so we don't want to do anything here
304
+ break;
305
+ case 'popstate':
306
+ // this is a browser back/forward navigation, so we want to do something here
307
+ // when the route changes and it maps to one of our drawer items, select it
308
+ this.NavigateFromUrl();
309
+ break;
310
+ default:
311
+ // this is a click on a link, so we want to do something here
312
+ // when the route changes and it maps to one of our drawer items, select it
313
+ this.NavigateFromUrl();
314
+ break;
315
+ }
316
+ }
317
+ else if (args instanceof NavigationSkipped) {
318
+ // check to see if the route in args is truly the same as the this.route
319
+ // if so, then we're navigating to the same route and we don't want to do anything
320
+ // if not, then we're navigating to a different route and we want to do something
321
+ if (this._mostRecentURL.trim().toLowerCase() != args.url.trim().toLowerCase()) {
322
+ this.NavigateFromUrl();
323
+ }
324
+ }
325
+ });
326
+ }
327
+ NavigateFromUrl() {
328
+ return __awaiter(this, void 0, void 0, function* () {
329
+ let url = this.router.url.trim().toLowerCase();
330
+ if (url === '/') {
331
+ this._mostRecentURL = '/home';
332
+ this.router.navigate(['/home']); // redirect to /home
333
+ this.gotFirstNav = true;
334
+ }
335
+ else {
336
+ this._mostRecentURL = this.router.url;
337
+ // see if this matches a drawer item or not
338
+ const di = this.drawerItems;
339
+ //const item = di.find(i => (<any>i).path.toLowerCase().trim() === url.toLowerCase().trim());
340
+ const item = di.find(i => url.toLowerCase().trim().startsWith(i.path.toLowerCase().trim()));
341
+ if (item) {
342
+ this.selectDrawerItem(this.drawerItems.indexOf(item));
343
+ this.gotFirstNav = true;
344
+ }
345
+ }
346
+ if (this.activeTabIndex > 0) {
347
+ // check to see if there are query params on the url and if so, stash em in the tabQueryParams array so we can restore the full set of query params later if we
348
+ // come back to this tab
349
+ const urlParts = this.router.url.split('?');
350
+ if (urlParts.length > 1) {
351
+ // we have query params, so stash em
352
+ const params = new URLSearchParams(urlParts[1]);
353
+ const keys = params.keys();
354
+ const queryParams = {};
355
+ for (const key of keys) {
356
+ queryParams[key] = params.get(key);
357
+ }
358
+ this.tabQueryParams['tab_' + this.activeTabIndex] = queryParams;
359
+ }
360
+ }
361
+ });
362
+ }
363
+ selectDrawerItem(index) {
364
+ this.selectedDrawerItem = this.drawerItems[index];
365
+ // Get the <ul> element that contains the <li> elements
366
+ const ulElement = this.drawerWrapper.nativeElement.querySelector('ul');
367
+ if (ulElement) {
368
+ // Get the <li> element at the specified index
369
+ const liElement = ulElement.children[index];
370
+ // add the k-selected class to the <li> element
371
+ this.renderer.addClass(liElement, 'k-selected');
372
+ // and remove k-selected from all other <li> within the <ul>
373
+ for (let i = 0; i < ulElement.children.length; ++i) {
374
+ if (i !== index)
375
+ this.renderer.removeClass(ulElement.children[i], 'k-selected');
376
+ }
377
+ }
378
+ // make sure that the first tab is selected since this is showing stuff in the Home/Nav tab
379
+ this.setActiveTabToHome();
380
+ }
381
+ setActiveTabToHome() {
382
+ if (this.activeTabIndex !== 0) {
383
+ this.activeTabIndex = 0;
384
+ this.tabstrip.selectTab(0);
385
+ //this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement).focus()
386
+ }
387
+ }
388
+ checkForBaseURL() {
389
+ setTimeout(() => {
390
+ // this is a hack to get the first navigation to work correctly when the route is to the / base URL that doesn't seem to trigger the rest of our code like all other routes
391
+ if (!this.gotFirstNav) {
392
+ this.gotFirstNav = true;
393
+ this.NavigateFromUrl();
394
+ }
395
+ }, 10);
396
+ }
397
+ getWorkspace() {
398
+ return __awaiter(this, void 0, void 0, function* () {
399
+ const md = new Metadata();
400
+ const rv = new RunView();
401
+ const workspaceParams = {
402
+ EntityName: "Workspaces",
403
+ ExtraFilter: `UserID=${md.CurrentUser.ID}`
404
+ };
405
+ const workspaces = yield rv.RunView(workspaceParams);
406
+ if (workspaces.Success) {
407
+ const workspaceRecord = yield md.GetEntityObject("Workspaces");
408
+ if (workspaces.Results.length) {
409
+ const workspace = workspaces.Results.find((workspace) => workspace.UserID === md.CurrentUser.ID);
410
+ yield workspaceRecord.Load(workspace.ID);
411
+ }
412
+ else {
413
+ workspaceRecord.NewRecord();
414
+ workspaceRecord.Name = `${md.CurrentUser.Name || md.CurrentUser.ID}'s Workspace`;
415
+ workspaceRecord.UserID = md.CurrentUser.ID;
416
+ yield workspaceRecord.Save();
417
+ }
418
+ this.workSpace = workspaceRecord;
419
+ const workspaceItemParams = {
420
+ EntityName: "Workspace Items",
421
+ ExtraFilter: `WorkspaceID='${this.workSpace.ID}'`
422
+ };
423
+ const workspaceItems = yield rv.RunView(workspaceItemParams);
424
+ if (workspaceItems.Success) {
425
+ this.workSpaceItems = workspaceItems.Results;
426
+ yield this.LoadWorkSpace();
427
+ }
428
+ }
429
+ });
430
+ }
431
+ LoadWorkSpace() {
432
+ return __awaiter(this, void 0, void 0, function* () {
433
+ const md = new Metadata();
434
+ this.tabs = []; // first clear out the tabs - this is often already the state but in case this is a full refresh, make sure we do this.
435
+ this.workSpaceItems.forEach((item, index) => __awaiter(this, void 0, void 0, function* () {
436
+ const itemData = item.Configuration ? JSON.parse(item.Configuration) : {};
437
+ const resourceData = new ResourceData({
438
+ ID: item.ID,
439
+ Name: item.Name,
440
+ ResourceTypeID: item.ResourceTypeID,
441
+ ResourceRecordID: item.ResourceRecordID,
442
+ Configuration: itemData,
443
+ });
444
+ const newTab = {
445
+ id: item.ID,
446
+ labelLoading: true,
447
+ contentLoading: false,
448
+ data: resourceData,
449
+ workspaceItem: null,
450
+ icon: resourceData.ResourceIcon
451
+ };
452
+ this.tabs.push(newTab);
453
+ setTimeout(() => __awaiter(this, void 0, void 0, function* () {
454
+ // non-blocking, load dynamically
455
+ newTab.label = yield this.GetWorkspaceItemDisplayName(resourceData);
456
+ newTab.labelLoading = false;
457
+ if (newTab === this.tabs[this.activeTabIndex - 1]) // subtract one since the activeTabIndex is relative to the full set of tabs and the this.tabs array doesn't include the HOME tab
458
+ this.setAppTitle(newTab.label);
459
+ }), 10);
460
+ }));
461
+ });
462
+ }
463
+ setAppTitle(title = '') {
464
+ if (title === '')
465
+ this.titleService.setTitle(this.applicationName);
466
+ else
467
+ this.titleService.setTitle(title + ' (' + this.applicationName + ')');
468
+ }
469
+ AddOrSelectTab(data) {
470
+ return __awaiter(this, void 0, void 0, function* () {
471
+ const t = this.tabs;
472
+ this.loader = true;
473
+ let existingTab;
474
+ if (data.ResourceType.trim().toLowerCase() === 'search results') {
475
+ // we have a different matching logic for search results because we want to match on the search input as well as the entity
476
+ existingTab = this.tabs.find(t => t.data.ResourceTypeID === data.ResourceTypeID &&
477
+ t.data.Configuration.Entity === data.Configuration.Entity &&
478
+ t.data.Configuration.SearchInput === data.Configuration.SearchInput);
479
+ }
480
+ else {
481
+ existingTab = this.tabs.find(t => t.data.ResourceTypeID === data.ResourceTypeID &&
482
+ t.data.ResourceRecordID === data.ResourceRecordID &&
483
+ data.ResourceRecordID !== null && data.ResourceRecordID !== undefined && data.ResourceRecordID > 0 // make sure that we don't match on null/undefined/0 ResourceRecordID's - these should always be NEW tabs
484
+ );
485
+ }
486
+ if (existingTab) {
487
+ const index = this.tabs.indexOf(existingTab);
488
+ this.activeTabIndex = index + 1; // add one because the HOME tab is not in the tabs array but it IS part of our tab structure
489
+ this.tabstrip.selectTab(this.activeTabIndex);
490
+ //this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement.nativeElement).focus()
491
+ this.scrollIntoView();
492
+ if (existingTab.label)
493
+ this.setAppTitle(existingTab.label);
494
+ else
495
+ this.setAppTitle();
496
+ this.loader = false;
497
+ }
498
+ else {
499
+ const newTab = {
500
+ id: -1,
501
+ data: data,
502
+ labelLoading: true,
503
+ contentLoading: false,
504
+ workspaceItem: null,
505
+ icon: data.ResourceIcon,
506
+ };
507
+ // save it before we push to the tabs colleciton because we want the WorkspaceItem ID to be populated in the tab.id before we initialize the new tab by adding it to the this.tabs array
508
+ yield this.SaveSingleWorkspaceItem(newTab);
509
+ // now add to data structure
510
+ this.tabs.push(newTab);
511
+ // select the new tab
512
+ this.activeTabIndex = this.tabs.length; // this is intentionally past array boundary because ActiveTabIndex includes the Home tab that is not part of the tabs array
513
+ this.tabstrip.selectTab(this.activeTabIndex);
514
+ //this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement).focus()
515
+ this.sharedService.InvokeManualResize();
516
+ this.scrollIntoView();
517
+ setTimeout(() => __awaiter(this, void 0, void 0, function* () {
518
+ // non-blocking this way
519
+ newTab.label = yield this.GetWorkspaceItemDisplayName(data); // do this after we fire up the loading so that we don't block anything
520
+ this.setAppTitle(newTab.label);
521
+ newTab.labelLoading = false;
522
+ this.loader = false;
523
+ }), 10);
524
+ }
525
+ });
526
+ }
527
+ updateBrowserURL(tab, data) {
528
+ // update the URL to reflect the current tab
529
+ // FIRST, construct the base URL based on the resource type
530
+ const rt = this.sharedService.ResourceTypeByID(data.ResourceTypeID);
531
+ let url = '/resource';
532
+ switch (rt === null || rt === void 0 ? void 0 : rt.Name.toLowerCase().trim()) {
533
+ case 'user views':
534
+ url += `/view/${data.ResourceRecordID}`;
535
+ break;
536
+ case 'dashboards':
537
+ url += `/dashboard/${data.ResourceRecordID}`;
538
+ break;
539
+ case 'reports':
540
+ url += `/report/${data.ResourceRecordID}`;
541
+ break;
542
+ case 'records':
543
+ url += `/record/${data.ResourceRecordID}?Entity=${data.Configuration.Entity}`;
544
+ break;
545
+ case 'search results':
546
+ url += `/search/${data.Configuration.SearchInput}?Entity=${data.Configuration.Entity}`;
547
+ break;
548
+ case 'settings':
549
+ url += `/settings`;
550
+ break;
551
+ case 'notifications':
552
+ url += `/notifications`;
553
+ break;
554
+ }
555
+ // SECOND, we need to, in some cases, append query params that the TAB had created, we don't know what those are, they could be anything. In the AfterViewInit() code above we cache
556
+ // these whenever they change for each tab.
557
+ // Split the URL into the path and existing query params
558
+ const [path, existingQuery] = url.split('?');
559
+ // Create a URLSearchParams object from the existing query params
560
+ const queryParams = new URLSearchParams(existingQuery);
561
+ // Your cached query params, assuming it's an object like { key1: 'value1', key2: 'value2' }
562
+ const tabIndex = this.tabs.indexOf(tab) + 1; // we add 1 Because the HOME tab is not in the array so we have to offset by 1 here for our data structure
563
+ const cachedQueryParams = this.tabQueryParams['tab_' + tabIndex]; // Replace with your actual method to get cached params
564
+ if (cachedQueryParams) {
565
+ // Merge cached query params if they don't already exist in the URL
566
+ const keys = Object.keys(cachedQueryParams);
567
+ for (const key of keys) {
568
+ if (!queryParams.has(key)) {
569
+ queryParams.append(key, cachedQueryParams[key]);
570
+ }
571
+ }
572
+ }
573
+ // Construct the new URL with merged query params
574
+ const params = queryParams.toString();
575
+ const newUrl = `${path}${params && params.length > 0 ? '?' + queryParams.toString() : ''}`;
576
+ // Update the most recent URL
577
+ this._mostRecentURL = newUrl;
578
+ // Update the browser URL without triggering Angular navigation
579
+ // this.location.go(newUrl);
580
+ this.router.navigateByUrl(newUrl); //, { skipLocationChange: true });
581
+ // Update the app title
582
+ this.setAppTitle(tab.label);
583
+ }
584
+ scrollIntoView() {
585
+ const containerElement = this.tabstrip.wrapper.nativeElement;
586
+ setTimeout(() => {
587
+ const newTabElement = containerElement.querySelector(`li:nth-child(${this.activeTabIndex + 1})`);
588
+ newTabElement.scrollIntoView({ inline: 'nearest' });
589
+ }, 200);
590
+ }
591
+ GetWorkspaceItemDisplayName(data) {
592
+ return __awaiter(this, void 0, void 0, function* () {
593
+ const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, data.ResourceType);
594
+ if (resourceReg) {
595
+ const resource = new resourceReg.SubClass();
596
+ return yield resource.GetResourceDisplayName(data);
597
+ }
598
+ else
599
+ return `Workspace Item ${data.ID}`;
600
+ });
601
+ }
602
+ SaveWorkspace() {
603
+ return __awaiter(this, void 0, void 0, function* () {
604
+ let bSuccess = true;
605
+ for (let i = 0; i < this.tabs.length; ++i) {
606
+ const tab = this.tabs[i];
607
+ bSuccess = (yield this.SaveSingleWorkspaceItem(tab)) && bSuccess;
608
+ }
609
+ return bSuccess;
610
+ });
611
+ }
612
+ SaveSingleWorkspaceItem(tab) {
613
+ var _a;
614
+ return __awaiter(this, void 0, void 0, function* () {
615
+ try {
616
+ let index = this.tabs.indexOf(tab);
617
+ if (index < 0)
618
+ index = this.tabs.length; // this situation occurs when the tab hasn't yet been added to the tabs collection so the index will be = the length of the tabs collection
619
+ const md = new Metadata();
620
+ let wsItem;
621
+ if (!tab.workspaceItem) {
622
+ wsItem = (yield md.GetEntityObject('Workspace Items'));
623
+ if (tab.data.ID && !isNaN(tab.data.ID) && tab.data.ID > 0)
624
+ yield wsItem.Load(tab.data.ID);
625
+ else {
626
+ wsItem.NewRecord();
627
+ wsItem.Name = tab.data.Name ? tab.data.Name : tab.data.ResourceType + ' Record ID:' + tab.data.ResourceRecordID;
628
+ wsItem.WorkSpaceID = this.workSpace.ID;
629
+ wsItem.ResourceTypeID = (_a = tab.data) === null || _a === void 0 ? void 0 : _a.ResourceTypeID;
630
+ }
631
+ tab.workspaceItem = wsItem;
632
+ }
633
+ else {
634
+ wsItem = tab.workspaceItem;
635
+ }
636
+ wsItem.ResourceRecordID = tab.data.ResourceRecordID;
637
+ wsItem.Sequence = index;
638
+ wsItem.Configuration = JSON.stringify(tab.data.Configuration); // JSON.stringify({ Entity: tab.data.Entity });
639
+ const result = yield wsItem.Save();
640
+ tab.id = wsItem.ID;
641
+ return result;
642
+ }
643
+ catch (err) {
644
+ LogError(err);
645
+ return false;
646
+ }
647
+ });
648
+ }
649
+ setTabContentLoadingStatus(tab, bLoading) {
650
+ tab.contentLoading = bLoading;
651
+ }
652
+ onClose(ev) {
653
+ return __awaiter(this, void 0, void 0, function* () {
654
+ if (ev.tab.selected) {
655
+ setTimeout(() => __awaiter(this, void 0, void 0, function* () {
656
+ // find the closest tab to the one we just closed
657
+ yield this.removeWorkspaceItem(this.tabs[ev.index - 1]);
658
+ if (ev.index < this.tabs.length + 1) {
659
+ // NOT the last tab, kendo by defulat will show the next tab, so let that be, but we need to update our routing info
660
+ // dont need to update active tab index or call selectTab() here because kendo does this and activetab index stays the same since we're closing the tab
661
+ const i = this.activeTabIndex > 0 ? this.activeTabIndex - 1 : 0;
662
+ const tabs = this.tabs;
663
+ const tab = tabs[i];
664
+ if (tab) {
665
+ const data = tab.data;
666
+ this.updateBrowserURL(tab, data);
667
+ }
668
+ }
669
+ else {
670
+ if (ev.index > 1) {
671
+ // the to-be-selected tab is a RESOURCE so do what's appropraite there
672
+ this.activeTabIndex = ev.index - 1;
673
+ this.tabstrip.selectTab(ev.index - 1);
674
+ //this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement).focus()
675
+ const i = this.activeTabIndex > 0 ? this.activeTabIndex - 1 : 0;
676
+ const tabs = this.tabs;
677
+ const tab = tabs[i];
678
+ if (tab) {
679
+ const data = tab.data;
680
+ this.updateBrowserURL(tab, data);
681
+ }
682
+ }
683
+ else {
684
+ // the tab that will be selected is the HOME tab o we need to update
685
+ this.activeTabIndex = 0;
686
+ this.tabstrip.selectTab(0);
687
+ //this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement).focus()
688
+ // in this situation we have the home tab showing, so we need to update the URL path based on what's selected in the drawer
689
+ let url = this.selectedDrawerItem ? this.selectedDrawerItem.path : '/home';
690
+ this.router.navigate([url]);
691
+ //this.location.go(url); // update the browser URL if needed
692
+ this._mostRecentURL = url;
693
+ }
694
+ }
695
+ }), 100);
696
+ }
697
+ });
698
+ }
699
+ removeWorkspaceItem(tab) {
700
+ return __awaiter(this, void 0, void 0, function* () {
701
+ // remove the tab from the tabs collection
702
+ const index = this.tabs.indexOf(tab);
703
+ if (index >= 0)
704
+ this.tabs.splice(index, 1);
705
+ if (!tab.workspaceItem && tab.id && tab.id > 0) {
706
+ // we lazy load the workspaceItem entity objects, so we load it here so we can delete it below, but only when it wasn't already loaded
707
+ const md = new Metadata();
708
+ tab.workspaceItem = (yield md.GetEntityObject('Workspace Items'));
709
+ yield tab.workspaceItem.Load(tab.id);
710
+ }
711
+ if (tab.workspaceItem) {
712
+ if (!(yield tab.workspaceItem.Delete())) {
713
+ // error deleting the workspace item, alert the user
714
+ this.sharedService.CreateSimpleNotification('Error deleting workspace item ' + tab.workspaceItem.Name + ' from the database. Please contact your system administrator.', 'error', 5000);
715
+ }
716
+ }
717
+ });
718
+ }
719
+ onTabSelect(e) {
720
+ e.preventDefault();
721
+ if (this.activeTabIndex !== e.index) {
722
+ this.activeTabIndex = e.index;
723
+ this.sharedService.InvokeManualResize();
724
+ if (e.index === 0) {
725
+ let url = this.selectedDrawerItem ? this.selectedDrawerItem.path : '/home';
726
+ if (this.selectedDrawerItem !== null && this.selectedDrawerItem !== undefined)
727
+ url = this.selectedDrawerItem.path;
728
+ this.router.navigate([url]);
729
+ //this.location.go(url); // update the browser URL if needed
730
+ this.setAppTitle();
731
+ this._mostRecentURL = url;
732
+ }
733
+ else {
734
+ const tab = this.tabs[e.index - 1];
735
+ if (tab) {
736
+ this.setAppTitle(tab.label);
737
+ const data = tab.data;
738
+ this.updateBrowserURL(tab, data);
739
+ }
740
+ }
741
+ }
742
+ }
743
+ getActiveTabId() {
744
+ var _a;
745
+ if (this.activeTabIndex === 0) {
746
+ return null;
747
+ }
748
+ else // subtract 1 from the activeTabIndex if it is not the first tab since our data structure is for tabs 1 to n
749
+ return (_a = this.tabs[this.activeTabIndex - 1]) === null || _a === void 0 ? void 0 : _a.id;
750
+ }
751
+ isTabActive(tabId) {
752
+ return this.getActiveTabId() === tabId;
753
+ }
754
+ ngOnDestroy() {
755
+ // Clean up the subscription when the component is destroyed
756
+ clearTimeout(this.resizeTimeout);
757
+ if (this.routeSub)
758
+ this.routeSub.unsubscribe();
759
+ window.removeEventListener('resize', () => { });
760
+ }
761
+ onDrawerSelect(ev) {
762
+ this.selectedDrawerItem = ev.item;
763
+ this.router.navigate([ev.item.path]);
764
+ this._mostRecentURL = ev.item.path;
765
+ // make sure that the first tab is selected since this is showing stuff in the Home/Nav tab
766
+ if (this.activeTabIndex !== 0) {
767
+ this.activeTabIndex = 0;
768
+ this.tabstrip.selectTab(0);
769
+ //this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement).focus()
770
+ }
771
+ this.setAppTitle(ev.item.text);
772
+ }
773
+ getEntityItemFromViewItem(viewItem) {
774
+ let entityItem = null;
775
+ for (let item of this.drawerItems) {
776
+ if (item.id == viewItem.parentId) {
777
+ // got the parent, this is the entity
778
+ return item;
779
+ }
780
+ }
781
+ return null;
782
+ }
783
+ getAppItemFromViewItem(viewItem) {
784
+ let entityItem = this.getEntityItemFromViewItem(viewItem), appItem = null;
785
+ if (entityItem)
786
+ for (let item of this.drawerItems) {
787
+ if (item.id == entityItem.parentId) {
788
+ // got the parent, this is the app
789
+ appItem = item;
790
+ break;
791
+ }
792
+ }
793
+ return appItem;
794
+ }
795
+ loadApp() {
796
+ return __awaiter(this, void 0, void 0, function* () {
797
+ const md = new Metadata();
798
+ yield this.LoadDrawer();
799
+ this.setDrawerConfig();
800
+ window.addEventListener('resize', () => {
801
+ this.setDrawerConfig();
802
+ });
803
+ });
804
+ }
805
+ LoadDrawer() {
806
+ return __awaiter(this, void 0, void 0, function* () {
807
+ const md = new Metadata();
808
+ this.drawerItems.length = 0; // clear the array
809
+ // the Drawer configuraion has the following sections:
810
+ /*
811
+ * Home - a simple view that shows all the other options - dashboards, reports, data, etc, and ALSO shows Favorites and Most Recently Used Records
812
+ * Ask Skip - interaction with Skip AI
813
+ * Data
814
+ * Dashboards
815
+ * Reports
816
+ * Settings
817
+ */
818
+ // Home
819
+ yield this.loadHome(md);
820
+ // Skip
821
+ yield this.loadSkip(md);
822
+ // Data
823
+ yield this.loadApplications(md);
824
+ // Dashboards
825
+ yield this.loadResourceType('Dashboards', 'Dashboards', '/dashboards', md.CurrentUser.ID);
826
+ // Reports
827
+ yield this.loadResourceType('Reports', 'Reports', '/reports', md.CurrentUser.ID);
828
+ // Settings
829
+ yield this.loadSettings(md);
830
+ this.loading = false;
831
+ });
832
+ }
833
+ loadSkip(md) {
834
+ return __awaiter(this, void 0, void 0, function* () {
835
+ const drawerItem = {
836
+ id: 'AskSkip',
837
+ selected: false,
838
+ text: 'Ask Skip',
839
+ path: '/askskip',
840
+ icon: 'k-i-user'
841
+ };
842
+ this.drawerItems.push(drawerItem);
843
+ });
844
+ }
845
+ loadHome(md) {
846
+ return __awaiter(this, void 0, void 0, function* () {
847
+ const drawerItem = {
848
+ id: 'Home',
849
+ selected: true,
850
+ text: 'Home',
851
+ path: '/home',
852
+ icon: 'k-i-home'
853
+ };
854
+ this.drawerItems.push(drawerItem);
855
+ });
856
+ }
857
+ loadSettings(md) {
858
+ return __awaiter(this, void 0, void 0, function* () {
859
+ const drawerItem = {
860
+ id: 'Settings',
861
+ selected: false,
862
+ text: 'Settings',
863
+ path: '/settings',
864
+ icon: 'k-i-gear'
865
+ };
866
+ this.drawerItems.push(drawerItem);
867
+ });
868
+ }
869
+ loadApplications(md) {
870
+ return __awaiter(this, void 0, void 0, function* () {
871
+ const drawerItem = {
872
+ id: 'Data',
873
+ selected: false,
874
+ text: 'Data',
875
+ path: '/data',
876
+ icon: 'k-i-data'
877
+ };
878
+ this.drawerItems.push(drawerItem);
879
+ });
880
+ }
881
+ loadResourceType(key, resourceType, path, currentUserID) {
882
+ return __awaiter(this, void 0, void 0, function* () {
883
+ const rt = this.sharedService.ResourceTypeByName(resourceType);
884
+ if (rt) {
885
+ const icon = rt.Icon;
886
+ const drawerItem = {
887
+ id: key,
888
+ selected: false,
889
+ text: resourceType,
890
+ path: path,
891
+ icon: icon ? 'k-i-' + icon : ''
892
+ };
893
+ this.drawerItems.push(drawerItem);
894
+ }
895
+ });
896
+ }
897
+ setDrawerConfig() {
898
+ const pageWidth = window.innerWidth;
899
+ if (pageWidth <= 840) {
900
+ this.mode = 'overlay';
901
+ this.mini = false;
902
+ }
903
+ else {
904
+ this.mode = 'push';
905
+ this.mini = true;
906
+ }
907
+ }
908
+ toggle() {
909
+ this.drawer.toggle();
910
+ this.sharedService.InvokeManualResize();
911
+ }
912
+ }
913
+ NavigationComponent.ɵfac = function NavigationComponent_Factory(t) { return new (t || NavigationComponent)(i0.ɵɵdirectiveInject(i1.Router), i0.ɵɵdirectiveInject(i1.ActivatedRoute), i0.ɵɵdirectiveInject(i2.SharedService), i0.ɵɵdirectiveInject(i3.Location), i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i4.Title)); };
914
+ NavigationComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NavigationComponent, selectors: [["app-navigation"]], viewQuery: function NavigationComponent_Query(rf, ctx) { if (rf & 1) {
915
+ i0.ɵɵviewQuery(DrawerComponent, 5);
916
+ i0.ɵɵviewQuery(_c0, 5);
917
+ i0.ɵɵviewQuery(_c1, 5);
918
+ i0.ɵɵviewQuery(_c2, 7, ElementRef);
919
+ } if (rf & 2) {
920
+ let _t;
921
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.drawer = _t.first);
922
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.drawerWrapper = _t.first);
923
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tabstrip = _t.first);
924
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.container = _t.first);
925
+ } }, hostVars: 2, hostBindings: function NavigationComponent_HostBindings(rf, ctx) { if (rf & 1) {
926
+ i0.ɵɵlistener("resize", function NavigationComponent_resize_HostBindingHandler() { return ctx.onWindowResize(); }, false, i0.ɵɵresolveWindow)("click", function NavigationComponent_click_HostBindingHandler() { return ctx.onClick(); }, false, i0.ɵɵresolveDocument);
927
+ } if (rf & 2) {
928
+ i0.ɵɵclassProp("mobile-screen", ctx.isMobileScreen);
929
+ } }, inputs: { applicationName: "applicationName" }, decls: 5, vars: 6, consts: [[1, "navigation-wrap", 3, "ngClass"], ["drawerWrapper", ""], ["type", "converging-spinner", 4, "ngIf"], [4, "ngIf"], ["class", "context-menu", 3, "ngStyle", 4, "ngIf"], ["type", "converging-spinner"], [3, "items", "mode", "mini", "animation", "autoCollapse", "select"], ["drawer", ""], ["mjFillContainer", ""], ["mjFillContainer", "", 1, "drawer-container", 3, "scrollable", "keepTabContent", "animate", "tabClose", "tabSelect"], ["tabstrip", ""], [3, "selected", "closable"], ["kendoTabTitle", ""], ["kendoTabContent", "", "class", "navigation-tab-contents"], [3, "selected", "closable", 4, "ngFor", "ngForOf"], ["name", "home", 3, "contextmenu"], [1, "nav-tab-title", 3, "contextmenu"], ["name", "clock", 3, "contextmenu"], [3, "name", "contextmenu"], [3, "Data", "isVisible", "ResourceRecordSaved", "ContentLoadingStarted", "ContentLoadingComplete"], [1, "context-menu", 3, "ngStyle"], [1, "context-menu-item", 3, "click"]], template: function NavigationComponent_Template(rf, ctx) { if (rf & 1) {
930
+ i0.ɵɵelementStart(0, "div", 0, 1);
931
+ i0.ɵɵtemplate(2, NavigationComponent_kendo_loader_2_Template, 1, 0, "kendo-loader", 2);
932
+ i0.ɵɵtemplate(3, NavigationComponent_kendo_drawer_container_3_Template, 10, 11, "kendo-drawer-container", 3);
933
+ i0.ɵɵelementEnd();
934
+ i0.ɵɵtemplate(4, NavigationComponent_div_4_Template, 7, 1, "div", 4);
935
+ } if (rf & 2) {
936
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(4, _c3, ctx.loader));
937
+ i0.ɵɵadvance(2);
938
+ i0.ɵɵproperty("ngIf", ctx.loading);
939
+ i0.ɵɵadvance(1);
940
+ i0.ɵɵproperty("ngIf", !ctx.loading);
941
+ i0.ɵɵadvance(1);
942
+ i0.ɵɵproperty("ngIf", ctx.contextMenuVisible);
943
+ } }, dependencies: [i3.NgClass, i3.NgForOf, i3.NgIf, i3.NgStyle, i1.RouterOutlet, i5.LoaderComponent, i6.TabStripComponent, i6.TabStripTabComponent, i6.TabContentDirective, i6.TabTitleDirective, i7.IconComponent, i8.FillContainer, i6.DrawerComponent, i6.DrawerContainerComponent, i6.DrawerContentComponent, i9.ResourceContainerComponent], styles: [".navigation-wrap[_ngcontent-%COMP%] {\r\n height: calc(100vh - 80px);\r\n width: 100%;\r\n overflow:hidden\r\n}\r\n\r\n.nav-tab-title[_ngcontent-%COMP%] {\r\n margin-left: 10px;\r\n}\r\n\r\n.context-menu[_ngcontent-%COMP%] {\r\n position: fixed;\r\n z-index: 9999;\r\n background-color: #ffffff;\r\n border: 1px solid #ccc;\r\n padding: 3px 3px;\r\n box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n.context-menu-item[_ngcontent-%COMP%] {\r\n padding: 8px 16px;\r\n cursor: pointer;\r\n}\r\n\r\n.context-menu-item[_ngcontent-%COMP%]:hover {\r\n background-color: #f1f1f1;\r\n}\r\n .navigation-wrap .drawer-container {\r\n padding: 20px;\r\n background: #FAFAFA;\r\n}\r\n .navigation-wrap .drawer-container .k-content {\r\n padding: 25px;\r\n}\r\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper {\r\n background: #fafafa;\r\n}\r\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item.k-active {\r\n border: 1px solid rgba(0, 0, 0, 0.08);\r\n}\r\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item {\r\n background: #fafafa;\r\n border-radius: 0;\r\n}"] });
944
+ (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NavigationComponent, [{
945
+ type: Component,
946
+ args: [{ selector: 'app-navigation', template: "<div class=\"navigation-wrap\" [ngClass]=\"{'waiting': loader}\" #drawerWrapper>\r\n <kendo-loader *ngIf=\"loading\" type=\"converging-spinner\" ></kendo-loader>\r\n <kendo-drawer-container *ngIf=\"!loading\" >\r\n <kendo-drawer\r\n #drawer\r\n [items]=\"drawerItems\"\r\n [mode]=\"mode\"\r\n [mini]=\"mini\"\r\n [animation]=\"false\"\r\n (select)=\"onDrawerSelect($event)\"\r\n [autoCollapse]=\"false\"\r\n >\r\n </kendo-drawer>\r\n <kendo-drawer-content mjFillContainer>\r\n <kendo-tabstrip mjFillContainer class=\"drawer-container\" [scrollable]=\"true\" [keepTabContent]=\"true\" (tabClose)=\"onClose($event)\" (tabSelect)=\"onTabSelect($event)\" [animate]=\"false\" #tabstrip>\r\n <kendo-tabstrip-tab [selected]=\"activeTabIndex === 0\" [closable]=\"false\">\r\n <ng-template kendoTabTitle>\r\n <kendo-icon name=\"home\" (contextmenu)=\"onTabContextMenu($event, 0)\"></kendo-icon>\r\n <span class=\"nav-tab-title\" (contextmenu)=\"onTabContextMenu($event, 0)\">Home</span>\r\n </ng-template>\r\n <ng-template kendoTabContent class=\"navigation-tab-contents\">\r\n <router-outlet></router-outlet>\r\n </ng-template>\r\n </kendo-tabstrip-tab>\r\n <kendo-tabstrip-tab *ngFor=\"let tab of tabs;let i = index\" [selected]=\"isTabActive(tab.id)\" [closable]=\"true\">\r\n <ng-template kendoTabTitle>\r\n <kendo-icon [style.display]=\"tab?.contentLoading ? 'inline' : 'none'\" name=\"clock\" (contextmenu)=\"onTabContextMenu($event, i)\"></kendo-icon>\r\n <kendo-icon [style.display]=\"!tab?.contentLoading && tab?.icon ? 'inline' : 'none'\" [name]=\"tab.icon\" (contextmenu)=\"onTabContextMenu($event, i)\"></kendo-icon>\r\n <!-- <kendo-icon *ngIf=\"tab?.contentLoading\" name=\"clock\"></kendo-icon>\r\n <kendo-icon *ngIf=\"!tab?.contentLoading && tab?.icon\" [name]=\"tab.icon\"></kendo-icon> -->\r\n <span class=\"nav-tab-title\" (contextmenu)=\"onTabContextMenu($event, i)\">{{ tab.labelLoading ? 'Loading...' : tab.label }}</span>\r\n </ng-template>\r\n <ng-template kendoTabContent class=\"navigation-tab-contents\">\r\n <app-resource [Data]=\"tab.data\" [isVisible]=\"tab?.id === getActiveTabId()\"\r\n (ResourceRecordSaved)=\"SaveSingleWorkspaceItem(tab)\"\r\n (ContentLoadingStarted)=\"setTabContentLoadingStatus(tab, true)\"\r\n (ContentLoadingComplete)=\"setTabContentLoadingStatus(tab, false)\"\r\n ></app-resource>\r\n </ng-template>\r\n </kendo-tabstrip-tab>\r\n </kendo-tabstrip>\r\n </kendo-drawer-content>\r\n </kendo-drawer-container>\r\n</div>\r\n\r\n<div class=\"context-menu\" [ngStyle]=\"contextMenuStyle\" *ngIf=\"contextMenuVisible\">\r\n <div class=\"context-menu-item\" (click)=\"handleContextMenuOption(1)\">Close All</div>\r\n <div class=\"context-menu-item\" (click)=\"handleContextMenuOption(2)\">Close Others</div>\r\n <div class=\"context-menu-item\" (click)=\"handleContextMenuOption(3)\">Close Tabs to the Right</div>\r\n </div>\r\n", styles: [".navigation-wrap {\r\n height: calc(100vh - 80px);\r\n width: 100%;\r\n overflow:hidden\r\n}\r\n\r\n.nav-tab-title {\r\n margin-left: 10px;\r\n}\r\n\r\n.context-menu {\r\n position: fixed;\r\n z-index: 9999;\r\n background-color: #ffffff;\r\n border: 1px solid #ccc;\r\n padding: 3px 3px;\r\n box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n.context-menu-item {\r\n padding: 8px 16px;\r\n cursor: pointer;\r\n}\r\n\r\n.context-menu-item:hover {\r\n background-color: #f1f1f1;\r\n}\r\n::ng-deep .navigation-wrap .drawer-container {\r\n padding: 20px;\r\n background: #FAFAFA;\r\n}\r\n::ng-deep .navigation-wrap .drawer-container .k-content {\r\n padding: 25px;\r\n}\r\n::ng-deep .navigation-wrap .drawer-container .k-tabstrip-items-wrapper {\r\n background: #fafafa;\r\n}\r\n::ng-deep .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item.k-active {\r\n border: 1px solid rgba(0, 0, 0, 0.08);\r\n}\r\n::ng-deep .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item {\r\n background: #fafafa;\r\n border-radius: 0;\r\n}\r\n"] }]
947
+ }], function () { return [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.SharedService }, { type: i3.Location }, { type: i0.Renderer2 }, { type: i4.Title }]; }, { applicationName: [{
948
+ type: Input
949
+ }], isMobileScreen: [{
950
+ type: HostBinding,
951
+ args: ['class.mobile-screen']
952
+ }], drawer: [{
953
+ type: ViewChild,
954
+ args: [DrawerComponent, { static: false }]
955
+ }], drawerWrapper: [{
956
+ type: ViewChild,
957
+ args: ['drawerWrapper', { static: false }]
958
+ }], tabstrip: [{
959
+ type: ViewChild,
960
+ args: ["tabstrip", { static: false }]
961
+ }], container: [{
962
+ type: ViewChild,
963
+ args: ['container', { static: true, read: ElementRef }]
964
+ }], onWindowResize: [{
965
+ type: HostListener,
966
+ args: ['window:resize']
967
+ }], onClick: [{
968
+ type: HostListener,
969
+ args: ['document:click']
970
+ }] }); })();