feat: ip access control

This commit is contained in:
jialin
2026-04-29 18:09:55 +08:00
committed by jialin
parent c68f546be9
commit ac99156c90
6 changed files with 85 additions and 32 deletions
+50 -21
View File
@@ -1,39 +1,66 @@
// columns.ts
import { tableSorter } from '@/config/settings';
import { AutoTooltip, DropdownButtons, icons } from '@gpustack/core-ui';
import { getGPUStackPlugin } from '@/plugins';
import {
AutoTooltip,
DropdownButtons,
IconFont,
icons
} from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Tag } from 'antd';
import { MenuProps, Tag } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import dayjs from 'dayjs';
import { useMemo } from 'react';
import { ListItem } from '../config/types';
type APIKeyAction = Global.ActionItem<ListItem> & {
onClick?: (record: ListItem) => void;
};
interface ColumnsHookProps {
handleSelect: (val: string, record: ListItem) => void;
handleSelect: (val: string, record: ListItem, item?: APIKeyAction) => void;
sortOrder: string[];
is_admin?: boolean;
onIPConfig?: (record: ListItem) => void;
}
const actionList: Global.ActionItem<string>[] = [
{
label: 'common.button.edit',
key: 'edit',
icon: icons.EditOutlined
},
{
label: 'common.button.delete',
key: 'delete',
icon: icons.DeleteOutlined,
props: { danger: true }
}
];
const useModelsColumns = ({
handleSelect,
sortOrder,
is_admin
is_admin,
onIPConfig
}: ColumnsHookProps): ColumnsType<ListItem> => {
const intl = useIntl();
const actionList = useMemo<APIKeyAction[]>(() => {
const list: APIKeyAction[] = [
{
label: 'common.button.edit',
key: 'edit',
icon: icons.EditOutlined
},
{
label: 'common.button.delete',
key: 'delete',
icon: icons.DeleteOutlined,
props: { danger: true }
}
];
const ipConfigComponent = getGPUStackPlugin()?.APIKeyIPConfig?.form;
if (ipConfigComponent && onIPConfig) {
list.splice(1, 0, {
label: 'apikeys.button.ipConfig',
key: 'ipConfig',
icon: <IconFont type="icon-safe-ip" />,
onClick: (record: ListItem) => onIPConfig(record)
});
}
return list;
}, [onIPConfig]);
return useMemo(() => {
return [
{
@@ -172,13 +199,15 @@ const useModelsColumns = ({
span: 3,
render: (text, record) => (
<DropdownButtons
items={actionList}
onSelect={(val) => handleSelect(val, record)}
items={actionList as MenuProps['items']}
onSelect={(val, item) =>
handleSelect(val, record, item as APIKeyAction)
}
/>
)
}
];
}, [intl, is_admin, handleSelect]);
}, [intl, is_admin, handleSelect, actionList]);
};
export default useModelsColumns;
+32 -7
View File
@@ -3,6 +3,7 @@ import { PaginationKey } from '@/config/settings';
import type { PageActionType } from '@/config/types';
import useTableFetch from '@/hooks/use-table-fetch';
import useQueryUserList from '@/pages/users/services/use-query-user-list';
import { getGPUStackPlugin } from '@/plugins';
import { useModel } from '@@/plugin-model';
import { DeleteModal, FilterBar, IconFont, NoResult } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
@@ -53,6 +54,12 @@ const APIKeys: React.FC = () => {
});
const intl = useIntl();
const apiKeyIPConfig = getGPUStackPlugin()?.APIKeyIPConfig;
const APIKeyIPConfigForm = apiKeyIPConfig?.form;
const { openIPConfigModalStatus, openIPConfigModal, closeIPConfigModal } =
apiKeyIPConfig?.useCreateIPConfig?.() || {};
const [openAddModal, setOpenAddModal] = useState<{
open: boolean;
action: PageActionType;
@@ -115,13 +122,23 @@ const APIKeys: React.FC = () => {
});
};
const onSelect = useMemoizedFn(async (val: string, record: ListItem) => {
if (val === 'delete') {
handleDelete(record);
} else if (val === 'edit') {
handleEditKey(record);
const onSelect = useMemoizedFn(
async (
val: string,
record: ListItem,
item?: { onClick?: (r: ListItem) => void }
) => {
if (item?.onClick) {
item.onClick(record);
return;
}
if (val === 'delete') {
handleDelete(record);
} else if (val === 'edit') {
handleEditKey(record);
}
}
});
);
const handleUserChange = (val: string) => {
handleQueryChange({
@@ -152,7 +169,8 @@ const APIKeys: React.FC = () => {
const columns = useKeysColumns({
handleSelect: onSelect,
sortOrder,
is_admin: currentUser?.is_admin
is_admin: currentUser?.is_admin,
onIPConfig: openIPConfigModal
});
return (
@@ -207,6 +225,13 @@ const APIKeys: React.FC = () => {
onCancel={handleModalCancel}
onOk={handleModalOk}
></AddAPIKeyModal>
{APIKeyIPConfigForm && (
<APIKeyIPConfigForm
open={openIPConfigModalStatus.open}
apiKey={openIPConfigModalStatus.currentData}
onClose={closeIPConfigModal}
/>
)}
<DeleteModal ref={modalRef}></DeleteModal>
</>
);