@memberjunction/ng-explorer-core 5.21.0 → 5.23.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 (105) hide show
  1. package/dist/generated/lazy-feature-config.d.ts +19 -0
  2. package/dist/generated/lazy-feature-config.d.ts.map +1 -0
  3. package/dist/generated/lazy-feature-config.js +144 -0
  4. package/dist/generated/lazy-feature-config.js.map +1 -0
  5. package/dist/lib/command-palette/command-palette.component.d.ts +10 -1
  6. package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
  7. package/dist/lib/command-palette/command-palette.component.js +68 -16
  8. package/dist/lib/command-palette/command-palette.component.js.map +1 -1
  9. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +49 -49
  10. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  11. package/dist/lib/generic/form-toolbar.js +10 -10
  12. package/dist/lib/generic/form-toolbar.js.map +1 -1
  13. package/dist/lib/generic/resource-container-component.d.ts +0 -1
  14. package/dist/lib/generic/resource-container-component.d.ts.map +1 -1
  15. package/dist/lib/generic/resource-container-component.js +3 -12
  16. package/dist/lib/generic/resource-container-component.js.map +1 -1
  17. package/dist/lib/oauth/oauth-callback.component.js +6 -6
  18. package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
  19. package/dist/lib/oauth/oauth.module.d.ts +2 -3
  20. package/dist/lib/oauth/oauth.module.d.ts.map +1 -1
  21. package/dist/lib/oauth/oauth.module.js +0 -4
  22. package/dist/lib/oauth/oauth.module.js.map +1 -1
  23. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +8 -23
  24. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
  25. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +68 -117
  26. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  27. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +9 -21
  28. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  29. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +66 -137
  30. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  31. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +3 -19
  32. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
  33. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +16 -98
  34. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
  35. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +0 -1
  36. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  37. package/dist/lib/resource-wrappers/dashboard-resource.component.js +4 -12
  38. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  39. package/dist/lib/resource-wrappers/view-resource.component.d.ts +13 -11
  40. package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
  41. package/dist/lib/resource-wrappers/view-resource.component.js +80 -89
  42. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  43. package/dist/lib/services/lazy-module-registry.d.ts +24 -9
  44. package/dist/lib/services/lazy-module-registry.d.ts.map +1 -1
  45. package/dist/lib/services/lazy-module-registry.js +32 -13
  46. package/dist/lib/services/lazy-module-registry.js.map +1 -1
  47. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
  48. package/dist/lib/shell/components/header/app-nav.component.js +18 -3
  49. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  50. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +38 -16
  51. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  52. package/dist/lib/shell/components/tabs/component-cache-manager.js +57 -35
  53. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  54. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +56 -1
  55. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  56. package/dist/lib/shell/components/tabs/tab-container.component.js +298 -53
  57. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  58. package/dist/lib/shell/services/settings-dialog.service.d.ts +8 -8
  59. package/dist/lib/shell/services/settings-dialog.service.d.ts.map +1 -1
  60. package/dist/lib/shell/services/settings-dialog.service.js +20 -26
  61. package/dist/lib/shell/services/settings-dialog.service.js.map +1 -1
  62. package/dist/lib/shell/shell.component.d.ts +26 -2
  63. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  64. package/dist/lib/shell/shell.component.js +225 -54
  65. package/dist/lib/shell/shell.component.js.map +1 -1
  66. package/dist/lib/shell/shell.module.d.ts +4 -5
  67. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  68. package/dist/lib/shell/shell.module.js +4 -8
  69. package/dist/lib/shell/shell.module.js.map +1 -1
  70. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +72 -71
  71. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  72. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +11 -11
  73. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js.map +1 -1
  74. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts +36 -12
  75. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts.map +1 -1
  76. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +78 -50
  77. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js.map +1 -1
  78. package/dist/lib/single-dashboard/single-dashboard.component.d.ts +12 -5
  79. package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
  80. package/dist/lib/single-dashboard/single-dashboard.component.js +44 -55
  81. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  82. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +10 -2
  83. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  84. package/dist/lib/single-list-detail/single-list-detail.component.js +313 -243
  85. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  86. package/dist/lib/user-menu/base-user-menu.d.ts +4 -0
  87. package/dist/lib/user-menu/base-user-menu.d.ts.map +1 -1
  88. package/dist/lib/user-menu/base-user-menu.js +26 -0
  89. package/dist/lib/user-menu/base-user-menu.js.map +1 -1
  90. package/dist/lib/user-menu/user-menu.types.d.ts +20 -0
  91. package/dist/lib/user-menu/user-menu.types.d.ts.map +1 -1
  92. package/dist/lib/user-menu/user-menu.types.js.map +1 -1
  93. package/dist/module.d.ts +23 -34
  94. package/dist/module.d.ts.map +1 -1
  95. package/dist/module.js +33 -74
  96. package/dist/module.js.map +1 -1
  97. package/dist/public-api.d.ts +1 -1
  98. package/dist/public-api.d.ts.map +1 -1
  99. package/dist/public-api.js +1 -1
  100. package/dist/public-api.js.map +1 -1
  101. package/package.json +38 -47
  102. package/dist/lib/services/lazy-feature-config.d.ts +0 -16
  103. package/dist/lib/services/lazy-feature-config.d.ts.map +0 -1
  104. package/dist/lib/services/lazy-feature-config.js +0 -113
  105. package/dist/lib/services/lazy-feature-config.js.map +0 -1
