@memberjunction/ng-dashboards 5.38.0 → 5.40.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/README.md +14 -7
- package/dist/AI/components/agents/agent-configuration.component.js +199 -198
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/ai-analytics-resource.component.js +20 -17
- package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +15 -0
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +166 -58
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +2 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +1 -0
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.js +55 -36
- package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +9 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +158 -117
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +1 -0
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +22 -8
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +217 -860
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1717 -7802
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +333 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +2125 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.format.d.ts +58 -0
- package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.format.js +260 -0
- package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.types.d.ts +319 -0
- package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
- package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +77 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.js +519 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +131 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +813 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +177 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1465 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +78 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js +492 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +56 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.js +271 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +306 -290
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +1 -1
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +209 -208
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +130 -128
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +17 -17
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +578 -538
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +331 -303
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
- package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.js +14 -2
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
- package/dist/AI/services/cache-metrics.d.ts +50 -0
- package/dist/AI/services/cache-metrics.d.ts.map +1 -0
- package/dist/AI/services/cache-metrics.js +43 -0
- package/dist/AI/services/cache-metrics.js.map +1 -0
- package/dist/APIKeys/api-applications-panel.component.js +2 -2
- package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
- package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
- package/dist/APIKeys/api-keys-resource.component.js +132 -131
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +141 -141
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +15 -15
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Admin/admin-data-schema.component.js +2 -2
- package/dist/Admin/admin-data-schema.component.js.map +1 -1
- package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
- package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
- package/dist/Admin/admin-identity-access.component.js +2 -2
- package/dist/Admin/admin-identity-access.component.js.map +1 -1
- package/dist/Admin/admin-monitoring.component.js +2 -2
- package/dist/Admin/admin-monitoring.component.js.map +1 -1
- package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
- package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +72 -50
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +103 -102
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +52 -51
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +39 -38
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
- package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +92 -89
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
- package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
- package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
- package/dist/DevTools/app-state-inspector.component.js +18 -17
- package/dist/DevTools/app-state-inspector.component.js.map +1 -1
- package/dist/DevTools/class-registry.component.js +88 -85
- package/dist/DevTools/class-registry.component.js.map +1 -1
- package/dist/DevTools/event-monitor.component.js +155 -150
- package/dist/DevTools/event-monitor.component.js.map +1 -1
- package/dist/DevTools/graphql-console.component.js +245 -243
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/DevTools/layout-inspector.component.js +18 -17
- package/dist/DevTools/layout-inspector.component.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +236 -229
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +390 -389
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +2 -2
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +14 -11
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -119
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/index.d.ts +3 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +3 -0
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +525 -566
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +135 -134
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/mcp-dashboard.component.js +443 -438
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
- package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +436 -427
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +1 -1
- package/dist/Testing/components/testing-runs.component.js +116 -115
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +6 -7
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +173 -172
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
- package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +116 -92
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +57 -35
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +80 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/communication-dashboards.module.d.ts +1 -1
- package/dist/communication-dashboards.module.d.ts.map +1 -1
- package/dist/communication-dashboards.module.js +7 -1
- package/dist/communication-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +12 -14
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +5 -14
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/dist/testing-dashboards.module.d.ts +4 -5
- package/dist/testing-dashboards.module.d.ts.map +1 -1
- package/dist/testing-dashboards.module.js +7 -5
- package/dist/testing-dashboards.module.js.map +1 -1
- package/package.json +57 -54
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
|
@@ -15,93 +15,176 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
15
15
|
*
|
|
16
16
|
* Registered as BaseResourceComponent for the Knowledge Hub application.
|
|
17
17
|
*/
|
|
18
|
-
import { Component, ChangeDetectorRef, inject, ViewChild } from '@angular/core';
|
|
18
|
+
import { Component, ChangeDetectorRef, inject, ViewChild, Input, Output, EventEmitter } from '@angular/core';
|
|
19
19
|
import { Subject } from 'rxjs';
|
|
20
20
|
import { CompositeKey, Metadata } from '@memberjunction/core';
|
|
21
21
|
import { UserInfoEngine, KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
|
|
22
22
|
import { RegisterClass } from '@memberjunction/global';
|
|
23
|
-
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
|
|
23
|
+
import { BaseResourceComponent, NavigationService, ActivityService } from '@memberjunction/ng-shared';
|
|
24
24
|
import { GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
|
|
25
25
|
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
26
26
|
import { DefaultClusterConfig, } from '@memberjunction/ng-clustering';
|
|
27
27
|
import { ClusteringService } from '@memberjunction/ng-clustering';
|
|
28
28
|
import * as i0 from "@angular/core";
|
|
29
|
-
import * as i1 from "@
|
|
30
|
-
import * as i2 from "@memberjunction/ng-
|
|
29
|
+
import * as i1 from "@angular/common";
|
|
30
|
+
import * as i2 from "@memberjunction/ng-ui-components";
|
|
31
|
+
import * as i3 from "@memberjunction/ng-clustering";
|
|
31
32
|
const _c0 = ["scatterPlot"];
|
|
32
33
|
const _c1 = () => [];
|
|
33
|
-
function
|
|
34
|
+
function ClusterVisualizationResourceComponent_Conditional_0_ng_container_0_Template(rf, ctx) { if (rf & 1) {
|
|
35
|
+
i0.ɵɵelementContainer(0);
|
|
36
|
+
} }
|
|
37
|
+
function ClusterVisualizationResourceComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
38
|
+
i0.ɵɵtemplate(0, ClusterVisualizationResourceComponent_Conditional_0_ng_container_0_Template, 1, 0, "ng-container", 2);
|
|
39
|
+
} if (rf & 2) {
|
|
40
|
+
i0.ɵɵnextContext();
|
|
41
|
+
const clusterBody_r1 = i0.ɵɵreference(3);
|
|
42
|
+
i0.ɵɵproperty("ngTemplateOutlet", clusterBody_r1);
|
|
43
|
+
} }
|
|
44
|
+
function ClusterVisualizationResourceComponent_Conditional_1_ng_container_8_Template(rf, ctx) { if (rf & 1) {
|
|
45
|
+
i0.ɵɵelementContainer(0);
|
|
46
|
+
} }
|
|
47
|
+
function ClusterVisualizationResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
34
48
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
35
|
-
i0.ɵɵelementStart(0, "div",
|
|
36
|
-
i0.ɵɵlistener("click", function
|
|
37
|
-
i0.ɵɵ
|
|
49
|
+
i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 3)(2, "div", 4)(3, "button", 5);
|
|
50
|
+
i0.ɵɵlistener("click", function ClusterVisualizationResourceComponent_Conditional_1_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnNewAnalysis()); });
|
|
51
|
+
i0.ɵɵelement(4, "i", 6);
|
|
52
|
+
i0.ɵɵelementStart(5, "span", 7);
|
|
53
|
+
i0.ɵɵtext(6, "New Analysis");
|
|
54
|
+
i0.ɵɵelementEnd()()()();
|
|
55
|
+
i0.ɵɵelementStart(7, "mj-page-body", 8);
|
|
56
|
+
i0.ɵɵtemplate(8, ClusterVisualizationResourceComponent_Conditional_1_ng_container_8_Template, 1, 0, "ng-container", 2);
|
|
57
|
+
i0.ɵɵelementEnd()();
|
|
58
|
+
} if (rf & 2) {
|
|
59
|
+
i0.ɵɵnextContext();
|
|
60
|
+
const clusterBody_r1 = i0.ɵɵreference(3);
|
|
61
|
+
i0.ɵɵadvance(7);
|
|
62
|
+
i0.ɵɵproperty("Flex", true)("Padding", false);
|
|
63
|
+
i0.ɵɵadvance();
|
|
64
|
+
i0.ɵɵproperty("ngTemplateOutlet", clusterBody_r1);
|
|
65
|
+
} }
|
|
66
|
+
function ClusterVisualizationResourceComponent_ng_template_2_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
67
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
68
|
+
i0.ɵɵelementStart(0, "div", 23);
|
|
69
|
+
i0.ɵɵlistener("click", function ClusterVisualizationResourceComponent_ng_template_2_For_8_Template_div_click_0_listener() { const saved_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSelectSaved(saved_r6)); });
|
|
70
|
+
i0.ɵɵelementStart(1, "div", 24);
|
|
38
71
|
i0.ɵɵtext(2);
|
|
39
72
|
i0.ɵɵelementEnd();
|
|
40
|
-
i0.ɵɵelementStart(3, "div",
|
|
73
|
+
i0.ɵɵelementStart(3, "div", 25)(4, "span");
|
|
41
74
|
i0.ɵɵtext(5);
|
|
42
75
|
i0.ɵɵelementEnd();
|
|
43
76
|
i0.ɵɵelementStart(6, "span");
|
|
44
77
|
i0.ɵɵtext(7);
|
|
45
78
|
i0.ɵɵelementEnd()();
|
|
46
|
-
i0.ɵɵelementStart(8, "button",
|
|
47
|
-
i0.ɵɵlistener("click", function
|
|
48
|
-
i0.ɵɵelement(9, "i",
|
|
79
|
+
i0.ɵɵelementStart(8, "button", 26);
|
|
80
|
+
i0.ɵɵlistener("click", function ClusterVisualizationResourceComponent_ng_template_2_For_8_Template_button_click_8_listener($event) { const saved_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnDeleteSaved(saved_r6, $event)); });
|
|
81
|
+
i0.ɵɵelement(9, "i", 27);
|
|
49
82
|
i0.ɵɵelementEnd()();
|
|
50
83
|
} if (rf & 2) {
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
i0.ɵɵclassProp("active",
|
|
84
|
+
const saved_r6 = ctx.$implicit;
|
|
85
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
86
|
+
i0.ɵɵclassProp("active", ctx_r2.IsActiveSaved(saved_r6));
|
|
54
87
|
i0.ɵɵadvance(2);
|
|
55
|
-
i0.ɵɵtextInterpolate(
|
|
88
|
+
i0.ɵɵtextInterpolate(saved_r6.Name);
|
|
56
89
|
i0.ɵɵadvance(3);
|
|
57
|
-
i0.ɵɵtextInterpolate(
|
|
90
|
+
i0.ɵɵtextInterpolate(saved_r6.EntityName);
|
|
58
91
|
i0.ɵɵadvance(2);
|
|
59
|
-
i0.ɵɵtextInterpolate(
|
|
92
|
+
i0.ɵɵtextInterpolate(ctx_r2.FormatDate(saved_r6.CreatedAt));
|
|
60
93
|
} }
|
|
61
|
-
function
|
|
62
|
-
i0.ɵɵelementStart(0, "div",
|
|
63
|
-
i0.ɵɵelement(1, "i",
|
|
94
|
+
function ClusterVisualizationResourceComponent_ng_template_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
95
|
+
i0.ɵɵelementStart(0, "div", 15);
|
|
96
|
+
i0.ɵɵelement(1, "i", 28);
|
|
64
97
|
i0.ɵɵelementStart(2, "p");
|
|
65
98
|
i0.ɵɵtext(3, "No saved visualizations yet");
|
|
66
99
|
i0.ɵɵelementEnd()();
|
|
67
100
|
} }
|
|
68
|
-
function
|
|
69
|
-
i0.ɵɵelementStart(0, "div",
|
|
70
|
-
i0.ɵɵelement(1, "i",
|
|
101
|
+
function ClusterVisualizationResourceComponent_ng_template_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
102
|
+
i0.ɵɵelementStart(0, "div", 29);
|
|
103
|
+
i0.ɵɵelement(1, "i", 30);
|
|
71
104
|
i0.ɵɵtext(2, " Records: ");
|
|
72
|
-
i0.ɵɵelementStart(3, "span",
|
|
105
|
+
i0.ɵɵelementStart(3, "span", 31);
|
|
73
106
|
i0.ɵɵtext(4);
|
|
74
107
|
i0.ɵɵelementEnd()();
|
|
75
|
-
i0.ɵɵelementStart(5, "div",
|
|
76
|
-
i0.ɵɵelement(6, "i",
|
|
108
|
+
i0.ɵɵelementStart(5, "div", 29);
|
|
109
|
+
i0.ɵɵelement(6, "i", 32);
|
|
77
110
|
i0.ɵɵtext(7, " Clusters: ");
|
|
78
|
-
i0.ɵɵelementStart(8, "span",
|
|
111
|
+
i0.ɵɵelementStart(8, "span", 31);
|
|
79
112
|
i0.ɵɵtext(9);
|
|
80
113
|
i0.ɵɵelementEnd()();
|
|
81
|
-
i0.ɵɵelementStart(10, "div",
|
|
82
|
-
i0.ɵɵelement(11, "i",
|
|
114
|
+
i0.ɵɵelementStart(10, "div", 29);
|
|
115
|
+
i0.ɵɵelement(11, "i", 33);
|
|
83
116
|
i0.ɵɵtext(12, " Silhouette: ");
|
|
84
|
-
i0.ɵɵelementStart(13, "span",
|
|
117
|
+
i0.ɵɵelementStart(13, "span", 31);
|
|
85
118
|
i0.ɵɵtext(14);
|
|
86
119
|
i0.ɵɵelementEnd()();
|
|
87
|
-
i0.ɵɵelementStart(15, "div",
|
|
88
|
-
i0.ɵɵelement(16, "i",
|
|
120
|
+
i0.ɵɵelementStart(15, "div", 29);
|
|
121
|
+
i0.ɵɵelement(16, "i", 34);
|
|
89
122
|
i0.ɵɵtext(17, " Computed: ");
|
|
90
|
-
i0.ɵɵelementStart(18, "span",
|
|
123
|
+
i0.ɵɵelementStart(18, "span", 31);
|
|
91
124
|
i0.ɵɵtext(19);
|
|
92
125
|
i0.ɵɵelementEnd()();
|
|
93
126
|
} if (rf & 2) {
|
|
94
|
-
const
|
|
127
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
95
128
|
i0.ɵɵadvance(4);
|
|
96
|
-
i0.ɵɵtextInterpolate(
|
|
129
|
+
i0.ɵɵtextInterpolate(ctx_r2.Result.Metrics.RecordCount);
|
|
97
130
|
i0.ɵɵadvance(5);
|
|
98
|
-
i0.ɵɵtextInterpolate(
|
|
131
|
+
i0.ɵɵtextInterpolate(ctx_r2.Result.Metrics.ClusterCount);
|
|
99
132
|
i0.ɵɵadvance(4);
|
|
100
|
-
i0.ɵɵclassProp("good",
|
|
133
|
+
i0.ɵɵclassProp("good", ctx_r2.IsSilhouetteGood);
|
|
101
134
|
i0.ɵɵadvance();
|
|
102
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
135
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.SilhouetteScoreFormatted, " ");
|
|
103
136
|
i0.ɵɵadvance(5);
|
|
104
|
-
i0.ɵɵtextInterpolate(
|
|
137
|
+
i0.ɵɵtextInterpolate(ctx_r2.ComputationTimeFormatted);
|
|
138
|
+
} }
|
|
139
|
+
function ClusterVisualizationResourceComponent_ng_template_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
140
|
+
i0.ɵɵelementStart(0, "div", 21);
|
|
141
|
+
i0.ɵɵelement(1, "i", 35);
|
|
142
|
+
i0.ɵɵelementStart(2, "span");
|
|
143
|
+
i0.ɵɵtext(3);
|
|
144
|
+
i0.ɵɵelementEnd()();
|
|
145
|
+
} if (rf & 2) {
|
|
146
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
147
|
+
i0.ɵɵadvance(3);
|
|
148
|
+
i0.ɵɵtextInterpolate(ctx_r2.RunError);
|
|
149
|
+
} }
|
|
150
|
+
function ClusterVisualizationResourceComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) {
|
|
151
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
152
|
+
i0.ɵɵelementStart(0, "div", 9)(1, "div", 10)(2, "div", 11)(3, "h2");
|
|
153
|
+
i0.ɵɵelement(4, "i", 12);
|
|
154
|
+
i0.ɵɵtext(5, " Saved Visualizations");
|
|
155
|
+
i0.ɵɵelementEnd()();
|
|
156
|
+
i0.ɵɵelementStart(6, "div", 13);
|
|
157
|
+
i0.ɵɵrepeaterCreate(7, ClusterVisualizationResourceComponent_ng_template_2_For_8_Template, 10, 5, "div", 14, i0.ɵɵcomponentInstance().TrackSavedBy, true);
|
|
158
|
+
i0.ɵɵconditionalCreate(9, ClusterVisualizationResourceComponent_ng_template_2_Conditional_9_Template, 4, 0, "div", 15);
|
|
159
|
+
i0.ɵɵelementEnd()();
|
|
160
|
+
i0.ɵɵelementStart(10, "div", 16)(11, "div", 17)(12, "div", 18);
|
|
161
|
+
i0.ɵɵtext(13);
|
|
162
|
+
i0.ɵɵelementEnd();
|
|
163
|
+
i0.ɵɵconditionalCreate(14, ClusterVisualizationResourceComponent_ng_template_2_Conditional_14_Template, 20, 6);
|
|
164
|
+
i0.ɵɵelementEnd();
|
|
165
|
+
i0.ɵɵelementStart(15, "div", 19)(16, "mj-cluster-scatter", 20, 1);
|
|
166
|
+
i0.ɵɵlistener("PointClicked", function ClusterVisualizationResourceComponent_ng_template_2_Template_mj_cluster_scatter_PointClicked_16_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPointClicked($event)); })("PointHovered", function ClusterVisualizationResourceComponent_ng_template_2_Template_mj_cluster_scatter_PointHovered_16_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnPointHovered($event)); })("OpenRecordRequested", function ClusterVisualizationResourceComponent_ng_template_2_Template_mj_cluster_scatter_OpenRecordRequested_16_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnOpenRecord($event)); })("LabelEdited", function ClusterVisualizationResourceComponent_ng_template_2_Template_mj_cluster_scatter_LabelEdited_16_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnLabelEdited($event)); });
|
|
167
|
+
i0.ɵɵelementEnd();
|
|
168
|
+
i0.ɵɵconditionalCreate(18, ClusterVisualizationResourceComponent_ng_template_2_Conditional_18_Template, 4, 1, "div", 21);
|
|
169
|
+
i0.ɵɵelementStart(19, "mj-cluster-config-panel", 22);
|
|
170
|
+
i0.ɵɵlistener("RunClustering", function ClusterVisualizationResourceComponent_ng_template_2_Template_mj_cluster_config_panel_RunClustering_19_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnRunClustering($event)); })("DimensionsChanged", function ClusterVisualizationResourceComponent_ng_template_2_Template_mj_cluster_config_panel_DimensionsChanged_19_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnDimensionsChanged($event)); })("SaveVisualization", function ClusterVisualizationResourceComponent_ng_template_2_Template_mj_cluster_config_panel_SaveVisualization_19_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSaveVisualization()); });
|
|
171
|
+
i0.ɵɵelementEnd()()()();
|
|
172
|
+
} if (rf & 2) {
|
|
173
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
174
|
+
i0.ɵɵadvance(7);
|
|
175
|
+
i0.ɵɵrepeater(ctx_r2.SavedVisualizations);
|
|
176
|
+
i0.ɵɵadvance(2);
|
|
177
|
+
i0.ɵɵconditional(ctx_r2.SavedVisualizations.length === 0 ? 9 : -1);
|
|
178
|
+
i0.ɵɵadvance(4);
|
|
179
|
+
i0.ɵɵtextInterpolate(ctx_r2.VisualizationTitle);
|
|
180
|
+
i0.ɵɵadvance();
|
|
181
|
+
i0.ɵɵconditional(ctx_r2.HasResult ? 14 : -1);
|
|
182
|
+
i0.ɵɵadvance(2);
|
|
183
|
+
i0.ɵɵproperty("Points", (ctx_r2.Result == null ? null : ctx_r2.Result.Points) ?? i0.ɵɵpureFunction0(14, _c1))("Clusters", (ctx_r2.Result == null ? null : ctx_r2.Result.Clusters) ?? i0.ɵɵpureFunction0(15, _c1))("IsLoading", ctx_r2.IsRunning)("ColorBy", ctx_r2.ActiveConfig.ColorBy ?? "cluster")("EntityName", ctx_r2.ActiveConfig.EntityName);
|
|
184
|
+
i0.ɵɵadvance(2);
|
|
185
|
+
i0.ɵɵconditional(ctx_r2.RunError ? 18 : -1);
|
|
186
|
+
i0.ɵɵadvance();
|
|
187
|
+
i0.ɵɵproperty("IsRunning", ctx_r2.IsRunning)("Metrics", ctx_r2.Metrics)("EntityOptions", ctx_r2.EntityOptions)("EntityDocOptions", ctx_r2.EntityDocOptions)("AllEntityDocOptions", ctx_r2.AllEntityDocOptions);
|
|
105
188
|
} }
|
|
106
189
|
/**
|
|
107
190
|
* Build an environment-scoped storage key so cluster data does not bleed
|
|
@@ -126,10 +209,20 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
126
209
|
scatterPlot;
|
|
127
210
|
cdr = inject(ChangeDetectorRef);
|
|
128
211
|
clusteringService = inject(ClusteringService);
|
|
212
|
+
activityService = inject(ActivityService);
|
|
129
213
|
navigationService = inject(NavigationService);
|
|
130
214
|
destroy$ = new Subject();
|
|
131
215
|
/** LLM-generated cluster labels for the current result */
|
|
132
216
|
ClusterLabels = [];
|
|
217
|
+
/**
|
|
218
|
+
* When true, this component is embedded inside the Visualize host surface.
|
|
219
|
+
* In that case the host owns the resource lifecycle (NotifyLoadComplete,
|
|
220
|
+
* agent context) and record navigation, so this component suppresses those
|
|
221
|
+
* and instead emits open-record intents via {@link OpenRecordRequested}.
|
|
222
|
+
*/
|
|
223
|
+
Embedded = false;
|
|
224
|
+
/** Emitted (only when Embedded) to ask the host to open an entity record. */
|
|
225
|
+
OpenRecordRequested = new EventEmitter();
|
|
133
226
|
// ================================================================
|
|
134
227
|
// Resource overrides
|
|
135
228
|
// ================================================================
|
|
@@ -154,6 +247,10 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
154
247
|
EntityOptions = [];
|
|
155
248
|
/** Entity document options for the selected entity (shown when 2+) */
|
|
156
249
|
EntityDocOptions = [];
|
|
250
|
+
/** All entity documents across entities (for the multi-entity source selector) */
|
|
251
|
+
AllEntityDocOptions = [];
|
|
252
|
+
/** User-facing error from the last run (e.g. multi-entity embedding mismatch) */
|
|
253
|
+
RunError = null;
|
|
157
254
|
/** Ordered field keys for prioritized display in scatter tooltip/detail */
|
|
158
255
|
FieldPriority = [];
|
|
159
256
|
/** Map of field names to human-readable display names */
|
|
@@ -170,13 +267,17 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
170
267
|
await this.loadEntityOptions();
|
|
171
268
|
this.loadSavedVisualizations();
|
|
172
269
|
this.restoreLastSession();
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
270
|
+
// When embedded in the Visualize host, the host owns agent context +
|
|
271
|
+
// the resource load lifecycle; skip them here to avoid double-reporting.
|
|
272
|
+
if (!this.Embedded) {
|
|
273
|
+
this.navigationService.SetAgentContext(this, {
|
|
274
|
+
IsVisualizationLoaded: !!this.Result,
|
|
275
|
+
VisualizationTitle: this.VisualizationTitle || null,
|
|
276
|
+
ClusterCount: this.Result?.Clusters?.length ?? 0,
|
|
277
|
+
TotalPoints: this.Result?.Points?.length ?? 0,
|
|
278
|
+
});
|
|
279
|
+
this.NotifyLoadComplete();
|
|
280
|
+
}
|
|
180
281
|
}
|
|
181
282
|
ngOnDestroy() {
|
|
182
283
|
super.ngOnDestroy();
|
|
@@ -210,16 +311,22 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
210
311
|
this.IsRunning = true;
|
|
211
312
|
this.ActiveConfig = config;
|
|
212
313
|
this.ClusterLabels = [];
|
|
314
|
+
this.RunError = null;
|
|
213
315
|
// Auto-hide detail panel from previous visualization
|
|
214
316
|
this.scatterPlot?.CloseDetailPanel();
|
|
215
317
|
// Update entity doc options if entity changed
|
|
216
318
|
this.updateEntityDocOptions(config.EntityName);
|
|
217
319
|
this.cdr.detectChanges();
|
|
320
|
+
const activityID = this.activityService.Start('Cluster analysis', {
|
|
321
|
+
icon: 'fa-solid fa-circle-nodes',
|
|
322
|
+
detail: `${config.EntityName || 'Multiple sources'} · ${config.Algorithm === 'kmeans' ? 'K-Means' : 'DBSCAN'}`,
|
|
323
|
+
});
|
|
218
324
|
try {
|
|
219
325
|
// Fetch vectors from the vector database
|
|
220
326
|
const vectors = await this.fetchVectorsForEntity(config);
|
|
221
327
|
// Run clustering (client-side UMAP + K-Means/DBSCAN)
|
|
222
328
|
this.Result = await this.clusteringService.RunClustering(vectors, config);
|
|
329
|
+
this.activityService.Complete(activityID, 'success', `${this.Result.Points.length} points · ${this.Result.Clusters.length} clusters`);
|
|
223
330
|
this.VisualizationTitle = `${config.EntityName} — ${config.Algorithm === 'kmeans' ? 'K-Means' : 'DBSCAN'}`;
|
|
224
331
|
this.FieldPriority = this.ComputeFieldPriority(config.EntityName);
|
|
225
332
|
// Fire LLM cluster naming in the background (non-blocking).
|
|
@@ -231,12 +338,25 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
231
338
|
catch (error) {
|
|
232
339
|
console.error('[ClusterVisualization] Pipeline error:', error);
|
|
233
340
|
this.Result = null;
|
|
341
|
+
this.RunError = error instanceof Error ? error.message : String(error);
|
|
342
|
+
this.activityService.Complete(activityID, 'error', this.RunError);
|
|
234
343
|
}
|
|
235
344
|
finally {
|
|
236
345
|
this.IsRunning = false;
|
|
237
346
|
this.cdr.detectChanges();
|
|
238
347
|
}
|
|
239
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Re-run when the user flips 2D⇄3D so the projection updates immediately.
|
|
351
|
+
* A 3D layout needs a Z coordinate that only a fresh projection produces, so
|
|
352
|
+
* toggling alone wouldn't change the existing plot.
|
|
353
|
+
*/
|
|
354
|
+
OnDimensionsChanged(dims) {
|
|
355
|
+
this.ActiveConfig = { ...this.ActiveConfig, Dimensions: dims };
|
|
356
|
+
if (this.Result && this.Result.Points.length > 0 && !this.IsRunning) {
|
|
357
|
+
void this.OnRunClustering(this.ActiveConfig);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
240
360
|
/** Handle point click — log for now */
|
|
241
361
|
OnPointClicked(_point) {
|
|
242
362
|
// Detail panel is handled by the scatter component internally
|
|
@@ -251,6 +371,11 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
251
371
|
const recordID = point.Metadata?.['RecordID'];
|
|
252
372
|
if (!entityName || !recordID)
|
|
253
373
|
return;
|
|
374
|
+
// When embedded, defer navigation to the host (shared drilldown owner).
|
|
375
|
+
if (this.Embedded) {
|
|
376
|
+
this.OpenRecordRequested.emit({ EntityName: entityName, RecordID: recordID });
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
254
379
|
const compositeKey = new CompositeKey();
|
|
255
380
|
compositeKey.SimpleLoadFromURLSegment(recordID);
|
|
256
381
|
this.navigationService.OpenEntityRecord(entityName, compositeKey);
|
|
@@ -354,6 +479,16 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
354
479
|
if (entityNames.length > 0) {
|
|
355
480
|
this.EntityOptions = entityNames.map(name => ({ Name: name }));
|
|
356
481
|
}
|
|
482
|
+
// Build the cross-entity document list that powers the multi-entity
|
|
483
|
+
// source selector (each option tagged with its owning entity).
|
|
484
|
+
const allDocs = [];
|
|
485
|
+
for (const name of entityNames) {
|
|
486
|
+
const docs = engine.GetEntityDocumentsForEntity(name).filter(d => d.Status === 'Active');
|
|
487
|
+
for (const d of docs) {
|
|
488
|
+
allDocs.push({ ID: d.ID, Name: d.Name, EntityName: name });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
this.AllEntityDocOptions = allDocs;
|
|
357
492
|
// Set default entity if config is blank
|
|
358
493
|
if (this.EntityOptions.length > 0 && !this.ActiveConfig.EntityName) {
|
|
359
494
|
this.ActiveConfig.EntityName = this.EntityOptions[0].Name;
|
|
@@ -390,44 +525,66 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
390
525
|
* that match the requested entity.
|
|
391
526
|
*/
|
|
392
527
|
async fetchVectorsForEntity(config) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const engine = KnowledgeHubMetadataEngine.Instance;
|
|
397
|
-
const entityDocs = engine.GetEntityDocumentsForEntity(config.EntityName)
|
|
398
|
-
.filter(d => d.Status === 'Active');
|
|
399
|
-
if (entityDocs.length === 0) {
|
|
400
|
-
return [];
|
|
401
|
-
}
|
|
402
|
-
entityDocID = entityDocs[0].ID;
|
|
528
|
+
const docIDs = this.resolveDocIDs(config);
|
|
529
|
+
if (docIDs.length === 0) {
|
|
530
|
+
return [];
|
|
403
531
|
}
|
|
404
|
-
|
|
532
|
+
const isMulti = docIDs.length > 1;
|
|
533
|
+
const docEntityMap = new Map(this.AllEntityDocOptions.map(d => [d.ID, d.EntityName ?? '']));
|
|
405
534
|
const provider = this.ProviderToUse;
|
|
406
535
|
const aiClient = new GraphQLAIClient(provider);
|
|
407
|
-
const result = await aiClient.FetchEntityVectors({
|
|
408
|
-
entityDocumentID: entityDocID,
|
|
409
|
-
maxRecords: config.MaxRecords,
|
|
410
|
-
filter: config.Filter || undefined,
|
|
411
|
-
});
|
|
412
|
-
if (!result.Success || result.Results.length === 0) {
|
|
413
|
-
return [];
|
|
414
|
-
}
|
|
415
|
-
// Convert vector DB results to ClusterInputVector format
|
|
416
536
|
const vectors = [];
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
Key: item.ID,
|
|
424
|
-
Label: label,
|
|
425
|
-
Vector: item.Values,
|
|
426
|
-
Metadata: metadata,
|
|
537
|
+
let expectedLen = -1;
|
|
538
|
+
for (const docID of docIDs) {
|
|
539
|
+
const result = await aiClient.FetchEntityVectors({
|
|
540
|
+
entityDocumentID: docID,
|
|
541
|
+
maxRecords: config.MaxRecords,
|
|
542
|
+
filter: config.Filter || undefined,
|
|
427
543
|
});
|
|
544
|
+
if (!result.Success || result.Results.length === 0)
|
|
545
|
+
continue;
|
|
546
|
+
for (const item of result.Results) {
|
|
547
|
+
if (!item.Values || item.Values.length === 0)
|
|
548
|
+
continue;
|
|
549
|
+
// Hard-block multi-entity embedding mismatches: vectors of different
|
|
550
|
+
// dimensionalities live in different spaces and aren't co-clusterable.
|
|
551
|
+
if (isMulti) {
|
|
552
|
+
if (expectedLen === -1) {
|
|
553
|
+
expectedLen = item.Values.length;
|
|
554
|
+
}
|
|
555
|
+
else if (item.Values.length !== expectedLen) {
|
|
556
|
+
throw new Error('The selected documents use different embedding models (vector sizes differ), ' +
|
|
557
|
+
'so their points are not comparable. Pick documents that share the same embedding model.');
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
const metadata = this.parseVectorMetadata(item.Metadata);
|
|
561
|
+
// Ensure each point knows its source entity for color-by-entity.
|
|
562
|
+
if (isMulti && !metadata['EntityName']) {
|
|
563
|
+
metadata['EntityName'] = docEntityMap.get(docID) ?? metadata['Entity'] ?? '';
|
|
564
|
+
}
|
|
565
|
+
const label = this.buildLabel(metadata);
|
|
566
|
+
vectors.push({
|
|
567
|
+
Key: item.ID,
|
|
568
|
+
Label: label,
|
|
569
|
+
Vector: item.Values,
|
|
570
|
+
Metadata: metadata,
|
|
571
|
+
});
|
|
572
|
+
}
|
|
428
573
|
}
|
|
429
574
|
return vectors;
|
|
430
575
|
}
|
|
576
|
+
/** Resolve which entity-document IDs to source vectors from for a run. */
|
|
577
|
+
resolveDocIDs(config) {
|
|
578
|
+
if (config.EntityDocumentIDs && config.EntityDocumentIDs.length > 0) {
|
|
579
|
+
return config.EntityDocumentIDs;
|
|
580
|
+
}
|
|
581
|
+
if (config.EntityDocumentID) {
|
|
582
|
+
return [config.EntityDocumentID];
|
|
583
|
+
}
|
|
584
|
+
const engine = KnowledgeHubMetadataEngine.Instance;
|
|
585
|
+
const docs = engine.GetEntityDocumentsForEntity(config.EntityName).filter(d => d.Status === 'Active');
|
|
586
|
+
return docs.length > 0 ? [docs[0].ID] : [];
|
|
587
|
+
}
|
|
431
588
|
/** Parse the JSON metadata string from the vector DB into a record */
|
|
432
589
|
parseVectorMetadata(metadataJson) {
|
|
433
590
|
try {
|
|
@@ -724,48 +881,12 @@ let ClusterVisualizationResourceComponent = class ClusterVisualizationResourceCo
|
|
|
724
881
|
} if (rf & 2) {
|
|
725
882
|
let _t;
|
|
726
883
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scatterPlot = _t.first);
|
|
727
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls:
|
|
728
|
-
|
|
729
|
-
i0.ɵɵ
|
|
730
|
-
i0.ɵɵlistener("click", function ClusterVisualizationResourceComponent_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnNewAnalysis()); });
|
|
731
|
-
i0.ɵɵelement(4, "i", 4);
|
|
732
|
-
i0.ɵɵtext(5, " New Analysis ");
|
|
733
|
-
i0.ɵɵelementEnd()()();
|
|
734
|
-
i0.ɵɵelementStart(6, "mj-page-body", 5)(7, "div", 6)(8, "div", 7)(9, "div", 8)(10, "h2");
|
|
735
|
-
i0.ɵɵelement(11, "i", 9);
|
|
736
|
-
i0.ɵɵtext(12, " Saved Clusters");
|
|
737
|
-
i0.ɵɵelementEnd()();
|
|
738
|
-
i0.ɵɵelementStart(13, "div", 10);
|
|
739
|
-
i0.ɵɵrepeaterCreate(14, ClusterVisualizationResourceComponent_For_15_Template, 10, 5, "div", 11, ctx.TrackSavedBy, true);
|
|
740
|
-
i0.ɵɵconditionalCreate(16, ClusterVisualizationResourceComponent_Conditional_16_Template, 4, 0, "div", 12);
|
|
741
|
-
i0.ɵɵelementEnd()();
|
|
742
|
-
i0.ɵɵelementStart(17, "div", 13)(18, "div", 14)(19, "div", 15);
|
|
743
|
-
i0.ɵɵtext(20);
|
|
744
|
-
i0.ɵɵelementEnd();
|
|
745
|
-
i0.ɵɵconditionalCreate(21, ClusterVisualizationResourceComponent_Conditional_21_Template, 20, 6);
|
|
746
|
-
i0.ɵɵelementEnd();
|
|
747
|
-
i0.ɵɵelementStart(22, "div", 16)(23, "mj-cluster-scatter", 17, 0);
|
|
748
|
-
i0.ɵɵlistener("PointClicked", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_PointClicked_23_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnPointClicked($event)); })("PointHovered", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_PointHovered_23_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnPointHovered($event)); })("OpenRecordRequested", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_OpenRecordRequested_23_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnOpenRecord($event)); })("LabelEdited", function ClusterVisualizationResourceComponent_Template_mj_cluster_scatter_LabelEdited_23_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnLabelEdited($event)); });
|
|
749
|
-
i0.ɵɵelementEnd();
|
|
750
|
-
i0.ɵɵelementStart(25, "mj-cluster-config-panel", 18);
|
|
751
|
-
i0.ɵɵlistener("RunClustering", function ClusterVisualizationResourceComponent_Template_mj_cluster_config_panel_RunClustering_25_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnRunClustering($event)); })("SaveVisualization", function ClusterVisualizationResourceComponent_Template_mj_cluster_config_panel_SaveVisualization_25_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnSaveVisualization()); });
|
|
752
|
-
i0.ɵɵelementEnd()()()()()();
|
|
884
|
+
} }, inputs: { Embedded: "Embedded" }, outputs: { OpenRecordRequested: "OpenRecordRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 1, consts: [["clusterBody", ""], ["scatterPlot", ""], [4, "ngTemplateOutlet"], ["Title", "Cluster Visualization", "Icon", "fa-solid fa-circle-nodes", "Subtitle", "Explore semantic clusters in your knowledge base"], ["actions", ""], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "action-btn-label"], [3, "Flex", "Padding"], [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, "main-area"], [1, "topbar"], [1, "topbar-title"], [1, "scatter-area"], [3, "PointClicked", "PointHovered", "OpenRecordRequested", "LabelEdited", "Points", "Clusters", "IsLoading", "ColorBy", "EntityName"], [1, "cluster-run-error"], [3, "RunClustering", "DimensionsChanged", "SaveVisualization", "IsRunning", "Metrics", "EntityOptions", "EntityDocOptions", "AllEntityDocOptions"], [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"], [1, "fa-solid", "fa-triangle-exclamation"]], template: function ClusterVisualizationResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
885
|
+
i0.ɵɵconditionalCreate(0, ClusterVisualizationResourceComponent_Conditional_0_Template, 1, 1, "ng-container")(1, ClusterVisualizationResourceComponent_Conditional_1_Template, 9, 3, "mj-page-layout");
|
|
886
|
+
i0.ɵɵtemplate(2, ClusterVisualizationResourceComponent_ng_template_2_Template, 20, 16, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
753
887
|
} if (rf & 2) {
|
|
754
|
-
i0.ɵɵ
|
|
755
|
-
|
|
756
|
-
i0.ɵɵadvance(8);
|
|
757
|
-
i0.ɵɵrepeater(ctx.SavedVisualizations);
|
|
758
|
-
i0.ɵɵadvance(2);
|
|
759
|
-
i0.ɵɵconditional(ctx.SavedVisualizations.length === 0 ? 16 : -1);
|
|
760
|
-
i0.ɵɵadvance(4);
|
|
761
|
-
i0.ɵɵtextInterpolate(ctx.VisualizationTitle);
|
|
762
|
-
i0.ɵɵadvance();
|
|
763
|
-
i0.ɵɵconditional(ctx.HasResult ? 21 : -1);
|
|
764
|
-
i0.ɵɵadvance(2);
|
|
765
|
-
i0.ɵɵproperty("Points", (ctx.Result == null ? null : ctx.Result.Points) ?? i0.ɵɵpureFunction0(13, _c1))("Clusters", (ctx.Result == null ? null : ctx.Result.Clusters) ?? i0.ɵɵpureFunction0(14, _c1))("IsLoading", ctx.IsRunning)("EntityName", ctx.ActiveConfig.EntityName);
|
|
766
|
-
i0.ɵɵadvance(2);
|
|
767
|
-
i0.ɵɵproperty("IsRunning", ctx.IsRunning)("Metrics", ctx.Metrics)("EntityOptions", ctx.EntityOptions)("EntityDocOptions", ctx.EntityDocOptions);
|
|
768
|
-
} }, dependencies: [i1.MJButtonDirective, i1.MJPageHeaderComponent, i1.MJPageLayoutComponent, i1.MJPageBodyComponent, i2.ClusterScatterComponent, i2.ClusterConfigPanelComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.cluster-viz-container[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\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}"] });
|
|
888
|
+
i0.ɵɵconditional(ctx.Embedded ? 0 : 1);
|
|
889
|
+
} }, dependencies: [i1.NgTemplateOutlet, i2.MJButtonDirective, i2.MJPageHeaderComponent, i2.MJPageLayoutComponent, i2.MJPageBodyComponent, i3.ClusterScatterComponent, i3.ClusterConfigPanelComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.cluster-viz-container[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n \n\n\n\n\n\n height: 100%;\n min-height: 0;\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.cluster-run-error[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 8px;\n max-width: 70%;\n padding: 10px 14px;\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n border-radius: 8px;\n font-size: 0.82rem;\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n\n\n.scatter-area[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n min-height: 0;\n}\n\n\n\n.scatter-area[_ngcontent-%COMP%] > mj-cluster-scatter[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n display: block;\n overflow: hidden;\n}\n\n\n\n\n\n\n.scatter-area[_ngcontent-%COMP%] > mj-cluster-config-panel[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 10;\n}\n.scatter-area[_ngcontent-%COMP%] .config-panel {\n pointer-events: auto;\n max-height: calc(100% - 24px);\n overflow-y: auto;\n overscroll-behavior: contain;\n}"] });
|
|
769
890
|
};
|
|
770
891
|
ClusterVisualizationResourceComponent = __decorate([
|
|
771
892
|
RegisterClass(BaseResourceComponent, 'ClusterVisualizationResource')
|
|
@@ -773,10 +894,14 @@ ClusterVisualizationResourceComponent = __decorate([
|
|
|
773
894
|
export { ClusterVisualizationResourceComponent };
|
|
774
895
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClusterVisualizationResourceComponent, [{
|
|
775
896
|
type: Component,
|
|
776
|
-
args: [{ standalone: false, selector: 'app-cluster-visualization-resource', template: "<mj-page-layout>\n <mj-page-header\n Title=\"Cluster Visualization\"\n Icon=\"fa-solid fa-circle-nodes\"\n Subtitle=\"Explore semantic clusters in your knowledge base\">\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewAnalysis()\">\n <i class=\"fa-solid fa-plus\"></i> New Analysis\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\" [Padding]=\"false\">\n<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 </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 </mj-page-body>\n</mj-page-layout>\n", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.cluster-viz-container {\n display: flex;\n flex: 1;\n min-height: 0;\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"] }]
|
|
897
|
+
args: [{ standalone: false, selector: 'app-cluster-visualization-resource', template: "@if (Embedded) {\n <ng-container *ngTemplateOutlet=\"clusterBody\"></ng-container>\n} @else {\n<mj-page-layout>\n <mj-page-header\n Title=\"Cluster Visualization\"\n Icon=\"fa-solid fa-circle-nodes\"\n Subtitle=\"Explore semantic clusters in your knowledge base\">\n <div actions>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewAnalysis()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"action-btn-label\">New Analysis</span>\n </button>\n </div>\n </mj-page-header>\n\n <mj-page-body [Flex]=\"true\" [Padding]=\"false\">\n <ng-container *ngTemplateOutlet=\"clusterBody\"></ng-container>\n </mj-page-body>\n</mj-page-layout>\n}\n\n<ng-template #clusterBody>\n<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 Visualizations</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 </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 [ColorBy]=\"ActiveConfig.ColorBy ?? 'cluster'\"\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 <!-- Run error banner (e.g. multi-entity embedding mismatch) -->\n @if (RunError) {\n <div class=\"cluster-run-error\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ RunError }}</span>\n </div>\n }\n\n <!-- Floating config panel -->\n <mj-cluster-config-panel\n [IsRunning]=\"IsRunning\"\n [Metrics]=\"Metrics\"\n [EntityOptions]=\"EntityOptions\"\n [EntityDocOptions]=\"EntityDocOptions\"\n [AllEntityDocOptions]=\"AllEntityDocOptions\"\n (RunClustering)=\"OnRunClustering($event)\"\n (DimensionsChanged)=\"OnDimensionsChanged($event)\"\n (SaveVisualization)=\"OnSaveVisualization()\">\n </mj-cluster-config-panel>\n </div>\n </div>\n</div>\n</ng-template>\n", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.cluster-viz-container {\n display: flex;\n flex: 1;\n /* height:100% so we fill the host whether the parent is a flex container\n (non-embedded, inside mj-page-body[Flex]) OR a plain block host\n (embedded inside Visualize, where :host is display:block and flex:1\n would otherwise be ignored, collapsing the area and clipping the\n floating config panel). */\n height: 100%;\n min-height: 0;\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/* Run error banner */\n.cluster-run-error {\n position: absolute;\n top: 12px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n display: flex;\n align-items: center;\n gap: 8px;\n max-width: 70%;\n padding: 10px 14px;\n background: var(--mj-status-error-bg);\n border: 1px solid var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n border-radius: 8px;\n font-size: 0.82rem;\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n/* Scatter area */\n.scatter-area {\n flex: 1;\n position: relative;\n overflow: hidden;\n min-height: 0;\n}\n\n/* The scatter SVG / empty-state should fill and be clipped to the area \u2026 */\n.scatter-area > mj-cluster-scatter {\n position: absolute;\n inset: 0;\n display: block;\n overflow: hidden;\n}\n\n/* \u2026 but the floating Configuration panel must never be clipped by the area's\n overflow. Constrain its height to the visible area and let its own body scroll\n when the Filter (Optional) section makes it tall. (Panel lives in the generic\n ng-clustering package; we only adjust its containment from here.) */\n.scatter-area > mj-cluster-config-panel {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 10;\n}\n.scatter-area ::ng-deep .config-panel {\n pointer-events: auto;\n max-height: calc(100% - 24px);\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n"] }]
|
|
777
898
|
}], null, { scatterPlot: [{
|
|
778
899
|
type: ViewChild,
|
|
779
900
|
args: ['scatterPlot']
|
|
901
|
+
}], Embedded: [{
|
|
902
|
+
type: Input
|
|
903
|
+
}], OpenRecordRequested: [{
|
|
904
|
+
type: Output
|
|
780
905
|
}] }); })();
|
|
781
906
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClusterVisualizationResourceComponent, { className: "ClusterVisualizationResourceComponent", filePath: "src/KnowledgeHub/components/clusters/cluster-visualization-resource.component.ts", lineNumber: 63 }); })();
|
|
782
907
|
/** Tree-shaking prevention */
|