@memberjunction/ng-explorer-core 5.36.0 → 5.38.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 (51) 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/__tests__/form-resolver.service.test.d.ts +2 -0
  6. package/dist/lib/__tests__/form-resolver.service.test.d.ts.map +1 -0
  7. package/dist/lib/__tests__/form-resolver.service.test.js +258 -0
  8. package/dist/lib/__tests__/form-resolver.service.test.js.map +1 -0
  9. package/dist/lib/conversation-feedback/conversation-feedback.d.ts +108 -0
  10. package/dist/lib/conversation-feedback/conversation-feedback.d.ts.map +1 -0
  11. package/dist/lib/conversation-feedback/conversation-feedback.js +809 -0
  12. package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -0
  13. package/dist/lib/conversation-feedback/index.d.ts +2 -0
  14. package/dist/lib/conversation-feedback/index.d.ts.map +1 -0
  15. package/dist/lib/conversation-feedback/index.js +2 -0
  16. package/dist/lib/conversation-feedback/index.js.map +1 -0
  17. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +10 -0
  18. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
  19. package/dist/lib/resource-wrappers/artifact-resource.component.js +15 -5
  20. package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
  21. package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
  22. package/dist/lib/resource-wrappers/record-resource.component.js +22 -6
  23. package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
  24. package/dist/lib/services/form-resolver.service.d.ts +139 -0
  25. package/dist/lib/services/form-resolver.service.d.ts.map +1 -0
  26. package/dist/lib/services/form-resolver.service.js +235 -0
  27. package/dist/lib/services/form-resolver.service.js.map +1 -0
  28. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
  29. package/dist/lib/shell/components/header/app-nav.component.js +12 -0
  30. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  31. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +24 -5
  32. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  33. package/dist/lib/shell/components/tabs/component-cache-manager.js +58 -14
  34. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  35. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +42 -0
  36. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  37. package/dist/lib/shell/components/tabs/tab-container.component.js +186 -12
  38. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  39. package/dist/lib/single-record/single-record.component.d.ts +41 -3
  40. package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
  41. package/dist/lib/single-record/single-record.component.js +192 -23
  42. package/dist/lib/single-record/single-record.component.js.map +1 -1
  43. package/dist/module.d.ts +32 -30
  44. package/dist/module.d.ts.map +1 -1
  45. package/dist/module.js +15 -6
  46. package/dist/module.js.map +1 -1
  47. package/dist/public-api.d.ts +1 -0
  48. package/dist/public-api.d.ts.map +1 -1
  49. package/dist/public-api.js +1 -0
  50. package/dist/public-api.js.map +1 -1
  51. package/package.json +46 -44
