@memberjunction/ng-explorer-core 5.37.0 → 5.39.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.
Files changed (31) hide show
  1. package/dist/generated/lazy-feature-config.d.ts +1 -1
  2. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  3. package/dist/generated/lazy-feature-config.js +4 -2
  4. package/dist/generated/lazy-feature-config.js.map +1 -1
  5. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +10 -0
  6. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
  7. package/dist/lib/resource-wrappers/artifact-resource.component.js +15 -5
  8. package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
  9. package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
  10. package/dist/lib/resource-wrappers/record-resource.component.js +22 -6
  11. package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
  12. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
  13. package/dist/lib/shell/components/header/app-nav.component.js +12 -0
  14. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  15. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +24 -5
  16. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  17. package/dist/lib/shell/components/tabs/component-cache-manager.js +58 -14
  18. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  19. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +42 -0
  20. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  21. package/dist/lib/shell/components/tabs/tab-container.component.js +195 -12
  22. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  23. package/dist/lib/shell/shell.component.d.ts +5 -4
  24. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  25. package/dist/lib/shell/shell.component.js +20 -9
  26. package/dist/lib/shell/shell.component.js.map +1 -1
  27. package/dist/lib/single-record/single-record.component.d.ts +31 -37
  28. package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
  29. package/dist/lib/single-record/single-record.component.js +64 -306
  30. package/dist/lib/single-record/single-record.component.js.map +1 -1
  31. package/package.json +46 -45
@@ -15,5 +15,5 @@
15
15
  * Covers all @RegisterClass decorated classes in lazy-loaded packages.
16
16
  */
17
17
  export declare const LAZY_FEATURE_CONFIG: Record<string, () => Promise<void>>;
18
- export declare const LAZY_FEATURE_CONFIG_COUNT = 98;
18
+ export declare const LAZY_FEATURE_CONFIG_COUNT = 100;
19
19
  //# sourceMappingURL=lazy-feature-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-feature-config.d.ts","sourceRoot":"","sources":["../../src/generated/lazy-feature-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuDH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAmInE,CAAC;AAEF,eAAO,MAAM,yBAAyB,KAAK,CAAC"}