@@ -0,0 +1,19 @@
1
+ /**
2
+ * AUTO-GENERATED FILE — DO NOT EDIT
3
+ * Generated by: mj codegen manifest --lazy-config
4
+ * Regenerate with: npm run mj:manifest:explorer
5
+ *
6
+ * Maps @RegisterClass entries to their lazy-loading chunks using compound keys.
7
+ * Compound key format: "BaseClassName::Key" (e.g., "BaseResourceComponent::HomeDashboard").
8
+ *
9
+ * When ClassFactory.GetRegistrationAsync() or CreateInstanceAsync() cannot find a
10
+ * registration synchronously, the registered lazy loader builds the compound key and
11
+ * looks it up here to dynamically import the chunk containing the class.
12
+ */
13
+ /**
14
+ * Complete mapping of compound keys (BaseClassName::Key) to lazy-loading functions.
15
+ * Covers all @RegisterClass decorated classes in lazy-loaded packages.
16
+ */
17
+ export declare const LAZY_FEATURE_CONFIG: Record<string, () => Promise<void>>;
18
+ export declare const LAZY_FEATURE_CONFIG_COUNT = 75;
19
+ //# sourceMappingURL=lazy-feature-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-feature-config.d.ts","sourceRoot":"","sources":["../../src/generated/lazy-feature-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoDH;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CA0GnE,CAAC;AAEF,eAAO,MAAM,yBAAyB,KAAK,CAAC"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * AUTO-GENERATED FILE — DO NOT EDIT
3
+ * Generated by: mj codegen manifest --lazy-config
4
+ * Regenerate with: npm run mj:manifest:explorer
5
+ *
6
+ * Maps @RegisterClass entries to their lazy-loading chunks using compound keys.
7
+ * Compound key format: "BaseClassName::Key" (e.g., "BaseResourceComponent::HomeDashboard").
8
+ *
9
+ * When ClassFactory.GetRegistrationAsync() or CreateInstanceAsync() cannot find a
10
+ * registration synchronously, the registered lazy loader builds the compound key and
11
+ * looks it up here to dynamically import the chunk containing the class.
12
+ */
13
+ /** Helper to create a loader that all entries in a feature share. */
14
+ function featureLoader(importFn) {
15
+ return () => importFn().then(() => { });
16
+ }
17
+ // --- @memberjunction/ng-dashboards → ./actions-dashboards.module (7 entries) ---
18
+ const loadActionsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/actions-dashboards.module'));
19
+ // --- @memberjunction/ng-dashboards → ./ai-dashboards.module (12 entries) ---
20
+ const loadAiDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/ai-dashboards.module'));
21
+ // --- @memberjunction/ng-dashboards → ./communication-dashboards.module (6 entries) ---
22
+ const loadCommunicationDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/communication-dashboards.module'));
23
+ // --- @memberjunction/ng-dashboards → ./component-studio-dashboards.module (1 entries) ---
24
+ const loadComponentStudioDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/component-studio-dashboards.module'));
25
+ // --- @memberjunction/ng-dashboards → ./core-dashboards.module (11 entries) ---
26
+ const loadCoreDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/core-dashboards.module'));
27
+ // --- @memberjunction/ng-dashboards → ./credentials-dashboards.module (6 entries) ---
28
+ const loadCredentialsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/credentials-dashboards.module'));
29
+ // --- @memberjunction/ng-dashboards → ./data-explorer-dashboards.module (2 entries) ---
30
+ const loadDataExplorerDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/data-explorer-dashboards.module'));
31
+ // --- @memberjunction/ng-dashboards → ./integration.module (6 entries) ---
32
+ const loadIntegrationModule = featureLoader(() => import('@memberjunction/ng-dashboards/integration.module'));
33
+ // --- @memberjunction/ng-dashboards → ./lists-dashboards.module (4 entries) ---
34
+ const loadListsDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/lists-dashboards.module'));
35
+ // --- @memberjunction/ng-dashboards → ./mcp.module (2 entries) ---
36
+ const loadMcpModule = featureLoader(() => import('@memberjunction/ng-dashboards/mcp.module'));
37
+ // --- @memberjunction/ng-dashboards → ./scheduling-dashboards.module (4 entries) ---
38
+ const loadSchedulingDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/scheduling-dashboards.module'));
39
+ // --- @memberjunction/ng-dashboards → ./testing-dashboards.module (6 entries) ---
40
+ const loadTestingDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/testing-dashboards.module'));
41
+ // --- @memberjunction/ng-explorer-settings → ./settings.module (6 entries) ---
42
+ const loadSettingsModule = featureLoader(() => import('@memberjunction/ng-explorer-settings/settings.module'));
43
+ // --- @memberjunction/ng-file-storage → ./file-storage.module (1 entries) ---
44
+ const loadFileStorageModule = featureLoader(() => import('@memberjunction/ng-file-storage/file-storage.module'));
45
+ // --- @memberjunction/ng-react → . (1 entries) ---
46
+ const loadNgReact = featureLoader(() => import('@memberjunction/ng-react'));
47
+ /**
48
+ * Complete mapping of compound keys (BaseClassName::Key) to lazy-loading functions.
49
+ * Covers all @RegisterClass decorated classes in lazy-loaded packages.
50
+ */
51
+ export const LAZY_FEATURE_CONFIG = {
52
+ // @memberjunction/ng-dashboards → ./actions-dashboards.module
53
+ 'BaseResourceComponent::ActionExplorerResource': loadActionsDashboardsModule,
54
+ 'BaseResourceComponent::ActionsCodeResource': loadActionsDashboardsModule,
55
+ 'BaseResourceComponent::ActionsEntitiesResource': loadActionsDashboardsModule,
56
+ 'BaseResourceComponent::ActionsMonitorResource': loadActionsDashboardsModule,
57
+ 'BaseResourceComponent::ActionsOverviewResource': loadActionsDashboardsModule,
58
+ 'BaseResourceComponent::ActionsScheduleResource': loadActionsDashboardsModule,
59
+ 'BaseResourceComponent::ActionsSecurityResource': loadActionsDashboardsModule,
60
+ // @memberjunction/ng-dashboards → ./ai-dashboards.module
61
+ 'BaseResourceComponent::AIAgentRequestsResource': loadAiDashboardsModule,
62
+ 'BaseResourceComponent::AIAgentsResource': loadAiDashboardsModule,
63
+ 'BaseResourceComponent::AIConfigResource': loadAiDashboardsModule,
64
+ 'BaseResourceComponent::AIModelsResource': loadAiDashboardsModule,
65
+ 'BaseResourceComponent::AIMonitorResource': loadAiDashboardsModule,
66
+ 'BaseResourceComponent::AIPromptsResource': loadAiDashboardsModule,
67
+ 'BaseResourceComponent::AutotaggingPipelineResource': loadAiDashboardsModule,
68
+ 'BaseResourceComponent::ClusterVisualizationResource': loadAiDashboardsModule,
69
+ 'BaseResourceComponent::DuplicateDetectionResource': loadAiDashboardsModule,
70
+ 'BaseResourceComponent::KnowledgeConfigResource': loadAiDashboardsModule,
71
+ 'BaseResourceComponent::KnowledgeSearchResource': loadAiDashboardsModule,
72
+ 'BaseResourceComponent::VectorManagementResource': loadAiDashboardsModule,
73
+ // @memberjunction/ng-dashboards → ./communication-dashboards.module
74
+ 'BaseDashboard::CommunicationDashboard': loadCommunicationDashboardsModule,
75
+ 'BaseResourceComponent::CommunicationLogsResource': loadCommunicationDashboardsModule,
76
+ 'BaseResourceComponent::CommunicationMonitorResource': loadCommunicationDashboardsModule,
77
+ 'BaseResourceComponent::CommunicationProvidersResource': loadCommunicationDashboardsModule,
78
+ 'BaseResourceComponent::CommunicationRunsResource': loadCommunicationDashboardsModule,
79
+ 'BaseResourceComponent::CommunicationTemplatesResource': loadCommunicationDashboardsModule,
80
+ // @memberjunction/ng-dashboards → ./component-studio-dashboards.module
81
+ 'BaseDashboard::ComponentStudioDashboard': loadComponentStudioDashboardsModule,
82
+ // @memberjunction/ng-dashboards → ./core-dashboards.module
83
+ 'BaseApplication::HomeApplication': loadCoreDashboardsModule,
84
+ 'BaseDashboard::EntityAdmin': loadCoreDashboardsModule,
85
+ 'BaseResourceComponent::APIKeysResource': loadCoreDashboardsModule,
86
+ 'BaseResourceComponent::DashboardBrowserResource': loadCoreDashboardsModule,
87
+ 'BaseResourceComponent::HomeDashboard': loadCoreDashboardsModule,
88
+ 'BaseResourceComponent::QueryBrowserResource': loadCoreDashboardsModule,
89
+ 'BaseResourceComponent::SystemDiagnosticsResource': loadCoreDashboardsModule,
90
+ 'BaseResourceComponent::VersionHistoryDiffResource': loadCoreDashboardsModule,
91
+ 'BaseResourceComponent::VersionHistoryGraphResource': loadCoreDashboardsModule,
92
+ 'BaseResourceComponent::VersionHistoryLabelsResource': loadCoreDashboardsModule,
93
+ 'BaseResourceComponent::VersionHistoryRestoreResource': loadCoreDashboardsModule,
94
+ // @memberjunction/ng-dashboards → ./credentials-dashboards.module
95
+ 'BaseDashboard::CredentialsDashboard': loadCredentialsDashboardsModule,
96
+ 'BaseResourceComponent::CredentialsAuditResource': loadCredentialsDashboardsModule,
97
+ 'BaseResourceComponent::CredentialsCategoriesResource': loadCredentialsDashboardsModule,
98
+ 'BaseResourceComponent::CredentialsListResource': loadCredentialsDashboardsModule,
99
+ 'BaseResourceComponent::CredentialsOverviewResource': loadCredentialsDashboardsModule,
100
+ 'BaseResourceComponent::CredentialsTypesResource': loadCredentialsDashboardsModule,
101
+ // @memberjunction/ng-dashboards → ./data-explorer-dashboards.module
102
+ 'BaseDashboard::DataExplorer': loadDataExplorerDashboardsModule,
103
+ 'BaseResourceComponent::DataExplorerResource': loadDataExplorerDashboardsModule,
104
+ // @memberjunction/ng-dashboards → ./integration.module
105
+ 'BaseResourceComponent::IntegrationActivity': loadIntegrationModule,
106
+ 'BaseResourceComponent::IntegrationConnections': loadIntegrationModule,
107
+ 'BaseResourceComponent::IntegrationMappingWorkspace': loadIntegrationModule,
108
+ 'BaseResourceComponent::IntegrationOverview': loadIntegrationModule,
109
+ 'BaseResourceComponent::IntegrationPipelines': loadIntegrationModule,
110
+ 'BaseResourceComponent::IntegrationSchedules': loadIntegrationModule,
111
+ // @memberjunction/ng-dashboards → ./lists-dashboards.module
112
+ 'BaseResourceComponent::ListsBrowseResource': loadListsDashboardsModule,
113
+ 'BaseResourceComponent::ListsCategoriesResource': loadListsDashboardsModule,
114
+ 'BaseResourceComponent::ListsMyListsResource': loadListsDashboardsModule,
115
+ 'BaseResourceComponent::ListsOperationsResource': loadListsDashboardsModule,
116
+ // @memberjunction/ng-dashboards → ./mcp.module
117
+ 'BaseDashboard::MCPDashboard': loadMcpModule,
118
+ 'BaseResourceComponent::MCPResource': loadMcpModule,
119
+ // @memberjunction/ng-dashboards → ./scheduling-dashboards.module
120
+ 'BaseDashboard::SchedulingDashboard': loadSchedulingDashboardsModule,
121
+ 'BaseResourceComponent::SchedulingActivityResource': loadSchedulingDashboardsModule,
122
+ 'BaseResourceComponent::SchedulingDashboardResource': loadSchedulingDashboardsModule,
123
+ 'BaseResourceComponent::SchedulingJobsResource': loadSchedulingDashboardsModule,
124
+ // @memberjunction/ng-dashboards → ./testing-dashboards.module
125
+ 'BaseDashboard::TestingDashboard': loadTestingDashboardsModule,
126
+ 'BaseResourceComponent::TestingAnalyticsResource': loadTestingDashboardsModule,
127
+ 'BaseResourceComponent::TestingDashboardTabResource': loadTestingDashboardsModule,
128
+ 'BaseResourceComponent::TestingExplorerResource': loadTestingDashboardsModule,
129
+ 'BaseResourceComponent::TestingReviewResource': loadTestingDashboardsModule,
130
+ 'BaseResourceComponent::TestingRunsResource': loadTestingDashboardsModule,
131
+ // @memberjunction/ng-explorer-settings → ./settings.module
132
+ 'BaseDashboard::ApplicationManagement': loadSettingsModule,
133
+ 'BaseDashboard::EntityPermissions': loadSettingsModule,
134
+ 'BaseDashboard::RoleManagement': loadSettingsModule,
135
+ 'BaseDashboard::SqlLogging': loadSettingsModule,
136
+ 'BaseDashboard::UserManagement': loadSettingsModule,
137
+ 'BaseNavigationComponent::Settings': loadSettingsModule,
138
+ // @memberjunction/ng-file-storage → ./file-storage.module
139
+ 'BaseResourceComponent::FileBrowserResource': loadFileStorageModule,
140
+ // @memberjunction/ng-react → .
141
+ 'RuntimeUtilities::RuntimeUtilities': loadNgReact,
142
+ };
143
+ export const LAZY_FEATURE_CONFIG_COUNT = 75;
144
+ //# sourceMappingURL=lazy-feature-config.js.map
@@ -0,0 +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 (12 entries) ---\nconst loadAiDashboardsModule = featureLoader(() => import('@memberjunction/ng-dashboards/ai-dashboards.module'));\n\n// --- @memberjunction/ng-dashboards → ./communication-dashboards.module (6 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 (11 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 (4 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 → ./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::AIConfigResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIModelsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIMonitorResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AIPromptsResource': loadAiDashboardsModule,\n 'BaseResourceComponent::AutotaggingPipelineResource': loadAiDashboardsModule,\n 'BaseResourceComponent::ClusterVisualizationResource': loadAiDashboardsModule,\n 'BaseResourceComponent::DuplicateDetectionResource': loadAiDashboardsModule,\n 'BaseResourceComponent::KnowledgeConfigResource': loadAiDashboardsModule,\n 'BaseResourceComponent::KnowledgeSearchResource': 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::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::APIKeysResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::DashboardBrowserResource': loadCoreDashboardsModule,\n 'BaseResourceComponent::HomeDashboard': loadCoreDashboardsModule,\n 'BaseResourceComponent::QueryBrowserResource': 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\n // @memberjunction/ng-dashboards → ./mcp.module\n 'BaseDashboard::MCPDashboard': loadMcpModule,\n 'BaseResourceComponent::MCPResource': loadMcpModule,\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 = 75;\n"]}
@@ -21,6 +21,7 @@ export declare class CommandPaletteComponent implements OnInit, OnDestroy {
21
21
  private destroy$;
22
22
  SearchInput: ElementRef<HTMLInputElement>;
23
23
  AppSelected: EventEmitter<string>;
24
+ KnowledgeSearchRequested: EventEmitter<string>;
24
25
  IsOpen: boolean;
25
26
  SearchQuery: string;
26
27
  AllApps: BaseApplication[];
@@ -61,6 +62,10 @@ export declare class CommandPaletteComponent implements OnInit, OnDestroy {
61
62
  * Select an application and emit event for shell to handle navigation
62
63
  */
63
64
  SelectApp(app: BaseApplication): void;
65
+ /**
66
+ * Navigate to Knowledge Hub search with the current query.
67
+ */
68
+ SearchKnowledgeHub(): void;
64
69
  /**
65
70
  * Close the command palette
66
71
  */
@@ -69,11 +74,15 @@ export declare class CommandPaletteComponent implements OnInit, OnDestroy {
69
74
  * Handle keyboard navigation
70
75
  */
71
76
  HandleKeyDown(event: KeyboardEvent): void;
77
+ /**
78
+ * Get the maximum selectable index (apps + knowledge search action if query present)
79
+ */
80
+ private maxSelectableIndex;
72
81
  /**
73
82
  * Ensure selected item is visible in results list
74
83
  */
75
84
  private scrollToSelected;
76
85
  static ɵfac: i0.ɵɵFactoryDeclaration<CommandPaletteComponent, never>;
77
- static ɵcmp: i0.ɵɵComponentDeclaration<CommandPaletteComponent, "mj-command-palette", never, {}, { "AppSelected": "AppSelected"; }, never, never, false, never>;
86
+ static ɵcmp: i0.ɵɵComponentDeclaration<CommandPaletteComponent, "mj-command-palette", never, {}, { "AppSelected": "AppSelected"; "KnowledgeSearchRequested": "KnowledgeSearchRequested"; }, never, never, false, never>;
78
87
  }
79
88
  //# sourceMappingURL=command-palette.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command-palette.component.d.ts","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAa,UAAU,EAAgB,iBAAiB,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AAG3I,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE;;;;;;;;;;;GAWG;AACH,qBAMa,uBAAwB,YAAW,MAAM,EAAE,SAAS;IAc7D,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,GAAG;IAfb,OAAO,CAAC,QAAQ,CAAuB;IAEb,WAAW,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC3D,WAAW,uBAA8B;IAEnD,MAAM,UAAS;IACf,WAAW,SAAM;IACjB,OAAO,EAAE,eAAe,EAAE,CAAM;IAChC,YAAY,EAAE,eAAe,EAAE,CAAM;IACrC,aAAa,SAAK;IAClB,YAAY,UAAS;gBAGX,OAAO,EAAE,qBAAqB,EAC9B,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,iBAAiB;IAGhC,QAAQ,IAAI,IAAI;IAqBhB,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,OAAO,CAAC,MAAM;IAiBd;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAQrC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IAEH,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAqCzC;;OAEG;IACH,OAAO,CAAC,gBAAgB;yCAjNb,uBAAuB;2CAAvB,uBAAuB;CAyNnC"}
1
+ {"version":3,"file":"command-palette.component.d.ts","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAa,UAAU,EAAgB,iBAAiB,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AAG3I,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE;;;;;;;;;;;GAWG;AACH,qBAMa,uBAAwB,YAAW,MAAM,EAAE,SAAS;IAe7D,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,GAAG;IAhBb,OAAO,CAAC,QAAQ,CAAuB;IAEb,WAAW,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC3D,WAAW,uBAA8B;IACzC,wBAAwB,uBAA8B;IAEhE,MAAM,UAAS;IACf,WAAW,SAAM;IACjB,OAAO,EAAE,eAAe,EAAE,CAAM;IAChC,YAAY,EAAE,eAAe,EAAE,CAAM;IACrC,aAAa,SAAK;IAClB,YAAY,UAAS;gBAGX,OAAO,EAAE,qBAAqB,EAC9B,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,iBAAiB;IAGhC,QAAQ,IAAI,IAAI;IAqBhB,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,OAAO,CAAC,MAAM;IAiBd;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAQrC;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAO1B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IAEH,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAyCzC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;yCAxOb,uBAAuB;2CAAvB,uBAAuB;CAgPnC"}
@@ -47,18 +47,42 @@ function CommandPaletteComponent_Conditional_1_For_7_Template(rf, ctx) { if (rf
47
47
  i0.ɵɵconditional(app_r5.Description ? 5 : -1);
48
48
  } }
49
49
  function CommandPaletteComponent_Conditional_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
50
+ const _r7 = i0.ɵɵgetCurrentView();
51
+ i0.ɵɵelementStart(0, "div", 16)(1, "span", 17);
52
+ i0.ɵɵtext(2, "Knowledge Search");
53
+ i0.ɵɵelementEnd()();
54
+ i0.ɵɵelementStart(3, "div", 18);
55
+ i0.ɵɵlistener("click", function CommandPaletteComponent_Conditional_1_Conditional_8_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SearchKnowledgeHub()); });
56
+ i0.ɵɵelement(4, "i", 19);
57
+ i0.ɵɵelementStart(5, "div", 13)(6, "div", 14);
58
+ i0.ɵɵtext(7, "Search Knowledge Hub");
59
+ i0.ɵɵelementEnd();
60
+ i0.ɵɵelementStart(8, "div", 15);
61
+ i0.ɵɵtext(9);
62
+ i0.ɵɵelementEnd()();
63
+ i0.ɵɵelementStart(10, "kbd", 20);
64
+ i0.ɵɵtext(11, "Enter");
65
+ i0.ɵɵelementEnd()();
66
+ } if (rf & 2) {
67
+ const ctx_r1 = i0.ɵɵnextContext(2);
68
+ i0.ɵɵadvance(3);
69
+ i0.ɵɵclassProp("selected", ctx_r1.FilteredApps.length === ctx_r1.SelectedIndex);
70
+ i0.ɵɵadvance(6);
71
+ i0.ɵɵtextInterpolate1("Search \"", ctx_r1.SearchQuery, "\" across entities, documents, and content");
72
+ } }
73
+ function CommandPaletteComponent_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
50
74
  i0.ɵɵelementStart(0, "div", 9);
