@memberjunction/ng-explorer-core 1.3.3 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-routing.module.d.ts +8 -2
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +29 -6
- package/dist/lib/app-view/application-view.component.d.ts.map +1 -1
- package/dist/lib/app-view/application-view.component.js +34 -24
- package/dist/lib/base-browser-component/base-browser-component.d.ts +3 -2
- package/dist/lib/base-browser-component/base-browser-component.d.ts.map +1 -1
- package/dist/lib/base-browser-component/base-browser-component.js +5 -4
- package/dist/lib/generic/resource-container-component.d.ts.map +1 -1
- package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts +4 -0
- package/dist/lib/generic-browser-list/generic-browser-list.component.d.ts.map +1 -1
- package/dist/lib/generic-browser-list/generic-browser-list.component.js +104 -74
- package/dist/lib/header/header.component.d.ts +1 -1
- package/dist/lib/header/header.component.js +2 -2
- package/dist/lib/home-component/home.component.js +11 -5
- package/dist/lib/list-view/list-view.component.d.ts +36 -0
- package/dist/lib/list-view/list-view.component.d.ts.map +1 -0
- package/dist/lib/list-view/list-view.component.js +189 -0
- package/dist/lib/navigation/navigation.component.d.ts +32 -6
- package/dist/lib/navigation/navigation.component.d.ts.map +1 -1
- package/dist/lib/navigation/navigation.component.js +123 -46
- package/dist/lib/resource-wrappers/record-resource.component.d.ts +2 -2
- package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.js +15 -11
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +26 -0
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -0
- package/dist/lib/single-list-detail/single-list-detail.component.js +213 -0
- package/dist/lib/single-record/single-record.component.d.ts +7 -4
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +83 -29
- package/dist/lib/single-view/single-view.component.d.ts +2 -0
- package/dist/lib/single-view/single-view.component.d.ts.map +1 -1
- package/dist/lib/single-view/single-view.component.js +27 -26
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +2 -1
- package/dist/module.d.ts +38 -37
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +18 -14
- package/dist/public-api.d.ts +2 -2
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -2
- package/package.json +17 -16
- package/dist/lib/generic/section-loader-component.d.ts +0 -18
- package/dist/lib/generic/section-loader-component.d.ts.map +0 -1
- package/dist/lib/generic/section-loader-component.js +0 -66
- package/dist/lib/join-grid/join-grid.component.d.ts +0 -31
- package/dist/lib/join-grid/join-grid.component.d.ts.map +0 -1
- package/dist/lib/join-grid/join-grid.component.js +0 -222
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { Component, ElementRef, ViewChild, HostListener, HostBinding, Input } from '@angular/core';
|
|
11
11
|
import { NavigationEnd, NavigationSkipped } from '@angular/router';
|
|
12
12
|
import { DrawerComponent } from "@progress/kendo-angular-layout";
|
|
13
|
-
import { Metadata, RunView, LogError } from '@memberjunction/core';
|
|
13
|
+
import { Metadata, RunView, LogError, LogStatus } from '@memberjunction/core';
|
|
14
14
|
import { MJEventType, MJGlobal } from '@memberjunction/global';
|
|
15
15
|
import { EventCodes, SharedService } from '@memberjunction/ng-shared';
|
|
16
16
|
import { BaseResourceComponent, ResourceData } from '@memberjunction/ng-shared';
|
|
@@ -85,7 +85,7 @@ function NavigationComponent_kendo_drawer_container_3_For_12_Template(rf, ctx) {
|
|
|
85
85
|
function NavigationComponent_kendo_drawer_container_3_For_14_Template(rf, ctx) { if (rf & 1) {
|
|
86
86
|
const _r26 = i0.ɵɵgetCurrentView();
|
|
87
87
|
i0.ɵɵelementStart(0, "mj-tab-body")(1, "mj-resource", 20);
|
|
88
|
-
i0.ɵɵlistener("ResourceRecordSaved", function NavigationComponent_kendo_drawer_container_3_For_14_Template_mj_resource_ResourceRecordSaved_1_listener() { const restoredCtx = i0.ɵɵrestoreView(_r26); const tab_r20 = restoredCtx.$implicit; const ctx_r25 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r25.
|
|
88
|
+
i0.ɵɵlistener("ResourceRecordSaved", function NavigationComponent_kendo_drawer_container_3_For_14_Template_mj_resource_ResourceRecordSaved_1_listener($event) { const restoredCtx = i0.ɵɵrestoreView(_r26); const tab_r20 = restoredCtx.$implicit; const ctx_r25 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r25.HandleResourceRecordSaved(tab_r20, $event)); })("ContentLoadingStarted", function NavigationComponent_kendo_drawer_container_3_For_14_Template_mj_resource_ContentLoadingStarted_1_listener() { const restoredCtx = i0.ɵɵrestoreView(_r26); const tab_r20 = restoredCtx.$implicit; const ctx_r27 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r27.setTabContentLoadingStatus(tab_r20, true)); })("ContentLoadingComplete", function NavigationComponent_kendo_drawer_container_3_For_14_Template_mj_resource_ContentLoadingComplete_1_listener() { const restoredCtx = i0.ɵɵrestoreView(_r26); const tab_r20 = restoredCtx.$implicit; const ctx_r28 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r28.setTabContentLoadingStatus(tab_r20, false)); });
|
|
89
89
|
i0.ɵɵelementEnd()();
|
|
90
90
|
} if (rf & 2) {
|
|
91
91
|
const tab_r20 = ctx.$implicit;
|
|
@@ -176,9 +176,7 @@ export class NavigationComponent {
|
|
|
176
176
|
this.tabs = [];
|
|
177
177
|
this.closedTabs = []; // should always be empty after using it
|
|
178
178
|
this.tabQueryParams = {};
|
|
179
|
-
|
|
180
|
-
// public selectedTabIndex: number = 0;
|
|
181
|
-
this.workSpace = {};
|
|
179
|
+
this.workSpace = undefined;
|
|
182
180
|
this.workSpaceItems = [];
|
|
183
181
|
this.panelItems = [];
|
|
184
182
|
this.showExpansionPanel = false;
|
|
@@ -274,7 +272,7 @@ export class NavigationComponent {
|
|
|
274
272
|
switch (event.event) {
|
|
275
273
|
case MJEventType.LoggedIn:
|
|
276
274
|
yield this.loadApp();
|
|
277
|
-
yield this.
|
|
275
|
+
yield this.loadWorkspace();
|
|
278
276
|
this._loggedIn = true;
|
|
279
277
|
// check for early events and replay them now that we're logged in
|
|
280
278
|
for (let i = 0; i < this._earlyEvents.length; ++i) {
|
|
@@ -310,6 +308,14 @@ export class NavigationComponent {
|
|
|
310
308
|
// another component requested that we add something to our tab structure
|
|
311
309
|
this.AddOrSelectTab(event.args);
|
|
312
310
|
break;
|
|
311
|
+
case EventCodes.CloseCurrentTab:
|
|
312
|
+
if (this.mjTabStrip && this.activeTabIndex > 0) {
|
|
313
|
+
this.mjTabStrip.CloseTab(this.activeTabIndex);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
LogError("no active tab to close or tabstrip not available");
|
|
317
|
+
}
|
|
318
|
+
break;
|
|
313
319
|
default:
|
|
314
320
|
break;
|
|
315
321
|
}
|
|
@@ -374,12 +380,11 @@ export class NavigationComponent {
|
|
|
374
380
|
// come back to this tab
|
|
375
381
|
const urlParts = this.router.url.split('?');
|
|
376
382
|
if (urlParts.length > 1) {
|
|
377
|
-
// we have query params, so stash
|
|
383
|
+
// we have query params, so stash them
|
|
378
384
|
const params = new URLSearchParams(urlParts[1]);
|
|
379
|
-
const keys = params.keys();
|
|
380
385
|
const queryParams = {};
|
|
381
|
-
for (const key of
|
|
382
|
-
queryParams[key] =
|
|
386
|
+
for (const [key, value] of params.entries()) {
|
|
387
|
+
queryParams[key] = value;
|
|
383
388
|
}
|
|
384
389
|
this.tabQueryParams['tab_' + this.activeTabIndex] = queryParams;
|
|
385
390
|
}
|
|
@@ -447,42 +452,54 @@ export class NavigationComponent {
|
|
|
447
452
|
}
|
|
448
453
|
}, 10);
|
|
449
454
|
}
|
|
450
|
-
|
|
455
|
+
/**
|
|
456
|
+
* This method will load the user's workspace and all the workspace items that are part of the workspace from the database.
|
|
457
|
+
*/
|
|
458
|
+
loadWorkspace() {
|
|
451
459
|
return __awaiter(this, void 0, void 0, function* () {
|
|
452
460
|
const md = new Metadata();
|
|
453
461
|
const rv = new RunView();
|
|
454
462
|
const workspaceParams = {
|
|
455
463
|
EntityName: "Workspaces",
|
|
456
|
-
ExtraFilter: `UserID=${md.CurrentUser.ID}
|
|
464
|
+
ExtraFilter: `UserID=${md.CurrentUser.ID}`,
|
|
465
|
+
OrderBy: "UpdatedAt DESC", // by default get the workspace that was most recently updated
|
|
466
|
+
ResultType: "entity_object" /*we want entity objects back so that we can modify them as needed*/
|
|
457
467
|
};
|
|
458
468
|
const workspaces = yield rv.RunView(workspaceParams);
|
|
459
469
|
if (workspaces.Success) {
|
|
460
|
-
const workspaceRecord = yield md.GetEntityObject("Workspaces");
|
|
461
470
|
if (workspaces.Results.length) {
|
|
462
|
-
|
|
463
|
-
yield workspaceRecord.Load(workspace.ID);
|
|
471
|
+
this.workSpace = workspaces.Results[0]; // by default get the first one, and since we are sorting by UpdatedAt DESC above, will be most recently modified one. Future feature for multi-workspace support we'll have to adjust this
|
|
464
472
|
}
|
|
465
473
|
else {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
474
|
+
// no matching record found, so create a new one
|
|
475
|
+
this.workSpace = yield md.GetEntityObject('Workspaces');
|
|
476
|
+
this.workSpace.NewRecord();
|
|
477
|
+
this.workSpace.Name = `${md.CurrentUser.Name || md.CurrentUser.ID}'s Workspace`;
|
|
478
|
+
this.workSpace.UserID = md.CurrentUser.ID;
|
|
479
|
+
yield this.workSpace.Save();
|
|
470
480
|
}
|
|
471
|
-
this.workSpace
|
|
481
|
+
if (!this.workSpace)
|
|
482
|
+
throw new Error('Error loading workspace');
|
|
472
483
|
const workspaceItemParams = {
|
|
473
484
|
EntityName: "Workspace Items",
|
|
474
485
|
ExtraFilter: `WorkspaceID='${this.workSpace.ID}'`,
|
|
486
|
+
OrderBy: "Sequence ASC", // get them in order
|
|
475
487
|
ResultType: "entity_object" /*we want entity objects back so that we can modify them as needed*/
|
|
476
488
|
};
|
|
477
489
|
const workspaceItems = yield rv.RunView(workspaceItemParams);
|
|
478
490
|
if (workspaceItems.Success) {
|
|
479
491
|
this.workSpaceItems = workspaceItems.Results;
|
|
480
|
-
yield this.
|
|
492
|
+
yield this.LoadWorkspaceItems();
|
|
481
493
|
}
|
|
482
494
|
}
|
|
495
|
+
else
|
|
496
|
+
throw new Error('Error loading workspace');
|
|
483
497
|
});
|
|
484
498
|
}
|
|
485
|
-
|
|
499
|
+
/**
|
|
500
|
+
* This method will load all the workspace items that are part of the workspace currently set in the workSpace member variable
|
|
501
|
+
*/
|
|
502
|
+
LoadWorkspaceItems() {
|
|
486
503
|
return __awaiter(this, void 0, void 0, function* () {
|
|
487
504
|
const md = new Metadata();
|
|
488
505
|
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.
|
|
@@ -506,7 +523,7 @@ export class NavigationComponent {
|
|
|
506
523
|
// now add to data structure
|
|
507
524
|
yield this.internalAddTab(newTab);
|
|
508
525
|
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
509
|
-
// non-blocking, load dynamically
|
|
526
|
+
// non-blocking, load the resource names dynamically as this requires additional DB lookups
|
|
510
527
|
newTab.label = yield this.GetWorkspaceItemDisplayName(resourceData);
|
|
511
528
|
newTab.labelLoading = false;
|
|
512
529
|
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
|
|
@@ -522,7 +539,12 @@ export class NavigationComponent {
|
|
|
522
539
|
else
|
|
523
540
|
this.titleService.setTitle(title + ' (' + this.applicationName + ')');
|
|
524
541
|
}
|
|
525
|
-
|
|
542
|
+
/**
|
|
543
|
+
* This method is responsible for searching for a matching tab in the existing tab structure of the loaded workspace. It returns either a Tab object or null if one isn't found that matches the ResourceData provided.
|
|
544
|
+
* @param data
|
|
545
|
+
* @returns
|
|
546
|
+
*/
|
|
547
|
+
findExistingTab(data) {
|
|
526
548
|
let existingTab;
|
|
527
549
|
if (data.ResourceType.trim().toLowerCase() === 'search results') {
|
|
528
550
|
// we have a different matching logic for search results because we want to match on the search input as well as the entity
|
|
@@ -548,18 +570,36 @@ export class NavigationComponent {
|
|
|
548
570
|
}
|
|
549
571
|
}
|
|
550
572
|
else {
|
|
551
|
-
existingTab = this.tabs.find(t =>
|
|
552
|
-
t.data.
|
|
553
|
-
|
|
554
|
-
|
|
573
|
+
existingTab = this.tabs.find(t => {
|
|
574
|
+
if (t.data.ResourceTypeID === data.ResourceTypeID &&
|
|
575
|
+
t.data.ResourceRecordID === data.ResourceRecordID) {
|
|
576
|
+
// we now have to do one more check, we have to make sure that all of the values within the Configuration object match as well
|
|
577
|
+
let bMatch = true;
|
|
578
|
+
// ignore keys that start with an underscore or are the NewRecordValues key
|
|
579
|
+
const keys = Object.keys(data.Configuration).filter(k => !k.startsWith('_') && k.trim().toLowerCase() !== 'newrecordvalues');
|
|
580
|
+
for (const key of keys) {
|
|
581
|
+
if (data.Configuration[key] !== t.data.Configuration[key]) {
|
|
582
|
+
bMatch = false;
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return bMatch;
|
|
587
|
+
}
|
|
588
|
+
else
|
|
589
|
+
return false;
|
|
590
|
+
});
|
|
555
591
|
}
|
|
556
592
|
return existingTab;
|
|
557
593
|
}
|
|
594
|
+
/**
|
|
595
|
+
* 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.
|
|
596
|
+
* @param data
|
|
597
|
+
*/
|
|
558
598
|
AddOrSelectTab(data) {
|
|
559
599
|
return __awaiter(this, void 0, void 0, function* () {
|
|
560
600
|
const t = this.tabs;
|
|
561
601
|
this.loader = true;
|
|
562
|
-
const existingTab = this.
|
|
602
|
+
const existingTab = this.findExistingTab(data);
|
|
563
603
|
if (existingTab) {
|
|
564
604
|
const index = this.tabs.indexOf(existingTab);
|
|
565
605
|
// add one because the HOME tab is not in the tabs array but it IS part of our tab structure
|
|
@@ -587,8 +627,6 @@ export class NavigationComponent {
|
|
|
587
627
|
yield this.internalAddTab(newTab);
|
|
588
628
|
// select the new tab
|
|
589
629
|
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
|
|
590
|
-
//this.tabstrip.selectTab(this.activeTabIndex);
|
|
591
|
-
//this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement).focus()
|
|
592
630
|
this.sharedService.InvokeManualResize();
|
|
593
631
|
this.scrollIntoView();
|
|
594
632
|
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -648,7 +686,11 @@ export class NavigationComponent {
|
|
|
648
686
|
url += `/query/${data.ResourceRecordID}`;
|
|
649
687
|
break;
|
|
650
688
|
case 'records':
|
|
651
|
-
|
|
689
|
+
const recIDAsString = data.ResourceRecordID !== null && data.ResourceRecordID !== undefined ? (typeof data.ResourceRecordID === "string" ? data.ResourceRecordID : data.ResourceRecordID.toString()) : "";
|
|
690
|
+
url += `/record/${recIDAsString.trim()}?Entity=${data.Configuration.Entity}`;
|
|
691
|
+
if (data.Configuration.NewRecordValues) {
|
|
692
|
+
url += `&NewRecordValues=${data.Configuration.NewRecordValues}`;
|
|
693
|
+
}
|
|
652
694
|
break;
|
|
653
695
|
case 'search results':
|
|
654
696
|
url += `/search/${data.Configuration.SearchInput}?Entity=${data.Configuration.Entity}`;
|
|
@@ -698,11 +740,8 @@ export class NavigationComponent {
|
|
|
698
740
|
this.setAppTitle(tab.label);
|
|
699
741
|
}
|
|
700
742
|
scrollIntoView() {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
// const newTabElement = containerElement.querySelector(`li:nth-child(${this.activeTabIndex + 1})`);
|
|
704
|
-
// newTabElement.scrollIntoView({ inline: 'nearest' });
|
|
705
|
-
// }, 200);
|
|
743
|
+
if (this.mjTabStrip)
|
|
744
|
+
this.mjTabStrip.scrollIntoView(this.activeTabIndex);
|
|
706
745
|
}
|
|
707
746
|
GetWorkspaceItemDisplayName(data) {
|
|
708
747
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -715,6 +754,10 @@ export class NavigationComponent {
|
|
|
715
754
|
return `Workspace Item ${data.ID}`;
|
|
716
755
|
});
|
|
717
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* Saves the workspace to the database.
|
|
759
|
+
* @returns
|
|
760
|
+
*/
|
|
718
761
|
SaveWorkspace() {
|
|
719
762
|
return __awaiter(this, void 0, void 0, function* () {
|
|
720
763
|
let bSuccess = true;
|
|
@@ -725,10 +768,32 @@ export class NavigationComponent {
|
|
|
725
768
|
return bSuccess;
|
|
726
769
|
});
|
|
727
770
|
}
|
|
771
|
+
HandleResourceRecordSaved(tab, resourceRecord) {
|
|
772
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
773
|
+
const oldId = tab.data.ResourceRecordID;
|
|
774
|
+
tab.data.ResourceRecordID = resourceRecord.PrimaryKey.ToURLSegment();
|
|
775
|
+
// we need to update the label in case the "Name" of the record changed, or if it was new and no longer is new
|
|
776
|
+
tab.label = yield this.GetWorkspaceItemDisplayName(tab.data);
|
|
777
|
+
// now check to see if the old id and the new ID are any different
|
|
778
|
+
// check for tab names that start with New as well...
|
|
779
|
+
// 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
|
|
780
|
+
// if (oldId !== tab.data.ResourceRecordID || tab.label?.toLowerCase().trim().startsWith('new') ) {
|
|
781
|
+
this.updateBrowserURL(tab, tab.data);
|
|
782
|
+
// }
|
|
783
|
+
return yield this.SaveSingleWorkspaceItem(tab);
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Saves a single workspace item to the database.
|
|
788
|
+
* @param tab
|
|
789
|
+
* @returns
|
|
790
|
+
*/
|
|
728
791
|
SaveSingleWorkspaceItem(tab) {
|
|
729
792
|
var _a;
|
|
730
793
|
return __awaiter(this, void 0, void 0, function* () {
|
|
731
794
|
try {
|
|
795
|
+
if (!this.workSpace)
|
|
796
|
+
throw new Error('No workspace loaded');
|
|
732
797
|
let index = this.tabs.indexOf(tab);
|
|
733
798
|
if (index < 0)
|
|
734
799
|
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
|
|
@@ -790,8 +855,9 @@ export class NavigationComponent {
|
|
|
790
855
|
return __awaiter(this, void 0, void 0, function* () {
|
|
791
856
|
const tabIndex = this.tabs.indexOf(tab);
|
|
792
857
|
if (tabIndex >= 0) {
|
|
793
|
-
|
|
794
|
-
|
|
858
|
+
// INTENTIONAL - do not use await here, we want to let the database updates happen in the background
|
|
859
|
+
this.removeWorkspaceItem(this.tabs[tabIndex], null /*no transaction group*/);
|
|
860
|
+
//await this.waitForDomUpdate(); // make sure dom is up to date
|
|
795
861
|
// now, check to see how many tabs we have left and if we have none, then we need to select the HOME tab
|
|
796
862
|
if (this.tabs.length > 0) {
|
|
797
863
|
if (newTabIndex === 0) {
|
|
@@ -862,8 +928,6 @@ export class NavigationComponent {
|
|
|
862
928
|
// make sure that the first tab is selected since this is showing stuff in the Home/Nav tab
|
|
863
929
|
if (this.activeTabIndex !== 0) {
|
|
864
930
|
this.activeTabIndex = 0;
|
|
865
|
-
//this.tabstrip.selectTab(0);
|
|
866
|
-
//this.renderer.selectRootElement(this.tabstrip.wrapper.nativeElement).focus()
|
|
867
931
|
}
|
|
868
932
|
this.setAppTitle(ev.item.text);
|
|
869
933
|
}
|
|
@@ -878,9 +942,8 @@ export class NavigationComponent {
|
|
|
878
942
|
this.mjTabStrip.SelectedTabIndex = index;
|
|
879
943
|
}
|
|
880
944
|
getEntityItemFromViewItem(viewItem) {
|
|
881
|
-
let entityItem = null;
|
|
882
945
|
for (let item of this.drawerItems) {
|
|
883
|
-
if (item.id
|
|
946
|
+
if (item.id === viewItem.parentId) {
|
|
884
947
|
// got the parent, this is the entity
|
|
885
948
|
return item;
|
|
886
949
|
}
|
|
@@ -952,6 +1015,8 @@ export class NavigationComponent {
|
|
|
952
1015
|
yield this.loadResourceType('Queries', 'Queries', '/queries', md.CurrentUser.ID);
|
|
953
1016
|
// Files
|
|
954
1017
|
yield this.loadFiles();
|
|
1018
|
+
// Lists
|
|
1019
|
+
yield this.loadLists();
|
|
955
1020
|
// Settings
|
|
956
1021
|
yield this.loadSettings(md);
|
|
957
1022
|
this.loading = false;
|
|
@@ -993,6 +1058,18 @@ export class NavigationComponent {
|
|
|
993
1058
|
this.drawerItems.push(drawerItem);
|
|
994
1059
|
});
|
|
995
1060
|
}
|
|
1061
|
+
loadLists() {
|
|
1062
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1063
|
+
const drawerItem = {
|
|
1064
|
+
id: 'Lists',
|
|
1065
|
+
selected: false,
|
|
1066
|
+
text: 'Lists',
|
|
1067
|
+
path: '/lists',
|
|
1068
|
+
icon: "fa-solid fa-list"
|
|
1069
|
+
};
|
|
1070
|
+
this.drawerItems.push(drawerItem);
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
996
1073
|
loadFiles() {
|
|
997
1074
|
return __awaiter(this, void 0, void 0, function* () {
|
|
998
1075
|
const rv = new RunView();
|
|
@@ -1039,7 +1116,7 @@ export class NavigationComponent {
|
|
|
1039
1116
|
this.drawerItems.push(drawerItem);
|
|
1040
1117
|
}
|
|
1041
1118
|
else {
|
|
1042
|
-
|
|
1119
|
+
LogStatus("no resource type found for " + resourceType);
|
|
1043
1120
|
}
|
|
1044
1121
|
});
|
|
1045
1122
|
}
|
|
@@ -1061,7 +1138,7 @@ export class NavigationComponent {
|
|
|
1061
1138
|
}
|
|
1062
1139
|
}
|
|
1063
1140
|
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)); };
|
|
1064
|
-
NavigationComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NavigationComponent, selectors: [["
|
|
1141
|
+
NavigationComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NavigationComponent, selectors: [["mj-navigation"]], viewQuery: function NavigationComponent_Query(rf, ctx) { if (rf & 1) {
|
|
1065
1142
|
i0.ɵɵviewQuery(DrawerComponent, 5);
|
|
1066
1143
|
i0.ɵɵviewQuery(_c0, 5);
|
|
1067
1144
|
i0.ɵɵviewQuery(_c1, 5);
|
|
@@ -1093,7 +1170,7 @@ NavigationComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: Navigat
|
|
|
1093
1170
|
} }, 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.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}"] });
|
|
1094
1171
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NavigationComponent, [{
|
|
1095
1172
|
type: Component,
|
|
1096
|
-
args: [{ selector: '
|
|
1173
|
+
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)\">\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\"></span>\n }\n @else if (tab?.icon) {\n <span [class]=\"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.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}"] }]
|
|
1097
1174
|
}], () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.SharedService }, { type: i3.Location }, { type: i0.Renderer2 }, { type: i4.Title }, { type: i0.ChangeDetectorRef }], { applicationName: [{
|
|
1098
1175
|
type: Input
|
|
1099
1176
|
}], isMobileScreen: [{
|
|
@@ -3,8 +3,8 @@ import { CompositeKey } from '@memberjunction/core';
|
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare function LoadRecordResource(): void;
|
|
5
5
|
export declare class EntityRecordResource extends BaseResourceComponent {
|
|
6
|
-
get
|
|
7
|
-
static
|
|
6
|
+
get PrimaryKey(): CompositeKey;
|
|
7
|
+
static GetPrimaryKey(data: ResourceData): CompositeKey;
|
|
8
8
|
GetResourceDisplayName(data: ResourceData): Promise<string>;
|
|
9
9
|
static ɵfac: i0.ɵɵFactoryDeclaration<EntityRecordResource, never>;
|
|
10
10
|
static ɵcmp: i0.ɵɵComponentDeclaration<EntityRecordResource, "mj-record-resource", never, {}, {}, never, never, false, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,EAAY,YAAY,EAAE,MAAM,sBAAsB,CAAC;;AAE9D,wBAAgB,kBAAkB,SAEjC;AAED,qBAKa,oBAAqB,SAAQ,qBAAqB;IAC3D,IAAW,
|
|
1
|
+
{"version":3,"file":"record-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,EAAY,YAAY,EAAE,MAAM,sBAAsB,CAAC;;AAE9D,wBAAgB,kBAAkB,SAEjC;AAED,qBAKa,oBAAqB,SAAQ,qBAAqB;IAC3D,IAAW,UAAU,IAAI,YAAY,CAEpC;WAEa,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY;IAYvD,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCAjBxD,oBAAoB;2CAApB,oBAAoB;CAiChC"}
|
|
@@ -25,10 +25,10 @@ export function LoadRecordResource() {
|
|
|
25
25
|
const test = new EntityRecordResource(); // this looks really dumb. Thing is, in production builds, tree shaking causes the class below to not be included in the bundle. This is a hack to force it to be included.
|
|
26
26
|
}
|
|
27
27
|
let EntityRecordResource = EntityRecordResource_1 = class EntityRecordResource extends BaseResourceComponent {
|
|
28
|
-
get
|
|
29
|
-
return EntityRecordResource_1.
|
|
28
|
+
get PrimaryKey() {
|
|
29
|
+
return EntityRecordResource_1.GetPrimaryKey(this.Data);
|
|
30
30
|
}
|
|
31
|
-
static
|
|
31
|
+
static GetPrimaryKey(data) {
|
|
32
32
|
const md = new Metadata();
|
|
33
33
|
const e = md.Entities.find(e => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());
|
|
34
34
|
if (!e) {
|
|
@@ -45,21 +45,25 @@ let EntityRecordResource = EntityRecordResource_1 = class EntityRecordResource e
|
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
47
|
const md = new Metadata();
|
|
48
|
-
let
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
let pk = EntityRecordResource_1.GetPrimaryKey(data);
|
|
49
|
+
if (pk.HasValue) {
|
|
50
|
+
const name = yield md.GetEntityRecordName(data.Configuration.Entity, pk);
|
|
51
|
+
const displayId = pk.KeyValuePairs.length > 1 ? pk.Values() : pk.GetValueByIndex(0);
|
|
52
|
+
return (name ? name : data.Configuration.Entity) + ` (${displayId})`;
|
|
53
|
+
}
|
|
54
|
+
else
|
|
55
|
+
return `New ${data.Configuration.Entity} Record`;
|
|
52
56
|
}
|
|
53
57
|
});
|
|
54
58
|
}
|
|
55
59
|
};
|
|
56
60
|
EntityRecordResource.ɵfac = /*@__PURE__*/ (() => { let ɵEntityRecordResource_BaseFactory; return function EntityRecordResource_Factory(t) { return (ɵEntityRecordResource_BaseFactory || (ɵEntityRecordResource_BaseFactory = i0.ɵɵgetInheritedFactory(EntityRecordResource)))(t || EntityRecordResource); }; })();
|
|
57
|
-
EntityRecordResource.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRecordResource, selectors: [["mj-record-resource"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars:
|
|
61
|
+
EntityRecordResource.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRecordResource, selectors: [["mj-record-resource"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 3, consts: [["mjFillContainer", "", 3, "PrimaryKey", "entityName", "newRecordValues", "loadComplete", "recordSaved"]], template: function EntityRecordResource_Template(rf, ctx) { if (rf & 1) {
|
|
58
62
|
i0.ɵɵelementStart(0, "mj-single-record", 0);
|
|
59
|
-
i0.ɵɵlistener("loadComplete", function EntityRecordResource_Template_mj_single_record_loadComplete_0_listener() { return ctx.NotifyLoadComplete(); });
|
|
63
|
+
i0.ɵɵlistener("loadComplete", function EntityRecordResource_Template_mj_single_record_loadComplete_0_listener() { return ctx.NotifyLoadComplete(); })("recordSaved", function EntityRecordResource_Template_mj_single_record_recordSaved_0_listener($event) { return ctx.ResourceRecordSaved($event); });
|
|
60
64
|
i0.ɵɵelementEnd();
|
|
61
65
|
} if (rf & 2) {
|
|
62
|
-
i0.ɵɵproperty("
|
|
66
|
+
i0.ɵɵproperty("PrimaryKey", ctx.PrimaryKey)("entityName", ctx.Data.Configuration.Entity)("newRecordValues", ctx.Data.Configuration.NewRecordValues);
|
|
63
67
|
} }, dependencies: [i1.FillContainer, i2.SingleRecordComponent], encapsulation: 2 });
|
|
64
68
|
EntityRecordResource = EntityRecordResource_1 = __decorate([
|
|
65
69
|
RegisterClass(BaseResourceComponent, 'Records')
|
|
@@ -69,7 +73,7 @@ export { EntityRecordResource };
|
|
|
69
73
|
type: Component,
|
|
70
74
|
args: [{
|
|
71
75
|
selector: 'mj-record-resource',
|
|
72
|
-
template: `<mj-single-record [
|
|
76
|
+
template: `<mj-single-record [PrimaryKey]="this.PrimaryKey" [entityName]="Data.Configuration.Entity" [newRecordValues]="Data.Configuration.NewRecordValues" (loadComplete)="NotifyLoadComplete()" (recordSaved)="ResourceRecordSaved($event)" mjFillContainer></mj-single-record>`
|
|
73
77
|
}]
|
|
74
78
|
}], null, null); })();
|
|
75
79
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityRecordResource, { className: "EntityRecordResource", filePath: "src/lib/resource-wrappers/record-resource.component.ts", lineNumber: 15 }); })();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
3
|
+
import { BaseEntity } from '@memberjunction/core';
|
|
4
|
+
import { SharedService } from '@memberjunction/ng-shared';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export declare class SingleListDetailComponent implements OnInit {
|
|
7
|
+
private router;
|
|
8
|
+
private route;
|
|
9
|
+
private sharedService;
|
|
10
|
+
private listRecord;
|
|
11
|
+
showLoader: boolean;
|
|
12
|
+
gridData: BaseEntity[];
|
|
13
|
+
listName: string;
|
|
14
|
+
showAddDialog: boolean;
|
|
15
|
+
showAddLoader: boolean;
|
|
16
|
+
userViews: BaseEntity[];
|
|
17
|
+
selectedUserView: BaseEntity | null;
|
|
18
|
+
constructor(router: Router, route: ActivatedRoute, sharedService: SharedService);
|
|
19
|
+
ngOnInit(): Promise<void>;
|
|
20
|
+
toggleAddDialog(show: boolean): Promise<void>;
|
|
21
|
+
addTolist(): Promise<void>;
|
|
22
|
+
private loadEntityViews;
|
|
23
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SingleListDetailComponent, never>;
|
|
24
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SingleListDetailComponent, "mj-list-detail", never, {}, {}, never, never, false, never>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=single-list-detail.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"single-list-detail.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-list-detail/single-list-detail.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,UAAU,EAA0D,MAAM,sBAAsB,CAAC;AAE1G,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;;AAE1D,qBAKa,yBAA0B,YAAW,MAAM;IAWvC,OAAO,CAAC,MAAM;IAAU,OAAO,CAAC,KAAK;IAAkB,OAAO,CAAC,aAAa;IAVzF,OAAO,CAAC,UAAU,CAA2B;IAEtC,UAAU,EAAE,OAAO,CAAS;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAM;IAC5B,QAAQ,EAAE,MAAM,CAAM;IACtB,aAAa,EAAE,OAAO,CAAS;IAC/B,aAAa,EAAE,OAAO,CAAS;IAC/B,SAAS,EAAE,UAAU,EAAE,CAAM;IAC7B,gBAAgB,EAAE,UAAU,GAAG,IAAI,CAAQ;gBAE7B,MAAM,EAAE,MAAM,EAAU,KAAK,EAAE,cAAc,EAAU,aAAa,EAAE,aAAa;IAE3F,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAiEzB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7C,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;YAsBzB,eAAe;yCA7GpB,yBAAyB;2CAAzB,yBAAyB;CAsIrC"}
|