feat: admin apikeys

This commit is contained in:
jialin
2026-04-17 20:35:16 +08:00
committed by jialin
parent f45d9bda61
commit 2d726ded30
8 changed files with 114 additions and 36 deletions
+5 -1
View File
@@ -129,6 +129,9 @@ interface FilterBarProps {
onClick: () => void;
onClear: () => void;
};
select?: {
showSearch?: boolean;
};
widths?: {
input?: number;
select?: number;
@@ -148,6 +151,7 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
showSelect,
buttonText,
buttonIcon,
select,
actionType = 'button',
marginBottom = 10,
marginTop = 10,
@@ -189,7 +193,7 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
{showSelect && (
<BaseSelect
allowClear
showSearch={false}
showSearch={select?.showSearch}
placeholder={selectHolder}
style={{ width: widths?.select || 230 }}
size="large"
-14
View File
@@ -215,20 +215,6 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => {
const userMenu = {
items: [
{
key: 'apikeys',
label: (
<span className="flex flex-center">
<IconFont type="icon-key" />
<span className="m-l-8" style={{ marginLeft: 8 }}>
{intl?.formatMessage?.({ id: 'menu.apikeys' })}
</span>
</span>
),
onClick: () => {
history.push('/api-keys');
}
},
{
key: 'settings',
label: (
+16 -3
View File
@@ -13,6 +13,7 @@ import { ListItem } from '../config/types';
interface ColumnsHookProps {
handleSelect: (val: string, record: ListItem) => void;
sortOrder: string[];
is_admin?: boolean;
}
const actionList: Global.ActionItem<string>[] = [
@@ -31,7 +32,8 @@ const actionList: Global.ActionItem<string>[] = [
const useModelsColumns = ({
handleSelect,
sortOrder
sortOrder,
is_admin
}: ColumnsHookProps): ColumnsType<ListItem> => {
const intl = useIntl();
@@ -69,7 +71,18 @@ const useModelsColumns = ({
dataIndex: 'masked_value',
key: 'masked_value',
render: (text: string, record: ListItem) => (
<AutoTooltip ghost style={{ maxWidth: 400 }}>
<AutoTooltip ghost style={{ maxWidth: 200 }}>
{text || '-'}
</AutoTooltip>
)
},
{
title: intl.formatMessage({ id: 'users.table.username' }),
dataIndex: 'user_name',
key: 'user_name',
hidden: !is_admin,
render: (text: string, record: ListItem) => (
<AutoTooltip ghost style={{ maxWidth: 200 }}>
{text || '-'}
</AutoTooltip>
)
@@ -166,7 +179,7 @@ const useModelsColumns = ({
)
}
];
}, [intl, handleSelect]);
}, [intl, is_admin, handleSelect]);
};
export default useModelsColumns;
+45 -5
View File
@@ -5,11 +5,13 @@ import { PageAction } from '@/config';
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 { useModel } from '@@/plugin-model';
import { useIntl } from '@umijs/max';
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
import { ConfigProvider, Table } from 'antd';
import _ from 'lodash';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import NoResult from '../_components/no-result';
import PageBox from '../_components/page-box';
import { deleteApisKey, queryApisKeysList } from './apis';
@@ -18,6 +20,8 @@ import { ListItem } from './config/types';
import useKeysColumns from './hooks/use-keys-columns';
const APIKeys: React.FC = () => {
const { initialState } = useModel('@@initialState');
const currentUser = initialState?.currentUser;
const {
TABLE_SORT_DIRECTIONS,
dataSource,
@@ -30,13 +34,25 @@ const APIKeys: React.FC = () => {
fetchData,
handlePageChange,
handleTableChange,
handleQueryChange,
handleSearch,
handleNameChange
} = useTableFetch<ListItem>({
key: PaginationKey.APIKeys,
fetchAPI: queryApisKeysList,
deleteAPI: deleteApisKey,
contentForDelete: 'apikeys.table.apikeys'
contentForDelete: 'apikeys.table.apikeys',
defaultQueryParams: {
user_id: currentUser?.is_admin ? '*' : undefined
}
});
const {
dataList: userList,
fetchData: fetchUserData,
cancelRequest: cancelUserRequest
} = useQueryUserList({
getLabel: (item) => item.username,
getValue: (item) => item.id
});
const intl = useIntl();
@@ -52,6 +68,15 @@ const APIKeys: React.FC = () => {
currentData: null
});
useEffect(() => {
fetchUserData({
page: -1
});
return () => {
cancelUserRequest();
};
}, []);
const handleAddKey = () => {
setOpenAddModal({
open: true,
@@ -101,6 +126,12 @@ const APIKeys: React.FC = () => {
}
});
const handleUserChange = (val: string) => {
handleQueryChange({
user_id: val || '*'
});
};
const renderEmpty = (type?: string) => {
if (type !== 'Table') return;
return (
@@ -121,7 +152,11 @@ const APIKeys: React.FC = () => {
);
};
const columns = useKeysColumns({ handleSelect: onSelect, sortOrder });
const columns = useKeysColumns({
handleSelect: onSelect,
sortOrder,
is_admin: currentUser?.is_admin
});
return (
<>
@@ -129,10 +164,15 @@ const APIKeys: React.FC = () => {
<FilterBar
marginBottom={22}
marginTop={30}
showSelect={currentUser?.is_admin}
selectOptions={userList}
select={{ showSearch: true }}
selectHolder={intl.formatMessage({ id: 'models.table.filterByName' })}
buttonText={intl.formatMessage({ id: 'apikeys.button.create' })}
handleSearch={handleSearch}
handleDeleteByBatch={handleDeleteBatch}
handleClickPrimary={handleAddKey}
handleSelectChange={handleUserChange}
handleInputChange={handleNameChange}
rowSelection={rowSelection}
widths={{ input: 300 }}
@@ -144,14 +184,14 @@ const APIKeys: React.FC = () => {
rowSelection={rowSelection}
loading={{
spinning: dataSource.loading,
size: 'middle'
size: 'default'
}}
sortDirections={TABLE_SORT_DIRECTIONS}
showSorterTooltip={false}
rowKey="id"
onChange={handleTableChange}
pagination={{
size: 'middle',
size: 'default',
showSizeChanger: true,
pageSize: queryParams.perPage,
current: queryParams.page,
@@ -198,7 +198,7 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
<CreateButton
type="link"
size="small"
onClick={() => navigate('/api-keys')}
onClick={() => navigate('/access-control/api-keys')}
>
{intl.formatMessage({
id: 'models.table.apiAccessInfo.gotoCreate'
@@ -94,7 +94,7 @@ const ViewCodeModal: React.FC<ViewModalProps> = (props) => {
<Button
type="link"
size="small"
href="#/api-keys"
href="#/access-control/api-keys"
target="_blank"
style={{ paddingInline: 2 }}
>
@@ -0,0 +1,36 @@
import { useQueryDataList } from '@/hooks/use-query-data-list';
import { useModel } from '@@/plugin-model';
import { queryUsersList } from '../apis';
import { ListItem } from '../config/types';
export const useQueryUserList = (optons?: {
getLabel?: (item: ListItem) => string;
getValue?: (item: ListItem) => any;
}) => {
const { initialState } = useModel('@@initialState');
const { dataList, loading, fetchData, cancelRequest } = useQueryDataList<
ListItem,
Global.SearchParams
>({
key: 'userList',
fetchList: queryUsersList,
getLabel: optons?.getLabel,
getValue: optons?.getValue
});
const fetchUserList = (params: Global.SearchParams) => {
if (!initialState?.currentUser?.is_admin) return;
return fetchData({
...params
});
};
return {
dataList,
loading,
fetchData: fetchUserList,
cancelRequest
};
};
export default useQueryUserList;