51
- i0.ɵɵelement(1, "i", 16);
52
- i0.ɵɵelementStart(2, "div", 17);
75
+ i0.ɵɵelement(1, "i", 21);
76
+ i0.ɵɵelementStart(2, "div", 22);
53
77
  i0.ɵɵtext(3, "No applications found");
54
78
  i0.ɵɵelementEnd();
55
- i0.ɵɵelementStart(4, "div", 18);
56
- i0.ɵɵtext(5, "Try a different search term");
79
+ i0.ɵɵelementStart(4, "div", 23);
80
+ i0.ɵɵtext(5, "Try a different search term or search the Knowledge Hub");
57
81
  i0.ɵɵelementEnd()();
58
82
  } }
59
- function CommandPaletteComponent_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
83
+ function CommandPaletteComponent_Conditional_1_Conditional_10_Template(rf, ctx) { if (rf & 1) {
60
84
  i0.ɵɵelementStart(0, "div", 10);
61
- i0.ɵɵelement(1, "mj-loading", 19);
85
+ i0.ɵɵelement(1, "mj-loading", 24);
62
86
  i0.ɵɵelementEnd();
63
87
  } if (rf & 2) {
64
88
  i0.ɵɵadvance();
@@ -74,9 +98,10 @@ function CommandPaletteComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
74
98
  i0.ɵɵelementEnd()();
75
99
  i0.ɵɵelementStart(5, "div", 7);
76
100
  i0.ɵɵrepeaterCreate(6, CommandPaletteComponent_Conditional_1_For_7_Template, 6, 9, "div", 8, i0.ɵɵrepeaterTrackByIdentity);
77
- i0.ɵɵconditionalCreate(8, CommandPaletteComponent_Conditional_1_Conditional_8_Template, 6, 0, "div", 9);
101
+ i0.ɵɵconditionalCreate(8, CommandPaletteComponent_Conditional_1_Conditional_8_Template, 12, 3);
102
+ i0.ɵɵconditionalCreate(9, CommandPaletteComponent_Conditional_1_Conditional_9_Template, 6, 0, "div", 9);
78
103
  i0.ɵɵelementEnd();
79
- i0.ɵɵconditionalCreate(9, CommandPaletteComponent_Conditional_1_Conditional_9_Template, 2, 1, "div", 10);
104
+ i0.ɵɵconditionalCreate(10, CommandPaletteComponent_Conditional_1_Conditional_10_Template, 2, 1, "div", 10);
80
105
  i0.ɵɵelementEnd();
81
106
  } if (rf & 2) {
82
107
  const ctx_r1 = i0.ɵɵnextContext();
@@ -85,9 +110,11 @@ function CommandPaletteComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
85
110
  i0.ɵɵadvance(3);
86
111
  i0.ɵɵrepeater(ctx_r1.FilteredApps);
87
112
  i0.ɵɵadvance(2);
88
- i0.ɵɵconditional(ctx_r1.FilteredApps.length === 0 && ctx_r1.SearchQuery ? 8 : -1);
113
+ i0.ɵɵconditional(ctx_r1.SearchQuery.trim().length > 0 ? 8 : -1);
114
+ i0.ɵɵadvance();
115
+ i0.ɵɵconditional(ctx_r1.FilteredApps.length === 0 && ctx_r1.SearchQuery ? 9 : -1);
89
116
  i0.ɵɵadvance();
90
- i0.ɵɵconditional(ctx_r1.IsNavigating ? 9 : -1);
117
+ i0.ɵɵconditional(ctx_r1.IsNavigating ? 10 : -1);
91
118
  } }