1
+ {"version":3,"file":"lazy-feature-config.d.ts","sourceRoot":"","sources":["../../src/generated/lazy-feature-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuDH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAqInE,CAAC;AAEF,eAAO,MAAM,yBAAyB,MAAM,CAAC"}
@@ -20,7 +20,7 @@ const loadActionsDashboardsModule = featureLoader(() => import('@memberjunction/
20
20
  const loadAiDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/ai-dashboards.module'));
21
21
  // --- @memberjunction/ng-dashboards → ./communication-dashboards.module (7 entries) ---
22
22
  const loadCommunicationDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/communication-dashboards.module'));
23
- // --- @memberjunction/ng-dashboards → ./component-studio-dashboards.module (1 entries) ---
23
+ // --- @memberjunction/ng-dashboards → ./component-studio-dashboards.module (3 entries) ---
24
24
  const loadComponentStudioDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/component-studio-dashboards.module'));
25
25
  // --- @memberjunction/ng-dashboards → ./core-dashboards.module (26 entries) ---
26
26
  const loadCoreDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/core-dashboards.module'));
@@ -85,6 +85,8 @@ export const LAZY_FEATURE_CONFIG = {
85
85
  'BaseResourceComponent::CommunicationTemplatesResource': loadCommunicationDashboardsModule,
86
86
  // @memberjunction/ng-dashboards → ./component-studio-dashboards.module
87
87
  'BaseDashboard::ComponentStudioDashboard': loadComponentStudioDashboardsModule,
88
+ 'BaseResourceComponent::ComponentStudioResource': loadComponentStudioDashboardsModule,
89
+ 'BaseResourceComponent::FormBuilderResource': loadComponentStudioDashboardsModule,
88
90
  // @memberjunction/ng-dashboards → ./core-dashboards.module
89
91
  'BaseApplication::HomeApplication': loadCoreDashboardsModule,
90
92
  'BaseDashboard::EntityAdmin': loadCoreDashboardsModule,
@@ -166,5 +168,5 @@ export const LAZY_FEATURE_CONFIG = {
166
168
  // @memberjunction/ng-react → .
167
169
  'RuntimeUtilities::RuntimeUtilities': loadNgReact,
168
170
  };
169
- export const LAZY_FEATURE_CONFIG_COUNT = 98;
171
+ export const LAZY_FEATURE_CONFIG_COUNT = 100;
170
172
  //# sourceMappingURL=lazy-feature-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-feature-config.js","sourceRoot":"","sources":["../../src/generated/lazy-feature-config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AUTO-GENERATED FILE — DO NOT EDIT\n * Generated by: mj codegen manifest --lazy-config\n * Regenerate with: npm run mj:manifest:explorer\n *\n * Maps @RegisterClass entries to their lazy-loading chunks using compound keys.\n * Compound key format: \"BaseClassName::Key\" (e.g., \"BaseResourceComponent::HomeDashboard\").\n *\n * When ClassFactory.GetRegistrationAsync() or CreateInstanceAsync() cannot find a\n * registration synchronously, the registered lazy loader builds the compound key and\n * looks it up here to dynamically import the chunk containing the class.\n */\n\n/** Helper to create a loader that all entries in a feature share. */\nfunction featureLoader(importFn: () => Promise<unknown>): () => Promise<void> {\n return () => importFn().then(() => {});\n}\n\n// --- @memberjunction/ng-dashboards → ./actions-dashboards.module (7 entries) ---\nconst loadActionsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/actions-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./ai-dashboards.module (15 entries) ---\nconst loadAiDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/ai-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./communication-dashboards.module (7 entries) ---\nconst loadCommunicationDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/communication-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./component-studio-dashboards.module (1 entries) ---\nconst loadComponentStudioDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/component-studio-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./core-dashboards.module (26 entries) ---\nconst loadCoreDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/core-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./credentials-dashboards.module (6 entries) ---\nconst loadCredentialsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/credentials-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./data-explorer-dashboards.module (2 entries) ---\nconst loadDataExplorerDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/data-explorer-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./integration.module (6 entries) ---\nconst loadIntegrationModule = featureLoader(() => import('@memberjunction/ng-dashboards/integration.module'));\n\n// --- @memberjunction/ng-dashboards → ./lists-dashboards.module (5 entries) ---\nconst loadListsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/lists-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./mcp.module (2 entries) ---\nconst loadMcpModule = featureLoader(() => import('@memberjunction/ng-dashboards/mcp.module'));\n\n// --- @memberjunction/ng-dashboards → ./module (3 entries) ---\nconst loadModule = featureLoader(() => import('@memberjunction/ng-dashboards/module'));\n\n// --- @memberjunction/ng-dashboards → ./scheduling-dashboards.module (4 entries) ---\nconst loadSchedulingDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/scheduling-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./testing-dashboards.module (6 entries) ---\nconst loadTestingDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/testing-dashboards.module'));\n\n// --- @memberjunction/ng-explorer-settings → ./settings.module (6 entries) ---\nconst loadSettingsModule = featureLoader(() => import('@memberjunction/ng-explorer-settings/settings.module'));\n\n// --- @memberjunction/ng-file-storage → ./file-storage.module (1 entries) ---\nconst loadFileStorageModule = featureLoader(() => import('@memberjunction/ng-file-storage/file-storage.module'));\n\n// --- @memberjunction/ng-react → . (1 entries) ---\nconst loadNgReact = featureLoader(() => import('@memberjunction/ng-react'));\n\n/**\n * Complete mapping of compound keys (BaseClassName::Key) to lazy-loading functions.\n * Covers all @RegisterClass decorated classes in lazy-loaded packages.\n */\nexport const LAZY_FEATURE_CONFIG: Record<string, () => Promise<void>> = {\n // @memberjunction/ng-dashboards → ./actions-dashboards.module\n 'BaseResourceComponent::ActionExplorerResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsCodeResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsEntitiesResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsMonitorResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsOverviewResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsScheduleResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsSecurityResource': loadActionsDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./ai-dashboards.module\n 'BaseResourceComponent::AIAgentRequestsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIAgentsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIAnalyticsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIConfigResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIModelsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIMonitorResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIPromptsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AnalyticsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AutotaggingPipelineResource': loadAiDashboardsModule,\n 'BaseResourceComponent::ClusterVisualizationResource': loadAiDashboardsModule,\n 'BaseResourceComponent::DuplicateDetectionResource': loadAiDashboardsModule,\n 'BaseResourceComponent::KnowledgeConfigResource': loadAiDashboardsModule,\n 'BaseResourceComponent::SchedulingResource': loadAiDashboardsModule,\n 'BaseResourceComponent::Tags': loadAiDashboardsModule,\n 'BaseResourceComponent::VectorManagementResource': loadAiDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./communication-dashboards.module\n 'BaseDashboard::CommunicationDashboard': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationLogsResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationMonitorResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationProvidersResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationRunsResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationsNewMessageResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationTemplatesResource': loadCommunicationDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./component-studio-dashboards.module\n 'BaseDashboard::ComponentStudioDashboard': loadComponentStudioDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./core-dashboards.module\n 'BaseApplication::HomeApplication': loadCoreDashboardsModule,\n 'BaseDashboard::EntityAdmin': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminDataSchema': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminDeveloperTools': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminIdentityAccess': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminMonitoring': loadCoreDashboardsModule,\n 'BaseResourceComponent::APIKeysResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::ApplicationRolesResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::AppStateInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::ClassRegistryInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::DashboardBrowserResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::EventMonitorInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::GraphQLConsoleInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::HomeDashboard': loadCoreDashboardsModule,\n 'BaseResourceComponent::LayoutInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::LazyModuleStatusInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::PermissionsAuditLogResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::PermissionsResourceAccessResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::PermissionsUserAccessResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::QueryBrowserResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::SettingsExplorerInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::SystemDiagnosticsResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryDiffResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryGraphResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryLabelsResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryRestoreResource': loadCoreDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./credentials-dashboards.module\n 'BaseDashboard::CredentialsDashboard': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsAuditResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsCategoriesResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsListResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsOverviewResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsTypesResource': loadCredentialsDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./data-explorer-dashboards.module\n 'BaseDashboard::DataExplorer': loadDataExplorerDashboardsModule,\n 'BaseResourceComponent::DataExplorerResource': loadDataExplorerDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./integration.module\n 'BaseResourceComponent::IntegrationActivity': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationConnections': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationMappingWorkspace': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationOverview': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationPipelines': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationSchedules': loadIntegrationModule,\n\n // @memberjunction/ng-dashboards → ./lists-dashboards.module\n 'BaseResourceComponent::ListsBrowseResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsCategoriesResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsMyListsResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsOperationsResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsSharedWithMeResource': loadListsDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./mcp.module\n 'BaseDashboard::MCPDashboard': loadMcpModule,\n 'BaseResourceComponent::MCPResource': loadMcpModule,\n\n // @memberjunction/ng-dashboards → ./module\n 'BaseResourceComponent::ArchiveConfigResource': loadModule,\n 'BaseResourceComponent::ArchiveRunsResource': loadModule,\n 'BaseResourceComponent::DatabaseDesignerDashboard': loadModule,\n\n // @memberjunction/ng-dashboards → ./scheduling-dashboards.module\n 'BaseDashboard::SchedulingDashboard': loadSchedulingDashboardsModule,\n 'BaseResourceComponent::SchedulingActivityResource': loadSchedulingDashboardsModule,\n 'BaseResourceComponent::SchedulingDashboardResource': loadSchedulingDashboardsModule,\n 'BaseResourceComponent::SchedulingJobsResource': loadSchedulingDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./testing-dashboards.module\n 'BaseDashboard::TestingDashboard': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingAnalyticsResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingDashboardTabResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingExplorerResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingReviewResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingRunsResource': loadTestingDashboardsModule,\n\n // @memberjunction/ng-explorer-settings → ./settings.module\n 'BaseDashboard::ApplicationManagement': loadSettingsModule,\n 'BaseDashboard::EntityPermissions': loadSettingsModule,\n 'BaseDashboard::RoleManagement': loadSettingsModule,\n 'BaseDashboard::SqlLogging': loadSettingsModule,\n 'BaseDashboard::UserManagement': loadSettingsModule,\n 'BaseNavigationComponent::Settings': loadSettingsModule,\n\n // @memberjunction/ng-file-storage → ./file-storage.module\n 'BaseResourceComponent::FileBrowserResource': loadFileStorageModule,\n\n // @memberjunction/ng-react → .\n 'RuntimeUtilities::RuntimeUtilities': loadNgReact,\n\n};\n\nexport const LAZY_FEATURE_CONFIG_COUNT = 98;\n"]}
1
+ {"version":3,"file":"lazy-feature-config.js","sourceRoot":"","sources":["../../src/generated/lazy-feature-config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AUTO-GENERATED FILE — DO NOT EDIT\n * Generated by: mj codegen manifest --lazy-config\n * Regenerate with: npm run mj:manifest:explorer\n *\n * Maps @RegisterClass entries to their lazy-loading chunks using compound keys.\n * Compound key format: \"BaseClassName::Key\" (e.g., \"BaseResourceComponent::HomeDashboard\").\n *\n * When ClassFactory.GetRegistrationAsync() or CreateInstanceAsync() cannot find a\n * registration synchronously, the registered lazy loader builds the compound key and\n * looks it up here to dynamically import the chunk containing the class.\n */\n\n/** Helper to create a loader that all entries in a feature share. */\nfunction featureLoader(importFn: () => Promise<unknown>): () => Promise<void> {\n return () => importFn().then(() => {});\n}\n\n// --- @memberjunction/ng-dashboards → ./actions-dashboards.module (7 entries) ---\nconst loadActionsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/actions-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./ai-dashboards.module (15 entries) ---\nconst loadAiDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/ai-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./communication-dashboards.module (7 entries) ---\nconst loadCommunicationDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/communication-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./component-studio-dashboards.module (3 entries) ---\nconst loadComponentStudioDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/component-studio-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./core-dashboards.module (26 entries) ---\nconst loadCoreDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/core-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./credentials-dashboards.module (6 entries) ---\nconst loadCredentialsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/credentials-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./data-explorer-dashboards.module (2 entries) ---\nconst loadDataExplorerDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/data-explorer-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./integration.module (6 entries) ---\nconst loadIntegrationModule = featureLoader(() => import('@memberjunction/ng-dashboards/integration.module'));\n\n// --- @memberjunction/ng-dashboards → ./lists-dashboards.module (5 entries) ---\nconst loadListsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/lists-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./mcp.module (2 entries) ---\nconst loadMcpModule = featureLoader(() => import('@memberjunction/ng-dashboards/mcp.module'));\n\n// --- @memberjunction/ng-dashboards → ./module (3 entries) ---\nconst loadModule = featureLoader(() => import('@memberjunction/ng-dashboards/module'));\n\n// --- @memberjunction/ng-dashboards → ./scheduling-dashboards.module (4 entries) ---\nconst loadSchedulingDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/scheduling-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./testing-dashboards.module (6 entries) ---\nconst loadTestingDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/testing-dashboards.module'));\n\n// --- @memberjunction/ng-explorer-settings → ./settings.module (6 entries) ---\nconst loadSettingsModule = featureLoader(() => import('@memberjunction/ng-explorer-settings/settings.module'));\n\n// --- @memberjunction/ng-file-storage → ./file-storage.module (1 entries) ---\nconst loadFileStorageModule = featureLoader(() => import('@memberjunction/ng-file-storage/file-storage.module'));\n\n// --- @memberjunction/ng-react → . (1 entries) ---\nconst loadNgReact = featureLoader(() => import('@memberjunction/ng-react'));\n\n/**\n * Complete mapping of compound keys (BaseClassName::Key) to lazy-loading functions.\n * Covers all @RegisterClass decorated classes in lazy-loaded packages.\n */\nexport const LAZY_FEATURE_CONFIG: Record<string, () => Promise<void>> = {\n // @memberjunction/ng-dashboards → ./actions-dashboards.module\n 'BaseResourceComponent::ActionExplorerResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsCodeResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsEntitiesResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsMonitorResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsOverviewResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsScheduleResource': loadActionsDashboardsModule,\n 'BaseResourceComponent::ActionsSecurityResource': loadActionsDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./ai-dashboards.module\n 'BaseResourceComponent::AIAgentRequestsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIAgentsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIAnalyticsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIConfigResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIModelsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIMonitorResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIPromptsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AnalyticsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AutotaggingPipelineResource': loadAiDashboardsModule,\n 'BaseResourceComponent::ClusterVisualizationResource': loadAiDashboardsModule,\n 'BaseResourceComponent::DuplicateDetectionResource': loadAiDashboardsModule,\n 'BaseResourceComponent::KnowledgeConfigResource': loadAiDashboardsModule,\n 'BaseResourceComponent::SchedulingResource': loadAiDashboardsModule,\n 'BaseResourceComponent::Tags': loadAiDashboardsModule,\n 'BaseResourceComponent::VectorManagementResource': loadAiDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./communication-dashboards.module\n 'BaseDashboard::CommunicationDashboard': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationLogsResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationMonitorResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationProvidersResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationRunsResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationsNewMessageResource': loadCommunicationDashboardsModule,\n 'BaseResourceComponent::CommunicationTemplatesResource': loadCommunicationDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./component-studio-dashboards.module\n 'BaseDashboard::ComponentStudioDashboard': loadComponentStudioDashboardsModule,\n 'BaseResourceComponent::ComponentStudioResource': loadComponentStudioDashboardsModule,\n 'BaseResourceComponent::FormBuilderResource': loadComponentStudioDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./core-dashboards.module\n 'BaseApplication::HomeApplication': loadCoreDashboardsModule,\n 'BaseDashboard::EntityAdmin': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminDataSchema': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminDeveloperTools': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminIdentityAccess': loadCoreDashboardsModule,\n 'BaseResourceComponent::AdminMonitoring': loadCoreDashboardsModule,\n 'BaseResourceComponent::APIKeysResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::ApplicationRolesResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::AppStateInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::ClassRegistryInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::DashboardBrowserResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::EventMonitorInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::GraphQLConsoleInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::HomeDashboard': loadCoreDashboardsModule,\n 'BaseResourceComponent::LayoutInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::LazyModuleStatusInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::PermissionsAuditLogResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::PermissionsResourceAccessResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::PermissionsUserAccessResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::QueryBrowserResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::SettingsExplorerInspector': loadCoreDashboardsModule,\n 'BaseResourceComponent::SystemDiagnosticsResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryDiffResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryGraphResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryLabelsResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::VersionHistoryRestoreResource': loadCoreDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./credentials-dashboards.module\n 'BaseDashboard::CredentialsDashboard': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsAuditResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsCategoriesResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsListResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsOverviewResource': loadCredentialsDashboardsModule,\n 'BaseResourceComponent::CredentialsTypesResource': loadCredentialsDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./data-explorer-dashboards.module\n 'BaseDashboard::DataExplorer': loadDataExplorerDashboardsModule,\n 'BaseResourceComponent::DataExplorerResource': loadDataExplorerDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./integration.module\n 'BaseResourceComponent::IntegrationActivity': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationConnections': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationMappingWorkspace': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationOverview': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationPipelines': loadIntegrationModule,\n 'BaseResourceComponent::IntegrationSchedules': loadIntegrationModule,\n\n // @memberjunction/ng-dashboards → ./lists-dashboards.module\n 'BaseResourceComponent::ListsBrowseResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsCategoriesResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsMyListsResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsOperationsResource': loadListsDashboardsModule,\n 'BaseResourceComponent::ListsSharedWithMeResource': loadListsDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./mcp.module\n 'BaseDashboard::MCPDashboard': loadMcpModule,\n 'BaseResourceComponent::MCPResource': loadMcpModule,\n\n // @memberjunction/ng-dashboards → ./module\n 'BaseResourceComponent::ArchiveConfigResource': loadModule,\n 'BaseResourceComponent::ArchiveRunsResource': loadModule,\n 'BaseResourceComponent::DatabaseDesignerDashboard': loadModule,\n\n // @memberjunction/ng-dashboards → ./scheduling-dashboards.module\n 'BaseDashboard::SchedulingDashboard': loadSchedulingDashboardsModule,\n 'BaseResourceComponent::SchedulingActivityResource': loadSchedulingDashboardsModule,\n 'BaseResourceComponent::SchedulingDashboardResource': loadSchedulingDashboardsModule,\n 'BaseResourceComponent::SchedulingJobsResource': loadSchedulingDashboardsModule,\n\n // @memberjunction/ng-dashboards → ./testing-dashboards.module\n 'BaseDashboard::TestingDashboard': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingAnalyticsResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingDashboardTabResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingExplorerResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingReviewResource': loadTestingDashboardsModule,\n 'BaseResourceComponent::TestingRunsResource': loadTestingDashboardsModule,\n\n // @memberjunction/ng-explorer-settings → ./settings.module\n 'BaseDashboard::ApplicationManagement': loadSettingsModule,\n 'BaseDashboard::EntityPermissions': loadSettingsModule,\n 'BaseDashboard::RoleManagement': loadSettingsModule,\n 'BaseDashboard::SqlLogging': loadSettingsModule,\n 'BaseDashboard::UserManagement': loadSettingsModule,\n 'BaseNavigationComponent::Settings': loadSettingsModule,\n\n // @memberjunction/ng-file-storage → ./file-storage.module\n 'BaseResourceComponent::FileBrowserResource': loadFileStorageModule,\n\n // @memberjunction/ng-react → .\n 'RuntimeUtilities::RuntimeUtilities': loadNgReact,\n\n};\n\nexport const LAZY_FEATURE_CONFIG_COUNT = 100;\n"]}
@@ -9,6 +9,16 @@ import * as i0 from "@angular/core";
9
9
  */
10
10
  export declare class ArtifactResource extends BaseResourceComponent {
11
11
  private readonly analyzeService;
12
+ private readonly applyService;
13
+ /**
14
+ * Apply-to-my-form handler — see InteractiveFormApplyService.
15
+ * Confirms with the user, then routes to Create or Modify depending on
16
+ * whether an Active override already exists for this entity+user.
17
+ */
18
+ onApplyFormRequested(event: {
19
+ spec: unknown;
20
+ entityName: string;
21
+ }): Promise<void>;
12
22
  currentUser: UserInfo | null;
13
23
  artifactId: string;
14
24
  environmentId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/artifact-resource.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAA+B,MAAM,+BAA+B,CAAC;;AAI1F;;;;GAIG;AACH,qBA6Ba,gBAAiB,SAAQ,qBAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;IAE1D,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACpC,UAAU,EAAE,MAAM,CAAM;IACxB,aAAa,EAAE,MAAM,CAAM;IAElC,QAAQ;IAoBR;;;;OAIG;IACG,kBAAkB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBxF,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAe3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCAnEpD,gBAAgB;2CAAhB,gBAAgB;CAsE5B"}
1
+ {"version":3,"file":"artifact-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/artifact-resource.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAA+B,MAAM,+BAA+B,CAAC;;AAK1F;;;;GAIG;AACH,qBA8Ba,gBAAiB,SAAQ,qBAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;IACjE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuC;IAEpE;;;;OAIG;IACG,oBAAoB,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhF,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACpC,UAAU,EAAE,MAAM,CAAM;IACxB,aAAa,EAAE,MAAM,CAAM;IAElC,QAAQ;IAoBR;;;;OAIG;IACG,kBAAkB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,YAAY,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBxF,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAe3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCAjFpD,gBAAgB;2CAAhB,gBAAgB;CAoF5B"}
@@ -8,14 +8,14 @@ import { Component, ViewEncapsulation, inject } from '@angular/core';
8
8
  import { RegisterClass } from '@memberjunction/global';
9
9
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
10
10
  import { MJEnvironmentEntityExtended } from '@memberjunction/core-entities';
11
- import { AnalyzeArtifactService } from '@memberjunction/ng-artifacts';
11
+ import { AnalyzeArtifactService, InteractiveFormApplyService } from '@memberjunction/ng-artifacts';
12
12
  import { MJNotificationService } from '@memberjunction/ng-notifications';
13
13
  import * as i0 from "@angular/core";
14
14
  import * as i1 from "@memberjunction/ng-artifacts";
15
15
  function ArtifactResource_Conditional_1_Template(rf, ctx) { if (rf & 1) {
16
16
  const _r1 = i0.ɵɵgetCurrentView();
17
17
  i0.ɵɵelementStart(0, "mj-artifact-viewer-panel", 2);
18
- i0.ɵɵlistener("analyzeRequested", function ArtifactResource_Conditional_1_Template_mj_artifact_viewer_panel_analyzeRequested_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAnalyzeRequested($event)); });
18
+ i0.ɵɵlistener("analyzeRequested", function ArtifactResource_Conditional_1_Template_mj_artifact_viewer_panel_analyzeRequested_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAnalyzeRequested($event)); })("applyFormRequested", function ArtifactResource_Conditional_1_Template_mj_artifact_viewer_panel_applyFormRequested_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onApplyFormRequested($event)); });
19
19
  i0.ɵɵelementEnd();
20
20
  } if (rf & 2) {
21
21
  const ctx_r1 = i0.ɵɵnextContext();
@@ -28,6 +28,15 @@ function ArtifactResource_Conditional_1_Template(rf, ctx) { if (rf & 1) {
28
28
  */
29
29
  let ArtifactResource = class ArtifactResource extends BaseResourceComponent {
30
30
  analyzeService = inject(AnalyzeArtifactService);
31
+ applyService = inject(InteractiveFormApplyService);
32
+ /**
33
+ * Apply-to-my-form handler — see InteractiveFormApplyService.
34
+ * Confirms with the user, then routes to Create or Modify depending on
35
+ * whether an Active override already exists for this entity+user.
36
+ */
37
+ async onApplyFormRequested(event) {
38
+ await this.applyService.ConfirmAndApply(event.spec, event.entityName, this.ProviderToUse);
39
+ }
31
40
  currentUser = null;
32
41
  artifactId = '';
33
42
  environmentId = '';
@@ -90,7 +99,7 @@ let ArtifactResource = class ArtifactResource extends BaseResourceComponent {
90
99
  return 'fa-solid fa-file-code';
91
100
  }
92
101
  static ɵfac = /*@__PURE__*/ (() => { let ɵArtifactResource_BaseFactory; return function ArtifactResource_Factory(__ngFactoryType__) { return (ɵArtifactResource_BaseFactory || (ɵArtifactResource_BaseFactory = i0.ɵɵgetInheritedFactory(ArtifactResource)))(__ngFactoryType__ || ArtifactResource); }; })();
93
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ArtifactResource, selectors: [["mj-artifact-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "artifact-container"], [3, "artifactId", "currentUser", "environmentId", "showSaveToCollection", "canShare", "canEdit"], [3, "analyzeRequested", "artifactId", "currentUser", "environmentId", "showSaveToCollection", "canShare", "canEdit"]], template: function ArtifactResource_Template(rf, ctx) { if (rf & 1) {
102
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ArtifactResource, selectors: [["mj-artifact-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "artifact-container"], [3, "artifactId", "currentUser", "environmentId", "showSaveToCollection", "canShare", "canEdit"], [3, "analyzeRequested", "applyFormRequested", "artifactId", "currentUser", "environmentId", "showSaveToCollection", "canShare", "canEdit"]], template: function ArtifactResource_Template(rf, ctx) { if (rf & 1) {
94
103
  i0.ɵɵelementStart(0, "div", 0);
95
104
  i0.ɵɵconditionalCreate(1, ArtifactResource_Conditional_1_Template, 1, 6, "mj-artifact-viewer-panel", 1);
96
105
  i0.ɵɵelementEnd();
@@ -115,11 +124,12 @@ export { ArtifactResource };
115
124
  [showSaveToCollection]="true"
116
125
  [canShare]="true"
117
126
  [canEdit]="true"
118
- (analyzeRequested)="onAnalyzeRequested($event)">
127
+ (analyzeRequested)="onAnalyzeRequested($event)"
128
+ (applyFormRequested)="onApplyFormRequested($event)">
119
129
  </mj-artifact-viewer-panel>
120
130
  }
121
131
  </div>
122
132
  `, encapsulation: ViewEncapsulation.None, styles: ["\n .artifact-container {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n "] }]
123
133
  }], null, null); })();
124
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactResource, { className: "ArtifactResource", filePath: "src/lib/resource-wrappers/artifact-resource.component.ts", lineNumber: 43 }); })();
134
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactResource, { className: "ArtifactResource", filePath: "src/lib/resource-wrappers/artifact-resource.component.ts", lineNumber: 45 }); })();
125
135
  //# sourceMappingURL=artifact-resource.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/artifact-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewEncapsulation, inject } from '@angular/core';\nimport { DataSnapshot, Metadata, UserInfo } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData, MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport { AnalyzeArtifactService } from '@memberjunction/ng-artifacts';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\n\n/**\n * Artifact Resource - displays versioned content artifacts\n * Wraps the artifact-viewer-panel component for tab-based display\n * Supports reports, dashboards, forms, and other artifact types\n */\n@RegisterClass(BaseResourceComponent, 'ArtifactResource')\n@Component({\n standalone: false,\n selector: 'mj-artifact-resource',\n template: `\n <div class=\"artifact-container\">\n @if (currentUser && artifactId) {\n <mj-artifact-viewer-panel\n [artifactId]=\"artifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [showSaveToCollection]=\"true\"\n [canShare]=\"true\"\n [canEdit]=\"true\"\n (analyzeRequested)=\"onAnalyzeRequested($event)\">\n </mj-artifact-viewer-panel>\n }\n </div>\n `,\n styles: [`\n .artifact-container {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n `],\n encapsulation: ViewEncapsulation.None\n})\nexport class ArtifactResource extends BaseResourceComponent {\n private readonly analyzeService = inject(AnalyzeArtifactService);\n\n public currentUser: UserInfo | null = null;\n public artifactId: string = '';\n public environmentId: string = '';\n\n ngOnInit() {\n super.ngOnInit();\n const md = this.ProviderToUse;\n this.currentUser = md.CurrentUser;\n\n // Get artifact ID from resource data\n if (this.Data && this.Data.ResourceRecordID) {\n this.artifactId = this.Data.ResourceRecordID;\n }\n\n // Environment ID — use the configured environment if present, otherwise\n // fall back to the default environment. Must be a valid UUID since\n // downstream saves (e.g. AnalyzeArtifactService creating artifacts)\n // require a non-empty EnvironmentID.\n this.environmentId = (this.Data?.Configuration?.['environmentId'] as string | undefined)\n || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n\n setTimeout(() => this.NotifyLoadComplete(), 100);\n }\n\n /**\n * Handler for the Analyze button on the artifact viewer panel.\n * Creates a Data Snapshot artifact from the live viewer state, opens a\n * new conversation with it attached as input, and routes the user there.\n */\n async onAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n if (!this.currentUser) return;\n\n try {\n const result = await this.analyzeService.StartAnalysisConversation({\n snapshot: event.snapshot,\n currentUser: this.currentUser,\n environmentId: this.environmentId,\n });\n\n // Route to the new conversation in the Conversations nav item\n await this.navigationService.OpenNavItemByName('Conversations', {\n conversationId: result.conversationId,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to start analysis conversation';\n MJNotificationService.Instance.CreateSimpleNotification(message, 'error', 5000);\n }\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n // Try to load artifact name from database\n if (data.ResourceRecordID) {\n try {\n const md = this.ProviderToUse;\n const artifact = await md.GetEntityObject<any>('MJ: Conversation Artifacts');\n await artifact.Load(data.ResourceRecordID);\n return artifact.Name || `Artifact - ${data.ResourceRecordID}`;\n } catch (error) {\n console.error('Error loading artifact name:', error);\n }\n }\n return 'Artifact';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-file-code';\n }\n}\n"]}
1
+ {"version":3,"file":"artifact-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/artifact-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewEncapsulation, inject } from '@angular/core';\nimport { DataSnapshot, Metadata, UserInfo } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData, MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport { AnalyzeArtifactService, InteractiveFormApplyService } from '@memberjunction/ng-artifacts';\nimport type { ComponentSpec } from '@memberjunction/interactive-component-types';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\n\n/**\n * Artifact Resource - displays versioned content artifacts\n * Wraps the artifact-viewer-panel component for tab-based display\n * Supports reports, dashboards, forms, and other artifact types\n */\n@RegisterClass(BaseResourceComponent, 'ArtifactResource')\n@Component({\n standalone: false,\n selector: 'mj-artifact-resource',\n template: `\n <div class=\"artifact-container\">\n @if (currentUser && artifactId) {\n <mj-artifact-viewer-panel\n [artifactId]=\"artifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [showSaveToCollection]=\"true\"\n [canShare]=\"true\"\n [canEdit]=\"true\"\n (analyzeRequested)=\"onAnalyzeRequested($event)\"\n (applyFormRequested)=\"onApplyFormRequested($event)\">\n </mj-artifact-viewer-panel>\n }\n </div>\n `,\n styles: [`\n .artifact-container {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n `],\n encapsulation: ViewEncapsulation.None\n})\nexport class ArtifactResource extends BaseResourceComponent {\n private readonly analyzeService = inject(AnalyzeArtifactService);\n private readonly applyService = inject(InteractiveFormApplyService);\n\n /**\n * Apply-to-my-form handler — see InteractiveFormApplyService.\n * Confirms with the user, then routes to Create or Modify depending on\n * whether an Active override already exists for this entity+user.\n */\n async onApplyFormRequested(event: { spec: unknown; entityName: string }): Promise<void> {\n await this.applyService.ConfirmAndApply(\n event.spec as ComponentSpec,\n event.entityName,\n this.ProviderToUse,\n );\n }\n\n public currentUser: UserInfo | null = null;\n public artifactId: string = '';\n public environmentId: string = '';\n\n ngOnInit() {\n super.ngOnInit();\n const md = this.ProviderToUse;\n this.currentUser = md.CurrentUser;\n\n // Get artifact ID from resource data\n if (this.Data && this.Data.ResourceRecordID) {\n this.artifactId = this.Data.ResourceRecordID;\n }\n\n // Environment ID — use the configured environment if present, otherwise\n // fall back to the default environment. Must be a valid UUID since\n // downstream saves (e.g. AnalyzeArtifactService creating artifacts)\n // require a non-empty EnvironmentID.\n this.environmentId = (this.Data?.Configuration?.['environmentId'] as string | undefined)\n || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n\n setTimeout(() => this.NotifyLoadComplete(), 100);\n }\n\n /**\n * Handler for the Analyze button on the artifact viewer panel.\n * Creates a Data Snapshot artifact from the live viewer state, opens a\n * new conversation with it attached as input, and routes the user there.\n */\n async onAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n if (!this.currentUser) return;\n\n try {\n const result = await this.analyzeService.StartAnalysisConversation({\n snapshot: event.snapshot,\n currentUser: this.currentUser,\n environmentId: this.environmentId,\n });\n\n // Route to the new conversation in the Conversations nav item\n await this.navigationService.OpenNavItemByName('Conversations', {\n conversationId: result.conversationId,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to start analysis conversation';\n MJNotificationService.Instance.CreateSimpleNotification(message, 'error', 5000);\n }\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n // Try to load artifact name from database\n if (data.ResourceRecordID) {\n try {\n const md = this.ProviderToUse;\n const artifact = await md.GetEntityObject<any>('MJ: Conversation Artifacts');\n await artifact.Load(data.ResourceRecordID);\n return artifact.Name || `Artifact - ${data.ResourceRecordID}`;\n } catch (error) {\n console.error('Error loading artifact name:', error);\n }\n }\n return 'Artifact';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-file-code';\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"record-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAAY,YAAY,EAAc,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;;AAC7F,qBAOa,oBAAqB,SAAQ,qBAAqB;IAC3D,IAAW,UAAU,IAAI,YAAY,CAEpC;WAEa,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,YAAY;IAarF,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCAtCtD,oBAAoB;2CAApB,oBAAoB;CAmDhC"}
1
+ {"version":3,"file":"record-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAAY,YAAY,EAAc,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;;AAC7F,qBAOa,oBAAqB,SAAQ,qBAAqB;IAC3D,IAAW,UAAU,IAAI,YAAY,CAEpC;WAEa,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,YAAY;IAwBrF,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IA2B3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCAxDtD,oBAAoB;2CAApB,oBAAoB;CAqEhC"}
@@ -19,9 +19,19 @@ let EntityRecordResource = class EntityRecordResource extends BaseResourceCompon
19
19
  static GetPrimaryKey(data, provider) {
20
20
  // global-provider-ok: static helper has no component instance scope; falls back to default provider
21
21
  const md = (provider ?? Metadata.Provider);
22
- const e = md.Entities.find((e) => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());
22
+ const requested = (data.Configuration.Entity ?? '').trim();
23
+ // Prefer EntityByName (project rule: never use Entities.find for
24
+ // single-entity lookups — case/whitespace tolerant + O(1) map). Fall
25
+ // back to DisplayName match for callers (AI agents, hand-typed URLs,
26
+ // external CTAs) that pass the human-readable display name instead
27
+ // of the canonical Name (e.g. "Users" for "MJ: Users").
28
+ let e = md.EntityByName(requested);
23
29
  if (!e) {
24
- throw new Error(`Entity ${data.Configuration.Entity} not found in metadata`);
30
+ const lowered = requested.toLowerCase();
31
+ e = md.Entities.find((x) => (x.DisplayName ?? '').trim().toLowerCase() === lowered);
32
+ }
33
+ if (!e) {
34
+ throw new Error(`Entity ${data.Configuration.Entity} not found in metadata (tried Name and DisplayName)`);
25
35
  }
26
36
  let compositeKey = new CompositeKey();
27
37
  compositeKey.LoadFromURLSegment(e, data.ResourceRecordID);
@@ -32,7 +42,13 @@ let EntityRecordResource = class EntityRecordResource extends BaseResourceCompon
32
42
  return '';
33
43
  }
34
44
  const md = this.ProviderToUse;
35
- const e = md.EntityByName(data.Configuration.Entity);
45
+ let e = md.EntityByName(data.Configuration.Entity);
46
+ if (!e) {
47
+ // Same DisplayName fallback as GetPrimaryKey — keeps the
48
+ // breadcrumb/title in sync when a CTA used the display name.
49
+ const lowered = (data.Configuration.Entity ?? '').trim().toLowerCase();
50
+ e = md.Entities.find((x) => (x.DisplayName ?? '').trim().toLowerCase() === lowered);
51
+ }
36
52
  if (!e) {
37
53
  return '';
38
54
  }
@@ -59,9 +75,9 @@ let EntityRecordResource = class EntityRecordResource extends BaseResourceCompon
59
75
  }
60
76
  }
61
77
  static ɵfac = /*@__PURE__*/ (() => { let ɵEntityRecordResource_BaseFactory; return function EntityRecordResource_Factory(__ngFactoryType__) { return (ɵEntityRecordResource_BaseFactory || (ɵEntityRecordResource_BaseFactory = i0.ɵɵgetInheritedFactory(EntityRecordResource)))(__ngFactoryType__ || EntityRecordResource); }; })();
62
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRecordResource, selectors: [["mj-record-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 3, consts: [[3, "loadComplete", "recordSaved", "PrimaryKey", "entityName", "newRecordValues"]], template: function EntityRecordResource_Template(rf, ctx) { if (rf & 1) {
78
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRecordResource, selectors: [["mj-record-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 3, consts: [[3, "loadComplete", "recordSaved", "recordDismissed", "PrimaryKey", "entityName", "newRecordValues"]], template: function EntityRecordResource_Template(rf, ctx) { if (rf & 1) {
63
79
  i0.ɵɵelementStart(0, "mj-single-record", 0);
64
- i0.ɵɵlistener("loadComplete", function EntityRecordResource_Template_mj_single_record_loadComplete_0_listener() { return ctx.NotifyLoadComplete(); })("recordSaved", function EntityRecordResource_Template_mj_single_record_recordSaved_0_listener($event) { return ctx.ResourceRecordSaved($event); });
80
+ i0.ɵɵlistener("loadComplete", function EntityRecordResource_Template_mj_single_record_loadComplete_0_listener() { return ctx.NotifyLoadComplete(); })("recordSaved", function EntityRecordResource_Template_mj_single_record_recordSaved_0_listener($event) { return ctx.ResourceRecordSaved($event); })("recordDismissed", function EntityRecordResource_Template_mj_single_record_recordDismissed_0_listener() { return ctx.NotifyCloseRequested(); });
65
81
  i0.ɵɵelementEnd();
66
82
  } if (rf & 2) {
67
83
  i0.ɵɵproperty("PrimaryKey", ctx.PrimaryKey)("entityName", ctx.Data.Configuration.Entity)("newRecordValues", ctx.Data.Configuration.NewRecordValues);
@@ -73,7 +89,7 @@ EntityRecordResource = EntityRecordResource_1 = __decorate([
73
89
  export { EntityRecordResource };
74
90
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityRecordResource, [{
75
91
  type: Component,
76
- args: [{ standalone: false, selector: 'mj-record-resource', template: `<mj-single-record [PrimaryKey]="this.PrimaryKey" [entityName]="Data.Configuration.Entity" [newRecordValues]="Data.Configuration.NewRecordValues" (loadComplete)="NotifyLoadComplete()" (recordSaved)="ResourceRecordSaved($event)" ></mj-single-record>`, styles: [":host { display: block; height: 100%; width: 100%; }"] }]
92
+ args: [{ standalone: false, selector: 'mj-record-resource', template: `<mj-single-record [PrimaryKey]="this.PrimaryKey" [entityName]="Data.Configuration.Entity" [newRecordValues]="Data.Configuration.NewRecordValues" (loadComplete)="NotifyLoadComplete()" (recordSaved)="ResourceRecordSaved($event)" (recordDismissed)="NotifyCloseRequested()"></mj-single-record>`, styles: [":host { display: block; height: 100%; width: 100%; }"] }]
77
93
  }], null, null); })();
78
94
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityRecordResource, { className: "EntityRecordResource", filePath: "src/lib/resource-wrappers/record-resource.component.ts", lineNumber: 13 }); })();
79
95
  //# sourceMappingURL=record-resource.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"record-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Metadata, CompositeKey, EntityInfo, IMetadataProvider } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'RecordResource')\n@Component({\n standalone: false,\n selector: 'mj-record-resource',\n styles: [`:host { display: block; height: 100%; width: 100%; }`],\n template: `<mj-single-record [PrimaryKey]=\"this.PrimaryKey\" [entityName]=\"Data.Configuration.Entity\" [newRecordValues]=\"Data.Configuration.NewRecordValues\" (loadComplete)=\"NotifyLoadComplete()\" (recordSaved)=\"ResourceRecordSaved($event)\" ></mj-single-record>`\n})\nexport class EntityRecordResource extends BaseResourceComponent {\n public get PrimaryKey(): CompositeKey {\n return EntityRecordResource.GetPrimaryKey(this.Data, this.ProviderToUse);\n }\n\n public static GetPrimaryKey(data: ResourceData, provider?: IMetadataProvider): CompositeKey {\n // global-provider-ok: static helper has no component instance scope; falls back to default provider\n const md = (provider ?? Metadata.Provider) as IMetadataProvider;\n const e = md.Entities.find((e: EntityInfo) => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());\n if (!e){\n throw new Error(`Entity ${data.Configuration.Entity} not found in metadata`);\n }\n\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromURLSegment(e, data.ResourceRecordID);\n return compositeKey;\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity) {\n return '';\n }\n\n const md = this.ProviderToUse;\n const e = md.EntityByName(data.Configuration.Entity);\n if (!e) {\n return '';\n }\n\n const pk: CompositeKey = EntityRecordResource.GetPrimaryKey(data, this.ProviderToUse);\n if (pk.HasValue) {\n const name = await md.GetEntityRecordName(data.Configuration.Entity, pk);\n return name ? name : e.DisplayNameOrName;\n } else {\n return `New ${e.DisplayNameOrName} Record`;\n }\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity){\n return ''\n }\n else {\n const md = this.ProviderToUse;\n const e = md.Entities.find(e => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());\n if (e)\n return e?.Icon;\n else\n return '';\n }\n }\n}\n"]}
1
+ {"version":3,"file":"record-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Metadata, CompositeKey, EntityInfo, IMetadataProvider } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'RecordResource')\n@Component({\n standalone: false,\n selector: 'mj-record-resource',\n styles: [`:host { display: block; height: 100%; width: 100%; }`],\n template: `<mj-single-record [PrimaryKey]=\"this.PrimaryKey\" [entityName]=\"Data.Configuration.Entity\" [newRecordValues]=\"Data.Configuration.NewRecordValues\" (loadComplete)=\"NotifyLoadComplete()\" (recordSaved)=\"ResourceRecordSaved($event)\" (recordDismissed)=\"NotifyCloseRequested()\"></mj-single-record>`\n})\nexport class EntityRecordResource extends BaseResourceComponent {\n public get PrimaryKey(): CompositeKey {\n return EntityRecordResource.GetPrimaryKey(this.Data, this.ProviderToUse);\n }\n\n public static GetPrimaryKey(data: ResourceData, provider?: IMetadataProvider): CompositeKey {\n // global-provider-ok: static helper has no component instance scope; falls back to default provider\n const md = (provider ?? Metadata.Provider) as IMetadataProvider;\n const requested = (data.Configuration.Entity ?? '').trim();\n // Prefer EntityByName (project rule: never use Entities.find for\n // single-entity lookups — case/whitespace tolerant + O(1) map). Fall\n // back to DisplayName match for callers (AI agents, hand-typed URLs,\n // external CTAs) that pass the human-readable display name instead\n // of the canonical Name (e.g. \"Users\" for \"MJ: Users\").\n let e: EntityInfo | undefined = md.EntityByName(requested);\n if (!e) {\n const lowered = requested.toLowerCase();\n e = md.Entities.find((x: EntityInfo) =>\n (x.DisplayName ?? '').trim().toLowerCase() === lowered);\n }\n if (!e){\n throw new Error(`Entity ${data.Configuration.Entity} not found in metadata (tried Name and DisplayName)`);\n }\n\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromURLSegment(e, data.ResourceRecordID);\n return compositeKey;\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity) {\n return '';\n }\n\n const md = this.ProviderToUse;\n let e = md.EntityByName(data.Configuration.Entity);\n if (!e) {\n // Same DisplayName fallback as GetPrimaryKey — keeps the\n // breadcrumb/title in sync when a CTA used the display name.\n const lowered = (data.Configuration.Entity ?? '').trim().toLowerCase();\n e = md.Entities.find((x: EntityInfo) =>\n (x.DisplayName ?? '').trim().toLowerCase() === lowered);\n }\n if (!e) {\n return '';\n }\n\n const pk: CompositeKey = EntityRecordResource.GetPrimaryKey(data, this.ProviderToUse);\n if (pk.HasValue) {\n const name = await md.GetEntityRecordName(data.Configuration.Entity, pk);\n return name ? name : e.DisplayNameOrName;\n } else {\n return `New ${e.DisplayNameOrName} Record`;\n }\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity){\n return ''\n }\n else {\n const md = this.ProviderToUse;\n const e = md.Entities.find(e => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());\n if (e)\n return e?.Icon;\n else\n return '';\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"app-nav.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAA2B,MAAM,eAAe,CAAC;AACtI,OAAO,EAAE,eAAe,EAAkB,OAAO,EAAE,qBAAqB,EAA0B,MAAM,qCAAqC,CAAC;AAC9I,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;;AAG1D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,qBAOa,eAAgB,YAAW,MAAM,EAAE,SAAS;IA8BrD,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IA/Bb,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,iBAAiB,CAAS;IAElC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,iBAAiB,CAAK;IAG9B,OAAO,CAAC,cAAc,CAA8B;IAE1C,YAAY,kCAAyC;IACrD,cAAc,wBAA+B;gBAG7C,gBAAgB,EAAE,qBAAqB,EACvC,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,iBAAiB;IAGhC;;OAEG;IACH,IACI,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,EASpC;IAED,IAAI,GAAG,IAAI,eAAe,GAAG,IAAI,CAEhC;IAED,QAAQ,IAAI,IAAI;IAahB,WAAW,IAAI,IAAI;IAKnB;;OAEG;YACW,gBAAgB;IA6C9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;OAGG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIjC;;OAEG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,EAAE,CAExB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAKhC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM;IAIrD;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI;IAOnD;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;yCA5OtC,eAAe;2CAAf,eAAe;CA6P3B"}
1
+ {"version":3,"file":"app-nav.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAA2B,MAAM,eAAe,CAAC;AACtI,OAAO,EAAE,eAAe,EAAkB,OAAO,EAAE,qBAAqB,EAA0B,MAAM,qCAAqC,CAAC;AAC9I,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;;AAG1D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,qBAOa,eAAgB,YAAW,MAAM,EAAE,SAAS;IA8BrD,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IA/Bb,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,iBAAiB,CAAS;IAElC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,iBAAiB,CAAK;IAG9B,OAAO,CAAC,cAAc,CAA8B;IAE1C,YAAY,kCAAyC;IACrD,cAAc,wBAA+B;gBAG7C,gBAAgB,EAAE,qBAAqB,EACvC,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,iBAAiB;IAGhC;;OAEG;IACH,IACI,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,EASpC;IAED,IAAI,GAAG,IAAI,eAAe,GAAG,IAAI,CAEhC;IAED,QAAQ,IAAI,IAAI;IAahB,WAAW,IAAI,IAAI;IAKnB;;OAEG;YACW,gBAAgB;IAyD9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;OAGG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIjC;;OAEG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,EAAE,CAExB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAKhC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM;IAIrD;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI;IAOnD;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;yCAxPtC,eAAe;2CAAf,eAAe;CAyQ3B"}
@@ -155,6 +155,18 @@ export class AppNavComponent {
155
155
  const config = this.workspaceManager.GetConfiguration();
156
156
  this.updateActiveStates(config);
157
157
  this.cdr.markForCheck();
158
+ // In Angular 21 zoneless mode, markForCheck() alone is unreliable when the trigger
159
+ // is an RxJS subscription (workspaceManager.Configuration here) not tracked by the
160
+ // zoneless scheduler — the dirty flag is set but no follow-up tick is scheduled.
161
+ // detectChanges() runs CD synchronously on this view, rendering the new data
162
+ // immediately. Wrapped because detectChanges throws if invoked re-entrantly during
163
+ // another in-flight CD pass — harmless if so.
164
+ try {
165
+ this.cdr.detectChanges();
166
+ }
167
+ catch {
168
+ // Re-entrant CD — harmless, the in-flight pass picks up our markForCheck.
169
+ }
158
170
  }
159
171
  /**
160
172
  * Update active state map based on current workspace configuration
@@ -1 +1 @@
1
- {"version":3,"file":"app-nav.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts","../../../../../src/lib/shell/components/header/app-nav.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { BaseApplication, DynamicNavItem, NavItem, WorkspaceStateManager, WorkspaceConfiguration } from '@memberjunction/ng-base-application';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { Subject, takeUntil } from 'rxjs';\n\n/**\n * Event emitted when a nav item is clicked\n */\nexport interface NavItemClickEvent {\n item: NavItem;\n shiftKey: boolean;\n}\n\n/**\n * Horizontal navigation items for the current app.\n * Uses OnPush change detection and reactive state management for optimal performance.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-nav',\n templateUrl: './app-nav.component.html',\n styleUrls: ['./app-nav.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppNavComponent implements OnInit, OnDestroy {\n private destroy$ = new Subject<void>();\n private _app: BaseApplication | null = null;\n private _cachedNavItems: NavItem[] = [];\n private _cachedAppColor: string = 'var(--mj-brand-primary)';\n private _servicesInjected = false;\n\n /**\n * Monotonically increasing counter used to detect and discard stale async results.\n *\n * Because GetNavItems() is async (HomeApplication does a DB lookup for record names),\n * and RxJS subscribe() does NOT serialize async callbacks, multiple calls to\n * updateCachedData() can overlap. Without this guard, a slow call (e.g., Home app\n * doing a DB lookup) that started BEFORE a fast call (e.g., switching to App B)\n * could resolve AFTER the fast call and overwrite the correct nav items with stale ones.\n *\n * How it works:\n * 1. Each updateCachedData() call increments this counter and captures it as `gen`\n * 2. After the await, it checks: does `gen` still match `_updateGeneration`?\n * 3. If not, a newer call started while we were waiting — discard our stale results\n */\n private _updateGeneration = 0;\n\n // Map of nav item key (Route or Label) to active state\n private activeStateMap = new Map<string, boolean>();\n\n @Output() navItemClick = new EventEmitter<NavItemClickEvent>();\n @Output() navItemDismiss = new EventEmitter<NavItem>();\n\n constructor(\n private workspaceManager: WorkspaceStateManager,\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef\n ) {}\n\n /**\n * Input setter for app - triggers cache update when app changes\n */\n @Input()\n set app(value: BaseApplication | null) {\n if (this._app !== value) {\n this._app = value;\n this._cachedNavItems = []; // Clear stale items immediately so previous app's items don't flash\n this.activeStateMap.clear();\n this._servicesInjected = false; // Reset injection flag\n this.updateCachedData();\n this.cdr.markForCheck();\n }\n }\n\n get app(): BaseApplication | null {\n return this._app;\n }\n\n ngOnInit(): void {\n // Subscribe to workspace configuration changes.\n // Must rebuild nav items (not just active states) because dynamic nav items\n // are generated based on the currently active tab - when a user navigates\n // from one record to another (e.g., via OpenEntityRecord), the active tab\n // changes and the dynamic nav item needs to reflect the new record.\n this.workspaceManager.Configuration\n .pipe(takeUntil(this.destroy$))\n .subscribe(async () => {\n await this.updateCachedData();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Update cached nav items and app color when app changes\n */\n private async updateCachedData(): Promise<void> {\n // Capture the current generation before any async work.\n // See _updateGeneration JSDoc for full explanation of the race condition this prevents.\n const gen = ++this._updateGeneration;\n\n if (this._app) {\n // Inject services once for apps that need them (e.g., HomeApplication for dynamic nav items)\n if (!this._servicesInjected) {\n const appWithServices = this._app as BaseApplication & {\n SetWorkspaceManager?: (manager: WorkspaceStateManager) => void;\n SetSharedService?: (service: SharedService) => void;\n };\n\n if (typeof appWithServices.SetWorkspaceManager === 'function') {\n appWithServices.SetWorkspaceManager(this.workspaceManager);\n }\n if (typeof appWithServices.SetSharedService === 'function') {\n appWithServices.SetSharedService(this.sharedService);\n }\n this._servicesInjected = true;\n }\n\n const items = await this._app.GetNavItems() || [];\n\n // If a newer call started while we were awaiting, our results are stale — bail out\n // so we don't overwrite the newer call's (correct) results.\n if (gen !== this._updateGeneration) {\n return;\n }\n\n // Only show items with Status 'Active' or undefined (default to Active)\n this._cachedNavItems = items.filter(item => !item.Status || item.Status === 'Active');\n\n this._cachedAppColor = this._app.GetColor() || 'var(--mj-brand-primary)';\n } else {\n this._cachedNavItems = [];\n this._cachedAppColor = 'var(--mj-brand-primary)';\n }\n\n // Update active states after nav items change\n const config = this.workspaceManager.GetConfiguration();\n this.updateActiveStates(config);\n this.cdr.markForCheck();\n }\n\n /**\n * Update active state map based on current workspace configuration\n */\n private updateActiveStates(config: WorkspaceConfiguration | null): void {\n this.activeStateMap.clear();\n\n if (!config || !this._app) {\n return;\n }\n\n const activeTab = config.tabs.find(t => t.id === config.activeTabId);\n if (!activeTab || activeTab.applicationId !== this._app.ID) {\n return;\n }\n\n // Compute active state for each nav item once\n for (const item of this._cachedNavItems) {\n const key = this.getItemKey(item);\n const isActive = this.computeIsActive(item, activeTab);\n this.activeStateMap.set(key, isActive);\n }\n }\n\n /**\n * Get unique key for nav item (used for tracking and active state).\n * Prefers RecordID for dynamic items to avoid label collisions.\n */\n private getItemKey(item: NavItem): string {\n return item.RecordID || item.Route || item.Label || '';\n }\n\n /**\n * Check if a nav item is dynamic (generated from recent orphan resources)\n */\n isDynamic(item: NavItem): boolean {\n return (item as DynamicNavItem).isDynamic === true;\n }\n\n /**\n * Compute if nav item is active based on active tab\n */\n private computeIsActive(item: NavItem, activeTab: any): boolean {\n // Check if nav item has a custom matching function (for dynamic items)\n const dynamicItem = item as NavItem & { isActiveMatch?: (tab: unknown) => boolean };\n if (dynamicItem.isActiveMatch && typeof dynamicItem.isActiveMatch === 'function') {\n return dynamicItem.isActiveMatch(activeTab);\n }\n\n const config = activeTab.configuration || {};\n\n // Match by DriverClass (most reliable for Custom resource types — always set correctly)\n if (item.DriverClass && (config['driverClass'] === item.DriverClass || config['resourceTypeDriverClass'] === item.DriverClass)) {\n return true;\n }\n\n // Match by navItemName from config (reliable — set when nav item opens)\n if (config['navItemName'] && config['navItemName'] === item.Label) {\n return true;\n }\n\n // Match by route (for route-based nav items)\n if (item.Route && config['route'] === item.Route) {\n return true;\n }\n\n // NOTE: We intentionally do NOT match by activeTab.title here.\n // Tab titles can be stale (updated asynchronously by DisplayNameChangedEvent\n // from cached components) and cause double-matches where two nav items\n // both appear active. DriverClass and navItemName are sufficient.\n return false;\n }\n\n /**\n * Get cached navigation items (no computation in getter)\n */\n get navItems(): NavItem[] {\n return this._cachedNavItems;\n }\n\n /**\n * Get cached app color (no computation in getter)\n */\n get appColor(): string {\n return this._cachedAppColor;\n }\n\n /**\n * Check if nav item is active (uses cached state from Map)\n */\n isActive(item: NavItem): boolean {\n const key = this.getItemKey(item);\n return this.activeStateMap.get(key) || false;\n }\n\n /**\n * Track function for @for to optimize rendering\n */\n trackByNavItem(_index: number, item: NavItem): string {\n return this.getItemKey(item);\n }\n\n /**\n * Handle nav item click\n */\n onNavClick(item: NavItem, event?: MouseEvent): void {\n this.navItemClick.emit({\n item,\n shiftKey: event?.shiftKey || false\n });\n }\n\n /**\n * Handle dismiss click on a dynamic nav item.\n * Removes from the app's recent stack and refreshes nav items immediately.\n * Stops propagation so the nav click handler doesn't fire.\n */\n onDismiss(item: NavItem, event: MouseEvent): void {\n event.stopPropagation();\n\n // Remove from the app's recent stack directly so we can refresh immediately\n if (this._app) {\n const appWithRemove = this._app as BaseApplication & {\n RemoveDynamicNavItem?: (navItem: NavItem) => void;\n };\n if (typeof appWithRemove.RemoveDynamicNavItem === 'function') {\n appWithRemove.RemoveDynamicNavItem(item);\n this.updateCachedData();\n }\n }\n\n this.navItemDismiss.emit(item);\n }\n\n}\n","<nav class=\"nav-list\" [style.--app-color]=\"appColor\">\n @for (item of navItems; track trackByNavItem($index, item)) {\n <div\n class=\"nav-item\"\n [class.active]=\"isActive(item)\"\n [class.dynamic]=\"isDynamic(item)\"\n [class.no-icon]=\"!item.Icon\"\n (click)=\"onNavClick(item, $event)\">\n @if (item.Icon) {\n <i [class]=\"item.Icon\"></i>\n }\n <span>{{ item.Label }}</span>\n @if (item.Badge) {\n <span class=\"badge\">{{ item.Badge }}</span>\n }\n @if (isDynamic(item)) {\n <button class=\"dismiss-btn\" title=\"Remove\" (click)=\"onDismiss(item, $event)\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n</nav>\n"]}
1
+ {"version":3,"file":"app-nav.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts","../../../../../src/lib/shell/components/header/app-nav.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAwC,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGtI,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;;;;;ICMlC,oBAA2B;;;IAAxB,2BAAmB;;;IAItB,+BAAoB;IAAA,YAAgB;IAAA,iBAAO;;;IAAvB,cAAgB;IAAhB,mCAAgB;;;;IAGpC,iCAA6E;IAAlC,6OAAS,iCAAuB,KAAC;IAC1E,uBAAiC;IACnC,iBAAS;;;;IAhBb,8BAKqC;IAAnC,wMAAS,kCAAwB,KAAC;IAClC,qFAAiB;IAGjB,4BAAM;IAAA,YAAgB;IAAA,iBAAO;IAC7B,wFAAkB;IAGlB,0FAAuB;IAKzB,iBAAM;;;;IAdJ,AADA,AADA,kDAA+B,sCACE,0BACL;IAE5B,cAEC;IAFD,uCAEC;IACK,eAAgB;IAAhB,mCAAgB;IACtB,cAEC;IAFD,wCAEC;IACD,cAIC;IAJD,oDAIC;;ADNP;;;GAGG;AAQH,MAAM,OAAO,eAAe;IA8BhB;IACA;IACA;IA/BF,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC/B,IAAI,GAA2B,IAAI,CAAC;IACpC,eAAe,GAAc,EAAE,CAAC;IAChC,eAAe,GAAW,yBAAyB,CAAC;IACpD,iBAAiB,GAAG,KAAK,CAAC;IAElC;;;;;;;;;;;;;OAaG;IACK,iBAAiB,GAAG,CAAC,CAAC;IAE9B,uDAAuD;IAC/C,cAAc,GAAG,IAAI,GAAG,EAAmB,CAAC;IAE1C,YAAY,GAAG,IAAI,YAAY,EAAqB,CAAC;IACrD,cAAc,GAAG,IAAI,YAAY,EAAW,CAAC;IAEvD,YACU,gBAAuC,EACvC,aAA4B,EAC5B,GAAsB;QAFtB,qBAAgB,GAAhB,gBAAgB,CAAuB;QACvC,kBAAa,GAAb,aAAa,CAAe;QAC5B,QAAG,GAAH,GAAG,CAAmB;IAC7B,CAAC;IAEJ;;OAEG;IACH,IACI,GAAG,CAAC,KAA6B;QACnC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC,oEAAoE;YAC/F,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;YAC5B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC,uBAAuB;YACvD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,QAAQ;QACN,gDAAgD;QAChD,4EAA4E;QAC5E,0EAA0E;QAC1E,0EAA0E;QAC1E,oEAAoE;QACpE,IAAI,CAAC,gBAAgB,CAAC,aAAa;aAChC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC9B,SAAS,CAAC,KAAK,IAAI,EAAE;YACpB,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAChC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB;QAC5B,wDAAwD;QACxD,wFAAwF;QACxF,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAErC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,6FAA6F;YAC7F,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,IAG5B,CAAC;gBAEF,IAAI,OAAO,eAAe,CAAC,mBAAmB,KAAK,UAAU,EAAE,CAAC;oBAC9D,eAAe,CAAC,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAC7D,CAAC;gBACD,IAAI,OAAO,eAAe,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;oBAC3D,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACvD,CAAC;gBACD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAChC,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;YAElD,mFAAmF;YACnF,4DAA4D;YAC5D,IAAI,GAAG,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,wEAAwE;YACxE,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;YAEtF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,yBAAyB,CAAC;QAC3E,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;YAC1B,IAAI,CAAC,eAAe,GAAG,yBAAyB,CAAC;QACnD,CAAC;QAED,8CAA8C;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;QACxD,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAExB,mFAAmF;QACnF,mFAAmF;QACnF,iFAAiF;QACjF,6EAA6E;QAC7E,mFAAmF;QACnF,8CAA8C;QAC9C,IAAI,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;QAC5E,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,MAAqC;QAC9D,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAE5B,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,CAAC,CAAC;QACrE,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,aAAa,KAAK,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,8CAA8C;QAC9C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACvD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,UAAU,CAAC,IAAa;QAC9B,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAAa;QACrB,OAAQ,IAAuB,CAAC,SAAS,KAAK,IAAI,CAAC;IACrD,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,IAAa,EAAE,SAAc;QACnD,uEAAuE;QACvE,MAAM,WAAW,GAAG,IAA+D,CAAC;QACpF,IAAI,WAAW,CAAC,aAAa,IAAI,OAAO,WAAW,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;YACjF,OAAO,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,aAAa,IAAI,EAAE,CAAC;QAE7C,wFAAwF;QACxF,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,yBAAyB,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/H,OAAO,IAAI,CAAC;QACd,CAAC;QAED,wEAAwE;QACxE,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,6CAA6C;QAC7C,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,+DAA+D;QAC/D,6EAA6E;QAC7E,uEAAuE;QACvE,kEAAkE;QAClE,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,IAAa;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,MAAc,EAAE,IAAa;QAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,IAAa,EAAE,KAAkB;QAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;YACrB,IAAI;YACJ,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,KAAK;SACnC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,IAAa,EAAE,KAAiB;QACxC,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,4EAA4E;QAC5E,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,aAAa,GAAG,IAAI,CAAC,IAE1B,CAAC;YACF,IAAI,OAAO,aAAa,CAAC,oBAAoB,KAAK,UAAU,EAAE,CAAC;gBAC7D,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;gBACzC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;yGAvQU,eAAe;6DAAf,eAAe;YCxB5B,8BAAqD;YACnD,iGAoBC;YACH,iBAAM;;YAtBgB,2CAA8B;YAClD,cAoBC;YApBD,2BAoBC;;;iFDGU,eAAe;cAP3B,SAAS;6BACI,KAAK,YACP,YAAY,mBAGL,uBAAuB,CAAC,MAAM;;kBA4B9C,MAAM;;kBACN,MAAM;;kBAWN,KAAK;;kFAtCK,eAAe","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';\nimport { BaseApplication, DynamicNavItem, NavItem, WorkspaceStateManager, WorkspaceConfiguration } from '@memberjunction/ng-base-application';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { Subject, takeUntil } from 'rxjs';\n\n/**\n * Event emitted when a nav item is clicked\n */\nexport interface NavItemClickEvent {\n item: NavItem;\n shiftKey: boolean;\n}\n\n/**\n * Horizontal navigation items for the current app.\n * Uses OnPush change detection and reactive state management for optimal performance.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-nav',\n templateUrl: './app-nav.component.html',\n styleUrls: ['./app-nav.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppNavComponent implements OnInit, OnDestroy {\n private destroy$ = new Subject<void>();\n private _app: BaseApplication | null = null;\n private _cachedNavItems: NavItem[] = [];\n private _cachedAppColor: string = 'var(--mj-brand-primary)';\n private _servicesInjected = false;\n\n /**\n * Monotonically increasing counter used to detect and discard stale async results.\n *\n * Because GetNavItems() is async (HomeApplication does a DB lookup for record names),\n * and RxJS subscribe() does NOT serialize async callbacks, multiple calls to\n * updateCachedData() can overlap. Without this guard, a slow call (e.g., Home app\n * doing a DB lookup) that started BEFORE a fast call (e.g., switching to App B)\n * could resolve AFTER the fast call and overwrite the correct nav items with stale ones.\n *\n * How it works:\n * 1. Each updateCachedData() call increments this counter and captures it as `gen`\n * 2. After the await, it checks: does `gen` still match `_updateGeneration`?\n * 3. If not, a newer call started while we were waiting — discard our stale results\n */\n private _updateGeneration = 0;\n\n // Map of nav item key (Route or Label) to active state\n private activeStateMap = new Map<string, boolean>();\n\n @Output() navItemClick = new EventEmitter<NavItemClickEvent>();\n @Output() navItemDismiss = new EventEmitter<NavItem>();\n\n constructor(\n private workspaceManager: WorkspaceStateManager,\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef\n ) {}\n\n /**\n * Input setter for app - triggers cache update when app changes\n */\n @Input()\n set app(value: BaseApplication | null) {\n if (this._app !== value) {\n this._app = value;\n this._cachedNavItems = []; // Clear stale items immediately so previous app's items don't flash\n this.activeStateMap.clear();\n this._servicesInjected = false; // Reset injection flag\n this.updateCachedData();\n this.cdr.markForCheck();\n }\n }\n\n get app(): BaseApplication | null {\n return this._app;\n }\n\n ngOnInit(): void {\n // Subscribe to workspace configuration changes.\n // Must rebuild nav items (not just active states) because dynamic nav items\n // are generated based on the currently active tab - when a user navigates\n // from one record to another (e.g., via OpenEntityRecord), the active tab\n // changes and the dynamic nav item needs to reflect the new record.\n this.workspaceManager.Configuration\n .pipe(takeUntil(this.destroy$))\n .subscribe(async () => {\n await this.updateCachedData();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Update cached nav items and app color when app changes\n */\n private async updateCachedData(): Promise<void> {\n // Capture the current generation before any async work.\n // See _updateGeneration JSDoc for full explanation of the race condition this prevents.\n const gen = ++this._updateGeneration;\n\n if (this._app) {\n // Inject services once for apps that need them (e.g., HomeApplication for dynamic nav items)\n if (!this._servicesInjected) {\n const appWithServices = this._app as BaseApplication & {\n SetWorkspaceManager?: (manager: WorkspaceStateManager) => void;\n SetSharedService?: (service: SharedService) => void;\n };\n\n if (typeof appWithServices.SetWorkspaceManager === 'function') {\n appWithServices.SetWorkspaceManager(this.workspaceManager);\n }\n if (typeof appWithServices.SetSharedService === 'function') {\n appWithServices.SetSharedService(this.sharedService);\n }\n this._servicesInjected = true;\n }\n\n const items = await this._app.GetNavItems() || [];\n\n // If a newer call started while we were awaiting, our results are stale — bail out\n // so we don't overwrite the newer call's (correct) results.\n if (gen !== this._updateGeneration) {\n return;\n }\n\n // Only show items with Status 'Active' or undefined (default to Active)\n this._cachedNavItems = items.filter(item => !item.Status || item.Status === 'Active');\n\n this._cachedAppColor = this._app.GetColor() || 'var(--mj-brand-primary)';\n } else {\n this._cachedNavItems = [];\n this._cachedAppColor = 'var(--mj-brand-primary)';\n }\n\n // Update active states after nav items change\n const config = this.workspaceManager.GetConfiguration();\n this.updateActiveStates(config);\n this.cdr.markForCheck();\n\n // In Angular 21 zoneless mode, markForCheck() alone is unreliable when the trigger\n // is an RxJS subscription (workspaceManager.Configuration here) not tracked by the\n // zoneless scheduler — the dirty flag is set but no follow-up tick is scheduled.\n // detectChanges() runs CD synchronously on this view, rendering the new data\n // immediately. Wrapped because detectChanges throws if invoked re-entrantly during\n // another in-flight CD pass — harmless if so.\n try {\n this.cdr.detectChanges();\n } catch {\n // Re-entrant CD — harmless, the in-flight pass picks up our markForCheck.\n }\n }\n\n /**\n * Update active state map based on current workspace configuration\n */\n private updateActiveStates(config: WorkspaceConfiguration | null): void {\n this.activeStateMap.clear();\n\n if (!config || !this._app) {\n return;\n }\n\n const activeTab = config.tabs.find(t => t.id === config.activeTabId);\n if (!activeTab || activeTab.applicationId !== this._app.ID) {\n return;\n }\n\n // Compute active state for each nav item once\n for (const item of this._cachedNavItems) {\n const key = this.getItemKey(item);\n const isActive = this.computeIsActive(item, activeTab);\n this.activeStateMap.set(key, isActive);\n }\n }\n\n /**\n * Get unique key for nav item (used for tracking and active state).\n * Prefers RecordID for dynamic items to avoid label collisions.\n */\n private getItemKey(item: NavItem): string {\n return item.RecordID || item.Route || item.Label || '';\n }\n\n /**\n * Check if a nav item is dynamic (generated from recent orphan resources)\n */\n isDynamic(item: NavItem): boolean {\n return (item as DynamicNavItem).isDynamic === true;\n }\n\n /**\n * Compute if nav item is active based on active tab\n */\n private computeIsActive(item: NavItem, activeTab: any): boolean {\n // Check if nav item has a custom matching function (for dynamic items)\n const dynamicItem = item as NavItem & { isActiveMatch?: (tab: unknown) => boolean };\n if (dynamicItem.isActiveMatch && typeof dynamicItem.isActiveMatch === 'function') {\n return dynamicItem.isActiveMatch(activeTab);\n }\n\n const config = activeTab.configuration || {};\n\n // Match by DriverClass (most reliable for Custom resource types — always set correctly)\n if (item.DriverClass && (config['driverClass'] === item.DriverClass || config['resourceTypeDriverClass'] === item.DriverClass)) {\n return true;\n }\n\n // Match by navItemName from config (reliable — set when nav item opens)\n if (config['navItemName'] && config['navItemName'] === item.Label) {\n return true;\n }\n\n // Match by route (for route-based nav items)\n if (item.Route && config['route'] === item.Route) {\n return true;\n }\n\n // NOTE: We intentionally do NOT match by activeTab.title here.\n // Tab titles can be stale (updated asynchronously by DisplayNameChangedEvent\n // from cached components) and cause double-matches where two nav items\n // both appear active. DriverClass and navItemName are sufficient.\n return false;\n }\n\n /**\n * Get cached navigation items (no computation in getter)\n */\n get navItems(): NavItem[] {\n return this._cachedNavItems;\n }\n\n /**\n * Get cached app color (no computation in getter)\n */\n get appColor(): string {\n return this._cachedAppColor;\n }\n\n /**\n * Check if nav item is active (uses cached state from Map)\n */\n isActive(item: NavItem): boolean {\n const key = this.getItemKey(item);\n return this.activeStateMap.get(key) || false;\n }\n\n /**\n * Track function for @for to optimize rendering\n */\n trackByNavItem(_index: number, item: NavItem): string {\n return this.getItemKey(item);\n }\n\n /**\n * Handle nav item click\n */\n onNavClick(item: NavItem, event?: MouseEvent): void {\n this.navItemClick.emit({\n item,\n shiftKey: event?.shiftKey || false\n });\n }\n\n /**\n * Handle dismiss click on a dynamic nav item.\n * Removes from the app's recent stack and refreshes nav items immediately.\n * Stops propagation so the nav click handler doesn't fire.\n */\n onDismiss(item: NavItem, event: MouseEvent): void {\n event.stopPropagation();\n\n // Remove from the app's recent stack directly so we can refresh immediately\n if (this._app) {\n const appWithRemove = this._app as BaseApplication & {\n RemoveDynamicNavItem?: (navItem: NavItem) => void;\n };\n if (typeof appWithRemove.RemoveDynamicNavItem === 'function') {\n appWithRemove.RemoveDynamicNavItem(item);\n this.updateCachedData();\n }\n }\n\n this.navItemDismiss.emit(item);\n }\n\n}\n","<nav class=\"nav-list\" [style.--app-color]=\"appColor\">\n @for (item of navItems; track trackByNavItem($index, item)) {\n <div\n class=\"nav-item\"\n [class.active]=\"isActive(item)\"\n [class.dynamic]=\"isDynamic(item)\"\n [class.no-icon]=\"!item.Icon\"\n (click)=\"onNavClick(item, $event)\">\n @if (item.Icon) {\n <i [class]=\"item.Icon\"></i>\n }\n <span>{{ item.Label }}</span>\n @if (item.Badge) {\n <span class=\"badge\">{{ item.Badge }}</span>\n }\n @if (isDynamic(item)) {\n <button class=\"dismiss-btn\" title=\"Remove\" (click)=\"onDismiss(item, $event)\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n</nav>\n"]}
@@ -10,6 +10,7 @@ export interface CachedComponentInfo {
10
10
  resourceType: string;
11
11
  resourceRecordId: string;
12
12
  applicationId: string;
13
+ keyDiscriminator?: string;
13
14
  isAttached: boolean;
14
15
  attachedToTabId: string | null;
15
16
  lastUsed: Date;
@@ -54,17 +55,23 @@ export declare class ComponentCacheManager {
54
55
  /**
55
56
  * Generate a unique cache key from resource identity.
56
57
  * This is the ONE canonical key format used by ALL cache operations.
58
+ *
59
+ * `discriminator` is appended into the recordId slot only when recordId is empty.
60
+ * It exists to prevent collisions between distinct "new record" tabs that share
61
+ * an empty recordId — e.g., a new MJ:Companies form and a new MJ:Employees form
62
+ * would otherwise both cache at `appId::RecordResource::__no_record__` and clobber
63
+ * each other. Passing the entity name as discriminator keeps them separate.
57
64
  */
58
65
  private getCacheKey;
59
66
  /**
60
67
  * Check if a component exists in cache and is available for reuse.
61
68
  */
62
- hasAvailableComponent(resourceType: string, recordId: string, appId: string): boolean;
69
+ hasAvailableComponent(resourceType: string, recordId: string, appId: string, discriminator?: string): boolean;
63
70
  /**
64
71
  * Get a cached component if available (not currently attached).
65
72
  * Lookup is by resource identity, not tab ID.
66
73
  */
67
- getCachedComponent(resourceType: string, recordId: string, appId: string): CachedComponentInfo | null;
74
+ getCachedComponent(resourceType: string, recordId: string, appId: string, discriminator?: string): CachedComponentInfo | null;
68
75
  /**
69
76
  * Store a component in the cache and mark as attached.
70
77
  */
@@ -72,14 +79,26 @@ export declare class ComponentCacheManager {
72
79
  /**
73
80
  * Mark a component as attached. Lookup by resource identity.
74
81
  */
75
- markAsAttached(resourceType: string, recordId: string, appId: string, tabId: string): void;
82
+ markAsAttached(resourceType: string, recordId: string, appId: string, tabId: string, discriminator?: string): void;
76
83
  /**
77
84
  * Mark a component as detached (available for reuse). Lookup by resource identity.
78
85
  *
79
86
  * This is the ONLY way to detach a component. Both single-resource mode and
80
87
  * Golden Layout mode use this same method to ensure consistent cache behavior.
81
88
  */
82
- markAsDetached(resourceType: string, recordId: string, appId: string): CachedComponentInfo | null;
89
+ markAsDetached(resourceType: string, recordId: string, appId: string, discriminator?: string): CachedComponentInfo | null;
90
+ /**
91
+ * Re-key a cached component when its underlying record identity changes.
92
+ *
93
+ * Used when a "new record" component (cached at `recordId = ''`) becomes a saved record
94
+ * (now identified by its new PK). Without re-keying, the next "new record" request would
95
+ * still resolve to this same cache entry, surfacing the previously-saved record on a form
96
+ * the user expects to be blank.
97
+ *
98
+ * Preserves the live component instance — only the cache key + stored identity change.
99
+ * Returns true if a matching entry was found and re-keyed, false otherwise.
100
+ */
101
+ rekeyComponent(resourceType: string, oldRecordId: string, newRecordId: string, appId: string, oldDiscriminator?: string, newDiscriminator?: string): boolean;
83
102
  /**
84
103
  * Find a cached component by tab ID and detach it.
85
104
  * This is a convenience wrapper for callers that only know the tab ID
@@ -100,7 +119,7 @@ export declare class ComponentCacheManager {
100
119
  /**
101
120
  * Remove and destroy a specific component from cache by resource identity.
102
121
  */
103
- destroyComponent(resourceType: string, recordId: string, appId: string): void;
122
+ destroyComponent(resourceType: string, recordId: string, appId: string, discriminator?: string): void;
104
123
  /**
105
124
  * Remove and destroy component by tab ID (convenience for Golden Layout tab close).
106
125
  */
@@ -1 +1 @@
1
- {"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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"}