@memberjunction/ng-dashboards 5.23.0 → 5.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/agents/agent-configuration.component.d.ts +15 -33
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +233 -493
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts +2 -2
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +7 -7
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +717 -8
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +7166 -1889
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +50 -4
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +759 -491
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.d.ts +4 -5
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +14 -15
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.d.ts +4 -4
- package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
- package/dist/AI/components/models/model-management.component.js +5 -5
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.d.ts +4 -4
- package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +5 -5
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts +2 -1
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.js +1 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.d.ts +2 -3
- package/dist/AI/components/system/system-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +9 -11
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +62 -7
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +825 -359
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.d.ts +2 -1
- package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +2 -0
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.d.ts +4 -5
- package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +11 -12
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/code-management.component.d.ts +2 -3
- package/dist/Actions/components/code-management.component.d.ts.map +1 -1
- package/dist/Actions/components/code-management.component.js +4 -6
- package/dist/Actions/components/code-management.component.js.map +1 -1
- package/dist/Actions/components/entity-integration.component.d.ts +2 -3
- package/dist/Actions/components/entity-integration.component.d.ts.map +1 -1
- package/dist/Actions/components/entity-integration.component.js +4 -6
- package/dist/Actions/components/entity-integration.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.d.ts +4 -5
- package/dist/Actions/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +10 -11
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +13 -12
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +39 -66
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.d.ts +2 -3
- package/dist/Actions/components/scheduled-actions.component.d.ts.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +4 -6
- package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
- package/dist/Actions/components/security-permissions.component.d.ts +2 -3
- package/dist/Actions/components/security-permissions.component.d.ts.map +1 -1
- package/dist/Actions/components/security-permissions.component.js +4 -6
- package/dist/Actions/components/security-permissions.component.js.map +1 -1
- package/dist/ApplicationRoles/application-roles-resource.component.d.ts +112 -0
- package/dist/ApplicationRoles/application-roles-resource.component.d.ts.map +1 -0
- package/dist/ApplicationRoles/application-roles-resource.component.js +532 -0
- package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -0
- package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +1 -0
- package/dist/Communication/communication-dashboard.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +4 -1
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +4 -1
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +4 -1
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +4 -1
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +4 -1
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +2 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +2 -0
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts +2 -3
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +10 -11
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +2 -0
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts +4 -4
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +8 -9
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts +2 -3
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +11 -12
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.d.ts.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +1 -0
- package/dist/Credentials/credentials-dashboard.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +2 -3
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +9 -10
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +23 -15
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +167 -213
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +68 -32
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +470 -437
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts +10 -3
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +35 -11
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DataExplorer/models/explorer-state.interface.d.ts +12 -3
- package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
- package/dist/DataExplorer/models/explorer-state.interface.js +5 -1
- package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts +4 -4
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +4 -5
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +2 -0
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +3 -0
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +2 -0
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +3 -0
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +3 -0
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +3 -0
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +412 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4267 -0
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +39 -4
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +187 -13
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +13 -2
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +329 -224
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +76 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +602 -0
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/index.d.ts +2 -1
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +2 -1
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +2 -0
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +2 -0
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -0
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts +2 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +2 -0
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.d.ts +7 -28
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +25 -107
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
- package/dist/MCP/mcp-resource.component.js +1 -0
- package/dist/MCP/mcp-resource.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +10 -23
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +41 -103
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.js +1 -0
- package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -0
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.js +1 -0
- package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +1 -0
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +4 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +9 -10
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.js +2 -0
- package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +2 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +2 -0
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.js +2 -0
- package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review-resource.component.js +2 -0
- package/dist/Testing/components/testing-review-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts +2 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +2 -0
- package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.d.ts +2 -1
- package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +1 -0
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.d.ts +4 -4
- package/dist/VersionHistory/components/diff-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.js +9 -10
- package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts +2 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +2 -0
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.d.ts +4 -4
- package/dist/VersionHistory/components/labels-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +10 -11
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.d.ts +2 -1
- package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +2 -0
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/__tests__/analytics-resource.test.d.ts +2 -0
- package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
- package/dist/__tests__/analytics-resource.test.js +181 -0
- package/dist/__tests__/analytics-resource.test.js.map +1 -0
- package/dist/__tests__/scheduling.test.d.ts +2 -0
- package/dist/__tests__/scheduling.test.d.ts.map +1 -0
- package/dist/__tests__/scheduling.test.js +205 -0
- package/dist/__tests__/scheduling.test.js.map +1 -0
- package/dist/ai-dashboards.module.d.ts +22 -18
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +29 -10
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +19 -18
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +8 -0
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +2 -1
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +7 -3
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +2 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -1
- package/dist/public-api.js.map +1 -1
- package/dist/shared/entity-field-display.d.ts +44 -0
- package/dist/shared/entity-field-display.d.ts.map +1 -0
- package/dist/shared/entity-field-display.js +118 -0
- package/dist/shared/entity-field-display.js.map +1 -0
- package/package.json +47 -46
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +0 -85
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +0 -1
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +0 -461
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +0 -1
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* Registered as BaseResourceComponent for the Knowledge Hub application.
|
|
11
11
|
*/
|
|
12
12
|
import { OnDestroy, AfterViewInit } from '@angular/core';
|
|
13
|
+
import { Subject } from 'rxjs';
|
|
13
14
|
import { ResourceData } from '@memberjunction/core-entities';
|
|
14
|
-
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
15
|
+
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
|
|
15
16
|
import { ClusterConfig, ClusterConfigPanelEntityOption, ClusterConfigPanelEntityDocOption, ClusterVisualizationResult, ClusterMetrics, ClusterPoint, ClusterLabel, SavedClusterVisualization } from '@memberjunction/ng-clustering';
|
|
16
17
|
import { ClusterScatterComponent } from '@memberjunction/ng-clustering';
|
|
17
18
|
import * as i0 from "@angular/core";
|
|
@@ -19,8 +20,8 @@ export declare class ClusterVisualizationResourceComponent extends BaseResourceC
|
|
|
19
20
|
scatterPlot?: ClusterScatterComponent;
|
|
20
21
|
private cdr;
|
|
21
22
|
private clusteringService;
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
protected navigationService: NavigationService;
|
|
24
|
+
protected destroy$: Subject<void>;
|
|
24
25
|
/** LLM-generated cluster labels for the current result */
|
|
25
26
|
ClusterLabels: ClusterLabel[];
|
|
26
27
|
GetResourceDisplayName(_data: ResourceData): Promise<string>;
|
|
@@ -37,6 +38,10 @@ export declare class ClusterVisualizationResourceComponent extends BaseResourceC
|
|
|
37
38
|
EntityOptions: ClusterConfigPanelEntityOption[];
|
|
38
39
|
/** Entity document options for the selected entity (shown when 2+) */
|
|
39
40
|
EntityDocOptions: ClusterConfigPanelEntityDocOption[];
|
|
41
|
+
/** Ordered field keys for prioritized display in scatter tooltip/detail */
|
|
42
|
+
FieldPriority: string[];
|
|
43
|
+
/** Map of field names to human-readable display names */
|
|
44
|
+
FieldDisplayNames: Record<string, string>;
|
|
40
45
|
SavedVisualizations: SavedClusterVisualization[];
|
|
41
46
|
ActiveSavedId: string | null;
|
|
42
47
|
private userSettingEntity;
|
|
@@ -78,7 +83,11 @@ export declare class ClusterVisualizationResourceComponent extends BaseResourceC
|
|
|
78
83
|
private fetchVectorsForEntity;
|
|
79
84
|
/** Parse the JSON metadata string from the vector DB into a record */
|
|
80
85
|
private parseVectorMetadata;
|
|
81
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* Build a human-readable label from vector metadata using entity field metadata.
|
|
88
|
+
* Combines all IsNameField fields in Sequence order (e.g., "Sarah Chen" from FirstName + LastName).
|
|
89
|
+
* Falls back to heuristic field detection when entity metadata isn't available.
|
|
90
|
+
*/
|
|
82
91
|
private buildLabel;
|
|
83
92
|
/**
|
|
84
93
|
* After clustering completes, send sample records per cluster to an LLM for naming.
|
|
@@ -87,6 +96,22 @@ export declare class ClusterVisualizationResourceComponent extends BaseResourceC
|
|
|
87
96
|
private requestClusterLabelsFromLLM;
|
|
88
97
|
/** Build a text block describing sample records per cluster for the LLM prompt */
|
|
89
98
|
private buildClusterDataForPrompt;
|
|
99
|
+
/**
|
|
100
|
+
* Handle inline label edits from the scatter component legend.
|
|
101
|
+
* Updates the ClusterLabels cache and marks the label as user-edited.
|
|
102
|
+
*/
|
|
103
|
+
OnLabelEdited(event: {
|
|
104
|
+
ClusterId: number;
|
|
105
|
+
OldLabel: string;
|
|
106
|
+
NewLabel: string;
|
|
107
|
+
}): void;
|
|
108
|
+
/**
|
|
109
|
+
* Compute the prioritized field order and display names from entity metadata.
|
|
110
|
+
* Sets both FieldPriority and FieldDisplayNames.
|
|
111
|
+
* Returns field names sorted: IsNameField first, then DefaultInView by Sequence,
|
|
112
|
+
* then remaining fields by Sequence.
|
|
113
|
+
*/
|
|
114
|
+
private ComputeFieldPriority;
|
|
90
115
|
/** Apply cluster labels to the result's Clusters array (sets the Label property) */
|
|
91
116
|
private applyLabelsToResult;
|
|
92
117
|
/**
|
|
@@ -96,6 +121,16 @@ export declare class ClusterVisualizationResourceComponent extends BaseResourceC
|
|
|
96
121
|
private stripVectorsFromResult;
|
|
97
122
|
/** Load saved visualizations from UserInfoEngine settings */
|
|
98
123
|
private loadSavedVisualizations;
|
|
124
|
+
/**
|
|
125
|
+
* Auto-save the current session to localStorage so it can be restored
|
|
126
|
+
* when the user navigates away and comes back.
|
|
127
|
+
*/
|
|
128
|
+
private saveLastSession;
|
|
129
|
+
/**
|
|
130
|
+
* Restore the last session from localStorage if no saved visualization is active.
|
|
131
|
+
* This handles the "navigate away and come back" case.
|
|
132
|
+
*/
|
|
133
|
+
private restoreLastSession;
|
|
99
134
|
/** Persist saved visualizations to UserInfoEngine settings */
|
|
100
135
|
private persistSavedVisualizations;
|
|
101
136
|
static ɵfac: i0.ɵɵFactoryDeclaration<ClusterVisualizationResourceComponent, never>;
|
package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster-visualization-resource.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/clusters/cluster-visualization-resource.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAgC,SAAS,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"cluster-visualization-resource.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/clusters/cluster-visualization-resource.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAgC,SAAS,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAC1G,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAmE,MAAM,+BAA+B,CAAC;AAE9H,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGrF,OAAO,EACH,aAAa,EACb,8BAA8B,EAC9B,iCAAiC,EAEjC,0BAA0B,EAC1B,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,yBAAyB,EAG5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAqB,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;;AAsB3F,qBAOa,qCAAsC,SAAQ,qBAAsB,YAAW,aAAa,EAAE,SAAS;IACtF,WAAW,CAAC,EAAE,uBAAuB,CAAC;IAEhE,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,iBAAiB,CAA6B;IACtD,UAAmB,iBAAiB,oBAA6B;IACjE,UAAmB,QAAQ,gBAAuB;IAElD,0DAA0D;IACnD,aAAa,EAAE,YAAY,EAAE,CAAM;IAMpC,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAQhE,mCAAmC;IAC5B,MAAM,EAAE,0BAA0B,GAAG,IAAI,CAAQ;IACxD,8CAA8C;IACvC,SAAS,UAAS;IACzB,gCAAgC;IACzB,YAAY,EAAE,aAAa,CAA0B;IAC5D,4BAA4B;IACrB,kBAAkB,SAA0B;IACnD,mDAAmD;IAC5C,aAAa,EAAE,8BAA8B,EAAE,CAAM;IAC5D,sEAAsE;IAC/D,gBAAgB,EAAE,iCAAiC,EAAE,CAAM;IAClE,2EAA2E;IACpE,aAAa,EAAE,MAAM,EAAE,CAAM;IACpC,yDAAyD;IAClD,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAG/C,mBAAmB,EAAE,yBAAyB,EAAE,CAAM;IACtD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG3C,OAAO,CAAC,iBAAiB,CAAoC;IAMvD,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAatC,WAAW,IAAI,IAAI;IAUnB,IAAW,OAAO,IAAI,cAAc,GAAG,IAAI,CAE1C;IAED,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED,IAAW,wBAAwB,IAAI,MAAM,CAE5C;IAED,IAAW,gBAAgB,IAAI,OAAO,CAErC;IAED,IAAW,wBAAwB,IAAI,MAAM,CAG5C;IAMD,oDAAoD;IACvC,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAsClE,uCAAuC;IAChC,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAIjD,yBAAyB;IAClB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI;IAIxD,sFAAsF;IAC/E,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAU9C,qCAAqC;IACxB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBjD,uFAAuF;IAC1E,aAAa,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC3E,mCAAmC;IACtB,aAAa,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9F,2CAA2C;IACpC,aAAa,IAAI,IAAI;IAUrB,aAAa,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO;IAIxD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,GAAG,MAAM;IAItE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAYtC,gEAAgE;YAClD,iBAAiB;IAwB/B,sEAAsE;IACtE,OAAO,CAAC,sBAAsB;IAoB9B;;;;OAIG;YACW,qBAAqB;IA6CnC,sEAAsE;IACtE,OAAO,CAAC,mBAAmB;IAQ3B;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAoClB;;;OAGG;YACW,2BAA2B;IAoCzC,kFAAkF;IAClF,OAAO,CAAC,yBAAyB;IA0BjC;;;OAGG;IACI,aAAa,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAe5F;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA+B5B,oFAAoF;IACpF,OAAO,CAAC,mBAAmB;IAW3B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAU9B,6DAA6D;IAC7D,OAAO,CAAC,uBAAuB;IAgB/B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA+B1B,8DAA8D;YAChD,0BAA0B;yCAxnB/B,qCAAqC;2CAArC,qCAAqC;CAipBjD;AAED,8BAA8B;AAC9B,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD"}
|
|
@@ -29,7 +29,6 @@ import * as i0 from "@angular/core";
|
|
|
29
29
|
import * as i1 from "@memberjunction/ng-clustering";
|
|
30
30
|
const _c0 = ["scatterPlot"];
|
|
31
31
|
const _c1 = () => [];
|
|
32
|
-
const _c2 = () => ["Entity", "Name", "Description"];
|
|
33
32
|
function ClusterVisualizationResourceComponent_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
34
33
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
35
34
|
i0.ɵɵelementStart(0, "div", 16);
|
|
@@ -103,7 +102,25 @@ function ClusterVisualizationResourceComponent_Conditional_17_Template(rf, ctx)
|
|
|
103
102
|
i0.ɵɵadvance(5);
|
|
104
103
|
i0.ɵɵtextInterpolate(ctx_r3.ComputationTimeFormatted);
|
|
105
104
|
} }
|
|
106
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Build an environment-scoped storage key so cluster data does not bleed
|
|
107
|
+
* across different database environments that share the same browser.
|
|
108
|
+
* Uses the GraphQL endpoint origin as the environment fingerprint.
|
|
109
|
+
*/
|
|
110
|
+
function buildEnvScopedKey(base) {
|
|
111
|
+
try {
|
|
112
|
+
const origin = Metadata.Provider.ConfigData?.URL;
|
|
113
|
+
if (origin) {
|
|
114
|
+
// Use just the origin portion (protocol + host) so path differences don't fragment keys
|
|
115
|
+
const url = new URL(origin);
|
|
116
|
+
return `${base}_${url.origin}`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch { /* fall through */ }
|
|
120
|
+
return base;
|
|
121
|
+
}
|
|
122
|
+
const SAVED_CLUSTERS_BASE_KEY = 'KnowledgeHub_SavedClusters';
|
|
123
|
+
const LAST_SESSION_BASE_KEY = 'KnowledgeHub_LastClusterSession';
|
|
107
124
|
let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceComponent extends BaseResourceComponent {
|
|
108
125
|
scatterPlot;
|
|
109
126
|
cdr = inject(ChangeDetectorRef);
|
|
@@ -136,6 +153,10 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
136
153
|
EntityOptions = [];
|
|
137
154
|
/** Entity document options for the selected entity (shown when 2+) */
|
|
138
155
|
EntityDocOptions = [];
|
|
156
|
+
/** Ordered field keys for prioritized display in scatter tooltip/detail */
|
|
157
|
+
FieldPriority = [];
|
|
158
|
+
/** Map of field names to human-readable display names */
|
|
159
|
+
FieldDisplayNames = {};
|
|
139
160
|
// Saved visualizations
|
|
140
161
|
SavedVisualizations = [];
|
|
141
162
|
ActiveSavedId = null;
|
|
@@ -147,8 +168,17 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
147
168
|
async ngAfterViewInit() {
|
|
148
169
|
await this.loadEntityOptions();
|
|
149
170
|
this.loadSavedVisualizations();
|
|
171
|
+
this.restoreLastSession();
|
|
172
|
+
this.navigationService.SetAgentContext(this, {
|
|
173
|
+
IsVisualizationLoaded: !!this.Result,
|
|
174
|
+
VisualizationTitle: this.VisualizationTitle || null,
|
|
175
|
+
ClusterCount: this.Result?.Clusters?.length ?? 0,
|
|
176
|
+
TotalPoints: this.Result?.Points?.length ?? 0,
|
|
177
|
+
});
|
|
178
|
+
this.NotifyLoadComplete();
|
|
150
179
|
}
|
|
151
180
|
ngOnDestroy() {
|
|
181
|
+
super.ngOnDestroy();
|
|
152
182
|
this.destroy$.next();
|
|
153
183
|
this.destroy$.complete();
|
|
154
184
|
}
|
|
@@ -179,6 +209,8 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
179
209
|
this.IsRunning = true;
|
|
180
210
|
this.ActiveConfig = config;
|
|
181
211
|
this.ClusterLabels = [];
|
|
212
|
+
// Auto-hide detail panel from previous visualization
|
|
213
|
+
this.scatterPlot?.CloseDetailPanel();
|
|
182
214
|
// Update entity doc options if entity changed
|
|
183
215
|
this.updateEntityDocOptions(config.EntityName);
|
|
184
216
|
this.cdr.detectChanges();
|
|
@@ -188,9 +220,12 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
188
220
|
// Run clustering (client-side UMAP + K-Means/DBSCAN)
|
|
189
221
|
this.Result = await this.clusteringService.RunClustering(vectors, config);
|
|
190
222
|
this.VisualizationTitle = `${config.EntityName} — ${config.Algorithm === 'kmeans' ? 'K-Means' : 'DBSCAN'}`;
|
|
223
|
+
this.FieldPriority = this.ComputeFieldPriority(config.EntityName);
|
|
191
224
|
// Fire LLM cluster naming in the background (non-blocking).
|
|
192
225
|
// Clusters render immediately; labels appear when LLM responds.
|
|
193
226
|
this.requestClusterLabelsFromLLM().catch(err => console.warn('[ClusterVisualization] Background naming failed:', err));
|
|
227
|
+
// Auto-save session state so it can be restored after navigation
|
|
228
|
+
this.saveLastSession();
|
|
194
229
|
}
|
|
195
230
|
catch (error) {
|
|
196
231
|
console.error('[ClusterVisualization] Pipeline error:', error);
|
|
@@ -242,6 +277,7 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
242
277
|
}
|
|
243
278
|
/** Select a saved visualization — restore from cache if available, otherwise re-run */
|
|
244
279
|
async OnSelectSaved(saved) {
|
|
280
|
+
this.scatterPlot?.CloseDetailPanel();
|
|
245
281
|
this.ActiveSavedId = saved.Id;
|
|
246
282
|
this.VisualizationTitle = saved.Name;
|
|
247
283
|
// Reconstruct config
|
|
@@ -282,6 +318,7 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
282
318
|
}
|
|
283
319
|
/** Start a new analysis (clear current) */
|
|
284
320
|
OnNewAnalysis() {
|
|
321
|
+
this.scatterPlot?.CloseDetailPanel();
|
|
285
322
|
this.ActiveSavedId = null;
|
|
286
323
|
this.Result = null;
|
|
287
324
|
this.ClusterLabels = [];
|
|
@@ -399,10 +436,38 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
399
436
|
return {};
|
|
400
437
|
}
|
|
401
438
|
}
|
|
402
|
-
/**
|
|
439
|
+
/**
|
|
440
|
+
* Build a human-readable label from vector metadata using entity field metadata.
|
|
441
|
+
* Combines all IsNameField fields in Sequence order (e.g., "Sarah Chen" from FirstName + LastName).
|
|
442
|
+
* Falls back to heuristic field detection when entity metadata isn't available.
|
|
443
|
+
*/
|
|
403
444
|
buildLabel(metadata) {
|
|
404
|
-
|
|
405
|
-
|
|
445
|
+
const entityName = metadata['Entity'];
|
|
446
|
+
if (entityName) {
|
|
447
|
+
try {
|
|
448
|
+
const md = new Metadata();
|
|
449
|
+
const entityInfo = md.Entities.find(e => e.Name === entityName);
|
|
450
|
+
if (entityInfo) {
|
|
451
|
+
// Combine all IsNameField fields in Sequence order
|
|
452
|
+
const nameFields = entityInfo.Fields
|
|
453
|
+
.filter(f => f.IsNameField)
|
|
454
|
+
.sort((a, b) => (a.Sequence ?? 9999) - (b.Sequence ?? 9999));
|
|
455
|
+
if (nameFields.length > 0) {
|
|
456
|
+
const parts = nameFields
|
|
457
|
+
.map(f => metadata[f.Name])
|
|
458
|
+
.filter(v => v != null && v.trim() !== '');
|
|
459
|
+
if (parts.length > 0)
|
|
460
|
+
return parts.join(' ');
|
|
461
|
+
}
|
|
462
|
+
// Single NameField fallback
|
|
463
|
+
if (entityInfo.NameField && metadata[entityInfo.NameField.Name]) {
|
|
464
|
+
return metadata[entityInfo.NameField.Name];
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
catch { /* metadata not available, fall through */ }
|
|
469
|
+
}
|
|
470
|
+
// Heuristic fallbacks
|
|
406
471
|
return metadata['Name']
|
|
407
472
|
|| metadata['Title']
|
|
408
473
|
|| metadata['Description']?.substring(0, 60)
|
|
@@ -475,6 +540,62 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
475
540
|
}
|
|
476
541
|
return lines.join('\n');
|
|
477
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* Handle inline label edits from the scatter component legend.
|
|
545
|
+
* Updates the ClusterLabels cache and marks the label as user-edited.
|
|
546
|
+
*/
|
|
547
|
+
OnLabelEdited(event) {
|
|
548
|
+
const existing = this.ClusterLabels.find(l => l.ClusterId === event.ClusterId);
|
|
549
|
+
if (existing) {
|
|
550
|
+
existing.Label = event.NewLabel;
|
|
551
|
+
existing.IsUserEdited = true;
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
this.ClusterLabels.push({
|
|
555
|
+
ClusterId: event.ClusterId,
|
|
556
|
+
Label: event.NewLabel,
|
|
557
|
+
IsUserEdited: true,
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
this.cdr.detectChanges();
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Compute the prioritized field order and display names from entity metadata.
|
|
564
|
+
* Sets both FieldPriority and FieldDisplayNames.
|
|
565
|
+
* Returns field names sorted: IsNameField first, then DefaultInView by Sequence,
|
|
566
|
+
* then remaining fields by Sequence.
|
|
567
|
+
*/
|
|
568
|
+
ComputeFieldPriority(entityName) {
|
|
569
|
+
try {
|
|
570
|
+
const md = new Metadata();
|
|
571
|
+
const entityInfo = md.Entities.find(e => e.Name === entityName);
|
|
572
|
+
if (!entityInfo)
|
|
573
|
+
return [];
|
|
574
|
+
const internalKeys = new Set([
|
|
575
|
+
'ID', 'Entity', 'EntityIcon', 'RecordID', 'TemplateID',
|
|
576
|
+
'__mj_UpdatedAt', '__mj_CreatedAt',
|
|
577
|
+
]);
|
|
578
|
+
// Build display names map
|
|
579
|
+
const displayNames = {};
|
|
580
|
+
for (const f of entityInfo.Fields) {
|
|
581
|
+
displayNames[f.Name] = f.DisplayNameOrName;
|
|
582
|
+
}
|
|
583
|
+
this.FieldDisplayNames = displayNames;
|
|
584
|
+
return entityInfo.Fields
|
|
585
|
+
.filter(f => !internalKeys.has(f.Name) && !f.IsVirtual && !f.IsPrimaryKey)
|
|
586
|
+
.sort((a, b) => {
|
|
587
|
+
if (a.IsNameField !== b.IsNameField)
|
|
588
|
+
return a.IsNameField ? -1 : 1;
|
|
589
|
+
if (a.DefaultInView !== b.DefaultInView)
|
|
590
|
+
return a.DefaultInView ? -1 : 1;
|
|
591
|
+
return (a.Sequence ?? 9999) - (b.Sequence ?? 9999);
|
|
592
|
+
})
|
|
593
|
+
.map(f => f.Name);
|
|
594
|
+
}
|
|
595
|
+
catch {
|
|
596
|
+
return [];
|
|
597
|
+
}
|
|
598
|
+
}
|
|
478
599
|
/** Apply cluster labels to the result's Clusters array (sets the Label property) */
|
|
479
600
|
applyLabelsToResult() {
|
|
480
601
|
if (!this.Result || this.ClusterLabels.length === 0)
|
|
@@ -502,8 +623,9 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
502
623
|
/** Load saved visualizations from UserInfoEngine settings */
|
|
503
624
|
loadSavedVisualizations() {
|
|
504
625
|
try {
|
|
626
|
+
const key = buildEnvScopedKey(SAVED_CLUSTERS_BASE_KEY);
|
|
505
627
|
const engine = UserInfoEngine.Instance;
|
|
506
|
-
const setting = engine.UserSettings.find(s => s.Setting ===
|
|
628
|
+
const setting = engine.UserSettings.find(s => s.Setting === key);
|
|
507
629
|
if (setting?.Value) {
|
|
508
630
|
this.userSettingEntity = setting;
|
|
509
631
|
this.SavedVisualizations = JSON.parse(setting.Value);
|
|
@@ -515,6 +637,57 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
515
637
|
}
|
|
516
638
|
this.cdr.detectChanges();
|
|
517
639
|
}
|
|
640
|
+
/**
|
|
641
|
+
* Auto-save the current session to localStorage so it can be restored
|
|
642
|
+
* when the user navigates away and comes back.
|
|
643
|
+
*/
|
|
644
|
+
saveLastSession() {
|
|
645
|
+
if (!this.Result)
|
|
646
|
+
return;
|
|
647
|
+
try {
|
|
648
|
+
const session = {
|
|
649
|
+
Result: this.stripVectorsFromResult(this.Result),
|
|
650
|
+
ClusterLabels: this.ClusterLabels,
|
|
651
|
+
Config: this.ActiveConfig,
|
|
652
|
+
Title: this.VisualizationTitle,
|
|
653
|
+
Viewport: this.scatterPlot?.GetViewportTransform() ?? null,
|
|
654
|
+
};
|
|
655
|
+
localStorage.setItem(buildEnvScopedKey(LAST_SESSION_BASE_KEY), JSON.stringify(session));
|
|
656
|
+
}
|
|
657
|
+
catch {
|
|
658
|
+
// localStorage quota exceeded or not available — non-critical
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Restore the last session from localStorage if no saved visualization is active.
|
|
663
|
+
* This handles the "navigate away and come back" case.
|
|
664
|
+
*/
|
|
665
|
+
restoreLastSession() {
|
|
666
|
+
if (this.Result || this.ActiveSavedId)
|
|
667
|
+
return; // Already showing something
|
|
668
|
+
try {
|
|
669
|
+
const raw = localStorage.getItem(buildEnvScopedKey(LAST_SESSION_BASE_KEY));
|
|
670
|
+
if (!raw)
|
|
671
|
+
return;
|
|
672
|
+
const session = JSON.parse(raw);
|
|
673
|
+
this.Result = session.Result;
|
|
674
|
+
this.ClusterLabels = session.ClusterLabels ?? [];
|
|
675
|
+
this.ActiveConfig = session.Config;
|
|
676
|
+
this.VisualizationTitle = session.Title ?? 'Restored Session';
|
|
677
|
+
this.FieldPriority = this.ComputeFieldPriority(session.Config.EntityName);
|
|
678
|
+
this.applyLabelsToResult();
|
|
679
|
+
this.cdr.detectChanges();
|
|
680
|
+
// Restore viewport after a tick to let the scatter component render
|
|
681
|
+
if (session.Viewport) {
|
|
682
|
+
setTimeout(() => {
|
|
683
|
+
this.scatterPlot?.SetViewportTransform(session.Viewport);
|
|
684
|
+
}, 50);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
catch {
|
|
688
|
+
localStorage.removeItem(buildEnvScopedKey(LAST_SESSION_BASE_KEY));
|
|
689
|
+
}
|
|
690
|
+
}
|
|
518
691
|
/** Persist saved visualizations to UserInfoEngine settings */
|
|
519
692
|
async persistSavedVisualizations() {
|
|
520
693
|
try {
|
|
@@ -523,15 +696,16 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
523
696
|
if (!userId)
|
|
524
697
|
return;
|
|
525
698
|
if (!this.userSettingEntity) {
|
|
699
|
+
const key = buildEnvScopedKey(SAVED_CLUSTERS_BASE_KEY);
|
|
526
700
|
const engine = UserInfoEngine.Instance;
|
|
527
|
-
const existing = engine.UserSettings.find(s => s.Setting ===
|
|
701
|
+
const existing = engine.UserSettings.find(s => s.Setting === key);
|
|
528
702
|
if (existing) {
|
|
529
703
|
this.userSettingEntity = existing;
|
|
530
704
|
}
|
|
531
705
|
else {
|
|
532
706
|
this.userSettingEntity = await md.GetEntityObject('MJ: User Settings');
|
|
533
707
|
this.userSettingEntity.UserID = userId;
|
|
534
|
-
this.userSettingEntity.Setting =
|
|
708
|
+
this.userSettingEntity.Setting = buildEnvScopedKey(SAVED_CLUSTERS_BASE_KEY);
|
|
535
709
|
}
|
|
536
710
|
}
|
|
537
711
|
this.userSettingEntity.Value = JSON.stringify(this.SavedVisualizations);
|
|
@@ -547,7 +721,7 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
547
721
|
} if (rf & 2) {
|
|
548
722
|
let _t;
|
|
549
723
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scatterPlot = _t.first);
|
|
550
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 22, vars:
|
|
724
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 22, vars: 13, consts: [["scatterPlot", ""], [1, "cluster-viz-container"], [1, "sidebar"], [1, "sidebar-header"], [1, "fa-solid", "fa-circle-nodes"], [1, "saved-list"], [1, "saved-item", 3, "active"], [1, "no-saved"], [1, "new-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "main-area"], [1, "topbar"], [1, "topbar-title"], [1, "scatter-area"], [3, "PointClicked", "PointHovered", "OpenRecordRequested", "LabelEdited", "Points", "Clusters", "IsLoading", "EntityName"], [3, "RunClustering", "SaveVisualization", "IsRunning", "Metrics", "EntityOptions", "EntityDocOptions"], [1, "saved-item", 3, "click"], [1, "saved-name"], [1, "saved-meta"], ["title", "Delete", 1, "delete-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "fa-solid", "fa-bookmark"], [1, "metric"], [1, "fa-solid", "fa-circle-dot"], [1, "metric-value"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-chart-line"], [1, "fa-solid", "fa-clock"]], template: function ClusterVisualizationResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
551
725
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
552
726
|
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "h2");
|
|
553
727
|
i0.ɵɵelement(4, "i", 4);
|
|
@@ -568,7 +742,7 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
568
742
|
i0.ɵɵconditionalCreate(17, ClusterVisualizationResourceComponent_Conditional_17_Template, 20, 6);
|
|
569
743
|
i0.ɵɵelementEnd();
|
|
570
744
|
i0.ɵɵelementStart(18, "div", 13)(19, "mj-cluster-scatter", 14, 0);
|
|
571
|
-
i0.ɵɵlistener("PointClicked", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_PointClicked_19_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnPointClicked($event)); })("PointHovered", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_PointHovered_19_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnPointHovered($event)); })("OpenRecordRequested", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_OpenRecordRequested_19_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnOpenRecord($event)); });
|
|
745
|
+
i0.ɵɵlistener("PointClicked", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_PointClicked_19_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnPointClicked($event)); })("PointHovered", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_PointHovered_19_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnPointHovered($event)); })("OpenRecordRequested", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_OpenRecordRequested_19_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnOpenRecord($event)); })("LabelEdited", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_LabelEdited_19_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnLabelEdited($event)); });
|
|
572
746
|
i0.ɵɵelementEnd();
|
|
573
747
|
i0.ɵɵelementStart(21, "mj-cluster-config-panel", 15);
|
|
574
748
|
i0.ɵɵlistener("RunClustering", function ClusterVisualizationResourceComponent_Template_mj_cluster_config_panel_RunClustering_21_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnRunClustering($event)); })("SaveVisualization", function ClusterVisualizationResourceComponent_Template_mj_cluster_config_panel_SaveVisualization_21_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnSaveVisualization()); });
|
|
@@ -583,7 +757,7 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
583
757
|
i0.ɵɵadvance();
|
|
584
758
|
i0.ɵɵconditional(ctx.HasResult ? 17 : -1);
|
|
585
759
|
i0.ɵɵadvance(2);
|
|
586
|
-
i0.ɵɵproperty("Points", (ctx.Result == null ? null : ctx.Result.Points) ?? i0.ɵɵpureFunction0(11, _c1))("Clusters", (ctx.Result == null ? null : ctx.Result.Clusters) ?? i0.ɵɵpureFunction0(12, _c1))("IsLoading", ctx.IsRunning)("
|
|
760
|
+
i0.ɵɵproperty("Points", (ctx.Result == null ? null : ctx.Result.Points) ?? i0.ɵɵpureFunction0(11, _c1))("Clusters", (ctx.Result == null ? null : ctx.Result.Clusters) ?? i0.ɵɵpureFunction0(12, _c1))("IsLoading", ctx.IsRunning)("EntityName", ctx.ActiveConfig.EntityName);
|
|
587
761
|
i0.ɵɵadvance(2);
|
|
588
762
|
i0.ɵɵproperty("IsRunning", ctx.IsRunning)("Metrics", ctx.Metrics)("EntityOptions", ctx.EntityOptions)("EntityDocOptions", ctx.EntityDocOptions);
|
|
589
763
|
} }, dependencies: [i1.ClusterScatterComponent, i1.ClusterConfigPanelComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.cluster-viz-container[_ngcontent-%COMP%] {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n width: 260px;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.sidebar-header[_ngcontent-%COMP%] {\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.sidebar-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 0.95rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.sidebar-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.saved-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.saved-item[_ngcontent-%COMP%] {\n padding: 12px 14px;\n border-radius: 8px;\n cursor: pointer;\n margin-bottom: 4px;\n transition: background 0.15s;\n position: relative;\n}\n\n.saved-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.saved-item.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.saved-name[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n font-weight: 500;\n margin-bottom: 3px;\n color: var(--mj-text-primary);\n padding-right: 20px;\n}\n\n.saved-meta[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n display: flex;\n gap: 10px;\n}\n\n.delete-btn[_ngcontent-%COMP%] {\n position: absolute;\n top: 10px;\n right: 10px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 0.7rem;\n padding: 2px 4px;\n opacity: 0;\n transition: opacity 0.15s, color 0.15s;\n}\n\n.saved-item[_ngcontent-%COMP%]:hover .delete-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.delete-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n}\n\n.no-saved[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.no-saved[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n margin-bottom: 8px;\n opacity: 0.4;\n}\n\n.no-saved[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n margin: 0;\n}\n\n.new-btn[_ngcontent-%COMP%] {\n margin: 12px;\n padding: 10px;\n border: 1px dashed var(--mj-border-strong);\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.15s;\n}\n\n.new-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n\n.main-area[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n\n\n.topbar[_ngcontent-%COMP%] {\n height: 48px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 20px;\n gap: 24px;\n flex-shrink: 0;\n}\n\n.topbar-title[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n margin-right: auto;\n color: var(--mj-text-primary);\n}\n\n.metric[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.metric[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.metric-value.good[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n\n\n.scatter-area[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n}"] });
|
|
@@ -594,12 +768,12 @@ ClusterVisualizationResourceComponent = __decorate([
|
|
|
594
768
|
export { ClusterVisualizationResourceComponent };
|
|
595
769
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClusterVisualizationResourceComponent, [{
|
|
596
770
|
type: Component,
|
|
597
|
-
args: [{ standalone: false, selector: 'app-cluster-visualization-resource', template: "<div class=\"cluster-viz-container\">\n <!-- Left Sidebar: Saved Visualizations -->\n <div class=\"sidebar\">\n <div class=\"sidebar-header\">\n <h2><i class=\"fa-solid fa-circle-nodes\"></i> Saved Clusters</h2>\n </div>\n <div class=\"saved-list\">\n @for (saved of SavedVisualizations; track TrackSavedBy($index, saved)) {\n <div class=\"saved-item\"\n [class.active]=\"IsActiveSaved(saved)\"\n (click)=\"OnSelectSaved(saved)\">\n <div class=\"saved-name\">{{ saved.Name }}</div>\n <div class=\"saved-meta\">\n <span>{{ saved.EntityName }}</span>\n <span>{{ FormatDate(saved.CreatedAt) }}</span>\n </div>\n <button class=\"delete-btn\"\n title=\"Delete\"\n (click)=\"OnDeleteSaved(saved, $event)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n\n @if (SavedVisualizations.length === 0) {\n <div class=\"no-saved\">\n <i class=\"fa-solid fa-bookmark\"></i>\n <p>No saved visualizations yet</p>\n </div>\n }\n </div>\n <button class=\"new-btn\" (click)=\"OnNewAnalysis()\">\n <i class=\"fa-solid fa-plus\"></i> New Cluster Analysis\n </button>\n </div>\n\n <!-- Main Area -->\n <div class=\"main-area\">\n <!-- Top metrics bar -->\n <div class=\"topbar\">\n <div class=\"topbar-title\">{{ VisualizationTitle }}</div>\n @if (HasResult) {\n <div class=\"metric\">\n <i class=\"fa-solid fa-circle-dot\"></i>\n Records: <span class=\"metric-value\">{{ Result!.Metrics.RecordCount }}</span>\n </div>\n <div class=\"metric\">\n <i class=\"fa-solid fa-layer-group\"></i>\n Clusters: <span class=\"metric-value\">{{ Result!.Metrics.ClusterCount }}</span>\n </div>\n <div class=\"metric\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Silhouette:\n <span class=\"metric-value\" [class.good]=\"IsSilhouetteGood\">\n {{ SilhouetteScoreFormatted }}\n </span>\n </div>\n <div class=\"metric\">\n <i class=\"fa-solid fa-clock\"></i>\n Computed: <span class=\"metric-value\">{{ ComputationTimeFormatted }}</span>\n </div>\n }\n </div>\n\n <!-- Scatter plot area -->\n <div class=\"scatter-area\">\n <mj-cluster-scatter\n #scatterPlot\n [Points]=\"Result?.Points ?? []\"\n [Clusters]=\"Result?.Clusters ?? []\"\n [IsLoading]=\"IsRunning\"\n [
|
|
771
|
+
args: [{ standalone: false, selector: 'app-cluster-visualization-resource', template: "<div class=\"cluster-viz-container\">\n <!-- Left Sidebar: Saved Visualizations -->\n <div class=\"sidebar\">\n <div class=\"sidebar-header\">\n <h2><i class=\"fa-solid fa-circle-nodes\"></i> Saved Clusters</h2>\n </div>\n <div class=\"saved-list\">\n @for (saved of SavedVisualizations; track TrackSavedBy($index, saved)) {\n <div class=\"saved-item\"\n [class.active]=\"IsActiveSaved(saved)\"\n (click)=\"OnSelectSaved(saved)\">\n <div class=\"saved-name\">{{ saved.Name }}</div>\n <div class=\"saved-meta\">\n <span>{{ saved.EntityName }}</span>\n <span>{{ FormatDate(saved.CreatedAt) }}</span>\n </div>\n <button class=\"delete-btn\"\n title=\"Delete\"\n (click)=\"OnDeleteSaved(saved, $event)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n\n @if (SavedVisualizations.length === 0) {\n <div class=\"no-saved\">\n <i class=\"fa-solid fa-bookmark\"></i>\n <p>No saved visualizations yet</p>\n </div>\n }\n </div>\n <button class=\"new-btn\" (click)=\"OnNewAnalysis()\">\n <i class=\"fa-solid fa-plus\"></i> New Cluster Analysis\n </button>\n </div>\n\n <!-- Main Area -->\n <div class=\"main-area\">\n <!-- Top metrics bar -->\n <div class=\"topbar\">\n <div class=\"topbar-title\">{{ VisualizationTitle }}</div>\n @if (HasResult) {\n <div class=\"metric\">\n <i class=\"fa-solid fa-circle-dot\"></i>\n Records: <span class=\"metric-value\">{{ Result!.Metrics.RecordCount }}</span>\n </div>\n <div class=\"metric\">\n <i class=\"fa-solid fa-layer-group\"></i>\n Clusters: <span class=\"metric-value\">{{ Result!.Metrics.ClusterCount }}</span>\n </div>\n <div class=\"metric\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Silhouette:\n <span class=\"metric-value\" [class.good]=\"IsSilhouetteGood\">\n {{ SilhouetteScoreFormatted }}\n </span>\n </div>\n <div class=\"metric\">\n <i class=\"fa-solid fa-clock\"></i>\n Computed: <span class=\"metric-value\">{{ ComputationTimeFormatted }}</span>\n </div>\n }\n </div>\n\n <!-- Scatter plot area -->\n <div class=\"scatter-area\">\n <mj-cluster-scatter\n #scatterPlot\n [Points]=\"Result?.Points ?? []\"\n [Clusters]=\"Result?.Clusters ?? []\"\n [IsLoading]=\"IsRunning\"\n [EntityName]=\"ActiveConfig.EntityName\"\n (PointClicked)=\"OnPointClicked($event)\"\n (PointHovered)=\"OnPointHovered($event)\"\n (OpenRecordRequested)=\"OnOpenRecord($event)\"\n (LabelEdited)=\"OnLabelEdited($event)\">\n </mj-cluster-scatter>\n\n <!-- Floating config panel -->\n <mj-cluster-config-panel\n [IsRunning]=\"IsRunning\"\n [Metrics]=\"Metrics\"\n [EntityOptions]=\"EntityOptions\"\n [EntityDocOptions]=\"EntityDocOptions\"\n (RunClustering)=\"OnRunClustering($event)\"\n (SaveVisualization)=\"OnSaveVisualization()\">\n </mj-cluster-config-panel>\n </div>\n </div>\n</div>\n", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.cluster-viz-container {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n/* ============================================================\n Left Sidebar\n ============================================================ */\n\n.sidebar {\n width: 260px;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.sidebar-header {\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.sidebar-header h2 {\n font-size: 0.95rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.sidebar-header h2 i {\n color: var(--mj-brand-primary);\n}\n\n.saved-list {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n}\n\n.saved-item {\n padding: 12px 14px;\n border-radius: 8px;\n cursor: pointer;\n margin-bottom: 4px;\n transition: background 0.15s;\n position: relative;\n}\n\n.saved-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.saved-item.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.saved-name {\n font-size: 0.85rem;\n font-weight: 500;\n margin-bottom: 3px;\n color: var(--mj-text-primary);\n padding-right: 20px;\n}\n\n.saved-meta {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n display: flex;\n gap: 10px;\n}\n\n.delete-btn {\n position: absolute;\n top: 10px;\n right: 10px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 0.7rem;\n padding: 2px 4px;\n opacity: 0;\n transition: opacity 0.15s, color 0.15s;\n}\n\n.saved-item:hover .delete-btn {\n opacity: 1;\n}\n\n.delete-btn:hover {\n color: var(--mj-status-error);\n}\n\n.no-saved {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.no-saved i {\n font-size: 1.5rem;\n margin-bottom: 8px;\n opacity: 0.4;\n}\n\n.no-saved p {\n font-size: 0.8rem;\n margin: 0;\n}\n\n.new-btn {\n margin: 12px;\n padding: 10px;\n border: 1px dashed var(--mj-border-strong);\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.8rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.15s;\n}\n\n.new-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* ============================================================\n Main Area\n ============================================================ */\n\n.main-area {\n flex: 1;\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n/* Top bar */\n.topbar {\n height: 48px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 20px;\n gap: 24px;\n flex-shrink: 0;\n}\n\n.topbar-title {\n font-size: 0.9rem;\n font-weight: 600;\n margin-right: auto;\n color: var(--mj-text-primary);\n}\n\n.metric {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.metric i {\n font-size: 0.7rem;\n}\n\n.metric-value {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n.metric-value.good {\n color: var(--mj-status-success);\n}\n\n/* Scatter area */\n.scatter-area {\n flex: 1;\n position: relative;\n overflow: hidden;\n}\n"] }]
|
|
598
772
|
}], null, { scatterPlot: [{
|
|
599
773
|
type: ViewChild,
|
|
600
774
|
args: ['scatterPlot']
|
|
601
775
|
}] }); })();
|
|
602
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClusterVisualizationResourceComponent, { className: "ClusterVisualizationResourceComponent", filePath: "src/KnowledgeHub/components/clusters/cluster-visualization-resource.component.ts", lineNumber:
|
|
776
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClusterVisualizationResourceComponent, { className: "ClusterVisualizationResourceComponent", filePath: "src/KnowledgeHub/components/clusters/cluster-visualization-resource.component.ts", lineNumber: 63 }); })();
|
|
603
777
|
/** Tree-shaking prevention */
|
|
604
778
|
export function LoadClusterVisualizationResource() {
|
|
605
779
|
// Prevents tree-shaking of the component
|