@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
|
@@ -15,17 +15,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
15
15
|
* @module MCP Dashboard
|
|
16
16
|
*/
|
|
17
17
|
import { Component } from '@angular/core';
|
|
18
|
-
import { NavigationEnd } from '@angular/router';
|
|
19
18
|
import { Subject, BehaviorSubject } from 'rxjs';
|
|
20
|
-
import { takeUntil, debounceTime, distinctUntilChanged
|
|
19
|
+
import { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
21
20
|
import { RunView, Metadata } from '@memberjunction/core';
|
|
22
21
|
import { BaseDashboard } from '@memberjunction/ng-shared';
|
|
23
22
|
import { MCPEngine, UserInfoEngine } from '@memberjunction/core-entities';
|
|
24
23
|
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
25
24
|
import * as i0 from "@angular/core";
|
|
26
|
-
import * as i1 from "
|
|
27
|
-
import * as i2 from "@memberjunction/ng-shared";
|
|
28
|
-
import * as i3 from "./services/mcp-tools.service";
|
|
25
|
+
import * as i1 from "./services/mcp-tools.service";
|
|
29
26
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
30
27
|
const _forTrack1 = ($index, $item) => $item.server.ID;
|
|
31
28
|
function MCPDashboardComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -1109,9 +1106,6 @@ function MCPDashboardComponent_Conditional_54_Template(rf, ctx) { if (rf & 1) {
|
|
|
1109
1106
|
*/
|
|
1110
1107
|
let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
1111
1108
|
cdr;
|
|
1112
|
-
router;
|
|
1113
|
-
route;
|
|
1114
|
-
navigationService;
|
|
1115
1109
|
mcpToolsService;
|
|
1116
1110
|
// ========================================
|
|
1117
1111
|
// State
|
|
@@ -1174,9 +1168,6 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
1174
1168
|
ToolsSortAscending = true;
|
|
1175
1169
|
ServerGroups = [];
|
|
1176
1170
|
ExpandedToolId = null;
|
|
1177
|
-
// Navigation state
|
|
1178
|
-
skipUrlUpdate = true;
|
|
1179
|
-
lastNavigatedUrl = '';
|
|
1180
1171
|
// Sync state
|
|
1181
1172
|
SyncStates = new Map();
|
|
1182
1173
|
syncSubscriptions = new Map();
|
|
@@ -1186,12 +1177,9 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
1186
1177
|
// Lifecycle
|
|
1187
1178
|
// ========================================
|
|
1188
1179
|
destroy$ = new Subject();
|
|
1189
|
-
constructor(cdr,
|
|
1180
|
+
constructor(cdr, mcpToolsService) {
|
|
1190
1181
|
super();
|
|
1191
1182
|
this.cdr = cdr;
|
|
1192
|
-
this.router = router;
|
|
1193
|
-
this.route = route;
|
|
1194
|
-
this.navigationService = navigationService;
|
|
1195
1183
|
this.mcpToolsService = mcpToolsService;
|
|
1196
1184
|
// Set up debounced settings persistence
|
|
1197
1185
|
this.settingsPersistSubject.pipe(debounceTime(500), takeUntil(this.destroy$)).subscribe(() => {
|
|
@@ -1204,40 +1192,24 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
1204
1192
|
this.checkOAuthCompletion();
|
|
1205
1193
|
// Load saved user preferences first
|
|
1206
1194
|
this.loadUserPreferences();
|
|
1207
|
-
//
|
|
1208
|
-
this.
|
|
1195
|
+
// Read initial tab from query params (deep link / direct URL)
|
|
1196
|
+
const initialParams = this.GetQueryParams();
|
|
1197
|
+
if (initialParams['tab'] && this.isValidTab(initialParams['tab'])) {
|
|
1198
|
+
this.ActiveTab = initialParams['tab'];
|
|
1199
|
+
}
|
|
1209
1200
|
// Apply configuration params if passed via NavigationService
|
|
1210
1201
|
this.applyConfigurationParams();
|
|
1211
|
-
// Enable URL updates after initialization
|
|
1212
|
-
this.skipUrlUpdate = false;
|
|
1213
|
-
// Subscribe to router events to handle browser back/forward
|
|
1214
|
-
this.subscribeToRouterEvents();
|
|
1215
1202
|
}
|
|
1216
1203
|
/**
|
|
1217
|
-
*
|
|
1204
|
+
* Called by the framework when the URL query params change due to
|
|
1205
|
+
* browser back/forward navigation or a deep link.
|
|
1218
1206
|
*/
|
|
1219
|
-
|
|
1220
|
-
const
|
|
1221
|
-
if (
|
|
1222
|
-
this.ActiveTab =
|
|
1207
|
+
OnQueryParamsChanged(params, source) {
|
|
1208
|
+
const tab = params['tab'];
|
|
1209
|
+
if (tab && this.isValidTab(tab) && tab !== this.ActiveTab) {
|
|
1210
|
+
this.ActiveTab = tab;
|
|
1211
|
+
this.cdr.detectChanges();
|
|
1223
1212
|
}
|
|
1224
|
-
this.lastNavigatedUrl = this.router.url;
|
|
1225
|
-
}
|
|
1226
|
-
/**
|
|
1227
|
-
* Parses URL query string to extract navigation state
|
|
1228
|
-
*/
|
|
1229
|
-
parseUrlState() {
|
|
1230
|
-
const url = this.router.url;
|
|
1231
|
-
const queryIndex = url.indexOf('?');
|
|
1232
|
-
if (queryIndex === -1)
|
|
1233
|
-
return null;
|
|
1234
|
-
const queryString = url.substring(queryIndex + 1);
|
|
1235
|
-
const params = new URLSearchParams(queryString);
|
|
1236
|
-
const tab = params.get('tab');
|
|
1237
|
-
if (tab && this.isValidTab(tab)) {
|
|
1238
|
-
return { tab };
|
|
1239
|
-
}
|
|
1240
|
-
return null;
|
|
1241
1213
|
}
|
|
1242
1214
|
/**
|
|
1243
1215
|
* Validates that a tab value is a valid MCPDashboardTab
|
|
@@ -1254,19 +1226,6 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
1254
1226
|
this.ActiveTab = config.tab;
|
|
1255
1227
|
}
|
|
1256
1228
|
}
|
|
1257
|
-
/**
|
|
1258
|
-
* Subscribes to router NavigationEnd events to handle browser back/forward
|
|
1259
|
-
*/
|
|
1260
|
-
subscribeToRouterEvents() {
|
|
1261
|
-
this.router.events
|
|
1262
|
-
.pipe(filter((event) => event instanceof NavigationEnd), takeUntil(this.destroy$))
|
|
1263
|
-
.subscribe(event => {
|
|
1264
|
-
const currentUrl = event.urlAfterRedirects || event.url;
|
|
1265
|
-
if (currentUrl !== this.lastNavigatedUrl) {
|
|
1266
|
-
this.onExternalNavigation(currentUrl);
|
|
1267
|
-
}
|
|
1268
|
-
});
|
|
1269
|
-
}
|
|
1270
1229
|
// ========================================
|
|
1271
1230
|
// User Settings Persistence
|
|
1272
1231
|
// ========================================
|
|
@@ -1361,36 +1320,6 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
1361
1320
|
console.warn('[MCPDashboard] Failed to persist user preferences:', error);
|
|
1362
1321
|
}
|
|
1363
1322
|
}
|
|
1364
|
-
/**
|
|
1365
|
-
* Handles external navigation (browser back/forward)
|
|
1366
|
-
*/
|
|
1367
|
-
onExternalNavigation(url) {
|
|
1368
|
-
this.lastNavigatedUrl = url;
|
|
1369
|
-
const queryIndex = url.indexOf('?');
|
|
1370
|
-
if (queryIndex === -1)
|
|
1371
|
-
return;
|
|
1372
|
-
const queryString = url.substring(queryIndex + 1);
|
|
1373
|
-
const params = new URLSearchParams(queryString);
|
|
1374
|
-
const tab = params.get('tab');
|
|
1375
|
-
if (tab && this.isValidTab(tab) && tab !== this.ActiveTab) {
|
|
1376
|
-
this.skipUrlUpdate = true;
|
|
1377
|
-
this.ActiveTab = tab;
|
|
1378
|
-
this.cdr.detectChanges();
|
|
1379
|
-
this.skipUrlUpdate = false;
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
/**
|
|
1383
|
-
* Updates URL query string to reflect current state using NavigationService
|
|
1384
|
-
*/
|
|
1385
|
-
updateUrl() {
|
|
1386
|
-
if (this.skipUrlUpdate)
|
|
1387
|
-
return;
|
|
1388
|
-
const queryParams = {
|
|
1389
|
-
tab: this.ActiveTab
|
|
1390
|
-
};
|
|
1391
|
-
this.navigationService.UpdateActiveTabQueryParams(queryParams);
|
|
1392
|
-
this.lastNavigatedUrl = this.router.url;
|
|
1393
|
-
}
|
|
1394
1323
|
// Required by BaseResourceComponent
|
|
1395
1324
|
async GetResourceDisplayName(data) {
|
|
1396
1325
|
return 'MCP Management';
|
|
@@ -1736,7 +1665,7 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
1736
1665
|
if (this.ActiveTab === tab)
|
|
1737
1666
|
return;
|
|
1738
1667
|
this.ActiveTab = tab;
|
|
1739
|
-
this.
|
|
1668
|
+
this.UpdateQueryParams({ tab: this.ActiveTab });
|
|
1740
1669
|
this.cdr.detectChanges();
|
|
1741
1670
|
}
|
|
1742
1671
|
// ========================================
|
|
@@ -2287,37 +2216,26 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
2287
2216
|
* Checks for OAuth completion by looking for query params set by the OAuth callback
|
|
2288
2217
|
*/
|
|
2289
2218
|
checkOAuthCompletion() {
|
|
2290
|
-
const params = this.
|
|
2219
|
+
const params = this.GetQueryParams();
|
|
2291
2220
|
if (params['oauth'] === 'success') {
|
|
2292
2221
|
// OAuth completed successfully
|
|
2293
2222
|
const connectionId = params['connectionId'];
|
|
2294
2223
|
console.log(`[MCPDashboard] OAuth authorization completed for connection: ${connectionId}`);
|
|
2295
2224
|
// Show success notification
|
|
2296
2225
|
this.showSuccessNotification('OAuth authorization completed successfully');
|
|
2297
|
-
// Clear the query params
|
|
2298
|
-
this.
|
|
2299
|
-
relativeTo: this.route,
|
|
2300
|
-
queryParams: {},
|
|
2301
|
-
queryParamsHandling: 'merge',
|
|
2302
|
-
replaceUrl: true
|
|
2303
|
-
});
|
|
2226
|
+
// Clear the OAuth query params, preserving the tab param
|
|
2227
|
+
this.UpdateQueryParams({ oauth: null, connectionId: null, error: null, error_description: null });
|
|
2304
2228
|
// Refresh data to pick up new OAuth state
|
|
2305
2229
|
this.loadAllData(true);
|
|
2306
2230
|
}
|
|
2307
2231
|
else if (params['oauth'] === 'error') {
|
|
2308
2232
|
// OAuth failed
|
|
2309
|
-
const errorCode = params['error'] || 'unknown_error';
|
|
2310
2233
|
const errorMessage = params['error_description'] || 'Authorization failed';
|
|
2311
|
-
console.error(`[MCPDashboard] OAuth authorization failed: ${
|
|
2234
|
+
console.error(`[MCPDashboard] OAuth authorization failed: ${params['error'] ?? 'unknown_error'} - ${errorMessage}`);
|
|
2312
2235
|
// Show error message
|
|
2313
2236
|
this.ErrorMessage = `OAuth authorization failed: ${errorMessage}`;
|
|
2314
|
-
// Clear the query params
|
|
2315
|
-
this.
|
|
2316
|
-
relativeTo: this.route,
|
|
2317
|
-
queryParams: {},
|
|
2318
|
-
queryParamsHandling: 'merge',
|
|
2319
|
-
replaceUrl: true
|
|
2320
|
-
});
|
|
2237
|
+
// Clear the OAuth query params
|
|
2238
|
+
this.UpdateQueryParams({ oauth: null, connectionId: null, error: null, error_description: null });
|
|
2321
2239
|
}
|
|
2322
2240
|
}
|
|
2323
2241
|
/**
|
|
@@ -2643,7 +2561,7 @@ let MCPDashboardComponent = class MCPDashboardComponent extends BaseDashboard {
|
|
|
2643
2561
|
this.ShowTestToolDialog = true;
|
|
2644
2562
|
this.cdr.detectChanges();
|
|
2645
2563
|
}
|
|
2646
|
-
static ɵfac = function MCPDashboardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MCPDashboardComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.
|
|
2564
|
+
static ɵfac = function MCPDashboardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MCPDashboardComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.MCPToolsService)); };
|
|
2647
2565
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MCPDashboardComponent, selectors: [["mj-mcp-dashboard"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 55, vars: 30, consts: [[1, "mcp-dashboard"], [1, "dashboard-header"], [1, "header-info"], [1, "dashboard-title"], [1, "fa-solid", "fa-plug-circle-bolt"], ["type", "button", "title", "Toggle Filters", 1, "filter-toggle-btn", 3, "click"], [1, "fa-solid", "fa-filter"], [1, "item-count"], [1, "header-controls"], [1, "tab-nav"], ["type", "button", 1, "tab-btn", 3, "click"], [1, "fa-solid", "fa-server"], [1, "tab-label"], [1, "tab-badge"], [1, "fa-solid", "fa-link"], [1, "fa-solid", "fa-wrench"], [1, "fa-solid", "fa-list-check"], ["mjButton", "", "variant", "primary"], ["mjButton", "", "variant", "flat", "title", "Refresh", 3, "disabled"], [1, "main-content"], [1, "filter-panel-container"], [3, "filtersChange", "closePanel", "filters", "activeTab", "totalCount", "filteredCount"], [1, "resize-handle"], [1, "content-area"], [1, "error-banner"], [1, "content-body"], ["text", "Loading MCP data..."], [3, "server", "visible"], [3, "connection", "servers", "visible"], [3, "Visible", "Servers", "Connections", "Tools", "SelectedServerID", "SelectedConnectionID", "SelectedToolID"], [3, "Visible", "Log"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "view-toggle"], ["type", "button", "title", "Card View", 1, "view-btn", 3, "click"], [1, "fa-solid", "fa-grip"], ["type", "button", "title", "List View", 1, "view-btn", 3, "click"], [1, "fa-solid", "fa-list"], [1, "fa-solid", "fa-play"], ["mjButton", "", "variant", "flat", "title", "Refresh", 3, "click", "disabled"], [1, "fa-solid", "fa-sync"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "data-grid", "servers-grid"], [1, "data-grid", "connections-grid"], [1, "data-table"], [1, "empty-state"], [1, "data-card", 3, "expanded"], [1, "data-card"], [1, "card-header", "clickable", 3, "click"], [1, "card-title"], [1, "fa-solid", "fa-chevron-right", "expand-arrow"], [1, "name", 3, "innerHTML"], [1, "status-badge", 3, "ngClass"], [1, "card-actions", 3, "click"], ["mjButton", "", "variant", "flat", "title", "Edit", 3, "click"], [1, "fa-solid", "fa-pen"], ["mjButton", "", "variant", "flat", "title", "Delete", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "card-body"], [1, "description", 3, "innerHTML"], [1, "details-grid"], [1, "detail"], [1, "label"], [1, "value"], [1, "detail", "full-width"], [1, "expanded-tools-section"], [1, "value", "url"], [1, "value", "command"], [1, "tools-section-header"], [1, "no-tools-message"], [1, "tools-mini-list"], [1, "fa-solid", "fa-info-circle"], [1, "tool-mini-card"], [1, "tool-mini-info"], [1, "tool-mini-name"], [1, "tool-mini-params"], [1, "fa-solid", "fa-sliders"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Test this tool", 3, "click"], ["mjButton", "", "variant", "flat", "title", "Sync Tools", 3, "click", "disabled"], [1, "fa-solid", "fa-sync", "fa-spin"], [1, "sync-progress-banner"], [1, "sync-result-banner", 3, "success", "error"], [1, "detail", "full-width", "error"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], [1, "sync-message"], [1, "sync-result-banner"], [1, "fa-solid", "fa-check-circle"], [1, "fa-solid", "fa-exclamation-circle"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Test this tool with this connection", 3, "click"], [1, "tools-container"], [1, "hint"], [1, "server-group", 3, "collapsed"], [1, "server-group"], [1, "server-group-header", 3, "click"], [1, "server-info"], [1, "fa-solid", "fa-chevron-right", "expand-icon"], [1, "server-name"], [1, "tool-count"], [1, "status-badge", "small", 3, "ngClass"], [1, "server-actions", 3, "click"], ["mjButton", "", "variant", "flat", "title", "Test a tool", 3, "click"], [1, "tools-grid"], [1, "tools-list"], [1, "tool-card", 3, "expanded"], [1, "tool-card"], [1, "tool-card-header", 3, "click"], [1, "tool-title"], [1, "tool-meta"], ["title", "Parameters", 1, "param-badge"], [1, "tool-description", 3, "innerHTML"], [1, "tool-card-actions"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "View details", 3, "click"], [1, "fa-solid"], [1, "tool-details"], [1, "detail-row"], [1, "detail-label"], [1, "detail-value", "mono"], [1, "detail-value"], [1, "detail-row", "full"], [1, "schema-preview"], [1, "tool-name-cell"], [1, "tool-name-info"], [1, "tool-title", 3, "innerHTML"], [1, "tool-code"], [1, "description-cell", 3, "innerHTML"], [1, "param-count"], [1, "actions-cell"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Test", 3, "click"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Details", 3, "click"], [1, "detail-row-expanded"], ["colspan", "6"], [1, "inline-details"], [1, "detail-section"], [1, "detail-section", "full"], [1, "sortable", 3, "click", "ngClass"], [1, "sort-icon", "fa-solid"], ["title", "Click for details", 1, "clickable-row", 3, "error-row"], ["title", "Click for details", 1, "clickable-row", 3, "click"], [1, "fa-solid", "fa-times-circle"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-question-circle"], [1, "tool-name"], [1, "error-message", 3, "title"], [1, "action-cell"], [1, "fa-solid", "fa-chevron-right"], [3, "close", "server", "visible"], [3, "close", "connection", "servers", "visible"], [3, "Close", "Visible", "Servers", "Connections", "Tools", "SelectedServerID", "SelectedConnectionID", "SelectedToolID"], [3, "Close", "RunAgain", "Visible", "Log"]], template: function MCPDashboardComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2648
2566
|
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h2", 3);
|
|
2649
2567
|
i0.ɵɵelement(4, "i", 4);
|
|
@@ -2760,6 +2678,6 @@ export { MCPDashboardComponent };
|
|
|
2760
2678
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MCPDashboardComponent, [{
|
|
2761
2679
|
type: Component,
|
|
2762
2680
|
args: [{ standalone: false, selector: 'mj-mcp-dashboard', template: "<div class=\"mcp-dashboard\">\n <!-- Header -->\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <h2 class=\"dashboard-title\">\n <i class=\"fa-solid fa-plug-circle-bolt\"></i>\n MCP Dashboard\n </h2>\n <button\n type=\"button\"\n class=\"filter-toggle-btn\"\n (click)=\"toggleFilterPanel()\"\n title=\"Toggle Filters\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (FilterPanelVisible) {\n Hide Filters\n } @else {\n Show Filters\n }\n </button>\n <span class=\"item-count\">{{ CurrentFilteredCount }} of {{ CurrentTotalCount }} items</span>\n </div>\n\n <div class=\"header-controls\">\n <!-- Tab Navigation -->\n <div class=\"tab-nav\">\n <button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'servers'\"\n (click)=\"setActiveTab('servers')\">\n <i class=\"fa-solid fa-server\"></i>\n <span class=\"tab-label\">Servers</span>\n <span class=\"tab-badge\">{{ servers.length }}</span>\n </button>\n <button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'connections'\"\n (click)=\"setActiveTab('connections')\">\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"tab-label\">Connections</span>\n <span class=\"tab-badge\">{{ connections.length }}</span>\n </button>\n <button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'tools'\"\n (click)=\"setActiveTab('tools')\">\n <i class=\"fa-solid fa-wrench\"></i>\n <span class=\"tab-label\">Tools</span>\n <span class=\"tab-badge\">{{ tools.length }}</span>\n </button>\n <button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"ActiveTab === 'logs'\"\n (click)=\"setActiveTab('logs')\">\n <i class=\"fa-solid fa-list-check\"></i>\n <span class=\"tab-label\">Logs</span>\n <span class=\"tab-badge\" [class.has-errors]=\"stats.failedExecutions > 0\">{{ executionLogs.length }}</span>\n </button>\n </div>\n\n <!-- Action Buttons based on tab -->\n @switch (ActiveTab) {\n @case ('servers') {\n <button mjButton variant=\"primary\" (click)=\"createServer()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Server\n </button>\n }\n @case ('connections') {\n <button mjButton variant=\"primary\" (click)=\"createConnection()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Connection\n </button>\n }\n @case ('tools') {\n <!-- View Mode Toggle -->\n <div class=\"view-toggle\">\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"ToolsViewMode === 'card'\"\n (click)=\"setToolsViewMode('card')\"\n title=\"Card View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"ToolsViewMode === 'list'\"\n (click)=\"setToolsViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n <button mjButton variant=\"primary\" (click)=\"openTestToolDialog()\">\n <i class=\"fa-solid fa-play\"></i>\n Test Tool\n </button>\n }\n @case ('logs') {\n <button mjButton variant=\"flat\" (click)=\"loadAllData()\" [disabled]=\"IsLoading\" title=\"Refresh\">\n <i class=\"fa-solid fa-sync\" [class.fa-spin]=\"IsLoading\"></i>\n Refresh\n </button>\n }\n }\n </div>\n </div>\n\n <!-- Main Content with Filter Panel -->\n <div class=\"main-content\">\n <!-- Filter Panel (Left) -->\n <div class=\"filter-panel-container\" [class.hidden]=\"!FilterPanelVisible\">\n <mj-mcp-filter-panel\n [filters]=\"CurrentFilters\"\n [activeTab]=\"ActiveTab\"\n [totalCount]=\"CurrentTotalCount\"\n [filteredCount]=\"CurrentFilteredCount\"\n (filtersChange)=\"onFiltersChange($event)\"\n (closePanel)=\"toggleFilterPanel()\">\n </mj-mcp-filter-panel>\n <!-- Resize Handle -->\n <div class=\"resize-handle\"></div>\n </div>\n\n <!-- Content Area -->\n <div class=\"content-area\">\n <!-- Error Message -->\n @if (ErrorMessage) {\n <div class=\"error-banner\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ ErrorMessage }}\n <button class=\"close-btn\" (click)=\"ErrorMessage = null\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n\n <!-- Content Body -->\n <div class=\"content-body\">\n @if (IsLoading) {\n <mj-loading text=\"Loading MCP data...\"></mj-loading>\n } @else {\n @switch (ActiveTab) {\n <!-- Servers Tab -->\n @case ('servers') {\n <div class=\"data-grid servers-grid\">\n @if (filteredServers.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-server\"></i>\n <p>No MCP servers configured</p>\n <button mjButton variant=\"primary\" (click)=\"createServer()\">\n Add Your First Server\n </button>\n </div>\n } @else {\n @for (server of filteredServers; track server.ID) {\n <div class=\"data-card\" [class.expanded]=\"isServerExpanded(server)\">\n <div class=\"card-header clickable\" (click)=\"toggleServerExpand(server)\">\n <div class=\"card-title\">\n <i class=\"fa-solid fa-chevron-right expand-arrow\" [class.rotated]=\"isServerExpanded(server)\"></i>\n <i [class]=\"getTransportIcon(server.TransportType)\"></i>\n <span class=\"name\" [innerHTML]=\"server.Name | highlightSearch:(filters$ | async)?.searchTerm\"></span>\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(server.Status)\">\n {{ server.Status }}\n </span>\n </div>\n <div class=\"card-actions\" (click)=\"$event.stopPropagation()\">\n <button mjButton variant=\"flat\" (click)=\"editServer(server)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button mjButton variant=\"flat\" (click)=\"deleteServer(server)\" title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n <div class=\"card-body\">\n @if (server.Description) {\n <p class=\"description\" [innerHTML]=\"server.Description | highlightSearch:(filters$ | async)?.searchTerm\"></p>\n }\n <div class=\"details-grid\">\n <div class=\"detail\">\n <span class=\"label\">Transport</span>\n <span class=\"value\">{{ server.TransportType }}</span>\n </div>\n <div class=\"detail\">\n <span class=\"label\">Auth</span>\n <span class=\"value\">{{ server.DefaultAuthType }}</span>\n </div>\n <div class=\"detail\">\n <span class=\"label\">Connections</span>\n <span class=\"value\">{{ server.ConnectionCount }}</span>\n </div>\n <div class=\"detail\">\n <span class=\"label\">Tools</span>\n <span class=\"value\">{{ server.ToolCount }}</span>\n </div>\n @if (server.ServerURL) {\n <div class=\"detail full-width\">\n <span class=\"label\">URL</span>\n <span class=\"value url\">{{ server.ServerURL }}</span>\n </div>\n }\n @if (server.Command) {\n <div class=\"detail full-width\">\n <span class=\"label\">Command</span>\n <span class=\"value command\">{{ server.Command }}</span>\n </div>\n }\n <div class=\"detail\">\n <span class=\"label\">Last Sync</span>\n <span class=\"value\">{{ formatDate(server.LastSyncAt) }}</span>\n </div>\n </div>\n </div>\n <!-- Expanded Tools Section -->\n @if (isServerExpanded(server)) {\n <div class=\"expanded-tools-section\">\n <div class=\"tools-section-header\">\n <i class=\"fa-solid fa-wrench\"></i>\n <span>Available Tools ({{ getToolsForServer(server.ID).length }})</span>\n </div>\n @if (getToolsForServer(server.ID).length === 0) {\n <div class=\"no-tools-message\">\n <i class=\"fa-solid fa-info-circle\"></i>\n No tools discovered yet. Sync a connection to discover tools.\n </div>\n } @else {\n <div class=\"tools-mini-list\">\n @for (tool of getToolsForServer(server.ID); track tool.ID) {\n <div class=\"tool-mini-card\">\n <div class=\"tool-mini-info\">\n <span class=\"tool-mini-name\">{{ tool.ToolTitle || tool.ToolName }}</span>\n <span class=\"tool-mini-params\">\n <i class=\"fa-solid fa-sliders\"></i>\n {{ getParamCount(tool) }} params\n </span>\n </div>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"runToolFromCard(tool); $event.stopPropagation()\"\n title=\"Test this tool\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n\n <!-- Connections Tab -->\n @case ('connections') {\n <div class=\"data-grid connections-grid\">\n @if (filteredConnections.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-link\"></i>\n <p>No connections configured</p>\n <button mjButton variant=\"primary\" (click)=\"createConnection()\">\n Add Your First Connection\n </button>\n </div>\n } @else {\n @for (conn of filteredConnections; track conn.ID) {\n <div class=\"data-card\" [class.expanded]=\"isConnectionExpanded(conn)\">\n <div class=\"card-header clickable\" (click)=\"toggleConnectionExpand(conn)\">\n <div class=\"card-title\">\n <i class=\"fa-solid fa-chevron-right expand-arrow\" [class.rotated]=\"isConnectionExpanded(conn)\"></i>\n <i class=\"fa-solid fa-link\"></i>\n <span class=\"name\" [innerHTML]=\"conn.Name | highlightSearch:(filters$ | async)?.searchTerm\"></span>\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(conn.Status)\">\n {{ conn.Status }}\n </span>\n </div>\n <div class=\"card-actions\" (click)=\"$event.stopPropagation()\">\n <button mjButton\n variant=\"flat\"\n (click)=\"syncConnectionTools(conn)\"\n [disabled]=\"isSyncing(conn.ID)\"\n title=\"Sync Tools\">\n @if (isSyncing(conn.ID)) {\n <i class=\"fa-solid fa-sync fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-sync\"></i>\n }\n </button>\n <button mjButton variant=\"flat\" (click)=\"editConnection(conn)\" title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button mjButton variant=\"flat\" (click)=\"deleteConnection(conn)\" title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n <!-- Sync Progress Banner -->\n @if (isSyncing(conn.ID)) {\n <div class=\"sync-progress-banner\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span class=\"sync-message\">{{ getSyncProgressMessage(conn.ID) || 'Syncing...' }}</span>\n </div>\n }\n <!-- Sync Result Banner -->\n @if (getSyncState(conn.ID)?.lastResult && !isSyncing(conn.ID)) {\n <div class=\"sync-result-banner\"\n [class.success]=\"getSyncState(conn.ID)?.lastResult?.Success\"\n [class.error]=\"!getSyncState(conn.ID)?.lastResult?.Success\">\n @if (getSyncState(conn.ID)?.lastResult?.Success) {\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Synced: {{ getSyncState(conn.ID)?.lastResult?.Added }} added,\n {{ getSyncState(conn.ID)?.lastResult?.Updated }} updated,\n {{ getSyncState(conn.ID)?.lastResult?.Deprecated }} deprecated\n </span>\n } @else {\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ getSyncState(conn.ID)?.lastResult?.ErrorMessage }}</span>\n }\n </div>\n }\n <div class=\"card-body\">\n @if (conn.Description) {\n <p class=\"description\" [innerHTML]=\"conn.Description | highlightSearch:(filters$ | async)?.searchTerm\"></p>\n }\n <div class=\"details-grid\">\n <div class=\"detail\">\n <span class=\"label\">Server</span>\n <span class=\"value\">{{ conn.ServerName }}</span>\n </div>\n <div class=\"detail\">\n <span class=\"label\">Auto Sync</span>\n <span class=\"value\">{{ conn.AutoSyncTools ? 'Yes' : 'No' }}</span>\n </div>\n <div class=\"detail\">\n <span class=\"label\">Logging</span>\n <span class=\"value\">{{ conn.LogToolCalls ? 'Enabled' : 'Disabled' }}</span>\n </div>\n <div class=\"detail\">\n <span class=\"label\">Last Connected</span>\n <span class=\"value\">{{ formatDate(conn.LastConnectedAt) }}</span>\n </div>\n @if (conn.LastErrorMessage) {\n <div class=\"detail full-width error\">\n <span class=\"label\">Last Error</span>\n <span class=\"value\">{{ conn.LastErrorMessage }}</span>\n </div>\n }\n </div>\n </div>\n <!-- Expanded Tools Section -->\n @if (isConnectionExpanded(conn)) {\n <div class=\"expanded-tools-section\">\n <div class=\"tools-section-header\">\n <i class=\"fa-solid fa-wrench\"></i>\n <span>Available Tools ({{ getToolsForConnection(conn.ID).length }})</span>\n </div>\n @if (getToolsForConnection(conn.ID).length === 0) {\n <div class=\"no-tools-message\">\n <i class=\"fa-solid fa-info-circle\"></i>\n No tools discovered yet. Click the sync button to discover tools.\n </div>\n } @else {\n <div class=\"tools-mini-list\">\n @for (tool of getToolsForConnection(conn.ID); track tool.ID) {\n <div class=\"tool-mini-card\">\n <div class=\"tool-mini-info\">\n <span class=\"tool-mini-name\">{{ tool.ToolTitle || tool.ToolName }}</span>\n <span class=\"tool-mini-params\">\n <i class=\"fa-solid fa-sliders\"></i>\n {{ getParamCount(tool) }} params\n </span>\n </div>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"runToolFromCard(tool, conn); $event.stopPropagation()\"\n title=\"Test this tool with this connection\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n\n <!-- Tools Tab -->\n @case ('tools') {\n @if (ServerGroups.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-wrench\"></i>\n <p>No tools discovered yet</p>\n <span class=\"hint\">Tools are discovered when connections sync with MCP servers</span>\n </div>\n } @else {\n <div class=\"tools-container\">\n <!-- Server Groups -->\n @for (group of ServerGroups; track group.server.ID) {\n <div class=\"server-group\" [class.collapsed]=\"!group.expanded\">\n <!-- Server Group Header -->\n <div class=\"server-group-header\" (click)=\"toggleServerGroup(group)\">\n <div class=\"server-info\">\n <i class=\"fa-solid fa-chevron-right expand-icon\" [class.expanded]=\"group.expanded\"></i>\n <i [class]=\"getTransportIcon(group.server.TransportType)\"></i>\n <span class=\"server-name\">{{ group.server.Name }}</span>\n <span class=\"tool-count\">{{ group.tools.length }} tools</span>\n <span class=\"status-badge small\" [ngClass]=\"getStatusClass(group.server.Status)\">\n {{ group.server.Status }}\n </span>\n </div>\n <div class=\"server-actions\" (click)=\"$event.stopPropagation()\">\n <button mjButton variant=\"flat\" (click)=\"openTestToolDialog(undefined, undefined)\" title=\"Test a tool\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n </div>\n </div>\n\n <!-- Tools Content -->\n @if (group.expanded) {\n <!-- Card View -->\n @if (ToolsViewMode === 'card') {\n <div class=\"tools-grid\">\n @for (tool of group.tools; track tool.ID) {\n <div class=\"tool-card\" [class.expanded]=\"isToolExpanded(tool)\">\n <div class=\"tool-card-header\" (click)=\"toggleToolExpand(tool)\">\n <div class=\"tool-title\">\n <i class=\"fa-solid fa-wrench\"></i>\n <span class=\"name\" [innerHTML]=\"(tool.ToolTitle || tool.ToolName) | highlightSearch:(filters$ | async)?.searchTerm\"></span>\n </div>\n <div class=\"tool-meta\">\n <span class=\"param-badge\" title=\"Parameters\">\n <i class=\"fa-solid fa-sliders\"></i>\n {{ getParamCount(tool) }}\n </span>\n <span class=\"status-badge small\" [ngClass]=\"getStatusClass(tool.Status)\">\n {{ tool.Status }}\n </span>\n </div>\n </div>\n @if (tool.ToolDescription) {\n <p class=\"tool-description\" [innerHTML]=\"tool.ToolDescription | highlightSearch:(filters$ | async)?.searchTerm\"></p>\n }\n <div class=\"tool-card-actions\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"openTestToolDialog(tool)\" title=\"Test this tool\">\n <i class=\"fa-solid fa-play\"></i>\n Test\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"toggleToolExpand(tool)\" title=\"View details\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!isToolExpanded(tool)\" [class.fa-chevron-up]=\"isToolExpanded(tool)\"></i>\n {{ isToolExpanded(tool) ? 'Less' : 'More' }}\n </button>\n </div>\n <!-- Expanded Details -->\n @if (isToolExpanded(tool)) {\n <div class=\"tool-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Tool Name:</span>\n <span class=\"detail-value mono\">{{ tool.ToolName }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Parameters:</span>\n <span class=\"detail-value\">\n {{ getParamCount(tool) }} total, {{ getRequiredParamCount(tool) }} required\n </span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Discovered:</span>\n <span class=\"detail-value\">{{ formatDate(tool.DiscoveredAt) }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Last Seen:</span>\n <span class=\"detail-value\">{{ formatDate(tool.LastSeenAt) }}</span>\n </div>\n @if (tool.InputSchema) {\n <div class=\"detail-row full\">\n <span class=\"detail-label\">Input Schema:</span>\n <pre class=\"schema-preview\">{{ getFormattedInputSchema(tool) }}</pre>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- List View -->\n <div class=\"tools-list\">\n <table>\n <thead>\n <tr>\n <th>Tool</th>\n <th>Description</th>\n <th>Params</th>\n <th>Status</th>\n <th>Last Seen</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (tool of group.tools; track tool.ID) {\n <tr [class.expanded]=\"isToolExpanded(tool)\">\n <td class=\"tool-name-cell\">\n <i class=\"fa-solid fa-wrench\"></i>\n <div class=\"tool-name-info\">\n <span class=\"tool-title\" [innerHTML]=\"(tool.ToolTitle || tool.ToolName) | highlightSearch:(filters$ | async)?.searchTerm\"></span>\n @if (tool.ToolTitle) {\n <span class=\"tool-code\">{{ tool.ToolName }}</span>\n }\n </div>\n </td>\n <td class=\"description-cell\" [innerHTML]=\"(tool.ToolDescription || '-') | highlightSearch:(filters$ | async)?.searchTerm\">\n </td>\n <td>\n <span class=\"param-count\">{{ getParamCount(tool) }}</span>\n </td>\n <td>\n <span class=\"status-badge small\" [ngClass]=\"getStatusClass(tool.Status)\">\n {{ tool.Status }}\n </span>\n </td>\n <td>{{ formatDate(tool.LastSeenAt) }}</td>\n <td class=\"actions-cell\">\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"openTestToolDialog(tool)\" title=\"Test\">\n <i class=\"fa-solid fa-play\"></i>\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"toggleToolExpand(tool)\" title=\"Details\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!isToolExpanded(tool)\" [class.fa-chevron-up]=\"isToolExpanded(tool)\"></i>\n </button>\n </td>\n </tr>\n @if (isToolExpanded(tool)) {\n <tr class=\"detail-row-expanded\">\n <td colspan=\"6\">\n <div class=\"inline-details\">\n <div class=\"detail-section\">\n <span class=\"detail-label\">Tool Name:</span>\n <span class=\"detail-value mono\">{{ tool.ToolName }}</span>\n </div>\n <div class=\"detail-section\">\n <span class=\"detail-label\">Discovered:</span>\n <span class=\"detail-value\">{{ formatDate(tool.DiscoveredAt) }}</span>\n </div>\n <div class=\"detail-section\">\n <span class=\"detail-label\">Required Params:</span>\n <span class=\"detail-value\">{{ getRequiredParamCount(tool) }}</span>\n </div>\n @if (tool.InputSchema) {\n <div class=\"detail-section full\">\n <span class=\"detail-label\">Input Schema:</span>\n <pre class=\"schema-preview\">{{ getFormattedInputSchema(tool) }}</pre>\n </div>\n }\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n }\n\n <!-- Logs Tab -->\n @case ('logs') {\n <div class=\"data-table\">\n @if (filteredLogs.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-list-check\"></i>\n <p>No recent execution logs</p>\n <span class=\"hint\">Logs appear when tools are executed via MCP connections</span>\n </div>\n } @else {\n <table>\n <thead>\n <tr>\n <th class=\"sortable\" [ngClass]=\"getLogSortClass('status')\" (click)=\"onLogSortColumn('status')\">\n Status\n <i class=\"sort-icon fa-solid\" [class.fa-sort-up]=\"LogsSortColumn === 'status' && LogsSortAscending\" [class.fa-sort-down]=\"LogsSortColumn === 'status' && !LogsSortAscending\" [class.fa-sort]=\"LogsSortColumn !== 'status'\"></i>\n </th>\n <th class=\"sortable\" [ngClass]=\"getLogSortClass('server')\" (click)=\"onLogSortColumn('server')\">\n Server\n <i class=\"sort-icon fa-solid\" [class.fa-sort-up]=\"LogsSortColumn === 'server' && LogsSortAscending\" [class.fa-sort-down]=\"LogsSortColumn === 'server' && !LogsSortAscending\" [class.fa-sort]=\"LogsSortColumn !== 'server'\"></i>\n </th>\n <th class=\"sortable\" [ngClass]=\"getLogSortClass('tool')\" (click)=\"onLogSortColumn('tool')\">\n Tool\n <i class=\"sort-icon fa-solid\" [class.fa-sort-up]=\"LogsSortColumn === 'tool' && LogsSortAscending\" [class.fa-sort-down]=\"LogsSortColumn === 'tool' && !LogsSortAscending\" [class.fa-sort]=\"LogsSortColumn !== 'tool'\"></i>\n </th>\n <th class=\"sortable\" [ngClass]=\"getLogSortClass('connection')\" (click)=\"onLogSortColumn('connection')\">\n Connection\n <i class=\"sort-icon fa-solid\" [class.fa-sort-up]=\"LogsSortColumn === 'connection' && LogsSortAscending\" [class.fa-sort-down]=\"LogsSortColumn === 'connection' && !LogsSortAscending\" [class.fa-sort]=\"LogsSortColumn !== 'connection'\"></i>\n </th>\n <th class=\"sortable\" [ngClass]=\"getLogSortClass('started')\" (click)=\"onLogSortColumn('started')\">\n Started\n <i class=\"sort-icon fa-solid\" [class.fa-sort-up]=\"LogsSortColumn === 'started' && LogsSortAscending\" [class.fa-sort-down]=\"LogsSortColumn === 'started' && !LogsSortAscending\" [class.fa-sort]=\"LogsSortColumn !== 'started'\"></i>\n </th>\n <th class=\"sortable\" [ngClass]=\"getLogSortClass('duration')\" (click)=\"onLogSortColumn('duration')\">\n Duration\n <i class=\"sort-icon fa-solid\" [class.fa-sort-up]=\"LogsSortColumn === 'duration' && LogsSortAscending\" [class.fa-sort-down]=\"LogsSortColumn === 'duration' && !LogsSortAscending\" [class.fa-sort]=\"LogsSortColumn !== 'duration'\"></i>\n </th>\n <th class=\"sortable\" [ngClass]=\"getLogSortClass('error')\" (click)=\"onLogSortColumn('error')\">\n Error\n <i class=\"sort-icon fa-solid\" [class.fa-sort-up]=\"LogsSortColumn === 'error' && LogsSortAscending\" [class.fa-sort-down]=\"LogsSortColumn === 'error' && !LogsSortAscending\" [class.fa-sort]=\"LogsSortColumn !== 'error'\"></i>\n </th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (log of filteredLogs; track log.ID) {\n <tr [class.error-row]=\"log.Status === 'Error'\"\n class=\"clickable-row\"\n (click)=\"onLogClick(log)\"\n title=\"Click for details\">\n <td>\n <span class=\"status-badge\" [ngClass]=\"getStatusClass(log.Status)\">\n @switch (log.Status) {\n @case ('Success') {\n <i class=\"fa-solid fa-check-circle\"></i>\n }\n @case ('Error') {\n <i class=\"fa-solid fa-times-circle\"></i>\n }\n @case ('Running') {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n @default {\n <i class=\"fa-solid fa-question-circle\"></i>\n }\n }\n {{ log.Status || 'Unknown' }}\n </span>\n </td>\n <td class=\"server-name\">{{ log.ServerName }}</td>\n <td class=\"tool-name\">{{ log.ToolName }}</td>\n <td>{{ log.ConnectionName }}</td>\n <td>{{ formatDate(log.StartedAt) }}</td>\n <td>{{ formatDuration(log.DurationMs) }}</td>\n <td class=\"error-message\" [title]=\"log.ErrorMessage || ''\">\n {{ log.ErrorMessage || '-' }}\n </td>\n <td class=\"action-cell\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n }\n }\n }\n </div>\n </div>\n </div>\n</div>\n\n<!-- Server Dialog -->\n@if (ShowServerDialog) {\n <mj-mcp-server-dialog\n [server]=\"EditingServer\"\n [visible]=\"ShowServerDialog\"\n (close)=\"onServerDialogClose($event)\">\n </mj-mcp-server-dialog>\n}\n\n<!-- Connection Dialog -->\n@if (ShowConnectionDialog) {\n <mj-mcp-connection-dialog\n [connection]=\"EditingConnection\"\n [servers]=\"servers\"\n [visible]=\"ShowConnectionDialog\"\n (close)=\"onConnectionDialogClose($event)\">\n </mj-mcp-connection-dialog>\n}\n\n<!-- Test Tool Dialog -->\n@if (ShowTestToolDialog) {\n <mj-mcp-test-tool-dialog\n [Visible]=\"ShowTestToolDialog\"\n [Servers]=\"servers\"\n [Connections]=\"connections\"\n [Tools]=\"tools\"\n [SelectedServerID]=\"TestToolServerID\"\n [SelectedConnectionID]=\"TestToolConnectionID\"\n [SelectedToolID]=\"TestToolID\"\n (Close)=\"onTestToolDialogClose()\">\n </mj-mcp-test-tool-dialog>\n}\n\n<!-- Log Detail Panel -->\n@if (ShowLogDetailPanel && SelectedLog) {\n <mj-mcp-log-detail-panel\n [Visible]=\"ShowLogDetailPanel\"\n [Log]=\"SelectedLog\"\n (Close)=\"onLogDetailClose()\"\n (RunAgain)=\"onRunAgainFromLog($event)\">\n </mj-mcp-log-detail-panel>\n}\n", styles: ["/* MCP Dashboard - Header + Filter Panel Layout */\n.mcp-dashboard {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n}\n\n/* ========================================\n Dashboard Header\n ======================================== */\n.dashboard-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 20px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 16px;\n}\n\n.header-info {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.dashboard-title {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.dashboard-title i {\n color: var(--mj-brand-primary);\n font-size: 20px;\n}\n\n.filter-toggle-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.filter-toggle-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.filter-toggle-btn i {\n font-size: 12px;\n}\n\n.item-count {\n font-size: 13px;\n color: var(--mj-text-secondary);\n padding: 4px 10px;\n background: var(--mj-bg-surface-card);\n border-radius: 4px;\n}\n\n.header-controls {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n/* Tab Navigation */\n.tab-nav {\n display: flex;\n gap: 4px;\n background: var(--mj-bg-surface-card);\n padding: 4px;\n border-radius: 8px;\n}\n\n.tab-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.tab-btn:hover {\n background: color-mix(in srgb, var(--mj-bg-surface) 70%, transparent);\n color: var(--mj-text-primary);\n}\n\n.tab-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n.tab-label {\n font-weight: 500;\n}\n\n.tab-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 18px;\n padding: 0 6px;\n background: var(--mj-border-default);\n border-radius: 9px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n}\n\n.tab-btn.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.tab-badge.has-errors {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n/* ========================================\n Main Content Area (with Filter Panel)\n ======================================== */\n.main-content {\n display: flex;\n flex-direction: row;\n flex: 1;\n overflow: hidden;\n min-width: 0;\n}\n\n/* Filter Panel Container */\n.filter-panel-container {\n display: flex;\n flex-shrink: 0;\n width: 280px;\n min-width: 200px;\n max-width: 400px;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n position: relative;\n transition: width 0.2s ease, margin 0.2s ease;\n}\n\n.filter-panel-container.hidden {\n width: 0;\n min-width: 0;\n margin-left: -1px;\n overflow: hidden;\n}\n\n/* Resize Handle */\n.resize-handle {\n position: absolute;\n top: 0;\n right: 0;\n width: 4px;\n height: 100%;\n cursor: col-resize;\n background: transparent;\n transition: background 0.2s ease;\n z-index: 10;\n}\n\n.resize-handle:hover,\n.resize-handle:active {\n background: var(--mj-brand-primary);\n}\n\n/* Content Area */\n.content-area {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n min-width: 0;\n}\n\n/* Content Body */\n.content-body {\n flex: 1;\n padding: 20px 24px;\n overflow: auto;\n}\n\n/* Error Banner */\n.error-banner {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n margin: 16px 24px 0 24px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error);\n border-radius: 8px;\n color: var(--mj-status-error);\n}\n\n.error-banner .close-btn {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-status-error);\n padding: 4px;\n}\n\n/* ========================================\n Data Display Components\n ======================================== */\n\n/* Data Grid (Cards) */\n.data-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n gap: 16px;\n}\n\n.data-card {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n transition: box-shadow 0.2s ease;\n}\n\n.data-card:hover {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n\n.card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.card-title {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.card-title i {\n color: var(--mj-brand-primary);\n}\n\n.card-title .name {\n font-weight: 600;\n font-size: 15px;\n}\n\n.card-actions {\n display: flex;\n gap: 4px;\n}\n\n.card-actions button {\n padding: 4px 8px;\n}\n\n.card-body {\n padding: 16px;\n}\n\n.card-body .description {\n margin: 0 0 12px 0;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px;\n}\n\n.detail {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail.full-width {\n grid-column: 1 / -1;\n}\n\n.detail.error .value {\n color: var(--mj-status-error);\n}\n\n.detail .label {\n font-size: 11px;\n text-transform: uppercase;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n.detail .value {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.detail .value.url,\n.detail .value.command {\n font-family: monospace;\n font-size: 12px;\n background: var(--mj-bg-surface-card);\n padding: 4px 8px;\n border-radius: 4px;\n word-break: break-all;\n}\n\n/* Status Badges */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-active {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.status-inactive {\n background: color-mix(in srgb, var(--mj-text-disabled) 10%, var(--mj-bg-surface));\n color: var(--mj-text-disabled);\n}\n\n.status-error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.status-deprecated {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.status-unknown {\n background: color-mix(in srgb, var(--mj-text-disabled) 10%, var(--mj-bg-surface));\n color: var(--mj-text-disabled);\n}\n\n/* Sync Progress & Result Banners */\n.sync-progress-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n.sync-progress-banner i {\n color: var(--mj-brand-primary);\n}\n\n.sync-progress-banner .sync-message {\n flex: 1;\n}\n\n.sync-result-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n font-size: 12px;\n border-bottom: 1px solid;\n}\n\n.sync-result-banner.success {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n color: var(--mj-color-success-700);\n}\n\n.sync-result-banner.success i {\n color: var(--mj-status-success);\n}\n\n.sync-result-banner.error {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n color: var(--mj-status-error);\n}\n\n.sync-result-banner.error i {\n color: var(--mj-status-error);\n}\n\n/* Data Table */\n.data-table {\n overflow: auto;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n\n.data-table table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table th,\n.data-table td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.data-table th {\n font-size: 11px;\n text-transform: uppercase;\n color: var(--mj-text-disabled);\n font-weight: 600;\n background: var(--mj-bg-surface-card);\n position: sticky;\n top: 0;\n}\n\n.data-table tbody tr {\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.data-table tbody tr:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.data-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n.data-table tbody tr.error-row {\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n}\n\n.data-table .tool-name {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 500;\n}\n\n.data-table .tool-name i {\n color: var(--mj-brand-primary);\n}\n\n.data-table .error-message {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--mj-status-error);\n font-size: 12px;\n}\n\n.data-table .server-name {\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n/* Sortable Column Headers */\n.data-table th.sortable {\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.data-table th.sortable:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.data-table th.sortable .sort-icon {\n margin-left: 6px;\n font-size: 10px;\n color: var(--mj-border-strong);\n transition: color 0.15s ease;\n}\n\n.data-table th.sortable:hover .sort-icon {\n color: var(--mj-text-disabled);\n}\n\n.data-table th.sorted-asc .sort-icon,\n.data-table th.sorted-desc .sort-icon {\n color: var(--mj-brand-primary);\n}\n\n/* Status badge icons */\n.status-badge i {\n font-size: 12px;\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n\n.empty-state i {\n font-size: 48px;\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.empty-state p {\n margin: 0 0 8px 0;\n font-size: 16px;\n color: var(--mj-text-primary);\n}\n\n.empty-state .hint {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-bottom: 16px;\n}\n\n/* ========================================\n View Mode Toggle\n ======================================== */\n.view-toggle {\n display: flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.view-toggle button {\n border-radius: 0;\n border: none;\n padding: 6px 10px;\n}\n\n.view-toggle button.active {\n background: var(--mj-brand-primary);\n color: var(--mj-color-neutral-0);\n}\n\n/* ========================================\n Tools Tab - Server Groups\n ======================================== */\n.tools-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.server-group {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.server-group-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.server-group-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.server-group.collapsed .server-group-header {\n border-bottom: none;\n}\n\n.server-info {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.expand-icon {\n font-size: 12px;\n color: var(--mj-text-disabled);\n transition: transform 0.2s ease;\n}\n\n.expand-icon.expanded {\n transform: rotate(90deg);\n}\n\n.server-name {\n font-weight: 600;\n font-size: 15px;\n color: var(--mj-text-primary);\n}\n\n.tool-count {\n font-size: 12px;\n color: var(--mj-text-secondary);\n background: rgba(0, 0, 0, 0.05);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-badge.small {\n padding: 2px 6px;\n font-size: 10px;\n}\n\n.server-actions {\n display: flex;\n gap: 4px;\n}\n\n/* ========================================\n Tools Grid (Card View)\n ======================================== */\n.tools-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 12px;\n padding: 16px;\n}\n\n.tool-card {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.tool-card:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tool-card.expanded {\n border-color: var(--mj-brand-primary);\n}\n\n.tool-card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 14px;\n cursor: pointer;\n}\n\n.tool-title {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.tool-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.tool-title .name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.tool-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.param-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: 10px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.param-badge i {\n font-size: 10px;\n}\n\n.tool-description {\n margin: 0;\n padding: 0 14px 8px 14px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.tool-card-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 14px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n/* Tool Details (Expanded) */\n.tool-details {\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.tool-details .detail-row {\n display: flex;\n padding: 6px 0;\n font-size: 12px;\n}\n\n.tool-details .detail-row.full {\n flex-direction: column;\n gap: 6px;\n}\n\n.tool-details .detail-label {\n min-width: 100px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.tool-details .detail-value {\n color: var(--mj-text-primary);\n}\n\n.tool-details .detail-value.mono {\n font-family: 'Consolas', 'Monaco', monospace;\n background: var(--mj-bg-surface);\n padding: 2px 6px;\n border-radius: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.schema-preview {\n margin: 0;\n padding: 10px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n font-family: 'Consolas', 'Monaco', monospace;\n font-size: 11px;\n line-height: 1.4;\n max-height: 200px;\n overflow: auto;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* ========================================\n Tools List View\n ======================================== */\n.tools-list {\n overflow: auto;\n}\n\n.tools-list table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.tools-list th,\n.tools-list td {\n padding: 10px 14px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.tools-list th {\n font-size: 11px;\n text-transform: uppercase;\n color: var(--mj-text-disabled);\n font-weight: 600;\n background: var(--mj-bg-surface-card);\n position: sticky;\n top: 0;\n}\n\n.tools-list tbody tr {\n transition: background 0.15s ease;\n}\n\n.tools-list tbody tr:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.tools-list tbody tr.expanded {\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, transparent);\n}\n\n.tool-name-cell {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n}\n\n.tool-name-cell i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n}\n\n.tool-name-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.tool-name-info .tool-title {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.tool-name-info .tool-code {\n font-size: 11px;\n font-family: monospace;\n color: var(--mj-text-secondary);\n}\n\n.description-cell {\n max-width: 300px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.param-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.actions-cell {\n white-space: nowrap;\n}\n\n/* Expanded Detail Row in List View */\n.detail-row-expanded td {\n padding: 0;\n background: var(--mj-bg-surface-card);\n}\n\n.inline-details {\n display: flex;\n flex-wrap: wrap;\n gap: 16px;\n padding: 14px;\n border-top: 1px dashed var(--mj-border-default);\n}\n\n.inline-details .detail-section {\n display: flex;\n gap: 8px;\n font-size: 12px;\n}\n\n.inline-details .detail-section.full {\n flex-basis: 100%;\n flex-direction: column;\n gap: 6px;\n}\n\n.inline-details .detail-label {\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.inline-details .detail-value {\n color: var(--mj-text-primary);\n}\n\n.inline-details .detail-value.mono {\n font-family: monospace;\n}\n\n/* ========================================\n Responsive Styles\n ======================================== */\n@media (max-width: 900px) {\n .mcp-dashboard {\n flex-direction: column;\n }\n\n .sidebar {\n width: 100%;\n min-width: 100%;\n flex-direction: row;\n height: auto;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .sidebar-header {\n padding: 12px 16px;\n border-bottom: none;\n border-right: 1px solid var(--mj-border-default);\n }\n\n .sidebar-nav {\n flex-direction: row;\n padding: 8px;\n overflow-x: auto;\n flex: 1;\n }\n\n .nav-item {\n padding: 8px 12px;\n margin-bottom: 0;\n margin-right: 4px;\n white-space: nowrap;\n }\n\n .sidebar-stats {\n display: none;\n }\n\n .sidebar-footer {\n border-top: none;\n border-left: 1px solid var(--mj-border-default);\n padding: 8px;\n }\n\n .data-grid {\n grid-template-columns: 1fr;\n }\n\n .header-actions {\n flex-wrap: wrap;\n }\n\n .search-box {\n min-width: 100%;\n order: 1;\n }\n}\n\n@media (max-width: 600px) {\n .content-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .header-actions {\n width: 100%;\n }\n\n .search-box {\n width: 100%;\n }\n}\n\n/* ========================================\n Clickable Log Rows\n ======================================== */\n.clickable-row {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.clickable-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent) !important;\n}\n\n.clickable-row .action-cell {\n color: var(--mj-border-strong);\n transition: color 0.15s ease;\n}\n\n.clickable-row:hover .action-cell {\n color: var(--mj-brand-primary);\n}\n\n.action-cell {\n width: 40px;\n text-align: center;\n}\n\n/* ========================================\n Expandable Card Styles\n ======================================== */\n.card-header.clickable {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.card-header.clickable:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.expand-arrow {\n font-size: 12px;\n color: var(--mj-text-disabled);\n transition: transform 0.2s ease;\n margin-right: 4px;\n}\n\n.expand-arrow.rotated {\n transform: rotate(90deg);\n}\n\n.data-card.expanded {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* ========================================\n Expanded Tools Section (Server/Connection Cards)\n ======================================== */\n.expanded-tools-section {\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.tools-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.tools-section-header i {\n font-size: 14px;\n}\n\n.no-tools-message {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.no-tools-message i {\n color: var(--mj-text-disabled);\n}\n\n/* Tools Mini List */\n.tools-mini-list {\n padding: 8px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n max-height: 300px;\n overflow-y: auto;\n}\n\n.tool-mini-card {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n transition: all 0.15s ease;\n}\n\n.tool-mini-card:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 2%, transparent);\n}\n\n.tool-mini-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n}\n\n.tool-mini-name {\n font-weight: 500;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tool-mini-params {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.tool-mini-params i {\n font-size: 10px;\n}\n\n.tool-mini-card button {\n flex-shrink: 0;\n margin-left: 8px;\n}\n\n/* Search Highlight */\n:host ::ng-deep .search-highlight,\n.search-highlight {\n background-color: color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: inherit;\n}\n"] }]
|
|
2763
|
-
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.
|
|
2764
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MCPDashboardComponent, { className: "MCPDashboardComponent", filePath: "src/MCP/mcp-dashboard.component.ts", lineNumber:
|
|
2681
|
+
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MCPToolsService }], null); })();
|
|
2682
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MCPDashboardComponent, { className: "MCPDashboardComponent", filePath: "src/MCP/mcp-dashboard.component.ts", lineNumber: 194 }); })();
|
|
2765
2683
|
//# sourceMappingURL=mcp-dashboard.component.js.map
|