@memberjunction/ng-explorer-core 2.48.0 → 2.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-routing.module.js +40 -53
- package/dist/app-routing.module.js.map +1 -1
- package/dist/generic/Events.types.js +104 -0
- package/dist/generic/Events.types.js.map +1 -1
- package/dist/generic/Item.types.js +28 -14
- package/dist/generic/Item.types.js.map +1 -1
- package/dist/generic/PathData.types.js +5 -0
- package/dist/generic/PathData.types.js.map +1 -1
- package/dist/generic/app-nav-view.types.js +3 -1
- package/dist/generic/app-nav-view.types.js.map +1 -1
- package/dist/lib/app-view/application-view.component.js +273 -294
- package/dist/lib/app-view/application-view.component.js.map +1 -1
- package/dist/lib/auth-button/auth-button.component.js +13 -22
- package/dist/lib/auth-button/auth-button.component.js.map +1 -1
- package/dist/lib/base-browser-component/base-browser-component.js +96 -108
- package/dist/lib/base-browser-component/base-browser-component.js.map +1 -1
- package/dist/lib/dashboard-browser-component/dashboard-browser.component.js +106 -124
- package/dist/lib/dashboard-browser-component/dashboard-browser.component.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +257 -281
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/data-browser-component/data-browser.component.js +122 -137
- package/dist/lib/data-browser-component/data-browser.component.js.map +1 -1
- package/dist/lib/expansion-panel-component/expansion-panel-component.js +100 -117
- package/dist/lib/expansion-panel-component/expansion-panel-component.js.map +1 -1
- package/dist/lib/favorites/favorites.component.js +44 -54
- package/dist/lib/favorites/favorites.component.js.map +1 -1
- package/dist/lib/files/files.component.js +12 -11
- package/dist/lib/files/files.component.js.map +1 -1
- package/dist/lib/generic/form-toolbar.js +21 -20
- package/dist/lib/generic/form-toolbar.js.map +1 -1
- package/dist/lib/generic/resource-container-component.js +23 -20
- package/dist/lib/generic/resource-container-component.js.map +1 -1
- package/dist/lib/generic-browse-list/generic-browse-list.component.js +48 -46
- package/dist/lib/generic-browse-list/generic-browse-list.component.js.map +1 -1
- package/dist/lib/generic-browser-list/generic-browser-list.component.js +353 -386
- package/dist/lib/generic-browser-list/generic-browser-list.component.js.map +1 -1
- package/dist/lib/guards/auth-guard.service.js +4 -2
- package/dist/lib/guards/auth-guard.service.js.map +1 -1
- package/dist/lib/guards/entities.guard.js +1 -1
- package/dist/lib/guards/entities.guard.js.map +1 -1
- package/dist/lib/header/MSFT_UserImageService.js +4 -3
- package/dist/lib/header/MSFT_UserImageService.js.map +1 -1
- package/dist/lib/header/header.component.js +111 -121
- package/dist/lib/header/header.component.js.map +1 -1
- package/dist/lib/home-component/home.component.js +34 -42
- package/dist/lib/home-component/home.component.js.map +1 -1
- package/dist/lib/home-wrapper/home-wrapper.component.js +6 -6
- package/dist/lib/home-wrapper/home-wrapper.component.js.map +1 -1
- package/dist/lib/list-view/list-view.component.js +132 -152
- package/dist/lib/list-view/list-view.component.js.map +1 -1
- package/dist/lib/navigation/navigation.component.js +568 -615
- package/dist/lib/navigation/navigation.component.js.map +1 -1
- package/dist/lib/query-browser-component/query-browser.component.js +30 -39
- package/dist/lib/query-browser-component/query-browser.component.js.map +1 -1
- package/dist/lib/report-browser-component/report-browser.component.js +18 -30
- package/dist/lib/report-browser-component/report-browser.component.js.map +1 -1
- package/dist/lib/resource-browser/resource-browser.component.js +435 -457
- package/dist/lib/resource-browser/resource-browser.component.js.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +12 -25
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js +18 -31
- package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js +15 -28
- package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.js +35 -47
- package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/report-resource.component.js +15 -28
- package/dist/lib/resource-wrappers/report-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +21 -34
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +23 -37
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/single-application/single-application.component.js +15 -20
- package/dist/lib/single-application/single-application.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +81 -95
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +28 -29
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +51 -64
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +158 -165
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-entity/single-entity.component.js +106 -118
- package/dist/lib/single-entity/single-entity.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +265 -287
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-query/single-query.component.js +35 -44
- package/dist/lib/single-query/single-query.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.js +64 -73
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-report/single-report.component.js +33 -43
- package/dist/lib/single-report/single-report.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +18 -30
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/single-view/single-view.component.js +107 -124
- package/dist/lib/single-view/single-view.component.js.map +1 -1
- package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js +197 -210
- package/dist/lib/tabbed-dashboard/tabbed-dashboard.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +137 -155
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +10 -8
- package/dist/lib/user-profile/user-profile.component.js.map +1 -1
- package/dist/module.js +51 -51
- package/dist/module.js.map +1 -1
- package/package.json +25 -25
|
@@ -1,12 +1,3 @@
|
|
|
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
1
|
import { Component, ElementRef, ViewChild, HostListener, HostBinding, Input } from '@angular/core';
|
|
11
2
|
import { NavigationEnd, NavigationSkipped } from '@angular/router';
|
|
12
3
|
import { DrawerComponent } from "@progress/kendo-angular-layout";
|
|
@@ -146,6 +137,41 @@ function NavigationComponent_div_5_Template(rf, ctx) { if (rf & 1) {
|
|
|
146
137
|
i0.ɵɵproperty("ngStyle", ctx_r1.contextMenuStyle);
|
|
147
138
|
} }
|
|
148
139
|
export class NavigationComponent {
|
|
140
|
+
router;
|
|
141
|
+
route;
|
|
142
|
+
sharedService;
|
|
143
|
+
location;
|
|
144
|
+
renderer;
|
|
145
|
+
titleService;
|
|
146
|
+
cdr;
|
|
147
|
+
applicationName;
|
|
148
|
+
drawerItems = [{
|
|
149
|
+
text: 'Loading...',
|
|
150
|
+
icon: 'k-i-apps',
|
|
151
|
+
}];
|
|
152
|
+
mode = 'push';
|
|
153
|
+
mini = true;
|
|
154
|
+
viewsList = [];
|
|
155
|
+
selectedDrawerItem = null;
|
|
156
|
+
selectedApp = null;
|
|
157
|
+
selectedEntity = null;
|
|
158
|
+
selectedView = null;
|
|
159
|
+
loading = true;
|
|
160
|
+
loader = false;
|
|
161
|
+
tabs = [];
|
|
162
|
+
closedTabs = []; // should always be empty after using it
|
|
163
|
+
tabQueryParams = {};
|
|
164
|
+
workSpace = undefined;
|
|
165
|
+
workSpaceItems = [];
|
|
166
|
+
panelItems = [];
|
|
167
|
+
showExpansionPanel = false;
|
|
168
|
+
routeSub = null;
|
|
169
|
+
isMobileScreen = false;
|
|
170
|
+
resizeTimeout;
|
|
171
|
+
drawer;
|
|
172
|
+
mjTabStrip;
|
|
173
|
+
drawerWrapper;
|
|
174
|
+
container;
|
|
149
175
|
onWindowResize() {
|
|
150
176
|
clearTimeout(this.resizeTimeout);
|
|
151
177
|
this.resizeTimeout = setTimeout(() => {
|
|
@@ -155,6 +181,8 @@ export class NavigationComponent {
|
|
|
155
181
|
onClick() {
|
|
156
182
|
this.contextMenuVisible = false;
|
|
157
183
|
}
|
|
184
|
+
contextMenuStyle = {};
|
|
185
|
+
contextMenuVisible = false;
|
|
158
186
|
// Inject the authentication service into your component through the constructor
|
|
159
187
|
constructor(router, route, sharedService, location, renderer, titleService, cdr) {
|
|
160
188
|
this.router = router;
|
|
@@ -164,38 +192,9 @@ export class NavigationComponent {
|
|
|
164
192
|
this.renderer = renderer;
|
|
165
193
|
this.titleService = titleService;
|
|
166
194
|
this.cdr = cdr;
|
|
167
|
-
this.drawerItems = [{
|
|
168
|
-
text: 'Loading...',
|
|
169
|
-
icon: 'k-i-apps',
|
|
170
|
-
}];
|
|
171
|
-
this.mode = 'push';
|
|
172
|
-
this.mini = true;
|
|
173
|
-
this.viewsList = [];
|
|
174
|
-
this.selectedDrawerItem = null;
|
|
175
|
-
this.selectedApp = null;
|
|
176
|
-
this.selectedEntity = null;
|
|
177
|
-
this.selectedView = null;
|
|
178
|
-
this.loading = true;
|
|
179
|
-
this.loader = false;
|
|
180
|
-
this.tabs = [];
|
|
181
|
-
this.closedTabs = []; // should always be empty after using it
|
|
182
|
-
this.tabQueryParams = {};
|
|
183
|
-
this.workSpace = undefined;
|
|
184
|
-
this.workSpaceItems = [];
|
|
185
|
-
this.panelItems = [];
|
|
186
|
-
this.showExpansionPanel = false;
|
|
187
|
-
this.routeSub = null;
|
|
188
|
-
this.isMobileScreen = false;
|
|
189
|
-
this.contextMenuStyle = {};
|
|
190
|
-
this.contextMenuVisible = false;
|
|
191
|
-
this._contextMenuSelectedTabIndex = -1;
|
|
192
|
-
this._loggedIn = false;
|
|
193
|
-
this._earlyEvents = [];
|
|
194
|
-
this.gotFirstNav = false;
|
|
195
|
-
this._mostRecentURL = '';
|
|
196
|
-
this._mostRecentHomeURL = ''; // used only when we're on the home tab so we can remember the full URL for the HOME tab when we come back to it from another tab
|
|
197
195
|
this.tabs = [];
|
|
198
196
|
}
|
|
197
|
+
_contextMenuSelectedTabIndex = -1;
|
|
199
198
|
handleTabContextMenu(event) {
|
|
200
199
|
event.mouseEvent.preventDefault();
|
|
201
200
|
this._contextMenuSelectedTabIndex = event.index;
|
|
@@ -207,55 +206,53 @@ export class NavigationComponent {
|
|
|
207
206
|
};
|
|
208
207
|
this.contextMenuVisible = true;
|
|
209
208
|
}
|
|
210
|
-
handleContextMenuOption(option) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
});
|
|
209
|
+
async handleContextMenuOption(option) {
|
|
210
|
+
this.closedTabs = [];
|
|
211
|
+
switch (option) {
|
|
212
|
+
case 1:
|
|
213
|
+
// Close All
|
|
214
|
+
this.closedTabs = this.closedTabs.concat(this.tabs);
|
|
215
|
+
this.tabs = [];
|
|
216
|
+
break;
|
|
217
|
+
case 2:
|
|
218
|
+
// Close Others
|
|
219
|
+
// the _contextMenuSelectedTabIndex is the index of the tab that was right-clicked on and it INCLUDES the home tab so we have to adjust it
|
|
220
|
+
// keep just that item
|
|
221
|
+
if (this._contextMenuSelectedTabIndex > 0) {
|
|
222
|
+
this.closedTabs = this.tabs.filter((tab, index) => index !== this._contextMenuSelectedTabIndex - 1);
|
|
223
|
+
this.tabs = [this.tabs[this._contextMenuSelectedTabIndex - 1]];
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
case 3:
|
|
227
|
+
// Close Tabs to the Right
|
|
228
|
+
const currentTabIndex = this._contextMenuSelectedTabIndex - 1; // because the HOME tab is not in the array so we have to offset by 1 here for our data structure
|
|
229
|
+
this.closedTabs = this.tabs.slice(currentTabIndex + 1); // close everything to right
|
|
230
|
+
this.tabs = this.tabs.slice(0, currentTabIndex + 1);
|
|
231
|
+
break;
|
|
232
|
+
default:
|
|
233
|
+
// Handle other options if needed
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
this.contextMenuVisible = false;
|
|
237
|
+
const md = new Metadata();
|
|
238
|
+
const transGroup = await md.CreateTransactionGroup();
|
|
239
|
+
for (let i = 0; i < this.closedTabs.length; ++i) {
|
|
240
|
+
const tab = this.closedTabs[i];
|
|
241
|
+
await this.removeWorkspaceItem(tab, transGroup);
|
|
242
|
+
}
|
|
243
|
+
transGroup.Submit(); // INTENTIONALLY NOT USING AWAIT here - let's let the database updates for workspace edits happen in the background, no need to wait
|
|
244
|
+
await this.waitForDomUpdate(); // make sure the DOM is updated before we do anything else so that the tab control knows about the changes from our data structure changes ABOVE
|
|
245
|
+
if (this.activeTabIndex > this.tabs.length) // DO NOT add 1 here because in this case, the array boundary is the max for the tab control
|
|
246
|
+
this.activeTabIndex = this.tabs.length; // don't subtract 1 here because the activeTabIndex is relative to the full set of tabs and the this.tabs array doesn't include the HOME tab
|
|
247
|
+
else
|
|
248
|
+
this.activeTabIndex = this.activeTabIndex; // this is a hack to force the tab control to update the selected tab
|
|
249
|
+
if (this.activeTabIndex === 0) {
|
|
250
|
+
// 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
|
|
251
|
+
let url = this.selectedDrawerItem ? this.selectedDrawerItem.path : '/home';
|
|
252
|
+
this.router.navigate([url]);
|
|
253
|
+
//this.location.go(url); // update the browser URL if needed
|
|
254
|
+
this._mostRecentURL = url;
|
|
255
|
+
}
|
|
259
256
|
}
|
|
260
257
|
checkViewportSize() {
|
|
261
258
|
this.isMobileScreen = window.innerWidth <= 840;
|
|
@@ -271,68 +268,69 @@ export class NavigationComponent {
|
|
|
271
268
|
this.tabQueryParams['tab_' + this.activeTabIndex] = params;
|
|
272
269
|
});
|
|
273
270
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
271
|
+
_loggedIn = false;
|
|
272
|
+
_earlyEvents = [];
|
|
273
|
+
async handleEvent(event, args) {
|
|
274
|
+
// event handler
|
|
275
|
+
switch (event.event) {
|
|
276
|
+
case MJEventType.LoggedIn:
|
|
277
|
+
await this.loadApp();
|
|
278
|
+
await this.loadWorkspace();
|
|
279
|
+
this._loggedIn = true;
|
|
280
|
+
// check for early events and replay them now that we're logged in
|
|
281
|
+
for (let i = 0; i < this._earlyEvents.length; ++i) {
|
|
282
|
+
const e = this._earlyEvents[i];
|
|
283
|
+
this.handleEvent(e.event, e.args); // recursve call to handle the event
|
|
284
|
+
}
|
|
285
|
+
this._earlyEvents.length = 0; // clear the array
|
|
286
|
+
// resize everything after a short delay
|
|
287
|
+
setTimeout(() => {
|
|
288
|
+
this.sharedService.InvokeManualResize();
|
|
289
|
+
}, 100);
|
|
290
|
+
this.checkForBaseURL();
|
|
291
|
+
break;
|
|
292
|
+
case MJEventType.ComponentEvent:
|
|
293
|
+
if (!this._loggedIn) {
|
|
294
|
+
// we're not logged in yet, so queue up the event to be handled later
|
|
295
|
+
this._earlyEvents.push({ event, args });
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// we're logged in so go ahead and handle normally
|
|
299
|
+
switch (event.eventCode) {
|
|
300
|
+
case EventCodes.ViewNotifications:
|
|
301
|
+
this.setActiveTabToHome();
|
|
302
|
+
break;
|
|
303
|
+
case EventCodes.ViewCreated:
|
|
304
|
+
case EventCodes.AddDashboard:
|
|
305
|
+
case EventCodes.AddReport:
|
|
306
|
+
case EventCodes.AddQuery:
|
|
307
|
+
case EventCodes.EntityRecordClicked:
|
|
308
|
+
case EventCodes.ViewClicked:
|
|
309
|
+
case EventCodes.ViewClicked:
|
|
310
|
+
case EventCodes.RunSearch:
|
|
311
|
+
case EventCodes.ListCreated:
|
|
312
|
+
case EventCodes.ListClicked:
|
|
313
|
+
// another component requested that we add something to our tab structure
|
|
314
|
+
this.AddOrSelectTab(event.args);
|
|
315
|
+
break;
|
|
316
|
+
case EventCodes.CloseCurrentTab:
|
|
317
|
+
if (this.mjTabStrip && this.activeTabIndex > 0) {
|
|
318
|
+
this.mjTabStrip.CloseTab(this.activeTabIndex);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
LogError("no active tab to close or tabstrip not available");
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
default:
|
|
325
|
+
break;
|
|
329
326
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
327
|
+
}
|
|
328
|
+
break;
|
|
329
|
+
default:
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
335
332
|
}
|
|
333
|
+
gotFirstNav = false;
|
|
336
334
|
ngOnInit() {
|
|
337
335
|
this.checkViewportSize();
|
|
338
336
|
// Subscribe to route changes
|
|
@@ -365,48 +363,48 @@ export class NavigationComponent {
|
|
|
365
363
|
}
|
|
366
364
|
});
|
|
367
365
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
366
|
+
_mostRecentURL = '';
|
|
367
|
+
_mostRecentHomeURL = ''; // used only when we're on the home tab so we can remember the full URL for the HOME tab when we come back to it from another tab
|
|
368
|
+
async NavigateFromUrl() {
|
|
369
|
+
let url = this.router.url.trim().toLowerCase();
|
|
370
|
+
if (url === '/') {
|
|
371
|
+
this._mostRecentURL = '/home';
|
|
372
|
+
this.router.navigate(['/home']); // redirect to /home
|
|
373
|
+
this.gotFirstNav = true;
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
this._mostRecentURL = this.router.url;
|
|
377
|
+
// see if this matches a drawer item or not
|
|
378
|
+
const item = this.drawerItems.find(i => url.toLowerCase().trim().startsWith(i.path?.toLowerCase().trim()));
|
|
379
|
+
if (item) {
|
|
380
|
+
this.selectDrawerItem(this.drawerItems.indexOf(item));
|
|
374
381
|
this.gotFirstNav = true;
|
|
375
382
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
// come back to this tab
|
|
388
|
-
const urlParts = this.router.url.split('?');
|
|
389
|
-
if (urlParts.length > 1) {
|
|
390
|
-
// we have query params, so stash them
|
|
391
|
-
const params = new URLSearchParams(urlParts[1]);
|
|
392
|
-
const queryParams = {};
|
|
393
|
-
for (const [key, value] of params.entries()) {
|
|
394
|
-
queryParams[key] = value;
|
|
395
|
-
}
|
|
396
|
-
this.tabQueryParams['tab_' + this.activeTabIndex] = queryParams;
|
|
383
|
+
}
|
|
384
|
+
if (this.activeTabIndex > 0) {
|
|
385
|
+
// 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
|
|
386
|
+
// come back to this tab
|
|
387
|
+
const urlParts = this.router.url.split('?');
|
|
388
|
+
if (urlParts.length > 1) {
|
|
389
|
+
// we have query params, so stash them
|
|
390
|
+
const params = new URLSearchParams(urlParts[1]);
|
|
391
|
+
const queryParams = {};
|
|
392
|
+
for (const [key, value] of params.entries()) {
|
|
393
|
+
queryParams[key] = value;
|
|
397
394
|
}
|
|
395
|
+
this.tabQueryParams['tab_' + this.activeTabIndex] = queryParams;
|
|
398
396
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
397
|
+
}
|
|
398
|
+
if (url.toLowerCase().includes('/app') && this.activeTabIndex > 0) {
|
|
399
|
+
this.setActiveTabToHome();
|
|
400
|
+
}
|
|
401
|
+
// finally, if we are on the home tab, update the _mostRecentHomeURL property to the current URL
|
|
402
|
+
if (this.activeTabIndex === 0) {
|
|
403
|
+
// only update the most recent home URL if we have a url that starts with something that is in the drawer
|
|
404
|
+
// or /app
|
|
405
|
+
if (!url.startsWith('/home') && (url.startsWith("/app") || this.drawerItems.find((item) => url.startsWith(item.path))))
|
|
406
|
+
this._mostRecentHomeURL = url;
|
|
407
|
+
}
|
|
410
408
|
}
|
|
411
409
|
selectDrawerItem(index) {
|
|
412
410
|
this.selectedDrawerItem = this.drawerItems[index];
|
|
@@ -477,87 +475,83 @@ export class NavigationComponent {
|
|
|
477
475
|
/**
|
|
478
476
|
* This method will load the user's workspace and all the workspace items that are part of the workspace from the database.
|
|
479
477
|
*/
|
|
480
|
-
loadWorkspace() {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
if (workspaces.
|
|
492
|
-
|
|
493
|
-
this.workSpace = workspaces.Results[0]; // by default get the first one, and since we are sorting by __mj_UpdatedAt DESC above, will be most recently modified one. Future feature for multi-workspace support we'll have to adjust this
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
// no matching record found, so create a new one
|
|
497
|
-
this.workSpace = yield md.GetEntityObject('Workspaces');
|
|
498
|
-
this.workSpace.NewRecord();
|
|
499
|
-
this.workSpace.Name = `${md.CurrentUser.Name || md.CurrentUser.ID}'s Workspace`;
|
|
500
|
-
this.workSpace.UserID = md.CurrentUser.ID;
|
|
501
|
-
yield this.workSpace.Save();
|
|
502
|
-
}
|
|
503
|
-
if (!this.workSpace)
|
|
504
|
-
throw new Error('Error loading workspace');
|
|
505
|
-
if (this.workSpace.IsSaved) {
|
|
506
|
-
const workspaceItemParams = {
|
|
507
|
-
EntityName: "Workspace Items",
|
|
508
|
-
ExtraFilter: `WorkspaceID='${this.workSpace.ID}'`,
|
|
509
|
-
OrderBy: "Sequence ASC", // get them in order
|
|
510
|
-
ResultType: "entity_object" /*we want entity objects back so that we can modify them as needed*/
|
|
511
|
-
};
|
|
512
|
-
const workspaceItems = yield rv.RunView(workspaceItemParams);
|
|
513
|
-
if (workspaceItems.Success) {
|
|
514
|
-
this.workSpaceItems = workspaceItems.Results;
|
|
515
|
-
yield this.LoadWorkspaceItems();
|
|
516
|
-
}
|
|
517
|
-
}
|
|
478
|
+
async loadWorkspace() {
|
|
479
|
+
const md = new Metadata();
|
|
480
|
+
const rv = new RunView();
|
|
481
|
+
const workspaceParams = {
|
|
482
|
+
EntityName: "Workspaces",
|
|
483
|
+
ExtraFilter: `UserID='${md.CurrentUser.ID}'`,
|
|
484
|
+
OrderBy: "__mj_UpdatedAt DESC", // by default get the workspace that was most recently updated
|
|
485
|
+
ResultType: "entity_object" /*we want entity objects back so that we can modify them as needed*/
|
|
486
|
+
};
|
|
487
|
+
const workspaces = await rv.RunView(workspaceParams);
|
|
488
|
+
if (workspaces.Success) {
|
|
489
|
+
if (workspaces.Results.length) {
|
|
490
|
+
this.workSpace = workspaces.Results[0]; // by default get the first one, and since we are sorting by __mj_UpdatedAt DESC above, will be most recently modified one. Future feature for multi-workspace support we'll have to adjust this
|
|
518
491
|
}
|
|
519
|
-
else
|
|
492
|
+
else {
|
|
493
|
+
// no matching record found, so create a new one
|
|
494
|
+
this.workSpace = await md.GetEntityObject('Workspaces');
|
|
495
|
+
this.workSpace.NewRecord();
|
|
496
|
+
this.workSpace.Name = `${md.CurrentUser.Name || md.CurrentUser.ID}'s Workspace`;
|
|
497
|
+
this.workSpace.UserID = md.CurrentUser.ID;
|
|
498
|
+
await this.workSpace.Save();
|
|
499
|
+
}
|
|
500
|
+
if (!this.workSpace)
|
|
520
501
|
throw new Error('Error loading workspace');
|
|
521
|
-
|
|
502
|
+
if (this.workSpace.IsSaved) {
|
|
503
|
+
const workspaceItemParams = {
|
|
504
|
+
EntityName: "Workspace Items",
|
|
505
|
+
ExtraFilter: `WorkspaceID='${this.workSpace.ID}'`,
|
|
506
|
+
OrderBy: "Sequence ASC", // get them in order
|
|
507
|
+
ResultType: "entity_object" /*we want entity objects back so that we can modify them as needed*/
|
|
508
|
+
};
|
|
509
|
+
const workspaceItems = await rv.RunView(workspaceItemParams);
|
|
510
|
+
if (workspaceItems.Success) {
|
|
511
|
+
this.workSpaceItems = workspaceItems.Results;
|
|
512
|
+
await this.LoadWorkspaceItems();
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
else
|
|
517
|
+
throw new Error('Error loading workspace');
|
|
522
518
|
}
|
|
523
519
|
/**
|
|
524
520
|
* This method will load all the workspace items that are part of the workspace currently set in the workSpace member variable
|
|
525
521
|
*/
|
|
526
|
-
LoadWorkspaceItems() {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
this.mjTabStrip.SelectedTabIndex = 0;
|
|
560
|
-
});
|
|
522
|
+
async LoadWorkspaceItems() {
|
|
523
|
+
const md = new Metadata();
|
|
524
|
+
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.
|
|
525
|
+
for (let item of this.workSpaceItems) {
|
|
526
|
+
const itemData = item.Configuration ? JSON.parse(item.Configuration) : {};
|
|
527
|
+
const resourceData = new ResourceData({
|
|
528
|
+
ID: item.ID,
|
|
529
|
+
Name: item.Name,
|
|
530
|
+
ResourceTypeID: item.ResourceTypeID,
|
|
531
|
+
ResourceRecordID: item.ResourceRecordID,
|
|
532
|
+
Configuration: itemData,
|
|
533
|
+
});
|
|
534
|
+
const newTab = {
|
|
535
|
+
id: item.ID,
|
|
536
|
+
labelLoading: true,
|
|
537
|
+
contentLoading: false,
|
|
538
|
+
data: resourceData,
|
|
539
|
+
workspaceItem: item, // provide the entity object here so we can modify it later if needed
|
|
540
|
+
icon: resourceData.ResourceIcon
|
|
541
|
+
};
|
|
542
|
+
// now add to data structure
|
|
543
|
+
await this.internalAddTab(newTab);
|
|
544
|
+
setTimeout(async () => {
|
|
545
|
+
// non-blocking, load the resource names dynamically as this requires additional DB lookups
|
|
546
|
+
newTab.label = await this.GetWorkspaceItemDisplayName(resourceData);
|
|
547
|
+
const resourceDynamicIcon = await this.GetWorkspaceItemIconClass(resourceData);
|
|
548
|
+
newTab.icon = resourceDynamicIcon ? resourceDynamicIcon : newTab.icon;
|
|
549
|
+
newTab.labelLoading = false;
|
|
550
|
+
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
|
|
551
|
+
this.setAppTitle(newTab.label);
|
|
552
|
+
}, 10);
|
|
553
|
+
}
|
|
554
|
+
this.mjTabStrip.SelectedTabIndex = 0;
|
|
561
555
|
}
|
|
562
556
|
setAppTitle(title = '') {
|
|
563
557
|
if (title === '')
|
|
@@ -621,68 +615,64 @@ export class NavigationComponent {
|
|
|
621
615
|
* This utility method is used to either Add a tab if a matching tab for the given data parameter isn't found, or to select the existing tab if it already exists.
|
|
622
616
|
* @param data
|
|
623
617
|
*/
|
|
624
|
-
AddOrSelectTab(data) {
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
618
|
+
async AddOrSelectTab(data) {
|
|
619
|
+
const t = this.tabs;
|
|
620
|
+
this.loader = true;
|
|
621
|
+
const existingTab = this.findExistingTab(data);
|
|
622
|
+
if (existingTab) {
|
|
623
|
+
// merge the data that we are provided with in terms of its raw query params with the existing tab
|
|
624
|
+
// override existing values in the data.Configuration.___rawQueryParams from keys in the data.Configuration.___rawQueryParams
|
|
625
|
+
existingTab.data.Configuration.___rawQueryParams = { ...existingTab.data.Configuration.___rawQueryParams, ...data.Configuration.___rawQueryParams };
|
|
626
|
+
const index = this.tabs.indexOf(existingTab);
|
|
627
|
+
// next, before we set the active tab, we need to merge the query params that we have for this tab with the query params that we have for the tab that we're about to select
|
|
628
|
+
// when the app first loads there won't be any query params for the tabs, but as we navigate around and the tabs get selected, we'll cache the query params for each tab
|
|
629
|
+
const tqp = this.tabQueryParams['tab_' + (index + 1)];
|
|
630
|
+
if (tqp)
|
|
631
|
+
this.tabQueryParams['tab_' + (index + 1)] = { ...tqp, ...existingTab.data.Configuration.___rawQueryParams };
|
|
632
|
+
else
|
|
633
|
+
this.tabQueryParams['tab_' + (index + 1)] = existingTab.data.Configuration.___rawQueryParams;
|
|
634
|
+
// add one because the HOME tab is not in the tabs array but it IS part of our tab structure
|
|
635
|
+
this.activeTabIndex = index + 1;
|
|
636
|
+
this.scrollIntoView();
|
|
637
|
+
if (existingTab.label)
|
|
638
|
+
this.setAppTitle(existingTab.label);
|
|
639
|
+
else
|
|
640
|
+
this.setAppTitle();
|
|
641
|
+
this.loader = false;
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
const newTab = {
|
|
645
|
+
id: "", // initially blank but will be changed to the WorkspaceItem ID once we save it
|
|
646
|
+
data: data,
|
|
647
|
+
labelLoading: true,
|
|
648
|
+
contentLoading: false,
|
|
649
|
+
workspaceItem: null,
|
|
650
|
+
icon: data.ResourceIcon,
|
|
651
|
+
};
|
|
652
|
+
// 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
|
|
653
|
+
await this.SaveSingleWorkspaceItem(newTab);
|
|
654
|
+
// now add to data structure
|
|
655
|
+
await this.internalAddTab(newTab);
|
|
656
|
+
// select the new tab
|
|
657
|
+
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
|
|
658
|
+
this.sharedService.InvokeManualResize();
|
|
659
|
+
this.scrollIntoView();
|
|
660
|
+
setTimeout(async () => {
|
|
661
|
+
// non-blocking this way
|
|
662
|
+
newTab.label = await this.GetWorkspaceItemDisplayName(data); // do this after we fire up the loading so that we don't block anything
|
|
663
|
+
const resourceDynamicIcon = await this.GetWorkspaceItemIconClass(data);
|
|
664
|
+
newTab.icon = resourceDynamicIcon ? resourceDynamicIcon : newTab.icon;
|
|
665
|
+
this.setAppTitle(newTab.label);
|
|
666
|
+
newTab.labelLoading = false;
|
|
648
667
|
this.loader = false;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
const newTab = {
|
|
652
|
-
id: "", // initially blank but will be changed to the WorkspaceItem ID once we save it
|
|
653
|
-
data: data,
|
|
654
|
-
labelLoading: true,
|
|
655
|
-
contentLoading: false,
|
|
656
|
-
workspaceItem: null,
|
|
657
|
-
icon: data.ResourceIcon,
|
|
658
|
-
};
|
|
659
|
-
// 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
|
|
660
|
-
yield this.SaveSingleWorkspaceItem(newTab);
|
|
661
|
-
// now add to data structure
|
|
662
|
-
yield this.internalAddTab(newTab);
|
|
663
|
-
// select the new tab
|
|
664
|
-
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
|
|
665
|
-
this.sharedService.InvokeManualResize();
|
|
666
|
-
this.scrollIntoView();
|
|
667
|
-
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
668
|
-
// non-blocking this way
|
|
669
|
-
newTab.label = yield this.GetWorkspaceItemDisplayName(data); // do this after we fire up the loading so that we don't block anything
|
|
670
|
-
const resourceDynamicIcon = yield this.GetWorkspaceItemIconClass(data);
|
|
671
|
-
newTab.icon = resourceDynamicIcon ? resourceDynamicIcon : newTab.icon;
|
|
672
|
-
this.setAppTitle(newTab.label);
|
|
673
|
-
newTab.labelLoading = false;
|
|
674
|
-
this.loader = false;
|
|
675
|
-
}), 10);
|
|
676
|
-
}
|
|
677
|
-
});
|
|
668
|
+
}, 10);
|
|
669
|
+
}
|
|
678
670
|
}
|
|
679
|
-
internalAddTab(newTab) {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
yield this.waitForDomUpdate();
|
|
685
|
-
});
|
|
671
|
+
async internalAddTab(newTab) {
|
|
672
|
+
// add the tab to the tabs collection
|
|
673
|
+
this.tabs.push(newTab);
|
|
674
|
+
// Manually trigger change detection and wait for DOM updates
|
|
675
|
+
await this.waitForDomUpdate();
|
|
686
676
|
}
|
|
687
677
|
waitForDomUpdate() {
|
|
688
678
|
return new Promise(resolve => {
|
|
@@ -692,16 +682,15 @@ export class NavigationComponent {
|
|
|
692
682
|
}
|
|
693
683
|
updateBrowserURL(tab, data) {
|
|
694
684
|
// update the URL to reflect the current tab
|
|
695
|
-
var _a;
|
|
696
685
|
// FIRST, construct the base URL based on the resource type
|
|
697
686
|
const rt = this.sharedService.ResourceTypeByID(data.ResourceTypeID);
|
|
698
687
|
let url = '/resource';
|
|
699
|
-
switch (rt
|
|
688
|
+
switch (rt?.Name.toLowerCase().trim()) {
|
|
700
689
|
case 'user views':
|
|
701
690
|
if (data.ResourceRecordID) {
|
|
702
691
|
url += `/view/${data.ResourceRecordID}`;
|
|
703
692
|
}
|
|
704
|
-
else if (
|
|
693
|
+
else if (data.Configuration?.Entity) {
|
|
705
694
|
// 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
|
|
706
695
|
// so we need to construct a URL that will load up the dynamic view
|
|
707
696
|
url += `/view/0?Entity=${data.Configuration.Entity}&ExtraFilter=${data.Configuration.ExtraFilter}`;
|
|
@@ -764,9 +753,9 @@ export class NavigationComponent {
|
|
|
764
753
|
delete this.tabQueryParams['tab_-1']; // remove it from the -1 key
|
|
765
754
|
const tqp = this.tabQueryParams['tab_' + tabIndex];
|
|
766
755
|
if (tqp)
|
|
767
|
-
this.tabQueryParams['tab_' + tabIndex] =
|
|
756
|
+
this.tabQueryParams['tab_' + tabIndex] = { ...tqp, ...cachedQueryParams }; // merge it with the existing key if it exists
|
|
768
757
|
else
|
|
769
|
-
this.tabQueryParams['tab_' + tabIndex] =
|
|
758
|
+
this.tabQueryParams['tab_' + tabIndex] = { ...cachedQueryParams }; // stuff it into the correct key
|
|
770
759
|
}
|
|
771
760
|
}
|
|
772
761
|
if (cachedQueryParams) {
|
|
@@ -793,118 +782,105 @@ export class NavigationComponent {
|
|
|
793
782
|
if (this.mjTabStrip)
|
|
794
783
|
this.mjTabStrip.scrollIntoView(this.activeTabIndex);
|
|
795
784
|
}
|
|
796
|
-
GetWorkspaceItemDisplayName(data) {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
}
|
|
806
|
-
});
|
|
785
|
+
async GetWorkspaceItemDisplayName(data) {
|
|
786
|
+
const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, data.ResourceType);
|
|
787
|
+
if (resourceReg) {
|
|
788
|
+
const resource = new resourceReg.SubClass();
|
|
789
|
+
return await resource.GetResourceDisplayName(data);
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
return `Workspace Item ${data.ID}`;
|
|
793
|
+
}
|
|
807
794
|
}
|
|
808
|
-
GetWorkspaceItemIconClass(data) {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
}
|
|
818
|
-
});
|
|
795
|
+
async GetWorkspaceItemIconClass(data) {
|
|
796
|
+
const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, data.ResourceType);
|
|
797
|
+
if (resourceReg) {
|
|
798
|
+
const resource = new resourceReg.SubClass();
|
|
799
|
+
return await resource.GetResourceIconClass(data);
|
|
800
|
+
}
|
|
801
|
+
else {
|
|
802
|
+
return '';
|
|
803
|
+
}
|
|
819
804
|
}
|
|
820
805
|
/**
|
|
821
806
|
* Saves the workspace to the database.
|
|
822
807
|
* @returns
|
|
823
808
|
*/
|
|
824
|
-
SaveWorkspace() {
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
return bSuccess;
|
|
832
|
-
});
|
|
809
|
+
async SaveWorkspace() {
|
|
810
|
+
let bSuccess = true;
|
|
811
|
+
for (let i = 0; i < this.tabs.length; ++i) {
|
|
812
|
+
const tab = this.tabs[i];
|
|
813
|
+
bSuccess = await this.SaveSingleWorkspaceItem(tab) && bSuccess;
|
|
814
|
+
}
|
|
815
|
+
return bSuccess;
|
|
833
816
|
}
|
|
834
|
-
HandleResourceRecordSaved(tab, resourceRecord) {
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
return yield this.SaveSingleWorkspaceItem(tab);
|
|
849
|
-
});
|
|
817
|
+
async HandleResourceRecordSaved(tab, resourceRecord) {
|
|
818
|
+
const oldId = tab.data.ResourceRecordID;
|
|
819
|
+
tab.data.ResourceRecordID = resourceRecord.PrimaryKey.ToURLSegment();
|
|
820
|
+
// we need to update the label in case the "Name" of the record changed, or if it was new and no longer is new
|
|
821
|
+
tab.label = await this.GetWorkspaceItemDisplayName(tab.data);
|
|
822
|
+
const resourceDynamicIcon = await this.GetWorkspaceItemIconClass(tab.data);
|
|
823
|
+
tab.icon = resourceDynamicIcon ? resourceDynamicIcon : tab.icon;
|
|
824
|
+
// now check to see if the old id and the new ID are any different
|
|
825
|
+
// check for tab names that start with New as well...
|
|
826
|
+
// and if so we need to replace the state in the URL for Angular so that we don't have a New Record situation in the URL but have the actual ID now
|
|
827
|
+
// if (oldId !== tab.data.ResourceRecordID || tab.label?.toLowerCase().trim().startsWith('new') ) {
|
|
828
|
+
this.updateBrowserURL(tab, tab.data);
|
|
829
|
+
// }
|
|
830
|
+
return await this.SaveSingleWorkspaceItem(tab);
|
|
850
831
|
}
|
|
851
832
|
/**
|
|
852
833
|
* Saves a single workspace item to the database.
|
|
853
834
|
* @param tab
|
|
854
835
|
* @returns
|
|
855
836
|
*/
|
|
856
|
-
SaveSingleWorkspaceItem(tab) {
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
if (
|
|
868
|
-
wsItem
|
|
869
|
-
if (tab.data.ID && tab.data.ID.length > 0)
|
|
870
|
-
yield wsItem.Load(tab.data.ID);
|
|
871
|
-
else {
|
|
872
|
-
wsItem.NewRecord();
|
|
873
|
-
wsItem.Name = tab.data.Name ? tab.data.Name : tab.data.ResourceType + ' Record:' + tab.data.ResourceRecordID;
|
|
874
|
-
wsItem.WorkspaceID = this.workSpace.ID;
|
|
875
|
-
wsItem.ResourceTypeID = (_a = tab.data) === null || _a === void 0 ? void 0 : _a.ResourceTypeID;
|
|
876
|
-
}
|
|
877
|
-
tab.workspaceItem = wsItem;
|
|
878
|
-
}
|
|
837
|
+
async SaveSingleWorkspaceItem(tab) {
|
|
838
|
+
try {
|
|
839
|
+
if (!this.workSpace)
|
|
840
|
+
throw new Error('No workspace loaded');
|
|
841
|
+
let index = this.tabs.indexOf(tab);
|
|
842
|
+
if (index < 0)
|
|
843
|
+
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
|
|
844
|
+
const md = new Metadata();
|
|
845
|
+
let wsItem;
|
|
846
|
+
if (!tab.workspaceItem) {
|
|
847
|
+
wsItem = await md.GetEntityObject('Workspace Items');
|
|
848
|
+
if (tab.data.ID && tab.data.ID.length > 0)
|
|
849
|
+
await wsItem.Load(tab.data.ID);
|
|
879
850
|
else {
|
|
880
|
-
wsItem
|
|
851
|
+
wsItem.NewRecord();
|
|
852
|
+
wsItem.Name = tab.data.Name ? tab.data.Name : tab.data.ResourceType + ' Record:' + tab.data.ResourceRecordID;
|
|
853
|
+
wsItem.WorkspaceID = this.workSpace.ID;
|
|
854
|
+
wsItem.ResourceTypeID = tab.data?.ResourceTypeID;
|
|
881
855
|
}
|
|
882
|
-
|
|
883
|
-
wsItem.Sequence = index;
|
|
884
|
-
wsItem.Configuration = JSON.stringify(tab.data.Configuration); // JSON.stringify({ Entity: tab.data.Entity });
|
|
885
|
-
const result = yield wsItem.Save();
|
|
886
|
-
tab.id = wsItem.ID;
|
|
887
|
-
return result;
|
|
856
|
+
tab.workspaceItem = wsItem;
|
|
888
857
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
return false;
|
|
858
|
+
else {
|
|
859
|
+
wsItem = tab.workspaceItem;
|
|
892
860
|
}
|
|
893
|
-
|
|
861
|
+
wsItem.ResourceRecordID = tab.data.ResourceRecordID.toString();
|
|
862
|
+
wsItem.Sequence = index;
|
|
863
|
+
wsItem.Configuration = JSON.stringify(tab.data.Configuration); // JSON.stringify({ Entity: tab.data.Entity });
|
|
864
|
+
const result = await wsItem.Save();
|
|
865
|
+
tab.id = wsItem.ID;
|
|
866
|
+
return result;
|
|
867
|
+
}
|
|
868
|
+
catch (err) {
|
|
869
|
+
LogError(err);
|
|
870
|
+
return false;
|
|
871
|
+
}
|
|
894
872
|
}
|
|
895
873
|
setTabContentLoadingStatus(tab, bLoading) {
|
|
896
874
|
tab.contentLoading = bLoading;
|
|
897
875
|
this.cdr.detectChanges(); // Manually trigger change detection
|
|
898
876
|
}
|
|
899
|
-
handleTabClosed(event) {
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
event.done(); // let the tab control know that we're done handling the event
|
|
907
|
-
});
|
|
877
|
+
async handleTabClosed(event) {
|
|
878
|
+
// get our tab data structure item based on the index that we get in the event
|
|
879
|
+
if (event.index !== null && event.index >= 0 && event.index <= this.tabs.length) {
|
|
880
|
+
const tab = this.tabs[event.index - 1]; // subtract 1 because the event index includes the home tab and our data structure does not
|
|
881
|
+
await this.closeTab(tab, event.newTabIndex);
|
|
882
|
+
}
|
|
883
|
+
event.done(); // let the tab control know that we're done handling the event
|
|
908
884
|
}
|
|
909
885
|
handleTabSelected(event) {
|
|
910
886
|
if (event.index !== null && event.index >= 0 && event.index <= this.tabs.length) {
|
|
@@ -916,65 +892,60 @@ export class NavigationComponent {
|
|
|
916
892
|
this.innerSelectTab(null); // home
|
|
917
893
|
}
|
|
918
894
|
}
|
|
919
|
-
closeTab(tab, newTabIndex) {
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
if (
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
this.innerSelectTab(null); // null param means home tab
|
|
931
|
-
}
|
|
932
|
-
else {
|
|
933
|
-
// not home tab
|
|
934
|
-
const tab = this.tabs[newTabIndex - 1]; // remove 1 because the newTabIndex includes the HOME tab and our data structure does not
|
|
935
|
-
this.updateBrowserURL(tab, tab === null || tab === void 0 ? void 0 : tab.data);
|
|
936
|
-
}
|
|
895
|
+
async closeTab(tab, newTabIndex) {
|
|
896
|
+
const tabIndex = this.tabs.indexOf(tab);
|
|
897
|
+
if (tabIndex >= 0) {
|
|
898
|
+
// INTENTIONAL - do not use await here, we want to let the database updates happen in the background
|
|
899
|
+
this.removeWorkspaceItem(this.tabs[tabIndex], null /*no transaction group*/);
|
|
900
|
+
//await this.waitForDomUpdate(); // make sure dom is up to date
|
|
901
|
+
// now, check to see how many tabs we have left and if we have none, then we need to select the HOME tab
|
|
902
|
+
if (this.tabs.length > 0) {
|
|
903
|
+
if (newTabIndex === 0) {
|
|
904
|
+
// home tab
|
|
905
|
+
this.innerSelectTab(null); // null param means home tab
|
|
937
906
|
}
|
|
938
907
|
else {
|
|
939
|
-
|
|
908
|
+
// not home tab
|
|
909
|
+
const tab = this.tabs[newTabIndex - 1]; // remove 1 because the newTabIndex includes the HOME tab and our data structure does not
|
|
910
|
+
this.updateBrowserURL(tab, tab?.data);
|
|
940
911
|
}
|
|
941
912
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
removeWorkspaceItem(tab, transGroup) {
|
|
945
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
946
|
-
// remove the tab from the tabs collection
|
|
947
|
-
const index = this.tabs.indexOf(tab);
|
|
948
|
-
if (index >= 0)
|
|
949
|
-
this.tabs.splice(index, 1);
|
|
950
|
-
if (!tab.workspaceItem && tab.id && tab.id.length > 0) {
|
|
951
|
-
// 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
|
|
952
|
-
const md = new Metadata();
|
|
953
|
-
tab.workspaceItem = (yield md.GetEntityObject('Workspace Items'));
|
|
954
|
-
yield tab.workspaceItem.Load(tab.id);
|
|
913
|
+
else {
|
|
914
|
+
this.innerSelectTab(null); // null param means home tab
|
|
955
915
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
async removeWorkspaceItem(tab, transGroup) {
|
|
919
|
+
// remove the tab from the tabs collection
|
|
920
|
+
const index = this.tabs.indexOf(tab);
|
|
921
|
+
if (index >= 0)
|
|
922
|
+
this.tabs.splice(index, 1);
|
|
923
|
+
if (!tab.workspaceItem && tab.id && tab.id.length > 0) {
|
|
924
|
+
// 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
|
|
925
|
+
const md = new Metadata();
|
|
926
|
+
tab.workspaceItem = await md.GetEntityObject('Workspace Items');
|
|
927
|
+
await tab.workspaceItem.Load(tab.id);
|
|
928
|
+
}
|
|
929
|
+
if (tab.workspaceItem) {
|
|
930
|
+
const entity = tab.workspaceItem;
|
|
931
|
+
if (!transGroup) {
|
|
932
|
+
if (!await entity.Delete()) {
|
|
933
|
+
// error deleting the workspace item, alert the user
|
|
934
|
+
this.sharedService.CreateSimpleNotification('Error deleting workspace item ' + tab.workspaceItem.Name + ' from the database. Please contact your system administrator.', 'error', 5000);
|
|
967
935
|
}
|
|
968
936
|
}
|
|
969
|
-
|
|
937
|
+
else {
|
|
938
|
+
entity.TransactionGroup = transGroup;
|
|
939
|
+
await entity.Delete();
|
|
940
|
+
}
|
|
941
|
+
}
|
|
970
942
|
}
|
|
971
943
|
getActiveTabId() {
|
|
972
|
-
var _a;
|
|
973
944
|
if (this.activeTabIndex === 0) {
|
|
974
945
|
return null;
|
|
975
946
|
}
|
|
976
947
|
else // subtract 1 from the activeTabIndex if it is not the first tab since our data structure is for tabs 1 to n
|
|
977
|
-
return
|
|
948
|
+
return this.tabs[this.activeTabIndex - 1]?.id;
|
|
978
949
|
}
|
|
979
950
|
isTabActive(tabId) {
|
|
980
951
|
return this.getActiveTabId() === tabId;
|
|
@@ -1027,150 +998,132 @@ export class NavigationComponent {
|
|
|
1027
998
|
}
|
|
1028
999
|
return appItem;
|
|
1029
1000
|
}
|
|
1030
|
-
loadApp() {
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
return childItem;
|
|
1044
|
-
});
|
|
1045
|
-
return item;
|
|
1046
|
-
});
|
|
1047
|
-
yield TemplateEngineBase.Instance.Config(false);
|
|
1048
|
-
yield CommunicationEngineBase.Instance.Config(false);
|
|
1049
|
-
yield EntityCommunicationsEngineClient.Instance.Config(false);
|
|
1050
|
-
yield this.LoadDrawer();
|
|
1051
|
-
this.setDrawerConfig();
|
|
1052
|
-
window.addEventListener('resize', () => {
|
|
1053
|
-
this.setDrawerConfig();
|
|
1001
|
+
async loadApp() {
|
|
1002
|
+
//setting the panelItems here because by this point
|
|
1003
|
+
//the provider class is set within the MetaData class
|
|
1004
|
+
//and the applications property is populated
|
|
1005
|
+
const md = new Metadata();
|
|
1006
|
+
const applications = md.Applications;
|
|
1007
|
+
this.panelItems = applications.map((app) => {
|
|
1008
|
+
let item = new TreeItem(app, ItemType.Application);
|
|
1009
|
+
item.ChildItems = app.ApplicationEntities.map((entity) => {
|
|
1010
|
+
let childItem = new TreeItem(entity, ItemType.Entity);
|
|
1011
|
+
childItem.Name = entity.Entity;
|
|
1012
|
+
childItem.ChildItems.push(new TreeItem({ Name: 'Stub Node' }, ItemType.StubData));
|
|
1013
|
+
return childItem;
|
|
1054
1014
|
});
|
|
1015
|
+
return item;
|
|
1055
1016
|
});
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
this.
|
|
1063
|
-
const items = md.VisibleExplorerNavigationItems.filter(item => item.ShowInNavigationDrawer);
|
|
1064
|
-
items.forEach(item => {
|
|
1065
|
-
const drawerItem = {
|
|
1066
|
-
id: item.ID,
|
|
1067
|
-
selected: false,
|
|
1068
|
-
text: item.Name,
|
|
1069
|
-
path: item.Route,
|
|
1070
|
-
icon: item.IconCSSClass
|
|
1071
|
-
};
|
|
1072
|
-
this.drawerItems.push(drawerItem);
|
|
1073
|
-
});
|
|
1074
|
-
this.loading = false;
|
|
1017
|
+
await TemplateEngineBase.Instance.Config(false);
|
|
1018
|
+
await CommunicationEngineBase.Instance.Config(false);
|
|
1019
|
+
await EntityCommunicationsEngineClient.Instance.Config(false);
|
|
1020
|
+
await this.LoadDrawer();
|
|
1021
|
+
this.setDrawerConfig();
|
|
1022
|
+
window.addEventListener('resize', () => {
|
|
1023
|
+
this.setDrawerConfig();
|
|
1075
1024
|
});
|
|
1076
1025
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1026
|
+
async LoadDrawer() {
|
|
1027
|
+
const md = new Metadata();
|
|
1028
|
+
//make sure SharedService_resourceTypes is populated first
|
|
1029
|
+
await SharedService.RefreshData(true);
|
|
1030
|
+
this.drawerItems.length = 0; // clear the array
|
|
1031
|
+
const items = md.VisibleExplorerNavigationItems.filter(item => item.ShowInNavigationDrawer);
|
|
1032
|
+
items.forEach(item => {
|
|
1079
1033
|
const drawerItem = {
|
|
1080
|
-
id:
|
|
1034
|
+
id: item.ID,
|
|
1081
1035
|
selected: false,
|
|
1082
|
-
text:
|
|
1083
|
-
path:
|
|
1084
|
-
icon:
|
|
1036
|
+
text: item.Name,
|
|
1037
|
+
path: item.Route,
|
|
1038
|
+
icon: item.IconCSSClass
|
|
1085
1039
|
};
|
|
1086
1040
|
this.drawerItems.push(drawerItem);
|
|
1087
1041
|
});
|
|
1042
|
+
this.loading = false;
|
|
1088
1043
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
this.drawerItems.push(drawerItem);
|
|
1099
|
-
});
|
|
1044
|
+
async loadSkip(md) {
|
|
1045
|
+
const drawerItem = {
|
|
1046
|
+
id: 'AskSkip',
|
|
1047
|
+
selected: false,
|
|
1048
|
+
text: 'Ask Skip',
|
|
1049
|
+
path: '/askskip',
|
|
1050
|
+
icon: "fa-solid fa-robot"
|
|
1051
|
+
};
|
|
1052
|
+
this.drawerItems.push(drawerItem);
|
|
1100
1053
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1054
|
+
async loadHome(md) {
|
|
1055
|
+
const drawerItem = {
|
|
1056
|
+
id: 'Home',
|
|
1057
|
+
selected: true,
|
|
1058
|
+
text: 'Home',
|
|
1059
|
+
path: '/home',
|
|
1060
|
+
icon: "fa-solid fa-house"
|
|
1061
|
+
};
|
|
1062
|
+
this.drawerItems.push(drawerItem);
|
|
1063
|
+
}
|
|
1064
|
+
async loadSettings(md) {
|
|
1065
|
+
const drawerItem = {
|
|
1066
|
+
id: 'Settings',
|
|
1067
|
+
selected: false,
|
|
1068
|
+
text: 'Settings',
|
|
1069
|
+
path: '/settings',
|
|
1070
|
+
icon: "fa-solid fa-gear"
|
|
1071
|
+
};
|
|
1072
|
+
this.drawerItems.push(drawerItem);
|
|
1073
|
+
}
|
|
1074
|
+
async loadLists() {
|
|
1075
|
+
const drawerItem = {
|
|
1076
|
+
id: 'Lists',
|
|
1077
|
+
selected: false,
|
|
1078
|
+
text: 'Lists',
|
|
1079
|
+
path: '/lists',
|
|
1080
|
+
icon: "fa-solid fa-list"
|
|
1081
|
+
};
|
|
1082
|
+
this.drawerItems.push(drawerItem);
|
|
1112
1083
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1084
|
+
async loadFiles() {
|
|
1085
|
+
const rv = new RunView();
|
|
1086
|
+
const viewResults = await rv.RunView({
|
|
1087
|
+
EntityName: 'File Storage Providers',
|
|
1088
|
+
ExtraFilter: 'IsActive = 1',
|
|
1089
|
+
});
|
|
1090
|
+
const filesEnabled = viewResults.RowCount > 0;
|
|
1091
|
+
if (filesEnabled) {
|
|
1115
1092
|
const drawerItem = {
|
|
1116
|
-
id: '
|
|
1093
|
+
id: 'Files',
|
|
1117
1094
|
selected: false,
|
|
1118
|
-
text: '
|
|
1119
|
-
path: '/
|
|
1120
|
-
icon: "fa-
|
|
1095
|
+
text: 'Files',
|
|
1096
|
+
path: '/files',
|
|
1097
|
+
icon: "fa-regular fa-folder"
|
|
1121
1098
|
};
|
|
1122
1099
|
this.drawerItems.push(drawerItem);
|
|
1123
|
-
}
|
|
1100
|
+
}
|
|
1124
1101
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
const drawerItem = {
|
|
1135
|
-
id: 'Files',
|
|
1136
|
-
selected: false,
|
|
1137
|
-
text: 'Files',
|
|
1138
|
-
path: '/files',
|
|
1139
|
-
icon: "fa-regular fa-folder"
|
|
1140
|
-
};
|
|
1141
|
-
this.drawerItems.push(drawerItem);
|
|
1142
|
-
}
|
|
1143
|
-
});
|
|
1102
|
+
async loadApplications(md) {
|
|
1103
|
+
const drawerItem = {
|
|
1104
|
+
id: 'Data',
|
|
1105
|
+
selected: false,
|
|
1106
|
+
text: 'Data',
|
|
1107
|
+
path: '/data',
|
|
1108
|
+
icon: "fa-solid fa-database"
|
|
1109
|
+
};
|
|
1110
|
+
this.drawerItems.push(drawerItem);
|
|
1144
1111
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1112
|
+
async loadResourceType(key, resourceType, path, currentUserID) {
|
|
1113
|
+
const rt = this.sharedService.ResourceTypeByName(resourceType);
|
|
1114
|
+
if (rt) {
|
|
1147
1115
|
const drawerItem = {
|
|
1148
|
-
id:
|
|
1116
|
+
id: key,
|
|
1149
1117
|
selected: false,
|
|
1150
|
-
text:
|
|
1151
|
-
path:
|
|
1152
|
-
icon: "fa-
|
|
1118
|
+
text: resourceType,
|
|
1119
|
+
path: path,
|
|
1120
|
+
icon: rt.Icon ? rt.Icon : "fa-regular fa-file-alt"
|
|
1153
1121
|
};
|
|
1154
1122
|
this.drawerItems.push(drawerItem);
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
const rt = this.sharedService.ResourceTypeByName(resourceType);
|
|
1160
|
-
if (rt) {
|
|
1161
|
-
const drawerItem = {
|
|
1162
|
-
id: key,
|
|
1163
|
-
selected: false,
|
|
1164
|
-
text: resourceType,
|
|
1165
|
-
path: path,
|
|
1166
|
-
icon: rt.Icon ? rt.Icon : "fa-regular fa-file-alt"
|
|
1167
|
-
};
|
|
1168
|
-
this.drawerItems.push(drawerItem);
|
|
1169
|
-
}
|
|
1170
|
-
else {
|
|
1171
|
-
LogStatus("no resource type found for " + resourceType);
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
LogStatus("no resource type found for " + resourceType);
|
|
1126
|
+
}
|
|
1174
1127
|
}
|
|
1175
1128
|
setDrawerConfig() {
|
|
1176
1129
|
const pageWidth = window.innerWidth;
|
|
@@ -1188,38 +1141,38 @@ export class NavigationComponent {
|
|
|
1188
1141
|
this.mini = !this.mini;
|
|
1189
1142
|
this.sharedService.InvokeManualResize();
|
|
1190
1143
|
}
|
|
1144
|
+
static ɵ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)); };
|
|
1145
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NavigationComponent, selectors: [["mj-navigation"]], viewQuery: function NavigationComponent_Query(rf, ctx) { if (rf & 1) {
|
|
1146
|
+
i0.ɵɵviewQuery(DrawerComponent, 5);
|
|
1147
|
+
i0.ɵɵviewQuery(_c0, 5);
|
|
1148
|
+
i0.ɵɵviewQuery(_c1, 5);
|
|
1149
|
+
i0.ɵɵviewQuery(_c2, 7, ElementRef);
|
|
1150
|
+
} if (rf & 2) {
|
|
1151
|
+
let _t;
|
|
1152
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.drawer = _t.first);
|
|
1153
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.mjTabStrip = _t.first);
|
|
1154
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.drawerWrapper = _t.first);
|
|
1155
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.container = _t.first);
|
|
1156
|
+
} }, hostVars: 2, hostBindings: function NavigationComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
1157
|
+
i0.ɵɵlistener("resize", function NavigationComponent_resize_HostBindingHandler() { return ctx.onWindowResize(); }, false, i0.ɵɵresolveWindow)("click", function NavigationComponent_click_HostBindingHandler() { return ctx.onClick(); }, false, i0.ɵɵresolveDocument);
|
|
1158
|
+
} if (rf & 2) {
|
|
1159
|
+
i0.ɵɵclassProp("mobile-screen", ctx.isMobileScreen);
|
|
1160
|
+
} }, inputs: { applicationName: "applicationName" }, decls: 6, vars: 6, consts: [["drawerWrapper", ""], ["drawer", ""], ["mjTabstrip", ""], [1, "navigation-wrap", 3, "ngClass"], ["type", "converging-spinner", 4, "ngIf"], [4, "ngIf"], ["action", "route"], ["class", "context-menu", 3, "ngStyle", 4, "ngIf"], ["type", "converging-spinner"], [3, "select", "items", "mode", "mini", "animation", "autoCollapse"], ["kendoDrawerItemTemplate", ""], ["mjFillContainer", ""], ["mjFillContainer", "", 3, "TabClosed", "TabSelected", "TabContextMenu", "ResizeContainer"], [3, "TabCloseable"], [1, "drawer-item-icon"], ["class", "item-descr-wrap", 4, "ngIf"], [1, "item-descr-wrap"], [1, "item-descr"], [1, "fa-regular", "fa-clock", "tab-icon"], [3, "class"], ["mjFillContainer", "", 1, "tab-resource", 3, "ResourceRecordSaved", "ContentLoadingStarted", "ContentLoadingComplete", "Data", "isVisible"], [1, "context-menu", 3, "ngStyle"], [1, "context-menu-item", 3, "click"]], template: function NavigationComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1161
|
+
i0.ɵɵelementStart(0, "div", 3, 0);
|
|
1162
|
+
i0.ɵɵtemplate(2, NavigationComponent_kendo_loader_2_Template, 1, 0, "kendo-loader", 4)(3, NavigationComponent_kendo_drawer_container_3_Template, 15, 6, "kendo-drawer-container", 5);
|
|
1163
|
+
i0.ɵɵelement(4, "mj-skip-button", 6);
|
|
1164
|
+
i0.ɵɵelementEnd();
|
|
1165
|
+
i0.ɵɵtemplate(5, NavigationComponent_div_5_Template, 7, 1, "div", 7);
|
|
1166
|
+
} if (rf & 2) {
|
|
1167
|
+
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(4, _c3, ctx.loader));
|
|
1168
|
+
i0.ɵɵadvance(2);
|
|
1169
|
+
i0.ɵɵproperty("ngIf", ctx.loading);
|
|
1170
|
+
i0.ɵɵadvance();
|
|
1171
|
+
i0.ɵɵproperty("ngIf", !ctx.loading);
|
|
1172
|
+
i0.ɵɵadvance(2);
|
|
1173
|
+
i0.ɵɵproperty("ngIf", ctx.contextMenuVisible);
|
|
1174
|
+
} }, dependencies: [i1.RouterOutlet, i3.NgClass, i3.NgIf, i3.NgStyle, i5.LoaderComponent, i6.FillContainer, i7.DrawerComponent, i7.DrawerContainerComponent, i7.DrawerContentComponent, i7.DrawerItemTemplateDirective, i8.SkipButtonComponent, i9.MJTabStripComponent, i9.MJTabBodyComponent, i9.MJTabComponent, i10.ResourceContainerComponent], styles: [".navigation-wrap[_ngcontent-%COMP%] {\n height: calc(100vh - 80px);\n width: 100%;\n overflow:hidden\n}\n\n.nav-tab-title[_ngcontent-%COMP%] {\n margin-left: 10px;\n}\n\n.drawer-item-icon[_ngcontent-%COMP%] {\n width: 12px;\n height: 12px;\n}\n\n.context-menu[_ngcontent-%COMP%] {\n position: fixed;\n z-index: 9999;\n background-color: #ffffff;\n border: 1px solid #ccc;\n padding: 3px 3px;\n box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n}\n\n.tab-icon[_ngcontent-%COMP%] {\n margin-right: 5px;\n}\n\n.context-menu-item[_ngcontent-%COMP%] {\n padding: 8px 16px;\n cursor: pointer;\n}\n\n.context-menu-item[_ngcontent-%COMP%]:hover {\n background-color: #f1f1f1;\n}\n .navigation-wrap .drawer-container {\n background: var(--gray-color);\n}\n .navigation-wrap .drawer-container .k-content {\n padding: 25px;\n}\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper {\n background: var(--med-gray);\n padding-left: 20px;\n}\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item.k-active{\n border: 1px solid var(--light-gray);\n background: var(--light-gray);\n border-radius: 8px 8px 0 0;\n color: var(--blue-text);\n\n}\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item:hover {\n color: var(--blue-text);\n}\n\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item {\n\n background: var(--med-gray);\n border-radius: 0;\n border-right: 1px solid #909090;\n}\n\n.tab-resource[_ngcontent-%COMP%] {\n display: block;\n}"] });
|
|
1191
1175
|
}
|
|
1192
|
-
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)); };
|
|
1193
|
-
NavigationComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NavigationComponent, selectors: [["mj-navigation"]], viewQuery: function NavigationComponent_Query(rf, ctx) { if (rf & 1) {
|
|
1194
|
-
i0.ɵɵviewQuery(DrawerComponent, 5);
|
|
1195
|
-
i0.ɵɵviewQuery(_c0, 5);
|
|
1196
|
-
i0.ɵɵviewQuery(_c1, 5);
|
|
1197
|
-
i0.ɵɵviewQuery(_c2, 7, ElementRef);
|
|
1198
|
-
} if (rf & 2) {
|
|
1199
|
-
let _t;
|
|
1200
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.drawer = _t.first);
|
|
1201
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.mjTabStrip = _t.first);
|
|
1202
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.drawerWrapper = _t.first);
|
|
1203
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.container = _t.first);
|
|
1204
|
-
} }, hostVars: 2, hostBindings: function NavigationComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
1205
|
-
i0.ɵɵlistener("resize", function NavigationComponent_resize_HostBindingHandler() { return ctx.onWindowResize(); }, false, i0.ɵɵresolveWindow)("click", function NavigationComponent_click_HostBindingHandler() { return ctx.onClick(); }, false, i0.ɵɵresolveDocument);
|
|
1206
|
-
} if (rf & 2) {
|
|
1207
|
-
i0.ɵɵclassProp("mobile-screen", ctx.isMobileScreen);
|
|
1208
|
-
} }, inputs: { applicationName: "applicationName" }, decls: 6, vars: 6, consts: [["drawerWrapper", ""], ["drawer", ""], ["mjTabstrip", ""], [1, "navigation-wrap", 3, "ngClass"], ["type", "converging-spinner", 4, "ngIf"], [4, "ngIf"], ["action", "route"], ["class", "context-menu", 3, "ngStyle", 4, "ngIf"], ["type", "converging-spinner"], [3, "select", "items", "mode", "mini", "animation", "autoCollapse"], ["kendoDrawerItemTemplate", ""], ["mjFillContainer", ""], ["mjFillContainer", "", 3, "TabClosed", "TabSelected", "TabContextMenu", "ResizeContainer"], [3, "TabCloseable"], [1, "drawer-item-icon"], ["class", "item-descr-wrap", 4, "ngIf"], [1, "item-descr-wrap"], [1, "item-descr"], [1, "fa-regular", "fa-clock", "tab-icon"], [3, "class"], ["mjFillContainer", "", 1, "tab-resource", 3, "ResourceRecordSaved", "ContentLoadingStarted", "ContentLoadingComplete", "Data", "isVisible"], [1, "context-menu", 3, "ngStyle"], [1, "context-menu-item", 3, "click"]], template: function NavigationComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1209
|
-
i0.ɵɵelementStart(0, "div", 3, 0);
|
|
1210
|
-
i0.ɵɵtemplate(2, NavigationComponent_kendo_loader_2_Template, 1, 0, "kendo-loader", 4)(3, NavigationComponent_kendo_drawer_container_3_Template, 15, 6, "kendo-drawer-container", 5);
|
|
1211
|
-
i0.ɵɵelement(4, "mj-skip-button", 6);
|
|
1212
|
-
i0.ɵɵelementEnd();
|
|
1213
|
-
i0.ɵɵtemplate(5, NavigationComponent_div_5_Template, 7, 1, "div", 7);
|
|
1214
|
-
} if (rf & 2) {
|
|
1215
|
-
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(4, _c3, ctx.loader));
|
|
1216
|
-
i0.ɵɵadvance(2);
|
|
1217
|
-
i0.ɵɵproperty("ngIf", ctx.loading);
|
|
1218
|
-
i0.ɵɵadvance();
|
|
1219
|
-
i0.ɵɵproperty("ngIf", !ctx.loading);
|
|
1220
|
-
i0.ɵɵadvance(2);
|
|
1221
|
-
i0.ɵɵproperty("ngIf", ctx.contextMenuVisible);
|
|
1222
|
-
} }, dependencies: [i1.RouterOutlet, i3.NgClass, i3.NgIf, i3.NgStyle, i5.LoaderComponent, i6.FillContainer, i7.DrawerComponent, i7.DrawerContainerComponent, i7.DrawerContentComponent, i7.DrawerItemTemplateDirective, i8.SkipButtonComponent, i9.MJTabStripComponent, i9.MJTabBodyComponent, i9.MJTabComponent, i10.ResourceContainerComponent], styles: [".navigation-wrap[_ngcontent-%COMP%] {\n height: calc(100vh - 80px);\n width: 100%;\n overflow:hidden\n}\n\n.nav-tab-title[_ngcontent-%COMP%] {\n margin-left: 10px;\n}\n\n.drawer-item-icon[_ngcontent-%COMP%] {\n width: 12px;\n height: 12px;\n}\n\n.context-menu[_ngcontent-%COMP%] {\n position: fixed;\n z-index: 9999;\n background-color: #ffffff;\n border: 1px solid #ccc;\n padding: 3px 3px;\n box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n}\n\n.tab-icon[_ngcontent-%COMP%] {\n margin-right: 5px;\n}\n\n.context-menu-item[_ngcontent-%COMP%] {\n padding: 8px 16px;\n cursor: pointer;\n}\n\n.context-menu-item[_ngcontent-%COMP%]:hover {\n background-color: #f1f1f1;\n}\n .navigation-wrap .drawer-container {\n background: var(--gray-color);\n}\n .navigation-wrap .drawer-container .k-content {\n padding: 25px;\n}\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper {\n background: var(--med-gray);\n padding-left: 20px;\n}\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item.k-active{\n border: 1px solid var(--light-gray);\n background: var(--light-gray);\n border-radius: 8px 8px 0 0;\n color: var(--blue-text);\n\n}\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item:hover {\n color: var(--blue-text);\n}\n\n .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item {\n\n background: var(--med-gray);\n border-radius: 0;\n border-right: 1px solid #909090;\n}\n\n.tab-resource[_ngcontent-%COMP%] {\n display: block;\n}"] });
|
|
1223
1176
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NavigationComponent, [{
|
|
1224
1177
|
type: Component,
|
|
1225
1178
|
args: [{ selector: 'mj-navigation', template: "<div class=\"navigation-wrap\" [ngClass]=\"{'waiting': loader}\" #drawerWrapper>\n <kendo-loader *ngIf=\"loading\" type=\"converging-spinner\" ></kendo-loader>\n <kendo-drawer-container *ngIf=\"!loading\" >\n <kendo-drawer\n #drawer\n [items]=\"drawerItems\"\n [mode]=\"mode\"\n [mini]=\"mini\"\n [animation]=\"false\"\n (select)=\"onDrawerSelect($event)\"\n [autoCollapse]=\"false\"\n >\n <ng-template kendoDrawerItemTemplate let-item>\n <div class=\"drawer-item-icon\">\n <span [class]=\"item.icon\"></span>\n </div>\n <div class=\"item-descr-wrap\" *ngIf=\"!mini\">\n <div>{{ item.text }}</div>\n <span class=\"item-descr\">{{ item.description }}</span>\n </div>\n </ng-template> \n </kendo-drawer>\n <kendo-drawer-content mjFillContainer>\n\n <mj-tabstrip #mjTabstrip mjFillContainer (TabClosed)=\"handleTabClosed($event)\" (TabSelected)=\"handleTabSelected($event)\" (TabContextMenu)=\"handleTabContextMenu($event)\" (ResizeContainer)=\"sharedService.InvokeManualResize()\">\n <mj-tab [TabCloseable]=\"false\">\n Home\n </mj-tab>\n <mj-tab-body>\n <router-outlet></router-outlet>\n </mj-tab-body>\n\n @for(tab of tabs; track tab.id; let i = $index) {\n <mj-tab [TabCloseable]=\"true\">\n @if(tab?.contentLoading) {\n <span class=\"fa-regular fa-clock tab-icon\"></span>\n }\n @else if (tab?.icon) {\n <span [class]=\"tab.icon + ' tab-icon'\"></span>\n }\n {{ tab.labelLoading ? 'Loading...' : tab.label }}\n </mj-tab>\n }\n @for(tab of tabs; track tab.id; let i = $index) {\n <mj-tab-body>\n <mj-resource [Data]=\"tab.data\" [isVisible]=\"activeTabIndex - 1 === i\"\n (ResourceRecordSaved)=\"HandleResourceRecordSaved(tab, $event)\"\n (ContentLoadingStarted)=\"setTabContentLoadingStatus(tab, true)\"\n (ContentLoadingComplete)=\"setTabContentLoadingStatus(tab, false)\"\n mjFillContainer\n class=\"tab-resource\"\n ></mj-resource>\n </mj-tab-body> \n }\n </mj-tabstrip>\n </kendo-drawer-content>\n </kendo-drawer-container>\n\n \n <mj-skip-button\n action=\"route\"\n ></mj-skip-button>\n <!-- Skip Button shows up through the above line of code -->\n</div>\n\n<div class=\"context-menu\" [ngStyle]=\"contextMenuStyle\" *ngIf=\"contextMenuVisible\">\n <div class=\"context-menu-item\" (click)=\"handleContextMenuOption(1)\">Close All</div>\n <div class=\"context-menu-item\" (click)=\"handleContextMenuOption(2)\">Close Others</div>\n <div class=\"context-menu-item\" (click)=\"handleContextMenuOption(3)\">Close Tabs to the Right</div>\n </div>\n", styles: [".navigation-wrap {\n height: calc(100vh - 80px);\n width: 100%;\n overflow:hidden\n}\n\n.nav-tab-title {\n margin-left: 10px;\n}\n\n.drawer-item-icon {\n width: 12px;\n height: 12px;\n}\n\n.context-menu {\n position: fixed;\n z-index: 9999;\n background-color: #ffffff;\n border: 1px solid #ccc;\n padding: 3px 3px;\n box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n}\n\n.tab-icon {\n margin-right: 5px;\n}\n\n.context-menu-item {\n padding: 8px 16px;\n cursor: pointer;\n}\n\n.context-menu-item:hover {\n background-color: #f1f1f1;\n}\n::ng-deep .navigation-wrap .drawer-container {\n background: var(--gray-color);\n}\n::ng-deep .navigation-wrap .drawer-container .k-content {\n padding: 25px;\n}\n::ng-deep .navigation-wrap .drawer-container .k-tabstrip-items-wrapper {\n background: var(--med-gray);\n padding-left: 20px;\n}\n::ng-deep .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item.k-active{\n border: 1px solid var(--light-gray);\n background: var(--light-gray);\n border-radius: 8px 8px 0 0;\n color: var(--blue-text);\n\n}\n::ng-deep .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item:hover {\n color: var(--blue-text);\n}\n\n::ng-deep .navigation-wrap .drawer-container .k-tabstrip-items-wrapper .k-item {\n\n background: var(--med-gray);\n border-radius: 0;\n border-right: 1px solid #909090;\n}\n\n.tab-resource {\n display: block;\n}"] }]
|