@memberjunction/ng-explorer-core 6.2.0-edge.4 → 6.2.0-edge.5
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.map +1 -1
- package/dist/app-routing.module.js +8 -6
- package/dist/app-routing.module.js.map +1 -1
- package/dist/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +3 -2
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts +2 -0
- package/dist/lib/oauth/oauth-callback.component.d.ts.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.js +10 -10
- package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +17 -3
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +211 -13
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +12 -3
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +18 -3
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +3 -3
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +5 -10
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts +16 -3
- package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts.map +1 -1
- package/dist/lib/server-connectivity/server-connectivity-banner.component.js +17 -3
- package/dist/lib/server-connectivity/server-connectivity-banner.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +34 -0
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +151 -38
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/deep-link-workspace.d.ts +25 -0
- package/dist/lib/shell/deep-link-workspace.d.ts.map +1 -0
- package/dist/lib/shell/deep-link-workspace.js +49 -0
- package/dist/lib/shell/deep-link-workspace.js.map +1 -0
- package/dist/lib/shell/shell.component.d.ts +12 -0
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +66 -8
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +12 -0
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +49 -8
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/package.json +57 -57
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OnInit, OnDestroy, AfterViewInit, ElementRef, ApplicationRef, EnvironmentInjector, ChangeDetectorRef, EventEmitter } from '@angular/core';
|
|
2
2
|
import { GoldenLayoutManager, WorkspaceStateManager, ApplicationManager } from '@memberjunction/ng-base-application';
|
|
3
|
+
import type { DeletedRecordRef } from '@memberjunction/ng-shared';
|
|
3
4
|
import { RecordSwitcherEntry } from '../record-open/record-switcher-sheet.component';
|
|
4
5
|
import { CachedComponentInfo } from './component-cache-manager';
|
|
5
6
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
@@ -65,6 +66,7 @@ export declare class TabContainerComponent extends BaseAngularComponent implemen
|
|
|
65
66
|
layoutInitError: EventEmitter<void>;
|
|
66
67
|
private pinService;
|
|
67
68
|
private navigationService;
|
|
69
|
+
private tabService;
|
|
68
70
|
private recordSwitcher;
|
|
69
71
|
private subscriptions;
|
|
70
72
|
private layoutInitRetryCount;
|
|
@@ -203,6 +205,7 @@ export declare class TabContainerComponent extends BaseAngularComponent implemen
|
|
|
203
205
|
* first so even the re-entrant case gets picked up by the in-flight pass.
|
|
204
206
|
*/
|
|
205
207
|
private flushRegionCd;
|
|
208
|
+
private recordsLayoutInitRetryCount;
|
|
206
209
|
/**
|
|
207
210
|
* Keep the RECORDS region in lockstep with the workspace configuration:
|
|
208
211
|
* resolve region visibility (active tab is a record), lazily initialize the
|
|
@@ -446,6 +449,37 @@ export declare class TabContainerComponent extends BaseAngularComponent implemen
|
|
|
446
449
|
* replaces the now-temp tab. End result: user lands on the app's home/default view.
|
|
447
450
|
*/
|
|
448
451
|
private handleResourceCloseRequested;
|
|
452
|
+
/**
|
|
453
|
+
* Close a tab and DESTROY (not just detach) its cached component.
|
|
454
|
+
*
|
|
455
|
+
* The default tab-close path detaches and keeps components alive for reuse —
|
|
456
|
+
* but a discarded or deleted record's form is exactly what we DON'T want to
|
|
457
|
+
* keep: it holds a stale BaseEntity in view mode. The next "Create New Record"
|
|
458
|
+
* click for the same entity would otherwise hit the cache discriminator
|
|
459
|
+
* lookup, find this stale component, and reattach it — surfacing a blank form
|
|
460
|
+
* in view mode instead of a fresh edit-mode form. Destroy here forces a cache
|
|
461
|
+
* miss on the next open.
|
|
462
|
+
*/
|
|
463
|
+
private closeTabDestroyingComponent;
|
|
464
|
+
/** Open an app's default tab (its home / landing surface), if it has one. */
|
|
465
|
+
private openAppDefaultTab;
|
|
466
|
+
/**
|
|
467
|
+
* A record was deleted in this session — from its own form, a custom form, a
|
|
468
|
+
* grid row, or any other `BaseEntity.Delete()`. Nothing may keep showing it:
|
|
469
|
+
*
|
|
470
|
+
* 1. Other record tabs whose origin chain names it get the record spliced out,
|
|
471
|
+
* so their crumb returns to where the user was before it.
|
|
472
|
+
* 2. Every record tab showing it closes, its cached form destroyed.
|
|
473
|
+
* 3. If one of those was the ACTIVE tab, the user is taken back to where it
|
|
474
|
+
* was opened from; with no origin (e.g. loaded straight from a URL), to the
|
|
475
|
+
* Home dashboard, or the tab's own app landing page when there is no Home
|
|
476
|
+
* app. Its URL's history entry is replaced so browser Back can't reopen it.
|
|
477
|
+
*
|
|
478
|
+
* Inactive tabs showing it just close: the user wasn't looking at them.
|
|
479
|
+
*/
|
|
480
|
+
HandleRecordDeleted(record: DeletedRecordRef): Promise<void>;
|
|
481
|
+
/** Where the user goes after the record they were looking at is deleted. */
|
|
482
|
+
private leaveDeletedRecord;
|
|
449
483
|
/**
|
|
450
484
|
* Generate a signature for tab content to detect when content changes
|
|
451
485
|
* This is needed because in single-resource mode, the same tab ID can have different content
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,SAAS,EACT,aAAa,EAEb,UAAU,EACV,cAAc,EACd,mBAAmB,EAKnB,iBAAiB,EAGjB,YAAY,EAEb,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, ViewChild, runInInjectionContext, createComponent, ViewEncapsulation, HostListener, Output, EventEmitter, inject } from '@angular/core';
|
|
2
|
-
import { GoldenLayoutManager, FlattenLayoutToSingleStack } from '@memberjunction/ng-base-application';
|
|
2
|
+
import { GoldenLayoutManager, FlattenLayoutToSingleStack, TabService } from '@memberjunction/ng-base-application';
|
|
3
3
|
import { MJGlobal } from '@memberjunction/global';
|
|
4
|
-
import { BaseResourceComponent, HomeAppPinService, NavigationService, IsRecordTabsStyle, IsRecordsTabConfiguration, IsRecordsRegionTab, IsRecordDockedToWorkspace, RECORD_DOCKED_TO_WORKSPACE_KEY, GetRecordSourceContext, SafeDetectChanges, ExplorerBreakpointService, ResolveRecordTypeIcon } from '@memberjunction/ng-shared';
|
|
4
|
+
import { BaseResourceComponent, HomeAppPinService, NavigationService, IsRecordTabsStyle, IsRecordsTabConfiguration, IsRecordsRegionTab, IsRecordDockedToWorkspace, RECORD_DOCKED_TO_WORKSPACE_KEY, GetRecordSourceContext, SafeDetectChanges, ExplorerBreakpointService, ResolveRecordTypeIcon, GetDeletedRecordFromEvent, RecordTabShowsRecord, RemoveDeletedRecordFromOrigin, OriginToTabConfiguration, OriginHasReturnTarget, NormalizeRecordIdForMatch } from '@memberjunction/ng-shared';
|
|
5
5
|
import { ResourceData, ResourcePermissionEngine } from '@memberjunction/core-entities';
|
|
6
6
|
import { RecordOriginCrumbComponent } from '../record-open/record-origin-crumb.component';
|
|
7
7
|
import { RecordSwitcherService } from '../record-open/record-switcher.service';
|
|
@@ -216,6 +216,7 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
216
216
|
layoutInitError = this.LayoutInitError;
|
|
217
217
|
pinService = inject(HomeAppPinService);
|
|
218
218
|
navigationService = inject(NavigationService);
|
|
219
|
+
tabService = inject(TabService);
|
|
219
220
|
recordSwitcher = inject(RecordSwitcherService);
|
|
220
221
|
subscriptions = [];
|
|
221
222
|
layoutInitRetryCount = 0;
|
|
@@ -473,6 +474,7 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
473
474
|
flushRegionCd() {
|
|
474
475
|
SafeDetectChanges(this.cdr);
|
|
475
476
|
}
|
|
477
|
+
recordsLayoutInitRetryCount = 0;
|
|
476
478
|
/**
|
|
477
479
|
* Keep the RECORDS region in lockstep with the workspace configuration:
|
|
478
480
|
* resolve region visibility (active tab is a record), lazily initialize the
|
|
@@ -493,6 +495,13 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
493
495
|
const recordTabs = config.tabs.filter(t => this.isRecordTab(t));
|
|
494
496
|
const activeTab = config.tabs.find(t => t.id === config.activeTabId);
|
|
495
497
|
const showing = !!activeTab && this.isRecordTab(activeTab);
|
|
498
|
+
if (showing !== this.ShowRecordsRegion) {
|
|
499
|
+
this.ShowRecordsRegion = showing;
|
|
500
|
+
// Flush NOW — the visibility class must land BEFORE records GL init/tab
|
|
501
|
+
// creation so synchronous TabShown events see ShowRecordsRegion=true and
|
|
502
|
+
// load the active record immediately instead of parking it.
|
|
503
|
+
this.flushRegionCd();
|
|
504
|
+
}
|
|
496
505
|
// EAGER init + sync on EVERY emission. The region container always keeps
|
|
497
506
|
// its full layout box (visibility-hidden, never display:none — see the
|
|
498
507
|
// component CSS), so the records GL can initialize and reconcile even
|
|
@@ -506,14 +515,8 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
506
515
|
if (this.recordsLayoutInitialized) {
|
|
507
516
|
this.syncRecordsTabs(recordTabs);
|
|
508
517
|
}
|
|
509
|
-
if (
|
|
510
|
-
this.
|
|
511
|
-
// Flush NOW — the visibility class must land in this pass, not
|
|
512
|
-
// whenever the next unrelated emission happens to run CD.
|
|
513
|
-
this.flushRegionCd();
|
|
514
|
-
if (showing) {
|
|
515
|
-
this.flushPendingRecordShows();
|
|
516
|
-
}
|
|
518
|
+
if (this.ShowRecordsRegion) {
|
|
519
|
+
this.flushPendingRecordShows();
|
|
517
520
|
}
|
|
518
521
|
if (showing && activeTab && this.recordsLayoutInitialized) {
|
|
519
522
|
this.focusRecordsTab(activeTab.id);
|
|
@@ -736,17 +739,24 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
736
739
|
return;
|
|
737
740
|
}
|
|
738
741
|
const container = this.RecordsGlContainer?.nativeElement;
|
|
739
|
-
if (!container) {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
742
|
+
if (!container || container.getBoundingClientRect().height === 0) {
|
|
743
|
+
// NEVER initialize GL inside a missing or zero-size (hidden) container —
|
|
744
|
+
// it bakes a 0x0 internal size into every stack it later creates and the
|
|
745
|
+
// region renders collapsed forever. If the records region IS the active
|
|
746
|
+
// surface (e.g. startup deep link to a record before layout settles),
|
|
747
|
+
// schedule a bounded retry so initialization is not stranded.
|
|
748
|
+
if (this.ShowRecordsRegion && this.recordsLayoutInitRetryCount < this.MAX_LAYOUT_INIT_RETRIES) {
|
|
749
|
+
this.recordsLayoutInitRetryCount++;
|
|
750
|
+
setTimeout(() => {
|
|
751
|
+
const latest = this.workspaceManager.GetConfiguration();
|
|
752
|
+
if (latest && !this.recordsLayoutInitialized) {
|
|
753
|
+
this.syncRecordsRegion(latest);
|
|
754
|
+
}
|
|
755
|
+
}, 50);
|
|
756
|
+
}
|
|
748
757
|
return;
|
|
749
758
|
}
|
|
759
|
+
this.recordsLayoutInitRetryCount = 0;
|
|
750
760
|
// Mobile: headerless GL — the record bar replaces the strip
|
|
751
761
|
this.recordsLayoutManager.Initialize(container, { HideHeaders: this.mobileRecordsActive });
|
|
752
762
|
this.recordsLayoutInitialized = true;
|
|
@@ -765,6 +775,14 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
765
775
|
// loading such a layout would render a ghost pane for a closed record.
|
|
766
776
|
if (layoutToLoad?.root && recordTabs.length > 0 && this.layoutCoversExactTabSet(layoutToLoad.root, recordTabs)) {
|
|
767
777
|
if (this.recordsLayoutManager.LoadLayout(layoutToLoad)) {
|
|
778
|
+
recordTabs.forEach(tab => this.updateTabDisplayName(tab));
|
|
779
|
+
setTimeout(() => {
|
|
780
|
+
const latest = this.workspaceManager.GetConfiguration();
|
|
781
|
+
if (latest?.activeTabId && this.ShowRecordsRegion) {
|
|
782
|
+
this.focusRecordsTab(latest.activeTabId);
|
|
783
|
+
}
|
|
784
|
+
this.recordsLayoutManager.updateSize();
|
|
785
|
+
}, 50);
|
|
768
786
|
return;
|
|
769
787
|
}
|
|
770
788
|
}
|
|
@@ -874,6 +892,23 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
874
892
|
this.ShowContextMenu(event.x, event.y, event.tabId, event.anchorEl);
|
|
875
893
|
}));
|
|
876
894
|
this.wireRecordsLayoutEvents();
|
|
895
|
+
// A record deleted in this session: close every tab showing it and move the
|
|
896
|
+
// user off it (see HandleRecordDeleted). Remote deletes are left to the
|
|
897
|
+
// record tab itself, which shows a banner rather than vanishing under the user.
|
|
898
|
+
this.subscriptions.push(MJGlobal.Instance.GetEventListener().subscribe(event => {
|
|
899
|
+
// Read the key NOW: right after raising 'delete' the entity calls
|
|
900
|
+
// NewRecord() and its key is gone.
|
|
901
|
+
const deleted = GetDeletedRecordFromEvent(event);
|
|
902
|
+
if (!deleted || deleted.Remote) {
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
// Deferred one macrotask: the event fires inside BaseEntity.Delete(), and
|
|
906
|
+
// the deleting form still has to finish (success toast, RecordDeleted
|
|
907
|
+
// handlers) before its tab is torn down.
|
|
908
|
+
setTimeout(() => {
|
|
909
|
+
this.HandleRecordDeleted(deleted).catch(err => LogError(err));
|
|
910
|
+
}, 0);
|
|
911
|
+
}));
|
|
877
912
|
// Breakpoint crossings rebuild the records GL in the other chrome mode
|
|
878
913
|
// (headerless+flattened vs full strip+splits). Skip-if-equal: the
|
|
879
914
|
// BehaviorSubject replays the current value on subscribe.
|
|
@@ -1036,6 +1071,11 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
1036
1071
|
}));
|
|
1037
1072
|
}
|
|
1038
1073
|
ngAfterViewInit() {
|
|
1074
|
+
const config = this.workspaceManager.GetConfiguration();
|
|
1075
|
+
if (config) {
|
|
1076
|
+
this.syncRecordsRegion(config);
|
|
1077
|
+
this.updateRecordSurfaceState(config);
|
|
1078
|
+
}
|
|
1039
1079
|
// Initialize Golden Layout only if we're not in single-resource mode
|
|
1040
1080
|
if (!this.UseSingleResourceMode) {
|
|
1041
1081
|
this.initializeGoldenLayout();
|
|
@@ -1727,13 +1767,26 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
1727
1767
|
const config = this.workspaceManager.GetConfiguration();
|
|
1728
1768
|
const tab = config?.tabs.find(t => t.id === tabId);
|
|
1729
1769
|
const isLastTab = config?.tabs.length === 1 && config.tabs[0].id === tabId;
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1770
|
+
this.closeTabDestroyingComponent(tabId);
|
|
1771
|
+
if (isLastTab && tab) {
|
|
1772
|
+
// CloseTab kept the tab around but unpinned it. Replace it with the app's
|
|
1773
|
+
// default tab so the user lands on a meaningful surface (typically the
|
|
1774
|
+
// home dashboard) instead of staying on the discarded form.
|
|
1775
|
+
await this.openAppDefaultTab(tab.applicationId);
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Close a tab and DESTROY (not just detach) its cached component.
|
|
1780
|
+
*
|
|
1781
|
+
* The default tab-close path detaches and keeps components alive for reuse —
|
|
1782
|
+
* but a discarded or deleted record's form is exactly what we DON'T want to
|
|
1783
|
+
* keep: it holds a stale BaseEntity in view mode. The next "Create New Record"
|
|
1784
|
+
* click for the same entity would otherwise hit the cache discriminator
|
|
1785
|
+
* lookup, find this stale component, and reattach it — surfacing a blank form
|
|
1786
|
+
* in view mode instead of a fresh edit-mode form. Destroy here forces a cache
|
|
1787
|
+
* miss on the next open.
|
|
1788
|
+
*/
|
|
1789
|
+
closeTabDestroyingComponent(tabId) {
|
|
1737
1790
|
if (this.singleResourceCacheIdentity?.tabId === tabId) {
|
|
1738
1791
|
// Single-resource mode: the component is tracked via singleResource* fields,
|
|
1739
1792
|
// and its cache entry is currently marked attached. Use the identity directly
|
|
@@ -1744,7 +1797,7 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
1744
1797
|
this.singleResourceComponentRef = null;
|
|
1745
1798
|
this.singleResourceCacheIdentity = null;
|
|
1746
1799
|
// Clear the host container's DOM so the user isn't briefly looking at the
|
|
1747
|
-
// destroyed component's wrapper between CloseTab and the
|
|
1800
|
+
// destroyed component's wrapper between CloseTab and the next tab's load.
|
|
1748
1801
|
const directContainer = this.DirectContentContainer?.nativeElement;
|
|
1749
1802
|
if (directContainer) {
|
|
1750
1803
|
while (directContainer.firstChild)
|
|
@@ -1758,18 +1811,78 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
1758
1811
|
this.componentRefs.delete(tabId);
|
|
1759
1812
|
}
|
|
1760
1813
|
this.workspaceManager.CloseTab(tabId);
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1814
|
+
}
|
|
1815
|
+
/** Open an app's default tab (its home / landing surface), if it has one. */
|
|
1816
|
+
async openAppDefaultTab(appId) {
|
|
1817
|
+
const app = this.appManager.GetAppById(appId);
|
|
1818
|
+
if (app) {
|
|
1819
|
+
const defaultTabRequest = await app.CreateDefaultTab();
|
|
1820
|
+
if (defaultTabRequest) {
|
|
1821
|
+
this.workspaceManager.OpenTab(defaultTabRequest, app.GetColor());
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
/**
|
|
1826
|
+
* A record was deleted in this session — from its own form, a custom form, a
|
|
1827
|
+
* grid row, or any other `BaseEntity.Delete()`. Nothing may keep showing it:
|
|
1828
|
+
*
|
|
1829
|
+
* 1. Other record tabs whose origin chain names it get the record spliced out,
|
|
1830
|
+
* so their crumb returns to where the user was before it.
|
|
1831
|
+
* 2. Every record tab showing it closes, its cached form destroyed.
|
|
1832
|
+
* 3. If one of those was the ACTIVE tab, the user is taken back to where it
|
|
1833
|
+
* was opened from; with no origin (e.g. loaded straight from a URL), to the
|
|
1834
|
+
* Home dashboard, or the tab's own app landing page when there is no Home
|
|
1835
|
+
* app. Its URL's history entry is replaced so browser Back can't reopen it.
|
|
1836
|
+
*
|
|
1837
|
+
* Inactive tabs showing it just close: the user wasn't looking at them.
|
|
1838
|
+
*/
|
|
1839
|
+
async HandleRecordDeleted(record) {
|
|
1840
|
+
const config = this.workspaceManager.GetConfiguration();
|
|
1841
|
+
if (!config) {
|
|
1842
|
+
return;
|
|
1843
|
+
}
|
|
1844
|
+
const showing = config.tabs.filter(t => RecordTabShowsRecord(t, record));
|
|
1845
|
+
const showingIds = new Set(showing.map(t => t.id));
|
|
1846
|
+
for (const tab of config.tabs) {
|
|
1847
|
+
if (showingIds.has(tab.id) || !IsRecordsTabConfiguration(tab.configuration)) {
|
|
1848
|
+
continue;
|
|
1849
|
+
}
|
|
1850
|
+
const origin = GetRecordSourceContext(tab.configuration) ?? undefined;
|
|
1851
|
+
const pruned = RemoveDeletedRecordFromOrigin(origin, record);
|
|
1852
|
+
if (pruned !== origin) {
|
|
1853
|
+
this.workspaceManager.UpdateTabConfiguration(tab.id, OriginToTabConfiguration(pruned));
|
|
1771
1854
|
}
|
|
1772
1855
|
}
|
|
1856
|
+
if (showing.length === 0) {
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
const activeTab = showing.find(t => t.id === config.activeTabId);
|
|
1860
|
+
const returnTo = activeTab
|
|
1861
|
+
? RemoveDeletedRecordFromOrigin(GetRecordSourceContext(activeTab.configuration) ?? undefined, record)
|
|
1862
|
+
: undefined;
|
|
1863
|
+
if (activeTab) {
|
|
1864
|
+
// Mark by what the tab's URL carries (its own entity string and id), not
|
|
1865
|
+
// the event's canonical name: the URL is built from the tab.
|
|
1866
|
+
const urlEntity = activeTab.configuration?.['Entity'];
|
|
1867
|
+
this.tabService.MarkRecordUrlForReplacement(typeof urlEntity === 'string' ? urlEntity : record.EntityName, NormalizeRecordIdForMatch(activeTab.resourceRecordId || record.RecordId));
|
|
1868
|
+
}
|
|
1869
|
+
for (const tab of showing) {
|
|
1870
|
+
this.closeTabDestroyingComponent(tab.id);
|
|
1871
|
+
}
|
|
1872
|
+
if (activeTab) {
|
|
1873
|
+
await this.leaveDeletedRecord(activeTab, returnTo);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
/** Where the user goes after the record they were looking at is deleted. */
|
|
1877
|
+
async leaveDeletedRecord(deletedTab, origin) {
|
|
1878
|
+
if (OriginHasReturnTarget(origin)) {
|
|
1879
|
+
await this.navigationService.ReturnToRecordSource(origin);
|
|
1880
|
+
return;
|
|
1881
|
+
}
|
|
1882
|
+
if (await this.navigationService.OpenHomeDashboard()) {
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
1885
|
+
await this.openAppDefaultTab(deletedTab.applicationId);
|
|
1773
1886
|
}
|
|
1774
1887
|
/**
|
|
1775
1888
|
* Generate a signature for tab content to detect when content changes
|
|
@@ -2971,5 +3084,5 @@ export class TabContainerComponent extends BaseAngularComponent {
|
|
|
2971
3084
|
type: HostListener,
|
|
2972
3085
|
args: ['window:resize']
|
|
2973
3086
|
}] }); })();
|
|
2974
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabContainerComponent, { className: "TabContainerComponent", filePath: "src/lib/shell/components/tabs/tab-container.component.ts", lineNumber:
|
|
3087
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabContainerComponent, { className: "TabContainerComponent", filePath: "src/lib/shell/components/tabs/tab-container.component.ts", lineNumber: 68 }); })();
|
|
2975
3088
|
//# sourceMappingURL=tab-container.component.js.map
|