92
119
  /**
93
120
  * Command Palette Component
@@ -108,6 +135,7 @@ export class CommandPaletteComponent {
108
135
  destroy$ = new Subject();
109
136
  SearchInput;
110
137
  AppSelected = new EventEmitter();
138
+ KnowledgeSearchRequested = new EventEmitter();
111
139
  IsOpen = false;
112
140
  SearchQuery = '';
113
141
  AllApps = [];
@@ -241,6 +269,16 @@ export class CommandPaletteComponent {
241
269
  // Emit event for shell to handle navigation (same pattern as app-switcher)
242
270
  this.AppSelected.emit(app.ID);
243
271
  }
272
+ /**
273
+ * Navigate to Knowledge Hub search with the current query.
274
+ */
275
+ SearchKnowledgeHub() {
276
+ if (this.IsNavigating)
277
+ return;
278
+ const query = this.SearchQuery.trim();
279
+ this.service.Close();
280
+ this.KnowledgeSearchRequested.emit(query);
281
+ }
244
282
  /**
245
283
  * Close the command palette
246
284
  */
@@ -262,7 +300,8 @@ export class CommandPaletteComponent {
262
300
  switch (event.key) {
263
301
  case 'ArrowDown':
264
302
  event.preventDefault();
265
- this.SelectedIndex = Math.min(this.SelectedIndex + 1, this.FilteredApps.length - 1);
303
+ // Allow selecting up to FilteredApps.length (the Knowledge Hub action is at that index)
304
+ this.SelectedIndex = Math.min(this.SelectedIndex + 1, this.maxSelectableIndex());
266
305
  this.scrollToSelected();
267
306
  break;
268
307
  case 'ArrowUp':
@@ -272,9 +311,13 @@ export class CommandPaletteComponent {
272
311
  break;
273
312
  case 'Enter':
274
313
  event.preventDefault();
275
- if (this.FilteredApps[this.SelectedIndex]) {
314
+ if (this.SelectedIndex < this.FilteredApps.length && this.FilteredApps[this.SelectedIndex]) {
276
315
  this.SelectApp(this.FilteredApps[this.SelectedIndex]);
277
316
  }
317
+ else if (this.SearchQuery.trim().length > 0 && this.SelectedIndex === this.FilteredApps.length) {
318
+ // Knowledge Hub search action is selected
319
+ this.SearchKnowledgeHub();
320
+ }
278
321
  break;
279
322
  case 'Escape':
280
323
  event.preventDefault();
@@ -282,6 +325,13 @@ export class CommandPaletteComponent {
282
325
  break;
283
326
  }
284
327
  }
328
+ /**
329
+ * Get the maximum selectable index (apps + knowledge search action if query present)
330
+ */
331
+ maxSelectableIndex() {
332
+ const hasKnowledgeAction = this.SearchQuery.trim().length > 0;
333
+ return hasKnowledgeAction ? this.FilteredApps.length : this.FilteredApps.length - 1;
334
+ }
285
335
  /**
286
336
  * Ensure selected item is visible in results list
287
337
  */
@@ -301,23 +351,25 @@ export class CommandPaletteComponent {
301
351
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.SearchInput = _t.first);
302
352
  } }, hostBindings: function CommandPaletteComponent_HostBindings(rf, ctx) { if (rf & 1) {
303
353
  i0.ɵɵlistener("keydown", function CommandPaletteComponent_keydown_HostBindingHandler($event) { return ctx.HandleKeyDown($event); }, i0.ɵɵresolveDocument);
304
- } }, outputs: { AppSelected: "AppSelected" }, standalone: false, decls: 2, vars: 2, consts: [["searchInput", ""], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop"], ["role", "dialog", "aria-label", "Search applications", "aria-modal", "true", 1, "command-palette-modal"], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop", 3, "click"], [1, "search-container"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search applications...", "autocomplete", "off", "spellcheck", "false", "aria-label", "Search applications", 1, "search-input", 3, "ngModelChange", "input", "ngModel"], ["role", "listbox", "aria-label", "Application results", 1, "results-list"], ["role", "option", 1, "result-item", 3, "selected"], ["role", "status", "aria-live", "polite", 1, "empty-state"], ["role", "status", "aria-live", "assertive", "aria-label", "Navigating to application", 1, "loading-overlay"], ["role", "option", 1, "result-item", 3, "click"], ["aria-hidden", "true", 1, "result-icon"], [1, "result-info"], [1, "result-name"], [1, "result-description"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], ["size", "small", 3, "showText"]], template: function CommandPaletteComponent_Template(rf, ctx) { if (rf & 1) {
354
+ } }, outputs: { AppSelected: "AppSelected", KnowledgeSearchRequested: "KnowledgeSearchRequested" }, standalone: false, decls: 2, vars: 2, consts: [["searchInput", ""], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop"], ["role", "dialog", "aria-label", "Search applications", "aria-modal", "true", 1, "command-palette-modal"], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop", 3, "click"], [1, "search-container"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search applications...", "autocomplete", "off", "spellcheck", "false", "aria-label", "Search applications", 1, "search-input", 3, "ngModelChange", "input", "ngModel"], ["role", "listbox", "aria-label", "Application results", 1, "results-list"], ["role", "option", 1, "result-item", 3, "selected"], ["role", "status", "aria-live", "polite", 1, "empty-state"], ["role", "status", "aria-live", "assertive", "aria-label", "Navigating to application", 1, "loading-overlay"], ["role", "option", 1, "result-item", 3, "click"], ["aria-hidden", "true", 1, "result-icon"], [1, "result-info"], [1, "result-name"], [1, "result-description"], [1, "results-section-divider"], [1, "section-label"], ["role", "option", 1, "result-item", "result-item-action", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-brain", "result-icon", "result-icon-knowledge"], [1, "result-kbd"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], ["size", "small", 3, "showText"]], template: function CommandPaletteComponent_Template(rf, ctx) { if (rf & 1) {
305
355
  i0.ɵɵconditionalCreate(0, CommandPaletteComponent_Conditional_0_Template, 1, 0, "div", 1);
306
- i0.ɵɵconditionalCreate(1, CommandPaletteComponent_Conditional_1_Template, 10, 3, "div", 2);
356
+ i0.ɵɵconditionalCreate(1, CommandPaletteComponent_Conditional_1_Template, 11, 4, "div", 2);
307
357
  } if (rf & 2) {
308
358
  i0.ɵɵconditional(ctx.IsOpen ? 0 : -1);
309
359
  i0.ɵɵadvance();
310
360
  i0.ɵɵconditional(ctx.IsOpen ? 1 : -1);
311
- } }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent], styles: ["\n\n.command-palette-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease-out;\n}\n\n\n\n.command-palette-modal[_ngcontent-%COMP%] {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: _ngcontent-%COMP%_slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.search-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n\n.results-list[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item[_ngcontent-%COMP%]:hover, \n.result-item.selected[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.result-item.selected[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-text[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.empty-subtext[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease-out;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n\n\n@media (max-width: 768px) {\n .command-palette-modal[_ngcontent-%COMP%] {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .result-name[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .result-description[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n}"] });
361
+ } }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent], styles: ["\n\n.command-palette-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease-out;\n}\n\n\n\n.command-palette-modal[_ngcontent-%COMP%] {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: _ngcontent-%COMP%_slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.search-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n\n.results-list[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item[_ngcontent-%COMP%]:hover, \n.result-item.selected[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.result-item.selected[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.results-section-divider[_ngcontent-%COMP%] {\n padding: 6px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 4px;\n}\n\n.section-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.result-item-action[_ngcontent-%COMP%] {\n border-top: none;\n}\n\n.result-icon-knowledge[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.result-kbd[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-family: inherit;\n flex-shrink: 0;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-text[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.empty-subtext[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease-out;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n\n\n@media (max-width: 768px) {\n .command-palette-modal[_ngcontent-%COMP%] {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .result-name[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .result-description[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n}"] });
312
362
  }
