@memberjunction/ng-explorer-core 0.9.79 → 0.9.116

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