@memberjunction/ng-dashboards 5.4.0 → 5.5.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/AI/components/agents/agent-configuration.component.js +4 -4
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +5 -4
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +3 -3
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +8 -7
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +3 -3
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +4 -4
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +3 -2
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +2 -2
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +4 -3
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +3 -3
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +3 -2
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +2 -2
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +3 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +3 -2
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +2 -2
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +6 -0
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +19 -6
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +4 -0
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +13 -4
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +13 -9
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +11 -11
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +3 -3
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +13 -9
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +11 -11
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +4 -3
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +4 -3
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +6 -6
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +4 -1
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +9 -8
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +2 -2
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Home/home-application.js +2 -2
- package/dist/Home/home-application.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +3 -3
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts +1 -0
- package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +17 -14
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts +1 -0
- package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +15 -12
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +3 -2
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +8 -7
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +22 -22
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +2 -0
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +14 -10
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js +2 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +1 -0
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +22 -18
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts +1 -0
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +14 -10
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.js +6 -6
- package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +2 -2
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +3 -3
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/package.json +38 -38
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-explorer-resource.component.d.ts","sourceRoot":"","sources":["../../src/DataExplorer/data-explorer-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAwD,MAAM,eAAe,CAAC;AAGtI,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAmB,MAAM,2BAA2B,CAAC;AACtG,OAAO,EAAE,YAAY,EAAqB,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;;AACvE;;;;GAIG;AACH,qBA2Ba,6BAA8B,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAmB7F,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,iBAAiB;IAftB,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IAC/C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEE,YAAY,EAAG,8BAA8B,CAAC;IAEzF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,WAAW,CAAS;gBAOhB,GAAG,EAAE,iBAAiB,EACtB,iBAAiB,EAAE,iBAAiB;IAShD,IAAa,IAAI,CAAC,KAAK,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"data-explorer-resource.component.d.ts","sourceRoot":"","sources":["../../src/DataExplorer/data-explorer-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAwD,MAAM,eAAe,CAAC;AAGtI,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAmB,MAAM,2BAA2B,CAAC;AACtG,OAAO,EAAE,YAAY,EAAqB,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;;AACvE;;;;GAIG;AACH,qBA2Ba,6BAA8B,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAmB7F,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,iBAAiB;IAftB,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IAC/C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEE,YAAY,EAAG,8BAA8B,CAAC;IAEzF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,WAAW,CAAS;gBAOhB,GAAG,EAAE,iBAAiB,EACtB,iBAAiB,EAAE,iBAAiB;IAShD,IAAa,IAAI,CAAC,KAAK,EAAE,YAAY,EAWpC;IAED,IAAa,IAAI,IAAI,YAAY,CAEhC;IAMD,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;IASb,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ/D,OAAO,CAAC,iBAAiB;IAwClB,kBAAkB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,YAAY,CAAA;KAAE,GAAG,IAAI;yCAnH/E,6BAA6B;2CAA7B,6BAA6B;CAwHzC"}
|
|
@@ -41,8 +41,11 @@ let DataExplorerResourceComponent = class DataExplorerResourceComponent extends
|
|
|
41
41
|
// Data Property Override
|
|
42
42
|
// ========================================
|
|
43
43
|
set Data(value) {
|
|
44
|
+
const previousConfig = JSON.stringify(super.Data?.Configuration || {});
|
|
44
45
|
super.Data = value;
|
|
45
|
-
|
|
46
|
+
const newConfig = JSON.stringify(value?.Configuration || {});
|
|
47
|
+
// Load on first set, or when the configuration has changed
|
|
48
|
+
if (!this._dataLoaded || previousConfig !== newConfig) {
|
|
46
49
|
this._dataLoaded = true;
|
|
47
50
|
this.loadConfiguration();
|
|
48
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-explorer-resource.component.js","sourceRoot":"","sources":["../../src/DataExplorer/data-explorer-resource.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAwC,uBAAuB,EAAE,SAAS,EAAoB,MAAM,eAAe,CAAC;AACtI,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,qBAAqB,EAAsC,MAAM,2BAA2B,CAAC;AAEtG,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;;;;AAErF;;;;GAIG;AA4BI,IAAM,6BAA6B,GAAnC,MAAM,6BAA8B,SAAQ,qBAAqB;IAmBxD;IACA;IAnBZ,2CAA2C;IAC3C,QAAQ;IACR,2CAA2C;IAEpC,YAAY,GAA8B,IAAI,CAAC;IAC/C,WAAW,GAAkB,IAAI,CAAC;IAClC,WAAW,GAAkB,IAAI,CAAC;IAEE,YAAY,CAAkC;IAExE,SAAS,GAAG,IAAI,OAAO,EAAQ,CAAC;IACzC,WAAW,GAAG,KAAK,CAAC;IAE5B,2CAA2C;IAC3C,cAAc;IACd,2CAA2C;IAE3C,YACY,GAAsB,EACtB,iBAAoC;QAE5C,KAAK,EAAE,CAAC;QAHA,QAAG,GAAH,GAAG,CAAmB;QACtB,sBAAiB,GAAjB,iBAAiB,CAAmB;IAGhD,CAAC;IAED,2CAA2C;IAC3C,yBAAyB;IACzB,2CAA2C;IAE3C,IAAa,IAAI,CAAC,KAAmB;QACjC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"data-explorer-resource.component.js","sourceRoot":"","sources":["../../src/DataExplorer/data-explorer-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy, ViewChild, ViewContainerRef } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { RegisterClass } from '@memberjunction/global';\nimport { CompositeKey } from '@memberjunction/core';\nimport { BaseResourceComponent, NavigationService, DashboardConfig } from '@memberjunction/ng-shared';\nimport { ResourceData, MJDashboardEntity } from '@memberjunction/core-entities';\nimport { DataExplorerDashboardComponent } from './data-explorer-dashboard.component';\nimport { DataExplorerFilter } from './models/explorer-state.interface';\n/**\n * Resource component for the Data Explorer.\n * Wraps DataExplorerDashboardComponent as a BaseResourceComponent for use\n * in application nav items with ResourceType: \"Custom\".\n */\n@RegisterClass(BaseResourceComponent, 'DataExplorerResource')\n@Component({\n standalone: false,\n selector: 'mj-data-explorer-resource',\n template: `\n <div class=\"data-explorer-resource-container\">\n <mj-data-explorer-dashboard\n [entityFilter]=\"entityFilter\"\n [contextName]=\"contextName\"\n [contextIcon]=\"contextIcon\"\n (OpenEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-data-explorer-dashboard>\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n .data-explorer-resource-container {\n width: 100%;\n height: 100%;\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class DataExplorerResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n // ========================================\n // State\n // ========================================\n\n public entityFilter: DataExplorerFilter | null = null;\n public contextName: string | null = null;\n public contextIcon: string | null = null;\n\n @ViewChild(DataExplorerDashboardComponent) dataExplorer!: DataExplorerDashboardComponent;\n\n private readonly _destroy$ = new Subject<void>();\n private _dataLoaded = false;\n\n // ========================================\n // Constructor\n // ========================================\n\n constructor(\n private cdr: ChangeDetectorRef,\n private navigationService: NavigationService\n ) {\n super();\n }\n\n // ========================================\n // Data Property Override\n // ========================================\n\n override set Data(value: ResourceData) {\n const previousConfig = JSON.stringify(super.Data?.Configuration || {});\n super.Data = value;\n\n const newConfig = JSON.stringify(value?.Configuration || {});\n\n // Load on first set, or when the configuration has changed\n if (!this._dataLoaded || previousConfig !== newConfig) {\n this._dataLoaded = true;\n this.loadConfiguration();\n }\n }\n\n override get Data(): ResourceData {\n return super.Data;\n }\n\n // ========================================\n // Lifecycle\n // ========================================\n\n ngOnInit(): void {\n // Configuration loaded via Data setter\n }\n\n ngOnDestroy(): void {\n this._destroy$.next();\n this._destroy$.complete();\n }\n\n // ========================================\n // BaseResourceComponent Implementation\n // ========================================\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return data.Name || 'Data';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-table-cells';\n }\n\n // ========================================\n // Private Methods\n // ========================================\n\n private loadConfiguration(): void {\n const data = this.Data;\n if (!data) {\n this.NotifyLoadComplete();\n return;\n }\n\n const config = data.Configuration || {};\n\n // Extract configuration options\n this.entityFilter = config['entityFilter'] as DataExplorerFilter || null;\n this.contextName = config['appName'] as string || null;\n this.contextIcon = config['appIcon'] as string || null;\n\n this.cdr.detectChanges();\n\n // Setup LoadCompleteEvent after view initializes\n setTimeout(() => {\n if (this.dataExplorer) {\n this.dataExplorer.LoadCompleteEvent = () => {\n this.NotifyLoadComplete();\n };\n\n // Initialize with minimal config (no database dashboard)\n const dashboardConfig: DashboardConfig = {\n dashboard: null as unknown as MJDashboardEntity,\n userState: {}\n };\n this.dataExplorer.Config = dashboardConfig;\n this.dataExplorer.Refresh();\n } else {\n this.NotifyLoadComplete();\n }\n }, 0);\n }\n\n // ========================================\n // Event Handlers\n // ========================================\n\n public onOpenEntityRecord(event: { EntityName: string; RecordPKey: CompositeKey }): void {\n if (event && event.EntityName && event.RecordPKey) {\n this.navigationService.OpenEntityRecord(event.EntityName, event.RecordPKey);\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-state.service.d.ts","sourceRoot":"","sources":["../../../src/DataExplorer/services/explorer-state.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;AAGnD,OAAO,EAAE,iBAAiB,EAA0B,UAAU,EAAE,YAAY,EAAoB,cAAc,EAAE,kBAAkB,EAAkB,kBAAkB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;;
|
|
1
|
+
{"version":3,"file":"explorer-state.service.d.ts","sourceRoot":"","sources":["../../../src/DataExplorer/services/explorer-state.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { BehaviorSubject } from 'rxjs';
|
|
|
3
3
|
import { Metadata, RunView, CompositeKey } from '@memberjunction/core';
|
|
4
4
|
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
5
5
|
import { DEFAULT_EXPLORER_STATE } from '../models/explorer-state.interface';
|
|
6
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
const BASE_SETTING_KEY = 'DataExplorer.State';
|
|
8
9
|
const MAX_RECENT_ITEMS = 20;
|
|
@@ -677,11 +678,11 @@ export class ExplorerStateService {
|
|
|
677
678
|
// Use UserInfoEngine for cached access to user favorites
|
|
678
679
|
const engine = UserInfoEngine.Instance;
|
|
679
680
|
// Filter to only entity favorites (where EntityID is the Entities entity)
|
|
680
|
-
const entityFavorites = engine.UserFavorites.filter(f => f.EntityID
|
|
681
|
+
const entityFavorites = engine.UserFavorites.filter(f => UUIDsEqual(f.EntityID, entitiesEntity.ID));
|
|
681
682
|
const favoriteEntities = [];
|
|
682
683
|
for (const fav of entityFavorites) {
|
|
683
684
|
// Look up entity name from RecordID (which is the Entity.ID)
|
|
684
|
-
const entity = this.metadata.Entities.find(e => e.ID
|
|
685
|
+
const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, fav.RecordID));
|
|
685
686
|
if (entity) {
|
|
686
687
|
favoriteEntities.push({
|
|
687
688
|
userFavoriteId: fav.ID,
|
|
@@ -713,10 +714,10 @@ export class ExplorerStateService {
|
|
|
713
714
|
const recordIndexMap = new Map(); // Map composite key to array index
|
|
714
715
|
for (const log of userRecordLogs) {
|
|
715
716
|
// Look up entity name from EntityID
|
|
716
|
-
const entity = this.metadata.Entities.find(e => e.ID
|
|
717
|
+
const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, log.EntityID));
|
|
717
718
|
if (entity) {
|
|
718
719
|
// Filter by application context if applicable
|
|
719
|
-
if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => ae.EntityID
|
|
720
|
+
if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => UUIDsEqual(ae.EntityID, log.EntityID))) {
|
|
720
721
|
continue; // Skip records from entities not in this application
|
|
721
722
|
}
|
|
722
723
|
const recordAccess = {
|
|
@@ -812,7 +813,7 @@ export class ExplorerStateService {
|
|
|
812
813
|
*/
|
|
813
814
|
addLocalRecentRecord(entityName, entityId, recordId, recordName) {
|
|
814
815
|
// Filter by application context if applicable
|
|
815
|
-
if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => ae.EntityID
|
|
816
|
+
if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => UUIDsEqual(ae.EntityID, entityId))) {
|
|
816
817
|
return; // Don't add records from entities not in this application
|
|
817
818
|
}
|
|
818
819
|
const currentRecords = [...this.recentRecords$.value];
|
|
@@ -853,16 +854,16 @@ export class ExplorerStateService {
|
|
|
853
854
|
// Use UserInfoEngine for cached access to user favorites
|
|
854
855
|
const engine = UserInfoEngine.Instance;
|
|
855
856
|
// Filter to non-entity favorites (exclude favorites where EntityID is the Entities entity)
|
|
856
|
-
const nonEntityFavorites = engine.UserFavorites.filter(f => f.EntityID
|
|
857
|
+
const nonEntityFavorites = engine.UserFavorites.filter(f => !UUIDsEqual(f.EntityID, entitiesEntityId));
|
|
857
858
|
const favoriteRecords = [];
|
|
858
859
|
const recordNameInputs = [];
|
|
859
860
|
const recordIndexMap = new Map();
|
|
860
861
|
for (const fav of nonEntityFavorites) {
|
|
861
862
|
// Look up entity info from the EntityID
|
|
862
|
-
const entity = this.metadata.Entities.find(e => e.ID
|
|
863
|
+
const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, fav.EntityID));
|
|
863
864
|
if (entity) {
|
|
864
865
|
// Filter by application context if applicable
|
|
865
|
-
if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => ae.EntityID
|
|
866
|
+
if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => UUIDsEqual(ae.EntityID, fav.EntityID))) {
|
|
866
867
|
continue; // Skip records from entities not in this application
|
|
867
868
|
}
|
|
868
869
|
const favoriteRecord = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-state.service.js","sourceRoot":"","sources":["../../../src/DataExplorer/services/explorer-state.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { Metadata, RunView, CompositeKey, EntityRecordNameInput } from '@memberjunction/core';\nimport { MJUserSettingEntity, MJUserFavoriteEntity, MJApplicationEntityEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { DataExplorerState, DEFAULT_EXPLORER_STATE, RecentItem, FavoriteItem, EntityCacheEntry, BreadcrumbItem, DataExplorerFilter, FavoriteEntity, RecentRecordAccess, FavoriteRecord, DataExplorerViewMode } from '../models/explorer-state.interface';\n\nconst BASE_SETTING_KEY = 'DataExplorer.State';\nconst MAX_RECENT_ITEMS = 20;\nconst MAX_RECENT_ENTITIES = 10;\nconst MAX_RECENT_RECORDS = 10;\nconst MAX_ENTITY_CACHE_SIZE = 50; // LRU cache limit\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ExplorerStateService {\n private state$ = new BehaviorSubject<DataExplorerState>(DEFAULT_EXPLORER_STATE);\n private metadata = new Metadata();\n private saveTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Current context filter (determines which settings key to use) */\n private currentFilter: DataExplorerFilter | null = null;\n\n /** Computed breadcrumbs based on current state */\n private breadcrumbs$ = new BehaviorSubject<BreadcrumbItem[]>([]);\n\n /** Recent records loaded from User Record Logs */\n private recentRecords$ = new BehaviorSubject<RecentRecordAccess[]>([]);\n\n /** Favorite records loaded from User Favorites (non-entity favorites) */\n private favoriteRecords$ = new BehaviorSubject<FavoriteRecord[]>([]);\n\n /** Application entities with DefaultForNewUser info (loaded once per context) */\n private applicationEntities: MJApplicationEntityEntity[] = [];\n\n /** Set of entity IDs that have DefaultForNewUser=true */\n private defaultEntityIds = new Set<string>();\n\n constructor() {\n // Don't load state in constructor - wait for setContext to be called\n }\n\n /**\n * Set the context filter and load context-specific state.\n * Call this before using the service to ensure proper context isolation.\n */\n async setContext(filter: DataExplorerFilter | null): Promise<void> {\n this.currentFilter = filter;\n await this.loadState();\n // Load application entities first (needed for filtering recent/favorite records)\n await this.loadApplicationEntities();\n // Then load the rest in parallel\n await Promise.all([\n this.loadFavoriteEntities(),\n this.loadFavoriteRecords(),\n this.loadRecentRecords()\n ]);\n this.updateBreadcrumbs();\n }\n\n /**\n * Get the storage key based on current context.\n * Uses application ID if available for context-specific storage.\n */\n private getSettingKey(): string {\n if (this.currentFilter?.applicationId) {\n return `${BASE_SETTING_KEY}.${this.currentFilter.applicationId}`;\n }\n return BASE_SETTING_KEY;\n }\n\n /**\n * Get observable of current state\n */\n get State(): Observable<DataExplorerState> {\n return this.state$.asObservable();\n }\n\n /**\n * Get current state value\n */\n get CurrentState(): DataExplorerState {\n return this.state$.value;\n }\n\n /**\n * Observable of current breadcrumbs\n */\n get Breadcrumbs(): Observable<BreadcrumbItem[]> {\n return this.breadcrumbs$.asObservable();\n }\n\n /**\n * Get current breadcrumbs value\n */\n get CurrentBreadcrumbs(): BreadcrumbItem[] {\n return this.breadcrumbs$.value;\n }\n\n /**\n * Get the current context filter\n */\n get CurrentFilter(): DataExplorerFilter | null {\n return this.currentFilter;\n }\n\n /**\n * Observable of recent records (from User Record Logs)\n */\n get RecentRecords(): Observable<RecentRecordAccess[]> {\n return this.recentRecords$.asObservable();\n }\n\n /**\n * Get current recent records value\n */\n get CurrentRecentRecords(): RecentRecordAccess[] {\n return this.recentRecords$.value;\n }\n\n /**\n * Observable of favorite records (from User Favorites, non-entity)\n */\n get FavoriteRecords(): Observable<FavoriteRecord[]> {\n return this.favoriteRecords$.asObservable();\n }\n\n /**\n * Get current favorite records value\n */\n get CurrentFavoriteRecords(): FavoriteRecord[] {\n return this.favoriteRecords$.value;\n }\n\n /**\n * Get the set of entity IDs with DefaultForNewUser=true\n */\n get DefaultEntityIds(): Set<string> {\n return this.defaultEntityIds;\n }\n\n /**\n * Update state partially\n */\n updateState(partial: Partial<DataExplorerState>): void {\n const newState = { ...this.state$.value, ...partial };\n this.state$.next(newState);\n this.updateBreadcrumbs();\n this.debouncedSave();\n }\n\n /**\n * Set selected entity\n * Caches current entity's filter before switching, restores new entity's cached filter\n */\n selectEntity(entityName: string | null): void {\n const currentState = this.state$.value;\n const entityCache = { ...currentState.entityCache };\n\n // Cache current entity's filter before switching (if we have a current entity)\n if (currentState.selectedEntityName && currentState.smartFilterPrompt) {\n entityCache[currentState.selectedEntityName] = {\n filterText: currentState.smartFilterPrompt,\n lastAccessed: Date.now()\n };\n }\n\n // Restore filter for new entity (if cached) or clear it\n let restoredFilter = '';\n if (entityName && entityCache[entityName]) {\n restoredFilter = entityCache[entityName].filterText;\n entityCache[entityName].lastAccessed = Date.now();\n }\n\n // Evict old entries if cache is too large (LRU)\n this.evictOldCacheEntries(entityCache);\n\n this.updateState({\n selectedEntityName: entityName,\n selectedViewId: null, // Reset view when entity changes\n smartFilterPrompt: restoredFilter, // Restore cached filter or empty\n selectedRecordId: null,\n detailPanelOpen: false,\n entityCache\n });\n }\n\n /**\n * Evict oldest cache entries if over limit (LRU eviction)\n */\n private evictOldCacheEntries(cache: Record<string, EntityCacheEntry>): void {\n const entries = Object.entries(cache);\n if (entries.length <= MAX_ENTITY_CACHE_SIZE) return;\n\n // Sort by lastAccessed (oldest first) and remove excess\n entries.sort((a, b) => a[1].lastAccessed - b[1].lastAccessed);\n const toRemove = entries.length - MAX_ENTITY_CACHE_SIZE;\n for (let i = 0; i < toRemove; i++) {\n delete cache[entries[i][0]];\n }\n }\n\n /**\n * Set selected view\n */\n selectView(viewId: string | null): void {\n this.updateState({\n selectedViewId: viewId,\n viewModified: false // Reset modified state when selecting a different view\n });\n }\n\n /**\n * Mark the current view as modified (has unsaved changes)\n */\n setViewModified(modified: boolean): void {\n this.updateState({ viewModified: modified });\n }\n\n /**\n * Toggle the view configuration panel\n */\n toggleViewConfigPanel(): void {\n this.updateState({ viewConfigPanelOpen: !this.state$.value.viewConfigPanelOpen });\n }\n\n /**\n * Open the view configuration panel\n */\n openViewConfigPanel(): void {\n this.updateState({ viewConfigPanelOpen: true });\n }\n\n /**\n * Close the view configuration panel\n */\n closeViewConfigPanel(): void {\n this.updateState({ viewConfigPanelOpen: false });\n }\n\n /**\n * Set view mode\n */\n setViewMode(mode: DataExplorerViewMode): void {\n this.updateState({ viewMode: mode });\n }\n\n /**\n * Set smart filter prompt\n * Also updates the entity cache for the current entity\n */\n setSmartFilterPrompt(prompt: string): void {\n const currentState = this.state$.value;\n const entityCache = { ...currentState.entityCache };\n\n // Update cache for current entity\n if (currentState.selectedEntityName) {\n if (prompt) {\n entityCache[currentState.selectedEntityName] = {\n filterText: prompt,\n lastAccessed: Date.now()\n };\n } else {\n // Clear cache entry if filter is empty\n delete entityCache[currentState.selectedEntityName];\n }\n }\n\n this.updateState({ smartFilterPrompt: prompt, entityCache });\n }\n\n /**\n * Select a record and open detail panel\n * @param recordId The composite key string for the record\n * @param recordName Optional display name for the record (for breadcrumbs)\n */\n selectRecord(recordId: string | null, recordName?: string): void {\n this.updateState({\n selectedRecordId: recordId,\n selectedRecordName: recordName || null,\n detailPanelOpen: recordId !== null\n });\n }\n\n /**\n * Close detail panel\n */\n closeDetailPanel(): void {\n this.updateState({\n detailPanelOpen: false,\n selectedRecordId: null,\n selectedRecordName: null\n });\n }\n\n /**\n * Toggle navigation panel collapsed state\n */\n toggleNavigationPanel(): void {\n this.updateState({\n navigationPanelCollapsed: !this.state$.value.navigationPanelCollapsed\n });\n }\n\n /**\n * Expand navigation panel and ensure a specific section is expanded\n */\n expandAndFocusSection(section: 'favorites' | 'recent' | 'entities'): void {\n const updates: Partial<DataExplorerState> = {\n navigationPanelCollapsed: false\n };\n\n // Ensure the target section is expanded\n switch (section) {\n case 'favorites':\n updates.favoritesSectionExpanded = true;\n break;\n case 'recent':\n updates.recentSectionExpanded = true;\n break;\n case 'entities':\n updates.entitiesSectionExpanded = true;\n break;\n }\n\n this.updateState(updates);\n }\n\n /**\n * Add item to recent history\n */\n addRecentItem(item: Omit<RecentItem, 'timestamp'>): void {\n const recentItems = [...this.state$.value.recentItems];\n\n // Remove existing entry if present (match by entity and composite key)\n const existingIndex = recentItems.findIndex(\n r => r.entityName === item.entityName && r.compositeKeyString === item.compositeKeyString\n );\n if (existingIndex >= 0) {\n recentItems.splice(existingIndex, 1);\n }\n\n // Add to front with timestamp\n recentItems.unshift({\n ...item,\n timestamp: new Date()\n });\n\n // Trim to max size\n if (recentItems.length > MAX_RECENT_ITEMS) {\n recentItems.length = MAX_RECENT_ITEMS;\n }\n\n this.updateState({ recentItems });\n }\n\n /**\n * Add item to favorites\n */\n addFavorite(item: FavoriteItem): void {\n const favorites = [...this.state$.value.favorites];\n\n // Check if already exists\n const exists = favorites.some(f =>\n f.type === item.type &&\n f.entityName === item.entityName &&\n f.compositeKeyString === item.compositeKeyString &&\n f.viewId === item.viewId\n );\n\n if (!exists) {\n favorites.push(item);\n this.updateState({ favorites });\n }\n }\n\n /**\n * Remove item from favorites\n */\n removeFavorite(item: FavoriteItem): void {\n const favorites = this.state$.value.favorites.filter(f =>\n !(f.type === item.type &&\n f.entityName === item.entityName &&\n f.compositeKeyString === item.compositeKeyString &&\n f.viewId === item.viewId)\n );\n this.updateState({ favorites });\n }\n\n /**\n * Toggle section expanded state\n */\n toggleSection(section: 'favorites' | 'recent' | 'entities' | 'views'): void {\n const key = `${section}SectionExpanded` as keyof DataExplorerState;\n this.updateState({ [key]: !this.state$.value[key] } as Partial<DataExplorerState>);\n }\n\n /**\n * Load state from UserSetting using UserInfoEngine for cached access\n */\n private async loadState(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n const settingKey = this.getSettingKey();\n const engine = UserInfoEngine.Instance;\n\n // Find the setting from cached user settings\n const setting = engine.UserSettings.find(s => s.Setting === settingKey);\n\n if (setting?.Value) {\n const savedState = JSON.parse(setting.Value) as Partial<DataExplorerState>;\n // Merge with defaults to handle new properties\n this.state$.next({ ...DEFAULT_EXPLORER_STATE, ...savedState });\n } else {\n // No saved state, use defaults\n this.state$.next({ ...DEFAULT_EXPLORER_STATE });\n }\n } catch (error) {\n console.warn('Failed to load Data Explorer state:', error);\n this.state$.next({ ...DEFAULT_EXPLORER_STATE });\n }\n }\n\n /**\n * Update breadcrumbs based on current state and filter\n */\n private updateBreadcrumbs(): void {\n const breadcrumbs: BreadcrumbItem[] = [];\n const state = this.state$.value;\n\n // Always add a root/home breadcrumb - use application name if available, otherwise \"All\"\n const rootLabel = this.currentFilter?.applicationName || 'All';\n breadcrumbs.push({\n label: rootLabel,\n type: 'application',\n icon: 'fa-solid fa-th-large'\n });\n\n // Add entity breadcrumb if selected\n if (state.selectedEntityName) {\n const entityInfo = this.metadata.Entities.find(e => e.Name === state.selectedEntityName);\n breadcrumbs.push({\n label: state.selectedEntityName,\n type: 'entity',\n entityName: state.selectedEntityName,\n icon: entityInfo?.Icon ? this.formatEntityIcon(entityInfo.Icon) : 'fa-solid fa-table'\n });\n }\n\n // Add record breadcrumb if selected\n if (state.selectedRecordId && state.selectedRecordName) {\n breadcrumbs.push({\n label: state.selectedRecordName,\n type: 'record',\n entityName: state.selectedEntityName || undefined,\n compositeKeyString: state.selectedRecordId,\n icon: 'fa-solid fa-file-alt'\n });\n }\n\n this.breadcrumbs$.next(breadcrumbs);\n }\n\n /**\n * Format entity icon to ensure proper Font Awesome class format\n */\n private formatEntityIcon(icon: string): string {\n if (!icon) return 'fa-solid fa-table';\n if (icon.startsWith('fa-') || icon.startsWith('fa ')) {\n if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||\n icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||\n icon.startsWith('fa ')) {\n return icon;\n }\n return `fa-solid ${icon}`;\n }\n return `fa-solid fa-${icon}`;\n }\n\n /**\n * Debounced save to avoid too many writes\n */\n private debouncedSave(): void {\n if (this.saveTimeout) {\n clearTimeout(this.saveTimeout);\n }\n this.saveTimeout = setTimeout(() => {\n this.saveState();\n }, 1000);\n }\n\n /**\n * Save state to UserSetting using UserInfoEngine for cached lookup\n */\n private async saveState(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n const settingKey = this.getSettingKey();\n const md = new Metadata();\n const engine = UserInfoEngine.Instance;\n\n // Find existing setting from cached user settings\n let setting = engine.UserSettings.find(s => s.Setting === settingKey);\n\n if (!setting) {\n // Create new setting if not found\n setting = await md.GetEntityObject<MJUserSettingEntity>('MJ: User Settings');\n setting.UserID = userId;\n setting.Setting = settingKey;\n }\n\n setting.Value = JSON.stringify(this.state$.value);\n await setting.Save();\n } catch (error) {\n console.warn('Failed to save Data Explorer state:', error);\n }\n }\n\n /**\n * Navigate to a specific breadcrumb level.\n * Clears any selection deeper than the clicked breadcrumb.\n */\n navigateToBreadcrumb(breadcrumb: BreadcrumbItem): void {\n switch (breadcrumb.type) {\n case 'application':\n // Clear entity and record selection (show home view)\n this.updateState({\n selectedEntityName: null,\n selectedViewId: null,\n selectedRecordId: null,\n selectedRecordName: null,\n smartFilterPrompt: '',\n detailPanelOpen: false\n });\n break;\n\n case 'entity':\n // Keep entity selected, clear record selection\n if (breadcrumb.entityName) {\n this.updateState({\n selectedRecordId: null,\n selectedRecordName: null,\n detailPanelOpen: false\n });\n }\n break;\n\n case 'record':\n // Already at record level, do nothing\n break;\n }\n }\n\n // ========================================\n // HOME SCREEN ENTITY MANAGEMENT\n // ========================================\n\n /**\n * Toggle between showing all entities or just common (DefaultForNewUser) entities\n */\n toggleShowAllEntities(): void {\n this.updateState({ showAllEntities: !this.state$.value.showAllEntities });\n }\n\n // ========================================\n // Concept D: Application Groups + Quick Access\n // ========================================\n\n /**\n * Toggle the quick access (right) panel open/closed\n */\n toggleQuickAccessPanel(): void {\n this.updateState({ quickAccessPanelOpen: !this.state$.value.quickAccessPanelOpen });\n }\n\n /**\n * Toggle a quick access section's expanded state\n */\n toggleQuickAccessSection(sectionId: string): void {\n const sections = { ...this.state$.value.quickAccessSections };\n sections[sectionId] = sections[sectionId] === false; // default to expanded (true)\n this.updateState({ quickAccessSections: sections });\n }\n\n /**\n * Toggle an application group's expanded/collapsed state\n */\n toggleAppGroupExpanded(appId: string): void {\n const expanded = [...this.state$.value.expandedAppGroups];\n const index = expanded.indexOf(appId);\n if (index >= 0) {\n expanded.splice(index, 1);\n } else {\n expanded.push(appId);\n }\n this.updateState({ expandedAppGroups: expanded });\n }\n\n /**\n * Set the home view mode (all vs favorites)\n */\n setHomeViewMode(mode: 'all' | 'favorites'): void {\n this.updateState({ homeViewMode: mode });\n }\n\n /**\n * Track entity access - called when user navigates to an entity\n */\n trackEntityAccess(entityName: string, entityId: string): void {\n const recentEntityAccesses = [...this.state$.value.recentEntityAccesses];\n\n // Find existing entry\n const existingIndex = recentEntityAccesses.findIndex(r => r.entityId === entityId);\n\n if (existingIndex >= 0) {\n // Update existing entry\n recentEntityAccesses[existingIndex] = {\n ...recentEntityAccesses[existingIndex],\n lastAccessed: new Date(),\n accessCount: recentEntityAccesses[existingIndex].accessCount + 1\n };\n // Move to front\n const [item] = recentEntityAccesses.splice(existingIndex, 1);\n recentEntityAccesses.unshift(item);\n } else {\n // Add new entry at front\n recentEntityAccesses.unshift({\n entityName,\n entityId,\n lastAccessed: new Date(),\n accessCount: 1\n });\n }\n\n // Trim to max size\n if (recentEntityAccesses.length > MAX_RECENT_ENTITIES) {\n recentEntityAccesses.length = MAX_RECENT_ENTITIES;\n }\n\n this.updateState({ recentEntityAccesses });\n }\n\n /**\n * Add entity to favorites using User Favorites entity\n */\n async addEntityToFavorites(entityName: string, entityId: string): Promise<boolean> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return false;\n\n // Check if already favorited\n const favorites = this.state$.value.favoriteEntities;\n if (favorites.some(f => f.entityId === entityId)) {\n return true; // Already favorited\n }\n\n // Get the Entities entity ID for favoriting\n const entitiesEntity = this.metadata.Entities.find(e => e.Name === 'MJ: Entities');\n if (!entitiesEntity) return false;\n\n // Create User Favorite record\n const md = new Metadata();\n const favorite = await md.GetEntityObject<MJUserFavoriteEntity>('MJ: User Favorites');\n favorite.UserID = userId;\n favorite.EntityID = entitiesEntity.ID;\n favorite.RecordID = entityId;\n\n const saved = await favorite.Save();\n if (saved) {\n // Update local state\n const favoriteEntities = [...favorites, {\n userFavoriteId: favorite.ID,\n entityName,\n entityId\n }];\n this.updateState({ favoriteEntities });\n }\n return saved;\n } catch (error) {\n console.warn('Failed to add entity to favorites:', error);\n return false;\n }\n }\n\n /**\n * Remove entity from favorites\n */\n async removeEntityFromFavorites(entityId: string): Promise<boolean> {\n try {\n const favorites = this.state$.value.favoriteEntities;\n const favorite = favorites.find(f => f.entityId === entityId);\n if (!favorite) return true; // Already not favorited\n\n // Delete User Favorite record\n const md = new Metadata();\n const favoriteEntity = await md.GetEntityObject<MJUserFavoriteEntity>('MJ: User Favorites');\n await favoriteEntity.Load(favorite.userFavoriteId);\n const deleted = await favoriteEntity.Delete();\n\n if (deleted) {\n // Update local state\n const favoriteEntities = favorites.filter(f => f.entityId !== entityId);\n this.updateState({ favoriteEntities });\n }\n return deleted;\n } catch (error) {\n console.warn('Failed to remove entity from favorites:', error);\n return false;\n }\n }\n\n /**\n * Check if an entity is favorited\n */\n isEntityFavorited(entityId: string): boolean {\n return this.state$.value.favoriteEntities.some(f => f.entityId === entityId);\n }\n\n /**\n * Load application entities with DefaultForNewUser information\n */\n private async loadApplicationEntities(): Promise<void> {\n try {\n if (!this.currentFilter?.applicationId) {\n this.applicationEntities = [];\n this.defaultEntityIds.clear();\n return;\n }\n\n const rv = new RunView();\n const result = await rv.RunView<MJApplicationEntityEntity>({\n EntityName: 'MJ: Application Entities',\n ExtraFilter: `ApplicationID = '${this.currentFilter.applicationId}'`,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.applicationEntities = result.Results;\n this.defaultEntityIds.clear();\n for (const appEntity of result.Results) {\n if (appEntity.DefaultForNewUser) {\n this.defaultEntityIds.add(appEntity.EntityID);\n }\n }\n }\n } catch (error) {\n console.warn('Failed to load application entities:', error);\n }\n }\n\n /**\n * Load favorite entities from User Favorites using UserInfoEngine\n */\n private async loadFavoriteEntities(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Get the Entities entity to filter favorites\n const entitiesEntity = this.metadata.Entities.find(e => e.Name === 'MJ: Entities');\n if (!entitiesEntity) return;\n\n // Use UserInfoEngine for cached access to user favorites\n const engine = UserInfoEngine.Instance;\n\n // Filter to only entity favorites (where EntityID is the Entities entity)\n const entityFavorites = engine.UserFavorites.filter(f => f.EntityID === entitiesEntity.ID);\n\n const favoriteEntities: FavoriteEntity[] = [];\n for (const fav of entityFavorites) {\n // Look up entity name from RecordID (which is the Entity.ID)\n const entity = this.metadata.Entities.find(e => e.ID === fav.RecordID);\n if (entity) {\n favoriteEntities.push({\n userFavoriteId: fav.ID,\n entityName: entity.Name,\n entityId: fav.RecordID\n });\n }\n }\n this.updateState({ favoriteEntities });\n } catch (error) {\n console.warn('Failed to load favorite entities:', error);\n }\n }\n\n /**\n * Load recent records from User Record Logs with batch record name lookup using UserInfoEngine\n */\n private async loadRecentRecords(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Use UserInfoEngine for cached access to user record logs\n const engine = UserInfoEngine.Instance;\n\n // Get recent records, limited to MAX_RECENT_RECORDS\n const userRecordLogs = engine.UserRecordLogs.slice(0, MAX_RECENT_RECORDS);\n\n const recentRecords: RecentRecordAccess[] = [];\n const recordNameInputs: EntityRecordNameInput[] = [];\n const recordIndexMap: Map<string, number> = new Map(); // Map composite key to array index\n\n for (const log of userRecordLogs) {\n // Look up entity name from EntityID\n const entity = this.metadata.Entities.find(e => e.ID === log.EntityID);\n if (entity) {\n // Filter by application context if applicable\n if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => ae.EntityID === log.EntityID)) {\n continue; // Skip records from entities not in this application\n }\n\n const recordAccess: RecentRecordAccess = {\n entityName: entity.Name,\n entityId: log.EntityID,\n recordId: log.RecordID,\n latestAt: log.LatestAt,\n totalCount: log.TotalCount\n };\n const index = recentRecords.length;\n recentRecords.push(recordAccess);\n\n // Build composite key for batch name lookup\n const compositeKey = this.buildCompositeKeyForRecord(entity.Name, log.RecordID);\n if (compositeKey) {\n recordNameInputs.push({ EntityName: entity.Name, CompositeKey: compositeKey });\n // Use the canonical concatenated string as the map key for consistent matching\n recordIndexMap.set(`${entity.Name}||${compositeKey.ToConcatenatedString()}`, index);\n }\n }\n }\n\n // Batch fetch record names\n if (recordNameInputs.length > 0) {\n try {\n const nameResults = await this.metadata.GetEntityRecordNames(recordNameInputs);\n for (const nameResult of nameResults) {\n if (nameResult.Success && nameResult.RecordName) {\n const key = `${nameResult.EntityName}||${nameResult.CompositeKey.ToConcatenatedString()}`;\n const index = recordIndexMap.get(key);\n if (index !== undefined) {\n recentRecords[index].recordName = nameResult.RecordName;\n }\n }\n }\n } catch (nameError) {\n console.warn('Failed to load record names:', nameError);\n // Continue without names - they'll show record IDs\n }\n }\n\n this.recentRecords$.next(recentRecords);\n } catch (error) {\n console.warn('Failed to load recent records:', error);\n }\n }\n\n /**\n * Build a CompositeKey for a record. RecordID may be stored as either:\n * - Concatenated format: \"FieldName|Value\" or \"Field1|Val1||Field2|Val2\"\n * - Plain value: just the raw value (e.g. a GUID)\n * Detects the format and constructs the key accordingly.\n */\n private buildCompositeKeyForRecord(entityName: string, recordId: string): CompositeKey | null {\n if (!recordId) return null;\n\n // If recordId contains '|', it's in concatenated format\n if (recordId.includes('|')) {\n try {\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromConcatenatedString(recordId);\n if (compositeKey.KeyValuePairs.length > 0) return compositeKey;\n } catch {\n // Fall through to entity-based lookup\n }\n }\n\n // Plain value — look up entity primary key field(s) to construct the key\n const entityInfo = this.metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) return null;\n\n const pkField = entityInfo.FirstPrimaryKey;\n if (!pkField) return null;\n\n const compositeKey = new CompositeKey();\n compositeKey.KeyValuePairs = [{ FieldName: pkField.Name, Value: recordId }];\n return compositeKey;\n }\n\n /**\n * Refresh recent records (call after navigating to a record)\n */\n async refreshRecentRecords(): Promise<void> {\n await this.loadRecentRecords();\n }\n\n /**\n * Add or update a recent record locally (without DB refresh).\n * Call this when a record is selected to provide instant UI feedback.\n * The DB write happens separately via RecentAccessService.logAccess().\n *\n * @param entityName The entity name\n * @param entityId The entity ID\n * @param recordId The record ID (primary key value)\n * @param recordName Optional display name for the record\n */\n addLocalRecentRecord(entityName: string, entityId: string, recordId: string, recordName?: string): void {\n // Filter by application context if applicable\n if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => ae.EntityID === entityId)) {\n return; // Don't add records from entities not in this application\n }\n\n const currentRecords = [...this.recentRecords$.value];\n\n // Find existing entry\n const existingIndex = currentRecords.findIndex(\n r => r.entityId === entityId && r.recordId === recordId\n );\n\n const newRecord: RecentRecordAccess = {\n entityName,\n entityId,\n recordId,\n recordName,\n latestAt: new Date(),\n totalCount: existingIndex >= 0 ? currentRecords[existingIndex].totalCount + 1 : 1\n };\n\n if (existingIndex >= 0) {\n // Remove existing entry (will be re-added at front)\n currentRecords.splice(existingIndex, 1);\n }\n\n // Add to front\n currentRecords.unshift(newRecord);\n\n // Trim to max size\n if (currentRecords.length > MAX_RECENT_RECORDS) {\n currentRecords.length = MAX_RECENT_RECORDS;\n }\n\n this.recentRecords$.next(currentRecords);\n }\n\n /**\n * Load favorite records from User Favorites (non-entity favorites) with batch record name lookup using UserInfoEngine.\n * Filters to only include records from entities in the current application context.\n */\n private async loadFavoriteRecords(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Get the Entities entity to exclude entity favorites\n const entitiesEntity = this.metadata.Entities.find(e => e.Name === 'MJ: Entities');\n const entitiesEntityId = entitiesEntity?.ID || '';\n\n // Use UserInfoEngine for cached access to user favorites\n const engine = UserInfoEngine.Instance;\n\n // Filter to non-entity favorites (exclude favorites where EntityID is the Entities entity)\n const nonEntityFavorites = engine.UserFavorites.filter(f => f.EntityID !== entitiesEntityId);\n\n const favoriteRecords: FavoriteRecord[] = [];\n const recordNameInputs: EntityRecordNameInput[] = [];\n const recordIndexMap: Map<string, number> = new Map();\n\n for (const fav of nonEntityFavorites) {\n // Look up entity info from the EntityID\n const entity = this.metadata.Entities.find(e => e.ID === fav.EntityID);\n if (entity) {\n // Filter by application context if applicable\n if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => ae.EntityID === fav.EntityID)) {\n continue; // Skip records from entities not in this application\n }\n\n const favoriteRecord: FavoriteRecord = {\n userFavoriteId: fav.ID,\n entityName: entity.Name,\n entityId: fav.EntityID,\n recordId: fav.RecordID\n };\n const index = favoriteRecords.length;\n favoriteRecords.push(favoriteRecord);\n\n // Build composite key for batch name lookup\n const compositeKey = this.buildCompositeKeyForRecord(entity.Name, fav.RecordID);\n if (compositeKey) {\n recordNameInputs.push({ EntityName: entity.Name, CompositeKey: compositeKey });\n // Use the canonical concatenated string as the map key for consistent matching\n recordIndexMap.set(`${entity.Name}||${compositeKey.ToConcatenatedString()}`, index);\n }\n }\n }\n\n // Batch fetch record names\n if (recordNameInputs.length > 0) {\n try {\n const nameResults = await this.metadata.GetEntityRecordNames(recordNameInputs);\n for (const nameResult of nameResults) {\n if (nameResult.Success && nameResult.RecordName) {\n const key = `${nameResult.EntityName}||${nameResult.CompositeKey.ToConcatenatedString()}`;\n const index = recordIndexMap.get(key);\n if (index !== undefined) {\n favoriteRecords[index].recordName = nameResult.RecordName;\n }\n }\n }\n } catch (nameError) {\n console.warn('Failed to load record names for favorites:', nameError);\n // Continue without names - they'll show record IDs\n }\n }\n\n this.favoriteRecords$.next(favoriteRecords);\n this.updateState({ favoriteRecords });\n } catch (error) {\n console.warn('Failed to load favorite records:', error);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"explorer-state.service.js","sourceRoot":"","sources":["../../../src/DataExplorer/services/explorer-state.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { Metadata, RunView, CompositeKey, EntityRecordNameInput } from '@memberjunction/core';\nimport { MJUserSettingEntity, MJUserFavoriteEntity, MJApplicationEntityEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { DataExplorerState, DEFAULT_EXPLORER_STATE, RecentItem, FavoriteItem, EntityCacheEntry, BreadcrumbItem, DataExplorerFilter, FavoriteEntity, RecentRecordAccess, FavoriteRecord, DataExplorerViewMode } from '../models/explorer-state.interface';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nconst BASE_SETTING_KEY = 'DataExplorer.State';\nconst MAX_RECENT_ITEMS = 20;\nconst MAX_RECENT_ENTITIES = 10;\nconst MAX_RECENT_RECORDS = 10;\nconst MAX_ENTITY_CACHE_SIZE = 50; // LRU cache limit\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ExplorerStateService {\n private state$ = new BehaviorSubject<DataExplorerState>(DEFAULT_EXPLORER_STATE);\n private metadata = new Metadata();\n private saveTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Current context filter (determines which settings key to use) */\n private currentFilter: DataExplorerFilter | null = null;\n\n /** Computed breadcrumbs based on current state */\n private breadcrumbs$ = new BehaviorSubject<BreadcrumbItem[]>([]);\n\n /** Recent records loaded from User Record Logs */\n private recentRecords$ = new BehaviorSubject<RecentRecordAccess[]>([]);\n\n /** Favorite records loaded from User Favorites (non-entity favorites) */\n private favoriteRecords$ = new BehaviorSubject<FavoriteRecord[]>([]);\n\n /** Application entities with DefaultForNewUser info (loaded once per context) */\n private applicationEntities: MJApplicationEntityEntity[] = [];\n\n /** Set of entity IDs that have DefaultForNewUser=true */\n private defaultEntityIds = new Set<string>();\n\n constructor() {\n // Don't load state in constructor - wait for setContext to be called\n }\n\n /**\n * Set the context filter and load context-specific state.\n * Call this before using the service to ensure proper context isolation.\n */\n async setContext(filter: DataExplorerFilter | null): Promise<void> {\n this.currentFilter = filter;\n await this.loadState();\n // Load application entities first (needed for filtering recent/favorite records)\n await this.loadApplicationEntities();\n // Then load the rest in parallel\n await Promise.all([\n this.loadFavoriteEntities(),\n this.loadFavoriteRecords(),\n this.loadRecentRecords()\n ]);\n this.updateBreadcrumbs();\n }\n\n /**\n * Get the storage key based on current context.\n * Uses application ID if available for context-specific storage.\n */\n private getSettingKey(): string {\n if (this.currentFilter?.applicationId) {\n return `${BASE_SETTING_KEY}.${this.currentFilter.applicationId}`;\n }\n return BASE_SETTING_KEY;\n }\n\n /**\n * Get observable of current state\n */\n get State(): Observable<DataExplorerState> {\n return this.state$.asObservable();\n }\n\n /**\n * Get current state value\n */\n get CurrentState(): DataExplorerState {\n return this.state$.value;\n }\n\n /**\n * Observable of current breadcrumbs\n */\n get Breadcrumbs(): Observable<BreadcrumbItem[]> {\n return this.breadcrumbs$.asObservable();\n }\n\n /**\n * Get current breadcrumbs value\n */\n get CurrentBreadcrumbs(): BreadcrumbItem[] {\n return this.breadcrumbs$.value;\n }\n\n /**\n * Get the current context filter\n */\n get CurrentFilter(): DataExplorerFilter | null {\n return this.currentFilter;\n }\n\n /**\n * Observable of recent records (from User Record Logs)\n */\n get RecentRecords(): Observable<RecentRecordAccess[]> {\n return this.recentRecords$.asObservable();\n }\n\n /**\n * Get current recent records value\n */\n get CurrentRecentRecords(): RecentRecordAccess[] {\n return this.recentRecords$.value;\n }\n\n /**\n * Observable of favorite records (from User Favorites, non-entity)\n */\n get FavoriteRecords(): Observable<FavoriteRecord[]> {\n return this.favoriteRecords$.asObservable();\n }\n\n /**\n * Get current favorite records value\n */\n get CurrentFavoriteRecords(): FavoriteRecord[] {\n return this.favoriteRecords$.value;\n }\n\n /**\n * Get the set of entity IDs with DefaultForNewUser=true\n */\n get DefaultEntityIds(): Set<string> {\n return this.defaultEntityIds;\n }\n\n /**\n * Update state partially\n */\n updateState(partial: Partial<DataExplorerState>): void {\n const newState = { ...this.state$.value, ...partial };\n this.state$.next(newState);\n this.updateBreadcrumbs();\n this.debouncedSave();\n }\n\n /**\n * Set selected entity\n * Caches current entity's filter before switching, restores new entity's cached filter\n */\n selectEntity(entityName: string | null): void {\n const currentState = this.state$.value;\n const entityCache = { ...currentState.entityCache };\n\n // Cache current entity's filter before switching (if we have a current entity)\n if (currentState.selectedEntityName && currentState.smartFilterPrompt) {\n entityCache[currentState.selectedEntityName] = {\n filterText: currentState.smartFilterPrompt,\n lastAccessed: Date.now()\n };\n }\n\n // Restore filter for new entity (if cached) or clear it\n let restoredFilter = '';\n if (entityName && entityCache[entityName]) {\n restoredFilter = entityCache[entityName].filterText;\n entityCache[entityName].lastAccessed = Date.now();\n }\n\n // Evict old entries if cache is too large (LRU)\n this.evictOldCacheEntries(entityCache);\n\n this.updateState({\n selectedEntityName: entityName,\n selectedViewId: null, // Reset view when entity changes\n smartFilterPrompt: restoredFilter, // Restore cached filter or empty\n selectedRecordId: null,\n detailPanelOpen: false,\n entityCache\n });\n }\n\n /**\n * Evict oldest cache entries if over limit (LRU eviction)\n */\n private evictOldCacheEntries(cache: Record<string, EntityCacheEntry>): void {\n const entries = Object.entries(cache);\n if (entries.length <= MAX_ENTITY_CACHE_SIZE) return;\n\n // Sort by lastAccessed (oldest first) and remove excess\n entries.sort((a, b) => a[1].lastAccessed - b[1].lastAccessed);\n const toRemove = entries.length - MAX_ENTITY_CACHE_SIZE;\n for (let i = 0; i < toRemove; i++) {\n delete cache[entries[i][0]];\n }\n }\n\n /**\n * Set selected view\n */\n selectView(viewId: string | null): void {\n this.updateState({\n selectedViewId: viewId,\n viewModified: false // Reset modified state when selecting a different view\n });\n }\n\n /**\n * Mark the current view as modified (has unsaved changes)\n */\n setViewModified(modified: boolean): void {\n this.updateState({ viewModified: modified });\n }\n\n /**\n * Toggle the view configuration panel\n */\n toggleViewConfigPanel(): void {\n this.updateState({ viewConfigPanelOpen: !this.state$.value.viewConfigPanelOpen });\n }\n\n /**\n * Open the view configuration panel\n */\n openViewConfigPanel(): void {\n this.updateState({ viewConfigPanelOpen: true });\n }\n\n /**\n * Close the view configuration panel\n */\n closeViewConfigPanel(): void {\n this.updateState({ viewConfigPanelOpen: false });\n }\n\n /**\n * Set view mode\n */\n setViewMode(mode: DataExplorerViewMode): void {\n this.updateState({ viewMode: mode });\n }\n\n /**\n * Set smart filter prompt\n * Also updates the entity cache for the current entity\n */\n setSmartFilterPrompt(prompt: string): void {\n const currentState = this.state$.value;\n const entityCache = { ...currentState.entityCache };\n\n // Update cache for current entity\n if (currentState.selectedEntityName) {\n if (prompt) {\n entityCache[currentState.selectedEntityName] = {\n filterText: prompt,\n lastAccessed: Date.now()\n };\n } else {\n // Clear cache entry if filter is empty\n delete entityCache[currentState.selectedEntityName];\n }\n }\n\n this.updateState({ smartFilterPrompt: prompt, entityCache });\n }\n\n /**\n * Select a record and open detail panel\n * @param recordId The composite key string for the record\n * @param recordName Optional display name for the record (for breadcrumbs)\n */\n selectRecord(recordId: string | null, recordName?: string): void {\n this.updateState({\n selectedRecordId: recordId,\n selectedRecordName: recordName || null,\n detailPanelOpen: recordId !== null\n });\n }\n\n /**\n * Close detail panel\n */\n closeDetailPanel(): void {\n this.updateState({\n detailPanelOpen: false,\n selectedRecordId: null,\n selectedRecordName: null\n });\n }\n\n /**\n * Toggle navigation panel collapsed state\n */\n toggleNavigationPanel(): void {\n this.updateState({\n navigationPanelCollapsed: !this.state$.value.navigationPanelCollapsed\n });\n }\n\n /**\n * Expand navigation panel and ensure a specific section is expanded\n */\n expandAndFocusSection(section: 'favorites' | 'recent' | 'entities'): void {\n const updates: Partial<DataExplorerState> = {\n navigationPanelCollapsed: false\n };\n\n // Ensure the target section is expanded\n switch (section) {\n case 'favorites':\n updates.favoritesSectionExpanded = true;\n break;\n case 'recent':\n updates.recentSectionExpanded = true;\n break;\n case 'entities':\n updates.entitiesSectionExpanded = true;\n break;\n }\n\n this.updateState(updates);\n }\n\n /**\n * Add item to recent history\n */\n addRecentItem(item: Omit<RecentItem, 'timestamp'>): void {\n const recentItems = [...this.state$.value.recentItems];\n\n // Remove existing entry if present (match by entity and composite key)\n const existingIndex = recentItems.findIndex(\n r => r.entityName === item.entityName && r.compositeKeyString === item.compositeKeyString\n );\n if (existingIndex >= 0) {\n recentItems.splice(existingIndex, 1);\n }\n\n // Add to front with timestamp\n recentItems.unshift({\n ...item,\n timestamp: new Date()\n });\n\n // Trim to max size\n if (recentItems.length > MAX_RECENT_ITEMS) {\n recentItems.length = MAX_RECENT_ITEMS;\n }\n\n this.updateState({ recentItems });\n }\n\n /**\n * Add item to favorites\n */\n addFavorite(item: FavoriteItem): void {\n const favorites = [...this.state$.value.favorites];\n\n // Check if already exists\n const exists = favorites.some(f =>\n f.type === item.type &&\n f.entityName === item.entityName &&\n f.compositeKeyString === item.compositeKeyString &&\n f.viewId === item.viewId\n );\n\n if (!exists) {\n favorites.push(item);\n this.updateState({ favorites });\n }\n }\n\n /**\n * Remove item from favorites\n */\n removeFavorite(item: FavoriteItem): void {\n const favorites = this.state$.value.favorites.filter(f =>\n !(f.type === item.type &&\n f.entityName === item.entityName &&\n f.compositeKeyString === item.compositeKeyString &&\n f.viewId === item.viewId)\n );\n this.updateState({ favorites });\n }\n\n /**\n * Toggle section expanded state\n */\n toggleSection(section: 'favorites' | 'recent' | 'entities' | 'views'): void {\n const key = `${section}SectionExpanded` as keyof DataExplorerState;\n this.updateState({ [key]: !this.state$.value[key] } as Partial<DataExplorerState>);\n }\n\n /**\n * Load state from UserSetting using UserInfoEngine for cached access\n */\n private async loadState(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n const settingKey = this.getSettingKey();\n const engine = UserInfoEngine.Instance;\n\n // Find the setting from cached user settings\n const setting = engine.UserSettings.find(s => s.Setting === settingKey);\n\n if (setting?.Value) {\n const savedState = JSON.parse(setting.Value) as Partial<DataExplorerState>;\n // Merge with defaults to handle new properties\n this.state$.next({ ...DEFAULT_EXPLORER_STATE, ...savedState });\n } else {\n // No saved state, use defaults\n this.state$.next({ ...DEFAULT_EXPLORER_STATE });\n }\n } catch (error) {\n console.warn('Failed to load Data Explorer state:', error);\n this.state$.next({ ...DEFAULT_EXPLORER_STATE });\n }\n }\n\n /**\n * Update breadcrumbs based on current state and filter\n */\n private updateBreadcrumbs(): void {\n const breadcrumbs: BreadcrumbItem[] = [];\n const state = this.state$.value;\n\n // Always add a root/home breadcrumb - use application name if available, otherwise \"All\"\n const rootLabel = this.currentFilter?.applicationName || 'All';\n breadcrumbs.push({\n label: rootLabel,\n type: 'application',\n icon: 'fa-solid fa-th-large'\n });\n\n // Add entity breadcrumb if selected\n if (state.selectedEntityName) {\n const entityInfo = this.metadata.Entities.find(e => e.Name === state.selectedEntityName);\n breadcrumbs.push({\n label: state.selectedEntityName,\n type: 'entity',\n entityName: state.selectedEntityName,\n icon: entityInfo?.Icon ? this.formatEntityIcon(entityInfo.Icon) : 'fa-solid fa-table'\n });\n }\n\n // Add record breadcrumb if selected\n if (state.selectedRecordId && state.selectedRecordName) {\n breadcrumbs.push({\n label: state.selectedRecordName,\n type: 'record',\n entityName: state.selectedEntityName || undefined,\n compositeKeyString: state.selectedRecordId,\n icon: 'fa-solid fa-file-alt'\n });\n }\n\n this.breadcrumbs$.next(breadcrumbs);\n }\n\n /**\n * Format entity icon to ensure proper Font Awesome class format\n */\n private formatEntityIcon(icon: string): string {\n if (!icon) return 'fa-solid fa-table';\n if (icon.startsWith('fa-') || icon.startsWith('fa ')) {\n if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||\n icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||\n icon.startsWith('fa ')) {\n return icon;\n }\n return `fa-solid ${icon}`;\n }\n return `fa-solid fa-${icon}`;\n }\n\n /**\n * Debounced save to avoid too many writes\n */\n private debouncedSave(): void {\n if (this.saveTimeout) {\n clearTimeout(this.saveTimeout);\n }\n this.saveTimeout = setTimeout(() => {\n this.saveState();\n }, 1000);\n }\n\n /**\n * Save state to UserSetting using UserInfoEngine for cached lookup\n */\n private async saveState(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n const settingKey = this.getSettingKey();\n const md = new Metadata();\n const engine = UserInfoEngine.Instance;\n\n // Find existing setting from cached user settings\n let setting = engine.UserSettings.find(s => s.Setting === settingKey);\n\n if (!setting) {\n // Create new setting if not found\n setting = await md.GetEntityObject<MJUserSettingEntity>('MJ: User Settings');\n setting.UserID = userId;\n setting.Setting = settingKey;\n }\n\n setting.Value = JSON.stringify(this.state$.value);\n await setting.Save();\n } catch (error) {\n console.warn('Failed to save Data Explorer state:', error);\n }\n }\n\n /**\n * Navigate to a specific breadcrumb level.\n * Clears any selection deeper than the clicked breadcrumb.\n */\n navigateToBreadcrumb(breadcrumb: BreadcrumbItem): void {\n switch (breadcrumb.type) {\n case 'application':\n // Clear entity and record selection (show home view)\n this.updateState({\n selectedEntityName: null,\n selectedViewId: null,\n selectedRecordId: null,\n selectedRecordName: null,\n smartFilterPrompt: '',\n detailPanelOpen: false\n });\n break;\n\n case 'entity':\n // Keep entity selected, clear record selection\n if (breadcrumb.entityName) {\n this.updateState({\n selectedRecordId: null,\n selectedRecordName: null,\n detailPanelOpen: false\n });\n }\n break;\n\n case 'record':\n // Already at record level, do nothing\n break;\n }\n }\n\n // ========================================\n // HOME SCREEN ENTITY MANAGEMENT\n // ========================================\n\n /**\n * Toggle between showing all entities or just common (DefaultForNewUser) entities\n */\n toggleShowAllEntities(): void {\n this.updateState({ showAllEntities: !this.state$.value.showAllEntities });\n }\n\n // ========================================\n // Concept D: Application Groups + Quick Access\n // ========================================\n\n /**\n * Toggle the quick access (right) panel open/closed\n */\n toggleQuickAccessPanel(): void {\n this.updateState({ quickAccessPanelOpen: !this.state$.value.quickAccessPanelOpen });\n }\n\n /**\n * Toggle a quick access section's expanded state\n */\n toggleQuickAccessSection(sectionId: string): void {\n const sections = { ...this.state$.value.quickAccessSections };\n sections[sectionId] = sections[sectionId] === false; // default to expanded (true)\n this.updateState({ quickAccessSections: sections });\n }\n\n /**\n * Toggle an application group's expanded/collapsed state\n */\n toggleAppGroupExpanded(appId: string): void {\n const expanded = [...this.state$.value.expandedAppGroups];\n const index = expanded.indexOf(appId);\n if (index >= 0) {\n expanded.splice(index, 1);\n } else {\n expanded.push(appId);\n }\n this.updateState({ expandedAppGroups: expanded });\n }\n\n /**\n * Set the home view mode (all vs favorites)\n */\n setHomeViewMode(mode: 'all' | 'favorites'): void {\n this.updateState({ homeViewMode: mode });\n }\n\n /**\n * Track entity access - called when user navigates to an entity\n */\n trackEntityAccess(entityName: string, entityId: string): void {\n const recentEntityAccesses = [...this.state$.value.recentEntityAccesses];\n\n // Find existing entry\n const existingIndex = recentEntityAccesses.findIndex(r => r.entityId === entityId);\n\n if (existingIndex >= 0) {\n // Update existing entry\n recentEntityAccesses[existingIndex] = {\n ...recentEntityAccesses[existingIndex],\n lastAccessed: new Date(),\n accessCount: recentEntityAccesses[existingIndex].accessCount + 1\n };\n // Move to front\n const [item] = recentEntityAccesses.splice(existingIndex, 1);\n recentEntityAccesses.unshift(item);\n } else {\n // Add new entry at front\n recentEntityAccesses.unshift({\n entityName,\n entityId,\n lastAccessed: new Date(),\n accessCount: 1\n });\n }\n\n // Trim to max size\n if (recentEntityAccesses.length > MAX_RECENT_ENTITIES) {\n recentEntityAccesses.length = MAX_RECENT_ENTITIES;\n }\n\n this.updateState({ recentEntityAccesses });\n }\n\n /**\n * Add entity to favorites using User Favorites entity\n */\n async addEntityToFavorites(entityName: string, entityId: string): Promise<boolean> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return false;\n\n // Check if already favorited\n const favorites = this.state$.value.favoriteEntities;\n if (favorites.some(f => f.entityId === entityId)) {\n return true; // Already favorited\n }\n\n // Get the Entities entity ID for favoriting\n const entitiesEntity = this.metadata.Entities.find(e => e.Name === 'MJ: Entities');\n if (!entitiesEntity) return false;\n\n // Create User Favorite record\n const md = new Metadata();\n const favorite = await md.GetEntityObject<MJUserFavoriteEntity>('MJ: User Favorites');\n favorite.UserID = userId;\n favorite.EntityID = entitiesEntity.ID;\n favorite.RecordID = entityId;\n\n const saved = await favorite.Save();\n if (saved) {\n // Update local state\n const favoriteEntities = [...favorites, {\n userFavoriteId: favorite.ID,\n entityName,\n entityId\n }];\n this.updateState({ favoriteEntities });\n }\n return saved;\n } catch (error) {\n console.warn('Failed to add entity to favorites:', error);\n return false;\n }\n }\n\n /**\n * Remove entity from favorites\n */\n async removeEntityFromFavorites(entityId: string): Promise<boolean> {\n try {\n const favorites = this.state$.value.favoriteEntities;\n const favorite = favorites.find(f => f.entityId === entityId);\n if (!favorite) return true; // Already not favorited\n\n // Delete User Favorite record\n const md = new Metadata();\n const favoriteEntity = await md.GetEntityObject<MJUserFavoriteEntity>('MJ: User Favorites');\n await favoriteEntity.Load(favorite.userFavoriteId);\n const deleted = await favoriteEntity.Delete();\n\n if (deleted) {\n // Update local state\n const favoriteEntities = favorites.filter(f => f.entityId !== entityId);\n this.updateState({ favoriteEntities });\n }\n return deleted;\n } catch (error) {\n console.warn('Failed to remove entity from favorites:', error);\n return false;\n }\n }\n\n /**\n * Check if an entity is favorited\n */\n isEntityFavorited(entityId: string): boolean {\n return this.state$.value.favoriteEntities.some(f => f.entityId === entityId);\n }\n\n /**\n * Load application entities with DefaultForNewUser information\n */\n private async loadApplicationEntities(): Promise<void> {\n try {\n if (!this.currentFilter?.applicationId) {\n this.applicationEntities = [];\n this.defaultEntityIds.clear();\n return;\n }\n\n const rv = new RunView();\n const result = await rv.RunView<MJApplicationEntityEntity>({\n EntityName: 'MJ: Application Entities',\n ExtraFilter: `ApplicationID = '${this.currentFilter.applicationId}'`,\n ResultType: 'entity_object'\n });\n\n if (result.Success && result.Results) {\n this.applicationEntities = result.Results;\n this.defaultEntityIds.clear();\n for (const appEntity of result.Results) {\n if (appEntity.DefaultForNewUser) {\n this.defaultEntityIds.add(appEntity.EntityID);\n }\n }\n }\n } catch (error) {\n console.warn('Failed to load application entities:', error);\n }\n }\n\n /**\n * Load favorite entities from User Favorites using UserInfoEngine\n */\n private async loadFavoriteEntities(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Get the Entities entity to filter favorites\n const entitiesEntity = this.metadata.Entities.find(e => e.Name === 'MJ: Entities');\n if (!entitiesEntity) return;\n\n // Use UserInfoEngine for cached access to user favorites\n const engine = UserInfoEngine.Instance;\n\n // Filter to only entity favorites (where EntityID is the Entities entity)\n const entityFavorites = engine.UserFavorites.filter(f => UUIDsEqual(f.EntityID, entitiesEntity.ID));\n\n const favoriteEntities: FavoriteEntity[] = [];\n for (const fav of entityFavorites) {\n // Look up entity name from RecordID (which is the Entity.ID)\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, fav.RecordID));\n if (entity) {\n favoriteEntities.push({\n userFavoriteId: fav.ID,\n entityName: entity.Name,\n entityId: fav.RecordID\n });\n }\n }\n this.updateState({ favoriteEntities });\n } catch (error) {\n console.warn('Failed to load favorite entities:', error);\n }\n }\n\n /**\n * Load recent records from User Record Logs with batch record name lookup using UserInfoEngine\n */\n private async loadRecentRecords(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Use UserInfoEngine for cached access to user record logs\n const engine = UserInfoEngine.Instance;\n\n // Get recent records, limited to MAX_RECENT_RECORDS\n const userRecordLogs = engine.UserRecordLogs.slice(0, MAX_RECENT_RECORDS);\n\n const recentRecords: RecentRecordAccess[] = [];\n const recordNameInputs: EntityRecordNameInput[] = [];\n const recordIndexMap: Map<string, number> = new Map(); // Map composite key to array index\n\n for (const log of userRecordLogs) {\n // Look up entity name from EntityID\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, log.EntityID));\n if (entity) {\n // Filter by application context if applicable\n if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => UUIDsEqual(ae.EntityID, log.EntityID))) {\n continue; // Skip records from entities not in this application\n }\n\n const recordAccess: RecentRecordAccess = {\n entityName: entity.Name,\n entityId: log.EntityID,\n recordId: log.RecordID,\n latestAt: log.LatestAt,\n totalCount: log.TotalCount\n };\n const index = recentRecords.length;\n recentRecords.push(recordAccess);\n\n // Build composite key for batch name lookup\n const compositeKey = this.buildCompositeKeyForRecord(entity.Name, log.RecordID);\n if (compositeKey) {\n recordNameInputs.push({ EntityName: entity.Name, CompositeKey: compositeKey });\n // Use the canonical concatenated string as the map key for consistent matching\n recordIndexMap.set(`${entity.Name}||${compositeKey.ToConcatenatedString()}`, index);\n }\n }\n }\n\n // Batch fetch record names\n if (recordNameInputs.length > 0) {\n try {\n const nameResults = await this.metadata.GetEntityRecordNames(recordNameInputs);\n for (const nameResult of nameResults) {\n if (nameResult.Success && nameResult.RecordName) {\n const key = `${nameResult.EntityName}||${nameResult.CompositeKey.ToConcatenatedString()}`;\n const index = recordIndexMap.get(key);\n if (index !== undefined) {\n recentRecords[index].recordName = nameResult.RecordName;\n }\n }\n }\n } catch (nameError) {\n console.warn('Failed to load record names:', nameError);\n // Continue without names - they'll show record IDs\n }\n }\n\n this.recentRecords$.next(recentRecords);\n } catch (error) {\n console.warn('Failed to load recent records:', error);\n }\n }\n\n /**\n * Build a CompositeKey for a record. RecordID may be stored as either:\n * - Concatenated format: \"FieldName|Value\" or \"Field1|Val1||Field2|Val2\"\n * - Plain value: just the raw value (e.g. a GUID)\n * Detects the format and constructs the key accordingly.\n */\n private buildCompositeKeyForRecord(entityName: string, recordId: string): CompositeKey | null {\n if (!recordId) return null;\n\n // If recordId contains '|', it's in concatenated format\n if (recordId.includes('|')) {\n try {\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromConcatenatedString(recordId);\n if (compositeKey.KeyValuePairs.length > 0) return compositeKey;\n } catch {\n // Fall through to entity-based lookup\n }\n }\n\n // Plain value — look up entity primary key field(s) to construct the key\n const entityInfo = this.metadata.Entities.find(e => e.Name === entityName);\n if (!entityInfo) return null;\n\n const pkField = entityInfo.FirstPrimaryKey;\n if (!pkField) return null;\n\n const compositeKey = new CompositeKey();\n compositeKey.KeyValuePairs = [{ FieldName: pkField.Name, Value: recordId }];\n return compositeKey;\n }\n\n /**\n * Refresh recent records (call after navigating to a record)\n */\n async refreshRecentRecords(): Promise<void> {\n await this.loadRecentRecords();\n }\n\n /**\n * Add or update a recent record locally (without DB refresh).\n * Call this when a record is selected to provide instant UI feedback.\n * The DB write happens separately via RecentAccessService.logAccess().\n *\n * @param entityName The entity name\n * @param entityId The entity ID\n * @param recordId The record ID (primary key value)\n * @param recordName Optional display name for the record\n */\n addLocalRecentRecord(entityName: string, entityId: string, recordId: string, recordName?: string): void {\n // Filter by application context if applicable\n if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => UUIDsEqual(ae.EntityID, entityId))) {\n return; // Don't add records from entities not in this application\n }\n\n const currentRecords = [...this.recentRecords$.value];\n\n // Find existing entry\n const existingIndex = currentRecords.findIndex(\n r => r.entityId === entityId && r.recordId === recordId\n );\n\n const newRecord: RecentRecordAccess = {\n entityName,\n entityId,\n recordId,\n recordName,\n latestAt: new Date(),\n totalCount: existingIndex >= 0 ? currentRecords[existingIndex].totalCount + 1 : 1\n };\n\n if (existingIndex >= 0) {\n // Remove existing entry (will be re-added at front)\n currentRecords.splice(existingIndex, 1);\n }\n\n // Add to front\n currentRecords.unshift(newRecord);\n\n // Trim to max size\n if (currentRecords.length > MAX_RECENT_RECORDS) {\n currentRecords.length = MAX_RECENT_RECORDS;\n }\n\n this.recentRecords$.next(currentRecords);\n }\n\n /**\n * Load favorite records from User Favorites (non-entity favorites) with batch record name lookup using UserInfoEngine.\n * Filters to only include records from entities in the current application context.\n */\n private async loadFavoriteRecords(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Get the Entities entity to exclude entity favorites\n const entitiesEntity = this.metadata.Entities.find(e => e.Name === 'MJ: Entities');\n const entitiesEntityId = entitiesEntity?.ID || '';\n\n // Use UserInfoEngine for cached access to user favorites\n const engine = UserInfoEngine.Instance;\n\n // Filter to non-entity favorites (exclude favorites where EntityID is the Entities entity)\n const nonEntityFavorites = engine.UserFavorites.filter(f => !UUIDsEqual(f.EntityID, entitiesEntityId));\n\n const favoriteRecords: FavoriteRecord[] = [];\n const recordNameInputs: EntityRecordNameInput[] = [];\n const recordIndexMap: Map<string, number> = new Map();\n\n for (const fav of nonEntityFavorites) {\n // Look up entity info from the EntityID\n const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, fav.EntityID));\n if (entity) {\n // Filter by application context if applicable\n if (this.currentFilter?.applicationId && !this.applicationEntities.some(ae => UUIDsEqual(ae.EntityID, fav.EntityID))) {\n continue; // Skip records from entities not in this application\n }\n\n const favoriteRecord: FavoriteRecord = {\n userFavoriteId: fav.ID,\n entityName: entity.Name,\n entityId: fav.EntityID,\n recordId: fav.RecordID\n };\n const index = favoriteRecords.length;\n favoriteRecords.push(favoriteRecord);\n\n // Build composite key for batch name lookup\n const compositeKey = this.buildCompositeKeyForRecord(entity.Name, fav.RecordID);\n if (compositeKey) {\n recordNameInputs.push({ EntityName: entity.Name, CompositeKey: compositeKey });\n // Use the canonical concatenated string as the map key for consistent matching\n recordIndexMap.set(`${entity.Name}||${compositeKey.ToConcatenatedString()}`, index);\n }\n }\n }\n\n // Batch fetch record names\n if (recordNameInputs.length > 0) {\n try {\n const nameResults = await this.metadata.GetEntityRecordNames(recordNameInputs);\n for (const nameResult of nameResults) {\n if (nameResult.Success && nameResult.RecordName) {\n const key = `${nameResult.EntityName}||${nameResult.CompositeKey.ToConcatenatedString()}`;\n const index = recordIndexMap.get(key);\n if (index !== undefined) {\n favoriteRecords[index].recordName = nameResult.RecordName;\n }\n }\n }\n } catch (nameError) {\n console.warn('Failed to load record names for favorites:', nameError);\n // Continue without names - they'll show record IDs\n }\n }\n\n this.favoriteRecords$.next(favoriteRecords);\n this.updateState({ favoriteRecords });\n } catch (error) {\n console.warn('Failed to load favorite records:', error);\n }\n }\n}\n"]}
|
|
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { Component, ViewChild } from '@angular/core';
|
|
8
8
|
import { BaseDashboard } from '@memberjunction/ng-shared';
|
|
9
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
10
10
|
import { CompositeKey, Metadata } from '@memberjunction/core';
|
|
11
11
|
import { Subject } from 'rxjs';
|
|
12
12
|
import { debounceTime } from 'rxjs/operators';
|
|
@@ -90,7 +90,7 @@ let EntityAdminDashboardComponent = class EntityAdminDashboardComponent extends
|
|
|
90
90
|
this.filterPanelVisible = state.filterPanelVisible;
|
|
91
91
|
this.filteredEntities = this.erdComposite?.filteredEntities || [];
|
|
92
92
|
if (state.selectedEntityId && this.erdComposite) {
|
|
93
|
-
this.selectedEntity = this.erdComposite.entities.find(e => e.ID
|
|
93
|
+
this.selectedEntity = this.erdComposite.entities.find(e => UUIDsEqual(e.ID, state.selectedEntityId)) || null;
|
|
94
94
|
}
|
|
95
95
|
else {
|
|
96
96
|
this.selectedEntity = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-admin-dashboard.component.js","sourceRoot":"","sources":["../../src/EntityAdmin/entity-admin-dashboard.component.ts","../../src/EntityAdmin/entity-admin-dashboard.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass } from '@memberjunction/global';\nimport { EntityInfo, CompositeKey, Metadata } from '@memberjunction/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\n\nimport { ERDCompositeComponent, ERDCompositeState } from '@memberjunction/ng-entity-relationship-diagram';\nimport { ResourceData, MJUserSettingEntity, UserInfoEngine } from '@memberjunction/core-entities';\n\n/** Settings key for ERD state persistence */\nconst ERD_SETTINGS_KEY = 'MJ.Admin.Entity.ERD';\n\n@Component({\n standalone: false,\n selector: 'mj-entity-admin-dashboard',\n templateUrl: './entity-admin-dashboard.component.html',\n styleUrls: ['./entity-admin-dashboard.component.css']\n})\n@RegisterClass(BaseDashboard, 'EntityAdmin')\nexport class EntityAdminDashboardComponent extends BaseDashboard implements AfterViewInit, OnDestroy {\n @ViewChild('erdComposite', { static: false }) erdComposite!: ERDCompositeComponent;\n\n public isLoading = false;\n public isRefreshingERD = false;\n public loadingMessage = '';\n public error: string | null = null;\n\n // Filter panel visibility for header controls\n public filterPanelVisible = true;\n public selectedEntity: EntityInfo | null = null;\n public filteredEntities: EntityInfo[] = [];\n\n // State management\n private userStateChangeSubject = new Subject<ERDCompositeState>();\n private hasLoadedUserState = false;\n private metadata = new Metadata();\n private userSettingEntity: MJUserSettingEntity | null = null;\n\n ngAfterViewInit(): void {\n // Setup debounced state persistence to MJ: User Settings\n this.userStateChangeSubject.pipe(\n debounceTime(1000)\n ).subscribe(state => {\n this.saveStateToUserSettings(state);\n });\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Entity Administration\"\n }\n\n override ngOnDestroy(): void {\n this.userStateChangeSubject.complete();\n super.ngOnDestroy();\n }\n\n protected initDashboard(): void {\n // Initialize dashboard - called by BaseDashboard\n }\n\n protected loadData(): void {\n // Data loading is handled by ERDCompositeComponent\n }\n\n public toggleFilterPanel(): void {\n this.filterPanelVisible = !this.filterPanelVisible;\n if (this.erdComposite) {\n this.erdComposite.onToggleFilterPanel();\n }\n }\n\n public onStateChange(state: ERDCompositeState): void {\n // Update local state to keep header controls in sync\n this.filterPanelVisible = state.filterPanelVisible;\n this.filteredEntities = this.erdComposite?.filteredEntities || [];\n\n if (state.selectedEntityId && this.erdComposite) {\n this.selectedEntity = this.erdComposite.entities.find(e => e.ID === state.selectedEntityId) || null;\n } else {\n this.selectedEntity = null;\n }\n\n // Load user state when data becomes available for the first time\n if (this.erdComposite?.isDataLoaded && !this.hasLoadedUserState) {\n this.hasLoadedUserState = true;\n this.loadStateFromUserSettings();\n }\n }\n\n public onUserStateChange(state: ERDCompositeState): void {\n // Queue state for debounced persistence\n this.userStateChangeSubject.next(state);\n }\n\n public onEntityOpened(entity: EntityInfo): void {\n this.openEntity(entity);\n }\n\n public onOpenRecord(event: {EntityName: string, RecordID: string}): void {\n this.OpenEntityRecord.emit({\n EntityName: event.EntityName,\n RecordPKey: new CompositeKey([{FieldName: 'ID', Value: event.RecordID}])\n });\n }\n\n public openEntity(entity: EntityInfo): void {\n this.Interaction.emit({\n type: 'openEntity',\n entity: entity,\n data: { entityId: entity.ID, entityName: entity.Name }\n });\n }\n\n /**\n * Load ERD state from MJ: User Settings entity using UserInfoEngine for cached access\n */\n private async loadStateFromUserSettings(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) {\n this.NotifyLoadComplete();\n return;\n }\n\n const engine = UserInfoEngine.Instance;\n\n // Find setting from cached user settings\n const setting = engine.UserSettings.find(s => s.Setting === ERD_SETTINGS_KEY);\n\n if (setting) {\n this.userSettingEntity = setting;\n if (this.userSettingEntity.Value) {\n const savedState = JSON.parse(this.userSettingEntity.Value) as Partial<ERDCompositeState>;\n if (this.erdComposite) {\n this.erdComposite.loadUserState(savedState);\n }\n }\n }\n\n this.NotifyLoadComplete();\n } catch (error) {\n console.warn('Failed to load ERD state from User Settings:', error);\n this.NotifyLoadComplete();\n }\n }\n\n /**\n * Save ERD state to MJ: User Settings entity using UserInfoEngine for cached lookup\n */\n private async saveStateToUserSettings(state: ERDCompositeState): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Find existing setting from cached user settings if not already loaded\n if (!this.userSettingEntity) {\n const engine = UserInfoEngine.Instance;\n const setting = engine.UserSettings.find(s => s.Setting === ERD_SETTINGS_KEY);\n\n if (setting) {\n this.userSettingEntity = setting;\n } else {\n this.userSettingEntity = await this.metadata.GetEntityObject<MJUserSettingEntity>('MJ: User Settings');\n this.userSettingEntity.UserID = userId;\n this.userSettingEntity.Setting = ERD_SETTINGS_KEY;\n }\n }\n\n // Save the state as JSON\n this.userSettingEntity.Value = JSON.stringify(state);\n await this.userSettingEntity.Save();\n } catch (error) {\n console.warn('Failed to save ERD state to User Settings:', error);\n }\n }\n}\n","<div class=\"entity-admin-dashboard-container\">\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <span class=\"visible-entities-count\">{{ filteredEntities.length }} visible entities</span>\n </div>\n <div class=\"header-controls\">\n <button \n class=\"control-btn\" \n (click)=\"toggleFilterPanel()\" \n [class.active]=\"filterPanelVisible\"\n title=\"Toggle Filters\">\n <span class=\"fa-solid fa-filter\"></span>\n Filters\n </button>\n </div>\n </div>\n \n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"loadingMessage\" size=\"large\"></mj-loading>\n </div>\n }\n \n @if (error) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error }}</p>\n </div>\n }\n \n @if (!isLoading && !error) {\n <div class=\"dashboard-content\">\n <mj-erd-composite \n #erdComposite\n [isRefreshingERD]=\"isRefreshingERD\"\n (stateChange)=\"onStateChange($event)\"\n (userStateChange)=\"onUserStateChange($event)\"\n (entityOpened)=\"onEntityOpened($event)\"\n (openRecord)=\"onOpenRecord($event)\"\n >\n </mj-erd-composite>\n </div>\n }\n</div>"]}
|
|
1
|
+
{"version":3,"file":"entity-admin-dashboard.component.js","sourceRoot":"","sources":["../../src/EntityAdmin/entity-admin-dashboard.component.ts","../../src/EntityAdmin/entity-admin-dashboard.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { EntityInfo, CompositeKey, Metadata } from '@memberjunction/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\n\nimport { ERDCompositeComponent, ERDCompositeState } from '@memberjunction/ng-entity-relationship-diagram';\nimport { ResourceData, MJUserSettingEntity, UserInfoEngine } from '@memberjunction/core-entities';\n\n/** Settings key for ERD state persistence */\nconst ERD_SETTINGS_KEY = 'MJ.Admin.Entity.ERD';\n\n@Component({\n standalone: false,\n selector: 'mj-entity-admin-dashboard',\n templateUrl: './entity-admin-dashboard.component.html',\n styleUrls: ['./entity-admin-dashboard.component.css']\n})\n@RegisterClass(BaseDashboard, 'EntityAdmin')\nexport class EntityAdminDashboardComponent extends BaseDashboard implements AfterViewInit, OnDestroy {\n @ViewChild('erdComposite', { static: false }) erdComposite!: ERDCompositeComponent;\n\n public isLoading = false;\n public isRefreshingERD = false;\n public loadingMessage = '';\n public error: string | null = null;\n\n // Filter panel visibility for header controls\n public filterPanelVisible = true;\n public selectedEntity: EntityInfo | null = null;\n public filteredEntities: EntityInfo[] = [];\n\n // State management\n private userStateChangeSubject = new Subject<ERDCompositeState>();\n private hasLoadedUserState = false;\n private metadata = new Metadata();\n private userSettingEntity: MJUserSettingEntity | null = null;\n\n ngAfterViewInit(): void {\n // Setup debounced state persistence to MJ: User Settings\n this.userStateChangeSubject.pipe(\n debounceTime(1000)\n ).subscribe(state => {\n this.saveStateToUserSettings(state);\n });\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Entity Administration\"\n }\n\n override ngOnDestroy(): void {\n this.userStateChangeSubject.complete();\n super.ngOnDestroy();\n }\n\n protected initDashboard(): void {\n // Initialize dashboard - called by BaseDashboard\n }\n\n protected loadData(): void {\n // Data loading is handled by ERDCompositeComponent\n }\n\n public toggleFilterPanel(): void {\n this.filterPanelVisible = !this.filterPanelVisible;\n if (this.erdComposite) {\n this.erdComposite.onToggleFilterPanel();\n }\n }\n\n public onStateChange(state: ERDCompositeState): void {\n // Update local state to keep header controls in sync\n this.filterPanelVisible = state.filterPanelVisible;\n this.filteredEntities = this.erdComposite?.filteredEntities || [];\n\n if (state.selectedEntityId && this.erdComposite) {\n this.selectedEntity = this.erdComposite.entities.find(e => UUIDsEqual(e.ID, state.selectedEntityId)) || null;\n } else {\n this.selectedEntity = null;\n }\n\n // Load user state when data becomes available for the first time\n if (this.erdComposite?.isDataLoaded && !this.hasLoadedUserState) {\n this.hasLoadedUserState = true;\n this.loadStateFromUserSettings();\n }\n }\n\n public onUserStateChange(state: ERDCompositeState): void {\n // Queue state for debounced persistence\n this.userStateChangeSubject.next(state);\n }\n\n public onEntityOpened(entity: EntityInfo): void {\n this.openEntity(entity);\n }\n\n public onOpenRecord(event: {EntityName: string, RecordID: string}): void {\n this.OpenEntityRecord.emit({\n EntityName: event.EntityName,\n RecordPKey: new CompositeKey([{FieldName: 'ID', Value: event.RecordID}])\n });\n }\n\n public openEntity(entity: EntityInfo): void {\n this.Interaction.emit({\n type: 'openEntity',\n entity: entity,\n data: { entityId: entity.ID, entityName: entity.Name }\n });\n }\n\n /**\n * Load ERD state from MJ: User Settings entity using UserInfoEngine for cached access\n */\n private async loadStateFromUserSettings(): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) {\n this.NotifyLoadComplete();\n return;\n }\n\n const engine = UserInfoEngine.Instance;\n\n // Find setting from cached user settings\n const setting = engine.UserSettings.find(s => s.Setting === ERD_SETTINGS_KEY);\n\n if (setting) {\n this.userSettingEntity = setting;\n if (this.userSettingEntity.Value) {\n const savedState = JSON.parse(this.userSettingEntity.Value) as Partial<ERDCompositeState>;\n if (this.erdComposite) {\n this.erdComposite.loadUserState(savedState);\n }\n }\n }\n\n this.NotifyLoadComplete();\n } catch (error) {\n console.warn('Failed to load ERD state from User Settings:', error);\n this.NotifyLoadComplete();\n }\n }\n\n /**\n * Save ERD state to MJ: User Settings entity using UserInfoEngine for cached lookup\n */\n private async saveStateToUserSettings(state: ERDCompositeState): Promise<void> {\n try {\n const userId = this.metadata.CurrentUser?.ID;\n if (!userId) return;\n\n // Find existing setting from cached user settings if not already loaded\n if (!this.userSettingEntity) {\n const engine = UserInfoEngine.Instance;\n const setting = engine.UserSettings.find(s => s.Setting === ERD_SETTINGS_KEY);\n\n if (setting) {\n this.userSettingEntity = setting;\n } else {\n this.userSettingEntity = await this.metadata.GetEntityObject<MJUserSettingEntity>('MJ: User Settings');\n this.userSettingEntity.UserID = userId;\n this.userSettingEntity.Setting = ERD_SETTINGS_KEY;\n }\n }\n\n // Save the state as JSON\n this.userSettingEntity.Value = JSON.stringify(state);\n await this.userSettingEntity.Save();\n } catch (error) {\n console.warn('Failed to save ERD state to User Settings:', error);\n }\n }\n}\n","<div class=\"entity-admin-dashboard-container\">\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <span class=\"visible-entities-count\">{{ filteredEntities.length }} visible entities</span>\n </div>\n <div class=\"header-controls\">\n <button \n class=\"control-btn\" \n (click)=\"toggleFilterPanel()\" \n [class.active]=\"filterPanelVisible\"\n title=\"Toggle Filters\">\n <span class=\"fa-solid fa-filter\"></span>\n Filters\n </button>\n </div>\n </div>\n \n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"loadingMessage\" size=\"large\"></mj-loading>\n </div>\n }\n \n @if (error) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error }}</p>\n </div>\n }\n \n @if (!isLoading && !error) {\n <div class=\"dashboard-content\">\n <mj-erd-composite \n #erdComposite\n [isRefreshingERD]=\"isRefreshingERD\"\n (stateChange)=\"onStateChange($event)\"\n (userStateChange)=\"onUserStateChange($event)\"\n (entityOpened)=\"onEntityOpened($event)\"\n (openRecord)=\"onOpenRecord($event)\"\n >\n </mj-erd-composite>\n </div>\n }\n</div>"]}
|
|
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var HomeApplication_1;
|
|
8
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
9
9
|
import { BaseApplication } from '@memberjunction/ng-base-application';
|
|
10
10
|
import { Metadata, CompositeKey, FieldValueCollection } from '@memberjunction/core';
|
|
11
11
|
/** Storage key and category for persisting the recent orphan stack */
|
|
@@ -175,7 +175,7 @@ let HomeApplication = class HomeApplication extends BaseApplication {
|
|
|
175
175
|
return;
|
|
176
176
|
}
|
|
177
177
|
const activeTab = config.tabs.find(t => t.id === config.activeTabId);
|
|
178
|
-
if (!activeTab || activeTab.applicationId
|
|
178
|
+
if (!activeTab || !UUIDsEqual(activeTab.applicationId, this.ID)) {
|
|
179
179
|
return;
|
|
180
180
|
}
|
|
181
181
|
// Build a fingerprint from tab ID + record content. In single-resource mode,
|