313
363
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CommandPaletteComponent, [{
314
364
  type: Component,
315
- args: [{ standalone: false, selector: 'mj-command-palette', template: "<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <div class=\"empty-state\"\n role=\"status\"\n aria-live=\"polite\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <div class=\"empty-text\">No applications found</div>\n <div class=\"empty-subtext\">Try a different search term</div>\n </div>\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n", styles: ["/* Backdrop with blur effect */\n.command-palette-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Modal - centered, Notion-style */\n.command-palette-modal {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n/* Search Container */\n.search-container {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Results List */\n.results-list {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n/* Section Header (for \"Recent\") */\n.section-header {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Result Item */\n.result-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item:hover,\n.result-item.selected {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected {\n position: relative;\n}\n\n.result-item.selected::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-text {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.empty-subtext {\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n/* Loading Overlay */\n.loading-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Animations */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n/* Scrollbar Styling (Webkit browsers) */\n.results-list::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .command-palette-modal {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input {\n font-size: 14px;\n }\n\n .result-name {\n font-size: 13px;\n }\n\n .result-description {\n font-size: 11px;\n }\n}\n"] }]
365
+ args: [{ standalone: false, selector: 'mj-command-palette', template: "<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Search Knowledge Hub Action -->\n @if (SearchQuery.trim().length > 0) {\n <div class=\"results-section-divider\">\n <span class=\"section-label\">Knowledge Search</span>\n </div>\n <div\n class=\"result-item result-item-action\"\n [class.selected]=\"FilteredApps.length === SelectedIndex\"\n (click)=\"SearchKnowledgeHub()\"\n role=\"option\">\n <i class=\"fa-solid fa-brain result-icon result-icon-knowledge\" aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">Search Knowledge Hub</div>\n <div class=\"result-description\">Search \"{{ SearchQuery }}\" across entities, documents, and content</div>\n </div>\n <kbd class=\"result-kbd\">Enter</kbd>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <div class=\"empty-state\"\n role=\"status\"\n aria-live=\"polite\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <div class=\"empty-text\">No applications found</div>\n <div class=\"empty-subtext\">Try a different search term or search the Knowledge Hub</div>\n </div>\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n", styles: ["/* Backdrop with blur effect */\n.command-palette-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Modal - centered, Notion-style */\n.command-palette-modal {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n/* Search Container */\n.search-container {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Results List */\n.results-list {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n/* Section Header (for \"Recent\") */\n.section-header {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Result Item */\n.result-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item:hover,\n.result-item.selected {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected {\n position: relative;\n}\n\n.result-item.selected::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Knowledge Search Section */\n.results-section-divider {\n padding: 6px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 4px;\n}\n\n.section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.result-item-action {\n border-top: none;\n}\n\n.result-icon-knowledge {\n color: var(--mj-brand-primary);\n}\n\n.result-kbd {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-family: inherit;\n flex-shrink: 0;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-text {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n}\n\n.empty-subtext {\n font-size: 14px;\n color: var(--mj-text-disabled);\n}\n\n/* Loading Overlay */\n.loading-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Animations */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n/* Scrollbar Styling (Webkit browsers) */\n.results-list::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .command-palette-modal {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input {\n font-size: 14px;\n }\n\n .result-name {\n font-size: 13px;\n }\n\n .result-description {\n font-size: 11px;\n }\n}\n"] }]
316
366
  }], () => [{ type: i1.CommandPaletteService }, { type: i2.ApplicationManager }, { type: i0.ChangeDetectorRef }], { SearchInput: [{
317
367
  type: ViewChild,
318
368
  args: ['searchInput']
319
369
  }], AppSelected: [{
320
370
  type: Output
371
+ }], KnowledgeSearchRequested: [{
372
+ type: Output
321
373
  }], HandleKeyDown: [{
322
374
  type: HostListener,
323
375
  args: ['document:keydown', ['$event']]
@@ -1 +1 @@
1
- {"version":3,"file":"command-palette.component.js","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts","../../../src/lib/command-palette/command-palette.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ViewChild, ElementRef, HostListener, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { CommandPaletteService } from './command-palette.service';\n\n/**\n * Command Palette Component\n *\n * Provides a Notion-style command palette for quickly searching and navigating to applications.\n * Triggered by Cmd+K (Mac) or Ctrl+/ (Windows/Linux).\n *\n * Features:\n * - Fuzzy search with relevance scoring\n * - Keyboard navigation (arrow keys, enter, escape)\n * - Loading state during navigation\n * - Empty state with helpful message\n */\n@Component({\n standalone: false,\n selector: 'mj-command-palette',\n templateUrl: './command-palette.component.html',\n styleUrls: ['./command-palette.component.css']\n})\nexport class CommandPaletteComponent implements OnInit, OnDestroy {\n private destroy$ = new Subject<void>();\n\n @ViewChild('searchInput') SearchInput!: ElementRef<HTMLInputElement>;\n @Output() AppSelected = new EventEmitter<string>();\n\n IsOpen = false;\n SearchQuery = '';\n AllApps: BaseApplication[] = [];\n FilteredApps: BaseApplication[] = [];\n SelectedIndex = 0;\n IsNavigating = false;\n\n constructor(\n private service: CommandPaletteService,\n private appManager: ApplicationManager,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n // Subscribe to service's open/close state\n this.service.IsOpen.pipe(takeUntil(this.destroy$)).subscribe((isOpen) => {\n this.IsOpen = isOpen;\n\n if (isOpen) {\n this.onOpen();\n } else {\n this.onClose();\n }\n\n this.cdr.detectChanges();\n });\n\n // Subscribe to application changes\n this.appManager.AllApplications.pipe(takeUntil(this.destroy$)).subscribe((apps) => {\n this.AllApps = apps;\n this.filterAndSortApps();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Called when command palette opens\n */\n private onOpen(): void {\n // Reset state\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n\n // Filter apps (will show all initially)\n this.filterAndSortApps();\n\n // Focus search input after view updates\n setTimeout(() => {\n if (this.SearchInput) {\n this.SearchInput.nativeElement.focus();\n }\n }, 100);\n }\n\n /**\n * Called when command palette closes\n */\n private onClose(): void {\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n }\n\n /**\n * Handle search query change\n */\n OnSearchChange(): void {\n this.filterAndSortApps();\n this.SelectedIndex = 0; // Reset selection\n }\n\n /**\n * Filter and sort applications based on search query\n */\n private filterAndSortApps(): void {\n const query = this.SearchQuery.toLowerCase().trim();\n\n // If no query, show all apps\n if (!query) {\n this.FilteredApps = [...this.AllApps];\n return;\n }\n\n // Score all apps\n const scored = this.AllApps.map(app => ({\n app,\n score: this.calculateMatchScore(app, query)\n }));\n\n // Filter to only matches (score > 0)\n const matches = scored.filter(item => item.score > 0);\n\n // Sort by score (descending)\n matches.sort((a, b) => b.score - a.score);\n\n // Extract apps\n this.FilteredApps = matches.map(item => item.app);\n }\n\n /**\n * Calculate match score for fuzzy search\n *\n * Scoring:\n * - Exact match: 1000 points\n * - Starts with: 500 points\n * - Contains: 100 points\n * - Description match: 50 points\n * - Initials match: 25 points (e.g., \"de\" matches \"Data Explorer\")\n */\n private calculateMatchScore(app: BaseApplication, query: string): number {\n const name = app.Name.toLowerCase();\n const desc = (app.Description || '').toLowerCase();\n\n // Exact match (highest priority)\n if (name === query) return 1000;\n\n // Starts with query (very high priority)\n if (name.startsWith(query)) return 500;\n\n // Contains query in name (high priority)\n if (name.includes(query)) return 100;\n\n // Description match (medium priority)\n if (desc.includes(query)) return 50;\n\n // Fuzzy match - initials (e.g., \"de\" matches \"Data Explorer\")\n const initials = name\n .split(' ')\n .map(word => word[0] || '')\n .join('')\n .toLowerCase();\n if (initials.includes(query)) return 25;\n\n return 0; // No match\n }\n\n /**\n * Select an application and emit event for shell to handle navigation\n */\n SelectApp(app: BaseApplication): void {\n if (this.IsNavigating) return;\n // Close the palette first\n this.service.Close();\n // Emit event for shell to handle navigation (same pattern as app-switcher)\n this.AppSelected.emit(app.ID);\n }\n\n /**\n * Close the command palette\n */\n Close(): void {\n this.service.Close();\n }\n\n /**\n * Handle keyboard navigation\n */\n @HostListener('document:keydown', ['$event'])\n HandleKeyDown(event: KeyboardEvent): void {\n if (!this.IsOpen) return;\n\n // Skip if user is typing in input (except for navigation keys)\n const target = event.target as HTMLElement;\n const navigationKeys = ['Escape', 'Enter', 'ArrowUp', 'ArrowDown'];\n if (target.tagName === 'INPUT' && !navigationKeys.includes(event.key)) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.SelectedIndex = Math.min(this.SelectedIndex + 1, this.FilteredApps.length - 1);\n this.scrollToSelected();\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n this.SelectedIndex = Math.max(this.SelectedIndex - 1, 0);\n this.scrollToSelected();\n break;\n\n case 'Enter':\n event.preventDefault();\n if (this.FilteredApps[this.SelectedIndex]) {\n this.SelectApp(this.FilteredApps[this.SelectedIndex]);\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n this.service.Close();\n break;\n }\n }\n\n /**\n * Ensure selected item is visible in results list\n */\n private scrollToSelected(): void {\n setTimeout(() => {\n const selected = document.querySelector('.result-item.selected');\n if (selected) {\n selected.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }, 0);\n }\n}\n","<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <div class=\"empty-state\"\n role=\"status\"\n aria-live=\"polite\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <div class=\"empty-text\">No applications found</div>\n <div class=\"empty-subtext\">Try a different search term</div>\n </div>\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n"]}
1
+ {"version":3,"file":"command-palette.component.js","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts","../../../src/lib/command-palette/command-palette.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ViewChild, ElementRef, HostListener, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { CommandPaletteService } from './command-palette.service';\n\n/**\n * Command Palette Component\n *\n * Provides a Notion-style command palette for quickly searching and navigating to applications.\n * Triggered by Cmd+K (Mac) or Ctrl+/ (Windows/Linux).\n *\n * Features:\n * - Fuzzy search with relevance scoring\n * - Keyboard navigation (arrow keys, enter, escape)\n * - Loading state during navigation\n * - Empty state with helpful message\n */\n@Component({\n standalone: false,\n selector: 'mj-command-palette',\n templateUrl: './command-palette.component.html',\n styleUrls: ['./command-palette.component.css']\n})\nexport class CommandPaletteComponent implements OnInit, OnDestroy {\n private destroy$ = new Subject<void>();\n\n @ViewChild('searchInput') SearchInput!: ElementRef<HTMLInputElement>;\n @Output() AppSelected = new EventEmitter<string>();\n @Output() KnowledgeSearchRequested = new EventEmitter<string>();\n\n IsOpen = false;\n SearchQuery = '';\n AllApps: BaseApplication[] = [];\n FilteredApps: BaseApplication[] = [];\n SelectedIndex = 0;\n IsNavigating = false;\n\n constructor(\n private service: CommandPaletteService,\n private appManager: ApplicationManager,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n // Subscribe to service's open/close state\n this.service.IsOpen.pipe(takeUntil(this.destroy$)).subscribe((isOpen) => {\n this.IsOpen = isOpen;\n\n if (isOpen) {\n this.onOpen();\n } else {\n this.onClose();\n }\n\n this.cdr.detectChanges();\n });\n\n // Subscribe to application changes\n this.appManager.AllApplications.pipe(takeUntil(this.destroy$)).subscribe((apps) => {\n this.AllApps = apps;\n this.filterAndSortApps();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Called when command palette opens\n */\n private onOpen(): void {\n // Reset state\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n\n // Filter apps (will show all initially)\n this.filterAndSortApps();\n\n // Focus search input after view updates\n setTimeout(() => {\n if (this.SearchInput) {\n this.SearchInput.nativeElement.focus();\n }\n }, 100);\n }\n\n /**\n * Called when command palette closes\n */\n private onClose(): void {\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n }\n\n /**\n * Handle search query change\n */\n OnSearchChange(): void {\n this.filterAndSortApps();\n this.SelectedIndex = 0; // Reset selection\n }\n\n /**\n * Filter and sort applications based on search query\n */\n private filterAndSortApps(): void {\n const query = this.SearchQuery.toLowerCase().trim();\n\n // If no query, show all apps\n if (!query) {\n this.FilteredApps = [...this.AllApps];\n return;\n }\n\n // Score all apps\n const scored = this.AllApps.map(app => ({\n app,\n score: this.calculateMatchScore(app, query)\n }));\n\n // Filter to only matches (score > 0)\n const matches = scored.filter(item => item.score > 0);\n\n // Sort by score (descending)\n matches.sort((a, b) => b.score - a.score);\n\n // Extract apps\n this.FilteredApps = matches.map(item => item.app);\n }\n\n /**\n * Calculate match score for fuzzy search\n *\n * Scoring:\n * - Exact match: 1000 points\n * - Starts with: 500 points\n * - Contains: 100 points\n * - Description match: 50 points\n * - Initials match: 25 points (e.g., \"de\" matches \"Data Explorer\")\n */\n private calculateMatchScore(app: BaseApplication, query: string): number {\n const name = app.Name.toLowerCase();\n const desc = (app.Description || '').toLowerCase();\n\n // Exact match (highest priority)\n if (name === query) return 1000;\n\n // Starts with query (very high priority)\n if (name.startsWith(query)) return 500;\n\n // Contains query in name (high priority)\n if (name.includes(query)) return 100;\n\n // Description match (medium priority)\n if (desc.includes(query)) return 50;\n\n // Fuzzy match - initials (e.g., \"de\" matches \"Data Explorer\")\n const initials = name\n .split(' ')\n .map(word => word[0] || '')\n .join('')\n .toLowerCase();\n if (initials.includes(query)) return 25;\n\n return 0; // No match\n }\n\n /**\n * Select an application and emit event for shell to handle navigation\n */\n SelectApp(app: BaseApplication): void {\n if (this.IsNavigating) return;\n // Close the palette first\n this.service.Close();\n // Emit event for shell to handle navigation (same pattern as app-switcher)\n this.AppSelected.emit(app.ID);\n }\n\n /**\n * Navigate to Knowledge Hub search with the current query.\n */\n SearchKnowledgeHub(): void {\n if (this.IsNavigating) return;\n const query = this.SearchQuery.trim();\n this.service.Close();\n this.KnowledgeSearchRequested.emit(query);\n }\n\n /**\n * Close the command palette\n */\n Close(): void {\n this.service.Close();\n }\n\n /**\n * Handle keyboard navigation\n */\n @HostListener('document:keydown', ['$event'])\n HandleKeyDown(event: KeyboardEvent): void {\n if (!this.IsOpen) return;\n\n // Skip if user is typing in input (except for navigation keys)\n const target = event.target as HTMLElement;\n const navigationKeys = ['Escape', 'Enter', 'ArrowUp', 'ArrowDown'];\n if (target.tagName === 'INPUT' && !navigationKeys.includes(event.key)) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n // Allow selecting up to FilteredApps.length (the Knowledge Hub action is at that index)\n this.SelectedIndex = Math.min(this.SelectedIndex + 1, this.maxSelectableIndex());\n this.scrollToSelected();\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n this.SelectedIndex = Math.max(this.SelectedIndex - 1, 0);\n this.scrollToSelected();\n break;\n\n case 'Enter':\n event.preventDefault();\n if (this.SelectedIndex < this.FilteredApps.length && this.FilteredApps[this.SelectedIndex]) {\n this.SelectApp(this.FilteredApps[this.SelectedIndex]);\n } else if (this.SearchQuery.trim().length > 0 && this.SelectedIndex === this.FilteredApps.length) {\n // Knowledge Hub search action is selected\n this.SearchKnowledgeHub();\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n this.service.Close();\n break;\n }\n }\n\n /**\n * Get the maximum selectable index (apps + knowledge search action if query present)\n */\n private maxSelectableIndex(): number {\n const hasKnowledgeAction = this.SearchQuery.trim().length > 0;\n return hasKnowledgeAction ? this.FilteredApps.length : this.FilteredApps.length - 1;\n }\n\n /**\n * Ensure selected item is visible in results list\n */\n private scrollToSelected(): void {\n setTimeout(() => {\n const selected = document.querySelector('.result-item.selected');\n if (selected) {\n selected.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }, 0);\n }\n}\n","<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Search Knowledge Hub Action -->\n @if (SearchQuery.trim().length > 0) {\n <div class=\"results-section-divider\">\n <span class=\"section-label\">Knowledge Search</span>\n </div>\n <div\n class=\"result-item result-item-action\"\n [class.selected]=\"FilteredApps.length === SelectedIndex\"\n (click)=\"SearchKnowledgeHub()\"\n role=\"option\">\n <i class=\"fa-solid fa-brain result-icon result-icon-knowledge\" aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">Search Knowledge Hub</div>\n <div class=\"result-description\">Search \"{{ SearchQuery }}\" across entities, documents, and content</div>\n </div>\n <kbd class=\"result-kbd\">Enter</kbd>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <div class=\"empty-state\"\n role=\"status\"\n aria-live=\"polite\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <div class=\"empty-text\">No applications found</div>\n <div class=\"empty-subtext\">Try a different search term or search the Knowledge Hub</div>\n </div>\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n"]}