@@ -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"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=form-resolver.service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-resolver.service.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/form-resolver.service.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Tests for FormResolverService.
3
+ *
4
+ * The service builds a SQL filter + ORDER BY against `EntityFormOverride`,
5
+ * runs it via RunView, and falls back to ClassFactory when no override matches.
6
+ * These tests capture the RunView call args (to validate filter shape) and
7
+ * stub responses to verify each resolution branch.
8
+ */
9
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
10
+ // ----- Module mocks -------------------------------------------------------
11
+ // Mock UserInfoEngine — the resolver's variant preferences now persist via
12
+ // the user-settings table (cross-device, cross-browser) instead of
13
+ // localStorage. In-memory map mirrors the engine's cache behavior.
14
+ const settingsBacking = {};
15
+ vi.mock('@memberjunction/core-entities', () => ({
16
+ UserInfoEngine: {
17
+ Instance: {
18
+ GetSetting: (key) => settingsBacking[key],
19
+ SetSettingDebounced: (key, value) => {
20
+ settingsBacking[key] = value;
21
+ },
22
+ DeleteSetting: async (key) => {
23
+ delete settingsBacking[key];
24
+ return true;
25
+ },
26
+ },
27
+ },
28
+ }));
29
+ vi.mock('@angular/core', () => ({
30
+ Injectable: () => (target) => target,
31
+ }));
32
+ // RunView mock — we capture every call's params so tests can assert on them.
33
+ const runViewCalls = [];
34
+ let runViewResponse = { Success: true, Results: [] };
35
+ vi.mock('@memberjunction/core', () => ({
36
+ LogError: vi.fn(),
37
+ RunView: class {
38
+ static FromMetadataProvider(_provider) {
39
+ return new (class {
40
+ async RunView(params, user) {
41
+ runViewCalls.push({ params, user });
42
+ return runViewResponse;
43
+ }
44
+ })();
45
+ }
46
+ },
47
+ }));
48
+ // ClassFactory mock — controls what the fallback branch returns.
49
+ let classFactoryReg = null;
50
+ vi.mock('@memberjunction/global', () => ({
51
+ MJGlobal: {
52
+ Instance: {
53
+ ClassFactory: {
54
+ GetRegistration: vi.fn(() => classFactoryReg),
55
+ },
56
+ },
57
+ },
58
+ // The post-refactor resolver uses UUIDsEqual to match a user-selected
59
+ // variant ID; stub it with a case-insensitive string compare.
60
+ UUIDsEqual: (a, b) => (a ?? '').toLowerCase() === (b ?? '').toLowerCase(),
61
+ }));
62
+ vi.mock('@memberjunction/ng-base-forms', () => ({
63
+ BaseFormComponent: class FakeBaseFormComponent {
64
+ },
65
+ }));
66
+ const entity = { ID: 'entity-1', Name: 'Customer' };
67
+ const user = (overrides) => ({ ID: 'user-1', UserRoles: [], ...overrides });
68
+ const provider = {};
69
+ const overrideRow = (overrides) => ({
70
+ ID: 'row-1', EntityID: 'entity-1', ComponentID: 'comp-1',
71
+ Scope: 'Global', UserID: null, RoleID: null,
72
+ Priority: 0, Status: 'Active', ...overrides,
73
+ });
74
+ let service;
75
+ beforeEach(async () => {
76
+ runViewCalls.length = 0;
77
+ runViewResponse = { Success: true, Results: [] };
78
+ classFactoryReg = null;
79
+ for (const k of Object.keys(settingsBacking))
80
+ delete settingsBacking[k];
81
+ vi.clearAllMocks();
82
+ const mod = await import('../services/form-resolver.service');
83
+ service = new mod.FormResolverService();
84
+ });
85
+ // ----- Tests --------------------------------------------------------------
86
+ describe('FormResolverService.ResolveFormForEntity', () => {
87
+ it('returns kind=interactive when an override matches', async () => {
88
+ runViewResponse = { Success: true, Results: [overrideRow({})] };
89
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
90
+ expect(result.kind).toBe('interactive');
91
+ if (result.kind === 'interactive') {
92
+ expect(result.override.ComponentID).toBe('comp-1');
93
+ }
94
+ });
95
+ it('passes only "MJ: Entity Form Overrides" to RunView', async () => {
96
+ await service.ResolveFormForEntity(entity, user({}), provider);
97
+ expect(runViewCalls[0].params.EntityName).toBe('MJ: Entity Form Overrides');
98
+ });
99
+ it('filters by the entity ID and does NOT filter by Status (returns full variant list)', async () => {
100
+ // Post-refactor: the resolver lists ALL applicable variants (any
101
+ // Status) so the variant switcher can show Pending / Inactive
102
+ // alongside Active. The Active pick happens in-memory via pickActive.
103
+ await service.ResolveFormForEntity(entity, user({}), provider);
104
+ const filter = runViewCalls[0].params.ExtraFilter;
105
+ expect(filter).toContain(`EntityID='entity-1'`);
106
+ expect(filter).not.toContain(`Status='Active'`);
107
+ });
108
+ it('orders by User > Role > Global scope, then Priority DESC, then CreatedAt DESC', async () => {
109
+ await service.ResolveFormForEntity(entity, user({}), provider);
110
+ const orderBy = runViewCalls[0].params.OrderBy;
111
+ expect(orderBy).toContain(`WHEN 'User' THEN 1`);
112
+ expect(orderBy).toContain(`WHEN 'Role' THEN 2`);
113
+ expect(orderBy).toContain('Priority DESC');
114
+ expect(orderBy).toContain('__mj_CreatedAt DESC');
115
+ });
116
+ it('includes UserID match in the filter', async () => {
117
+ await service.ResolveFormForEntity(entity, user({ ID: 'me' }), provider);
118
+ const filter = runViewCalls[0].params.ExtraFilter;
119
+ expect(filter).toContain(`Scope='User' AND UserID='me'`);
120
+ });
121
+ it('includes role-membership clause for each role the user has', async () => {
122
+ const u = user({ UserRoles: [{ RoleID: 'r1' }, { RoleID: 'r2' }] });
123
+ await service.ResolveFormForEntity(entity, u, provider);
124
+ const filter = runViewCalls[0].params.ExtraFilter;
125
+ expect(filter).toContain(`Scope='Role' AND RoleID IN ('r1','r2')`);
126
+ });
127
+ it('emits an always-false role clause when the user has no roles', async () => {
128
+ await service.ResolveFormForEntity(entity, user({ UserRoles: [] }), provider);
129
+ const filter = runViewCalls[0].params.ExtraFilter;
130
+ // No roles = the user can never match a Role-scoped row. We encode that
131
+ // as (1=0) rather than producing `IN ()` which is invalid SQL.
132
+ expect(filter).toContain('(1=0)');
133
+ expect(filter).not.toContain('IN ()');
134
+ });
135
+ it('does NOT cap the query at MaxRows=1 — needs the full variant list', async () => {
136
+ // Post-refactor: the resolver returns variants for the picker, so it
137
+ // can't limit to one row. The pickActive() in-memory still selects
138
+ // the top match for the default-rendered form.
139
+ await service.ResolveFormForEntity(entity, user({}), provider);
140
+ expect(runViewCalls[0].params.MaxRows).toBeUndefined();
141
+ });
142
+ it('returns variants list alongside the resolved override', async () => {
143
+ const variants = [
144
+ overrideRow({ ID: 'v-active', Status: 'Active', Scope: 'User', UserID: 'user-1' }),
145
+ overrideRow({ ID: 'v-pending', Status: 'Pending', Scope: 'User', UserID: 'user-1' }),
146
+ overrideRow({ ID: 'v-inactive', Status: 'Inactive', Scope: 'Global' }),
147
+ ];
148
+ runViewResponse = { Success: true, Results: variants };
149
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
150
+ expect(result.variants?.length).toBe(3);
151
+ expect(result.variants?.map(v => v.ID).sort()).toEqual(['v-active', 'v-inactive', 'v-pending']);
152
+ });
153
+ });
154
+ describe('FormResolverService.ListVariantsForEntity', () => {
155
+ it('returns the full applicable list (any status)', async () => {
156
+ runViewResponse = {
157
+ Success: true,
158
+ Results: [
159
+ overrideRow({ ID: 'v1', Status: 'Active' }),
160
+ overrideRow({ ID: 'v2', Status: 'Pending' }),
161
+ ],
162
+ };
163
+ const variants = await service.ListVariantsForEntity(entity, user({}), provider);
164
+ expect(variants.length).toBe(2);
165
+ });
166
+ });
167
+ describe('FormResolverService session-local variant selection', () => {
168
+ beforeEach(() => {
169
+ // The resolver writes to localStorage; reset before each test.
170
+ if (typeof window !== 'undefined' && window.localStorage) {
171
+ window.localStorage.clear();
172
+ }
173
+ });
174
+ it('honours a saved variant ID over the default Active pick', async () => {
175
+ runViewResponse = {
176
+ Success: true,
177
+ Results: [
178
+ overrideRow({ ID: 'v-default-active', Status: 'Active', Scope: 'Global', Priority: 0 }),
179
+ overrideRow({ ID: 'v-user-selected', Status: 'Active', Scope: 'User', UserID: 'user-1', Priority: 0 }),
180
+ ],
181
+ };
182
+ // Save the user's choice
183
+ service.SetSelectedVariant(entity.Name, 'v-user-selected');
184
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
185
+ expect(result.kind).toBe('interactive');
186
+ if (result.kind === 'interactive') {
187
+ expect(result.override.ID).toBe('v-user-selected');
188
+ }
189
+ });
190
+ it('clears a saved variant ID that no longer matches an Active row', async () => {
191
+ runViewResponse = {
192
+ Success: true,
193
+ Results: [overrideRow({ ID: 'v-active', Status: 'Active' })],
194
+ };
195
+ service.SetSelectedVariant(entity.Name, 'v-stale');
196
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
197
+ expect(result.kind).toBe('interactive');
198
+ if (result.kind === 'interactive') {
199
+ expect(result.override.ID).toBe('v-active');
200
+ }
201
+ // Stale selection should have been cleared
202
+ expect(service.GetSelectedVariant(entity.Name)).toBeNull();
203
+ });
204
+ it('ClearSelectedVariant wipes the stored choice', () => {
205
+ service.SetSelectedVariant(entity.Name, 'v1');
206
+ expect(service.GetSelectedVariant(entity.Name)).toBe('v1');
207
+ service.ClearSelectedVariant(entity.Name);
208
+ expect(service.GetSelectedVariant(entity.Name)).toBeNull();
209
+ });
210
+ it('SetExplicitDefault stores the sentinel so pickActive returns null even when Active overrides exist', async () => {
211
+ // Hardcoded — matches FormResolverService.EXPLICIT_DEFAULT_SENTINEL.
212
+ const SENTINEL = '__codegen-default__';
213
+ service.SetExplicitDefault(entity.Name);
214
+ expect(service.GetSelectedVariant(entity.Name)).toBe(SENTINEL);
215
+ runViewResponse = { Success: true, Results: [overrideRow({ ID: 'v-active', Scope: 'Global', Status: 'Active' })] };
216
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
217
+ // Even with an Active override in the variants list, the sentinel
218
+ // forces a fall-through to the CodeGen / Angular fallback.
219
+ expect(result.kind).not.toBe('interactive');
220
+ });
221
+ it('is case-insensitive on the entity name', () => {
222
+ service.SetSelectedVariant('Customer', 'v1');
223
+ expect(service.GetSelectedVariant('customer')).toBe('v1');
224
+ expect(service.GetSelectedVariant('CUSTOMER')).toBe('v1');
225
+ });
226
+ });
227
+ describe('FormResolverService.ResolveFormForEntity — fallback behaviour', () => {
228
+ it('uses ResultType=simple to skip BaseEntity hydration on the hot path', async () => {
229
+ await service.ResolveFormForEntity(entity, user({}), provider);
230
+ expect(runViewCalls[0].params.ResultType).toBe('simple');
231
+ });
232
+ it('falls back to ClassFactory when no override matches', async () => {
233
+ runViewResponse = { Success: true, Results: [] };
234
+ classFactoryReg = { SubClass: class FakeForm {
235
+ } };
236
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
237
+ expect(result.kind).toBe('class');
238
+ if (result.kind === 'class') {
239
+ expect(result.subClass).toBe(classFactoryReg.SubClass);
240
+ }
241
+ });
242
+ it('returns kind=none when neither override nor ClassFactory has a form', async () => {
243
+ runViewResponse = { Success: true, Results: [] };
244
+ classFactoryReg = null;
245
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
246
+ expect(result.kind).toBe('none');
247
+ });
248
+ it('falls through when the RunView fails (treats lookup failure as "no override")', async () => {
249
+ runViewResponse = { Success: false, ErrorMessage: 'db down' };
250
+ classFactoryReg = { SubClass: class FakeForm {
251
+ } };
252
+ const result = await service.ResolveFormForEntity(entity, user({}), provider);
253
+ // Lookup failure should NOT block the user from seeing the class-based form
254
+ // — better to show *something* than to fail closed on every entity load.
255
+ expect(result.kind).toBe('class');
256
+ });
257
+ });
258
+ //# sourceMappingURL=form-resolver.service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-resolver.service.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/form-resolver.service.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tests for FormResolverService.\n *\n * The service builds a SQL filter + ORDER BY against `EntityFormOverride`,\n * runs it via RunView, and falls back to ClassFactory when no override matches.\n * These tests capture the RunView call args (to validate filter shape) and\n * stub responses to verify each resolution branch.\n */\nimport { describe, it, expect, vi, beforeEach } from 'vitest';\n\n// ----- Module mocks -------------------------------------------------------\n\n// Mock UserInfoEngine — the resolver's variant preferences now persist via\n// the user-settings table (cross-device, cross-browser) instead of\n// localStorage. In-memory map mirrors the engine's cache behavior.\nconst settingsBacking: Record<string, string> = {};\nvi.mock('@memberjunction/core-entities', () => ({\n UserInfoEngine: {\n Instance: {\n GetSetting: (key: string) => settingsBacking[key],\n SetSettingDebounced: (key: string, value: string) => {\n settingsBacking[key] = value;\n },\n DeleteSetting: async (key: string) => {\n delete settingsBacking[key];\n return true;\n },\n },\n },\n}));\n\nvi.mock('@angular/core', () => ({\n Injectable: () => (target: Function) => target,\n}));\n\n// RunView mock — we capture every call's params so tests can assert on them.\nconst runViewCalls: Array<{ params: any; user: any }> = [];\nlet runViewResponse: { Success: boolean; Results?: any[]; ErrorMessage?: string } = { Success: true, Results: [] };\n\nvi.mock('@memberjunction/core', () => ({\n LogError: vi.fn(),\n RunView: class {\n static FromMetadataProvider(_provider: any) {\n return new (class {\n async RunView(params: any, user: any) {\n runViewCalls.push({ params, user });\n return runViewResponse;\n }\n })();\n }\n },\n}));\n\n// ClassFactory mock — controls what the fallback branch returns.\nlet classFactoryReg: { SubClass: any } | null = null;\nvi.mock('@memberjunction/global', () => ({\n MJGlobal: {\n Instance: {\n ClassFactory: {\n GetRegistration: vi.fn(() => classFactoryReg),\n },\n },\n },\n // The post-refactor resolver uses UUIDsEqual to match a user-selected\n // variant ID; stub it with a case-insensitive string compare.\n UUIDsEqual: (a: string, b: string) => (a ?? '').toLowerCase() === (b ?? '').toLowerCase(),\n}));\n\nvi.mock('@memberjunction/ng-base-forms', () => ({\n BaseFormComponent: class FakeBaseFormComponent {},\n}));\n\n// ----- Test setup ---------------------------------------------------------\n\nimport type { FormResolverService } from '../services/form-resolver.service';\n\nconst entity = { ID: 'entity-1', Name: 'Customer' } as any;\nconst user = (overrides: Partial<{ ID: string; UserRoles: Array<{ RoleID: string }> }>) =>\n ({ ID: 'user-1', UserRoles: [], ...overrides } as any);\nconst provider = {} as any;\n\nconst overrideRow = (overrides: Partial<{\n ID: string; EntityID: string; ComponentID: string;\n Scope: 'User' | 'Role' | 'Global';\n UserID: string | null; RoleID: string | null;\n Priority: number; Status: 'Active' | 'Inactive' | 'Pending';\n}>) => ({\n ID: 'row-1', EntityID: 'entity-1', ComponentID: 'comp-1',\n Scope: 'Global' as const, UserID: null, RoleID: null,\n Priority: 0, Status: 'Active' as const, ...overrides,\n});\n\nlet service: FormResolverService;\n\nbeforeEach(async () => {\n runViewCalls.length = 0;\n runViewResponse = { Success: true, Results: [] };\n classFactoryReg = null;\n for (const k of Object.keys(settingsBacking)) delete settingsBacking[k];\n vi.clearAllMocks();\n const mod = await import('../services/form-resolver.service');\n service = new mod.FormResolverService();\n});\n\n// ----- Tests --------------------------------------------------------------\n\ndescribe('FormResolverService.ResolveFormForEntity', () => {\n\n it('returns kind=interactive when an override matches', async () => {\n runViewResponse = { Success: true, Results: [overrideRow({})] };\n\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n\n expect(result.kind).toBe('interactive');\n if (result.kind === 'interactive') {\n expect(result.override.ComponentID).toBe('comp-1');\n }\n });\n\n it('passes only \"MJ: Entity Form Overrides\" to RunView', async () => {\n await service.ResolveFormForEntity(entity, user({}), provider);\n expect(runViewCalls[0].params.EntityName).toBe('MJ: Entity Form Overrides');\n });\n\n it('filters by the entity ID and does NOT filter by Status (returns full variant list)', async () => {\n // Post-refactor: the resolver lists ALL applicable variants (any\n // Status) so the variant switcher can show Pending / Inactive\n // alongside Active. The Active pick happens in-memory via pickActive.\n await service.ResolveFormForEntity(entity, user({}), provider);\n const filter = runViewCalls[0].params.ExtraFilter;\n expect(filter).toContain(`EntityID='entity-1'`);\n expect(filter).not.toContain(`Status='Active'`);\n });\n\n it('orders by User > Role > Global scope, then Priority DESC, then CreatedAt DESC', async () => {\n await service.ResolveFormForEntity(entity, user({}), provider);\n const orderBy = runViewCalls[0].params.OrderBy;\n expect(orderBy).toContain(`WHEN 'User' THEN 1`);\n expect(orderBy).toContain(`WHEN 'Role' THEN 2`);\n expect(orderBy).toContain('Priority DESC');\n expect(orderBy).toContain('__mj_CreatedAt DESC');\n });\n\n it('includes UserID match in the filter', async () => {\n await service.ResolveFormForEntity(entity, user({ ID: 'me' }), provider);\n const filter = runViewCalls[0].params.ExtraFilter;\n expect(filter).toContain(`Scope='User' AND UserID='me'`);\n });\n\n it('includes role-membership clause for each role the user has', async () => {\n const u = user({ UserRoles: [{ RoleID: 'r1' }, { RoleID: 'r2' }] });\n await service.ResolveFormForEntity(entity, u, provider);\n const filter = runViewCalls[0].params.ExtraFilter;\n expect(filter).toContain(`Scope='Role' AND RoleID IN ('r1','r2')`);\n });\n\n it('emits an always-false role clause when the user has no roles', async () => {\n await service.ResolveFormForEntity(entity, user({ UserRoles: [] }), provider);\n const filter = runViewCalls[0].params.ExtraFilter;\n // No roles = the user can never match a Role-scoped row. We encode that\n // as (1=0) rather than producing `IN ()` which is invalid SQL.\n expect(filter).toContain('(1=0)');\n expect(filter).not.toContain('IN ()');\n });\n\n it('does NOT cap the query at MaxRows=1 — needs the full variant list', async () => {\n // Post-refactor: the resolver returns variants for the picker, so it\n // can't limit to one row. The pickActive() in-memory still selects\n // the top match for the default-rendered form.\n await service.ResolveFormForEntity(entity, user({}), provider);\n expect(runViewCalls[0].params.MaxRows).toBeUndefined();\n });\n\n it('returns variants list alongside the resolved override', async () => {\n const variants = [\n overrideRow({ ID: 'v-active', Status: 'Active', Scope: 'User', UserID: 'user-1' }),\n overrideRow({ ID: 'v-pending', Status: 'Pending', Scope: 'User', UserID: 'user-1' }),\n overrideRow({ ID: 'v-inactive', Status: 'Inactive', Scope: 'Global' }),\n ];\n runViewResponse = { Success: true, Results: variants };\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n expect(result.variants?.length).toBe(3);\n expect(result.variants?.map(v => v.ID).sort()).toEqual(['v-active', 'v-inactive', 'v-pending']);\n });\n});\n\ndescribe('FormResolverService.ListVariantsForEntity', () => {\n\n it('returns the full applicable list (any status)', async () => {\n runViewResponse = {\n Success: true,\n Results: [\n overrideRow({ ID: 'v1', Status: 'Active' }),\n overrideRow({ ID: 'v2', Status: 'Pending' }),\n ],\n };\n const variants = await service.ListVariantsForEntity(entity, user({}), provider);\n expect(variants.length).toBe(2);\n });\n});\n\ndescribe('FormResolverService session-local variant selection', () => {\n\n beforeEach(() => {\n // The resolver writes to localStorage; reset before each test.\n if (typeof window !== 'undefined' && window.localStorage) {\n window.localStorage.clear();\n }\n });\n\n it('honours a saved variant ID over the default Active pick', async () => {\n runViewResponse = {\n Success: true,\n Results: [\n overrideRow({ ID: 'v-default-active', Status: 'Active', Scope: 'Global', Priority: 0 }),\n overrideRow({ ID: 'v-user-selected', Status: 'Active', Scope: 'User', UserID: 'user-1', Priority: 0 }),\n ],\n };\n // Save the user's choice\n service.SetSelectedVariant(entity.Name, 'v-user-selected');\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n expect(result.kind).toBe('interactive');\n if (result.kind === 'interactive') {\n expect(result.override.ID).toBe('v-user-selected');\n }\n });\n\n it('clears a saved variant ID that no longer matches an Active row', async () => {\n runViewResponse = {\n Success: true,\n Results: [ overrideRow({ ID: 'v-active', Status: 'Active' }) ],\n };\n service.SetSelectedVariant(entity.Name, 'v-stale');\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n expect(result.kind).toBe('interactive');\n if (result.kind === 'interactive') {\n expect(result.override.ID).toBe('v-active');\n }\n // Stale selection should have been cleared\n expect(service.GetSelectedVariant(entity.Name)).toBeNull();\n });\n\n it('ClearSelectedVariant wipes the stored choice', () => {\n service.SetSelectedVariant(entity.Name, 'v1');\n expect(service.GetSelectedVariant(entity.Name)).toBe('v1');\n service.ClearSelectedVariant(entity.Name);\n expect(service.GetSelectedVariant(entity.Name)).toBeNull();\n });\n\n it('SetExplicitDefault stores the sentinel so pickActive returns null even when Active overrides exist', async () => {\n // Hardcoded — matches FormResolverService.EXPLICIT_DEFAULT_SENTINEL.\n const SENTINEL = '__codegen-default__';\n service.SetExplicitDefault(entity.Name);\n expect(service.GetSelectedVariant(entity.Name)).toBe(SENTINEL);\n runViewResponse = { Success: true, Results: [overrideRow({ ID: 'v-active', Scope: 'Global', Status: 'Active' })] };\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n // Even with an Active override in the variants list, the sentinel\n // forces a fall-through to the CodeGen / Angular fallback.\n expect(result.kind).not.toBe('interactive');\n });\n\n it('is case-insensitive on the entity name', () => {\n service.SetSelectedVariant('Customer', 'v1');\n expect(service.GetSelectedVariant('customer')).toBe('v1');\n expect(service.GetSelectedVariant('CUSTOMER')).toBe('v1');\n });\n});\n\ndescribe('FormResolverService.ResolveFormForEntity — fallback behaviour', () => {\n\n it('uses ResultType=simple to skip BaseEntity hydration on the hot path', async () => {\n await service.ResolveFormForEntity(entity, user({}), provider);\n expect(runViewCalls[0].params.ResultType).toBe('simple');\n });\n\n it('falls back to ClassFactory when no override matches', async () => {\n runViewResponse = { Success: true, Results: [] };\n classFactoryReg = { SubClass: class FakeForm {} };\n\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n\n expect(result.kind).toBe('class');\n if (result.kind === 'class') {\n expect(result.subClass).toBe(classFactoryReg.SubClass);\n }\n });\n\n it('returns kind=none when neither override nor ClassFactory has a form', async () => {\n runViewResponse = { Success: true, Results: [] };\n classFactoryReg = null;\n\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n\n expect(result.kind).toBe('none');\n });\n\n it('falls through when the RunView fails (treats lookup failure as \"no override\")', async () => {\n runViewResponse = { Success: false, ErrorMessage: 'db down' };\n classFactoryReg = { SubClass: class FakeForm {} };\n\n const result = await service.ResolveFormForEntity(entity, user({}), provider);\n\n // Lookup failure should NOT block the user from seeing the class-based form\n // — better to show *something* than to fail closed on every entity load.\n expect(result.kind).toBe('class');\n });\n});\n"]}
@@ -0,0 +1,108 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { BaseResourceComponent } from '@memberjunction/ng-shared';
3
+ import * as i0 from "@angular/core";
4
+ export interface FeedbackRow {
5
+ ratingID: string;
6
+ rating: number;
7
+ comments: string | null;
8
+ createdAt: string;
9
+ raterName: string | null;
10
+ raterEmail: string | null;
11
+ conversationDetailID: string;
12
+ conversationID: string | null;
13
+ conversationName: string | null;
14
+ messageText: string | null;
15
+ messageSnippet: string | null;
16
+ messageRole: string | null;
17
+ agentID: string | null;
18
+ agentName: string | null;
19
+ }
20
+ export type RatingBand = 'all' | 'high' | 'mid' | 'low';
21
+ export type DateRange = 'all' | '1d' | '7d' | '30d' | '90d';
22
+ export declare class ConversationFeedbackResource extends BaseResourceComponent implements OnInit {
23
+ isInitializing: boolean;
24
+ loading: boolean;
25
+ statsLoading: boolean;
26
+ error: string | null;
27
+ ratingBand: RatingBand;
28
+ dateRange: DateRange;
29
+ searchTerm: string;
30
+ rows: FeedbackRow[];
31
+ totalRowCount: number;
32
+ pageSize: number;
33
+ currentPage: number;
34
+ readonly pageSizeOptions: number[];
35
+ stats: {
36
+ total: number;
37
+ avgRating: number;
38
+ percentPositive: number;
39
+ percentNegative: number;
40
+ };
41
+ selectedRow: FeedbackRow | null;
42
+ private searchDebounceTimer;
43
+ private cdr;
44
+ private appManager;
45
+ GetResourceDisplayName(): Promise<string>;
46
+ GetResourceIconClass(): Promise<string>;
47
+ ngOnInit(): Promise<void>;
48
+ /** Manual refresh from the page header — same path as a filter change. */
49
+ loadFeedback(): Promise<void>;
50
+ setBand(band: RatingBand): void;
51
+ setDateRange(range: DateRange): void;
52
+ /**
53
+ * Search input fires on every keystroke; debounce so we don't slam the
54
+ * server while the user is typing. 250ms is enough to feel responsive
55
+ * without firing on intermediate states.
56
+ */
57
+ onSearchChange(): void;
58
+ onPageChange(event: {
59
+ PageNumber: number;
60
+ PageSize: number;
61
+ StartRow: number;
62
+ }): void;
63
+ onPageSizeChange(size: number): void;
64
+ openDrawer(row: FeedbackRow): void;
65
+ closeDrawer(): void;
66
+ openConversation(): Promise<void>;
67
+ onEscape(): void;
68
+ bandClassFor(rating: number): string;
69
+ trackByRatingID: (_: number, row: FeedbackRow) => string;
70
+ /** 1-based index of the first row on the current page (0 when empty). */
71
+ get rangeStart(): number;
72
+ /** 1-based index of the last row on the current page (clamped to total). */
73
+ get rangeEnd(): number;
74
+ /**
75
+ * True when the filtered set fits on a single page — in this case
76
+ * mj-pagination hides itself, so the footer renders a fallback summary
77
+ * line. When false we let mj-pagination own the bar (it has its own
78
+ * `1-N of M` summary on the left + nav controls on the right).
79
+ */
80
+ get isSinglePage(): boolean;
81
+ /**
82
+ * Run both the rows-query (paged) and the stats-query (aggregate) against
83
+ * the current filter state. Called when filters change or on initial load.
84
+ */
85
+ private applyFilters;
86
+ /**
87
+ * Fetch the current page of rows from the server. The mj-pagination
88
+ * footer reads `totalRowCount` to derive the page count.
89
+ */
90
+ private loadRows;
91
+ /**
92
+ * Aggregate counts over the same filter universe as `loadRows()`. Runs in
93
+ * parallel with the rows query so the stat cards and the table stay in
94
+ * sync after every filter change.
95
+ */
96
+ private loadStats;
97
+ /**
98
+ * Build the Nunjucks-bound parameter set passed to both queries. Server-side
99
+ * filtering: emit only the keys that actually have a value so the SQL's
100
+ * `{% if X %}` blocks stay inert when filters are at their default.
101
+ */
102
+ private buildQueryParameters;
103
+ private dateRangeCutoffIso;
104
+ private mapRow;
105
+ static ɵfac: i0.ɵɵFactoryDeclaration<ConversationFeedbackResource, never>;
106
+ static ɵcmp: i0.ɵɵComponentDeclaration<ConversationFeedbackResource, "mj-conversation-feedback", never, {}, {}, never, never, false, never>;
107
+ }
108
+ //# sourceMappingURL=conversation-feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-feedback.d.ts","sourceRoot":"","sources":["../../../src/lib/conversation-feedback/conversation-feedback.ts"],"names":[],"mappings":"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"}