-
Notifications
You must be signed in to change notification settings - Fork 292
Expand file tree
/
Copy pathMcpDeploymentsPage.tsx
More file actions
99 lines (90 loc) · 3.34 KB
/
McpDeploymentsPage.tsx
File metadata and controls
99 lines (90 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import * as React from 'react';
import { ApplicationsPage, SimpleSelect } from 'mod-arch-shared';
import { useNamespaceSelector, useModularArchContext } from 'mod-arch-core';
import { Flex, FlexItem } from '@patternfly/react-core';
import { McpDeployment } from '~/app/mcpDeploymentTypes';
import useMcpDeployments from './useMcpDeployments';
import McpDeploymentsTable from './McpDeploymentsTable';
import McpDeploymentsToolbar from './McpDeploymentsToolbar';
import McpDeploymentsEmptyState from './McpDeploymentsEmptyState';
import { getServerDisplayName } from './utils';
const McpDeploymentsPage: React.FC = () => {
const [deployments, loaded, loadError, refresh] = useMcpDeployments();
const [filterText, setFilterText] = React.useState('');
const { namespaces = [], preferredNamespace, updatePreferredNamespace } = useNamespaceSelector();
const { config } = useModularArchContext();
const isMandatoryNamespace = Boolean(config.mandatoryNamespace);
const projectOptions = namespaces.map((ns) => ({
key: ns.name,
label: ns.name,
}));
const selectedProject = preferredNamespace?.name || namespaces[0]?.name || '';
const handleProjectChange = (key: string, isPlaceholder: boolean) => {
if (isPlaceholder || !key || isMandatoryNamespace) {
return;
}
updatePreferredNamespace({ name: key });
};
const handleDeleteClick = React.useCallback(
(_deployment: McpDeployment) => {
// Delete flow handled by RHOAIENG-53380
refresh();
},
[refresh],
);
const filteredDeployments = React.useMemo(() => {
if (!filterText) {
return deployments.items;
}
const lower = filterText.toLowerCase();
return deployments.items.filter(
(d) =>
d.name.toLowerCase().includes(lower) ||
getServerDisplayName(d).toLowerCase().includes(lower),
);
}, [deployments.items, filterText]);
const clearFilters = React.useCallback(() => setFilterText(''), []);
const isEmpty = loaded && !loadError && deployments.items.length === 0;
return (
<ApplicationsPage
title="MCP server deployments"
description="Manage and view the health and performance of your deployed MCP servers."
headerContent={
<Flex alignItems={{ default: 'alignItemsCenter' }} spaceItems={{ default: 'spaceItemsSm' }}>
<FlexItem>Project</FlexItem>
<FlexItem>
<SimpleSelect
options={projectOptions}
value={selectedProject}
onChange={handleProjectChange}
isDisabled={isMandatoryNamespace || namespaces.length === 0}
isScrollable
maxMenuHeight="300px"
popperProps={{ maxWidth: '400px' }}
dataTestId="mcp-deployments-project-selector"
/>
</FlexItem>
</Flex>
}
loadError={loadError}
loaded={loaded}
empty={isEmpty}
emptyStatePage={<McpDeploymentsEmptyState />}
provideChildrenPadding
>
<McpDeploymentsTable
deployments={filteredDeployments}
toolbarContent={
<McpDeploymentsToolbar
filterText={filterText}
onFilterChange={setFilterText}
onClearFilters={clearFilters}
/>
}
onClearFilters={clearFilters}
onDeleteClick={handleDeleteClick}
/>
</ApplicationsPage>
);
};
export default McpDeploymentsPage;