diff --git a/config/routes.ts b/config/routes.ts
index 1c7469e8..5b45a427 100644
--- a/config/routes.ts
+++ b/config/routes.ts
@@ -273,7 +273,7 @@ const baseRoutes = [
selectedIcon: 'icon-cluster2-filled',
defaultIcon: 'icon-cluster2-outline',
component: './cluster-management/clusters',
- subMenu: ['/resources/clusters/detail', '/resources/clusters/create']
+ subMenu: ['/resources/clusters/create']
},
{
name: 'workers',
@@ -301,16 +301,6 @@ const baseRoutes = [
selectedIcon: 'icon-credential-filled',
defaultIcon: 'icon-credential-outline',
component: './cluster-management/credentials'
- },
- {
- name: 'clusterDetail',
- path: '/resources/clusters/detail',
- key: 'clusterDetail',
- icon: 'icon-cluster2-outline',
- selectedIcon: 'icon-cluster2-filled',
- defaultIcon: 'icon-cluster2-outline',
- hideInMenu: true,
- component: './cluster-management/cluster-detail'
}
]
},
diff --git a/src/pages/cluster-management/clusters.tsx b/src/pages/cluster-management/clusters.tsx
index 23623af2..763dd9fd 100644
--- a/src/pages/cluster-management/clusters.tsx
+++ b/src/pages/cluster-management/clusters.tsx
@@ -5,6 +5,7 @@ import type { PageActionType } from '@/config/types';
import useExpandedRowKeys from '@/hooks/use-expanded-row-keys';
import useTableFetch from '@/hooks/use-table-fetch';
import useWatchList from '@/hooks/use-watch-list';
+import { getGPUStackPlugin } from '@/plugins';
import {
DeleteModal,
FilterBar,
@@ -14,7 +15,7 @@ import {
TableOrder,
TableProvider
} from '@gpustack/core-ui';
-import { useIntl, useNavigate } from '@umijs/max';
+import { useIntl } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
import { message } from 'antd';
import { useAtom } from 'jotai';
@@ -82,10 +83,13 @@ const Clusters: React.FC = () => {
mine: true
}
});
- const navigate = useNavigate();
const { goToGrafana, ActionButton } = useGranfanaLink({
type: 'cluster'
});
+ // Cluster Access lives in the enterprise plugin: it contributes the
+ // row action and this self-controlled drawer, owning its own
+ // open/close state. OSS just mounts it (nothing without a plugin).
+ const AccessDrawer = getGPUStackPlugin()?.clusterDetail?.AccessDrawer;
const { watchDataList: allWorkerPoolList } = useWatchList(WORKER_POOLS_API);
const [expandAtom] = useAtom(expandKeysAtom);
const [clusterSession, setClusterSession] = useAtom(clusterSessionAtom);
@@ -272,14 +276,6 @@ const Clusters: React.FC = () => {
);
};
- const handleOnCell = useMemoizedFn((record: ClusterListItem, dataIndex) => {
- if (dataIndex === 'name') {
- navigate(
- `/resources/clusters/detail?id=${record.id}&name=${record.name}&page=clusters`
- );
- }
- });
-
useEffect(() => {
const fetchCredentialList = async () => {
const data = await queryCredentialList({ page: -1 });
@@ -366,7 +362,7 @@ const Clusters: React.FC = () => {
);
};
- const columns = useClusterColumns(handleSelect, handleOnCell);
+ const columns = useClusterColumns(handleSelect);
return (
<>
@@ -482,6 +478,7 @@ const Clusters: React.FC = () => {
onClose={handleClusterModalClose}
>
{AddWorkerModal}
+ {AccessDrawer && }
>
);
};
diff --git a/src/pages/cluster-management/hooks/use-cluster-columns.tsx b/src/pages/cluster-management/hooks/use-cluster-columns.tsx
index c1ef413e..e8cd7bc5 100644
--- a/src/pages/cluster-management/hooks/use-cluster-columns.tsx
+++ b/src/pages/cluster-management/hooks/use-cluster-columns.tsx
@@ -13,7 +13,7 @@ import {
type TableColumnProps as SealColumnProps
} from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
-import { Tooltip, Typography } from 'antd';
+import { Tooltip } from 'antd';
import dayjs from 'dayjs';
import { useAtomValue } from 'jotai';
import { useMemo } from 'react';
@@ -85,21 +85,15 @@ const clusterActionList = [
];
const useClusterColumns = (
- handleSelect: (val: string, record: ClusterListItem, item?: any) => void,
- onCellClick?: (record: ClusterListItem, dataIndex: string) => void
+ handleSelect: (val: string, record: ClusterListItem, item?: any) => void
): SealColumnProps[] => {
const intl = useIntl();
const systemConfig = useAtomValue(systemConfigAtom);
const pluginCols = usePluginListColumns('clusters');
- // The cluster-detail page is shipped in OSS source, but OSS keeps
- // it unreachable from the cluster list — the link is only
- // surfaced when a plugin opts in via
- // `clusterDetail.linkableName`. Without a plugin we render the
- // name as plain text (matches the pre-restore behaviour); with one
- // we use Typography.Link wired to the parent's `onCellClick`.
-
- const { linkableName: nameLinkable, useGenerateActions } =
- getGPUStackPlugin()?.clusterDetail || {};
+ // The cluster name is plain text: there is no cluster-detail page
+ // to route into. A plugin may still contribute extra row actions
+ // (topology, Cluster Access) via `clusterDetail.useGenerateActions`.
+ const { useGenerateActions } = getGPUStackPlugin()?.clusterDetail || {};
const actionList =
useGenerateActions?.({ actions: clusterActionList }) || clusterActionList;
@@ -160,13 +154,7 @@ const useClusterColumns = (
render: (text: string, record: ClusterListItem) => (
<>
- {nameLinkable ? (
- onCellClick?.(record, 'name')}>
- {record.name}
-
- ) : (
- {record.name}
- )}
+ {record.name}
{record.is_default && (