diff --git a/react/src/components/UserCredentialList.tsx b/react/src/components/UserCredentialList.tsx index 84e302582..c1ed52526 100644 --- a/react/src/components/UserCredentialList.tsx +++ b/react/src/components/UserCredentialList.tsx @@ -3,6 +3,7 @@ import { filterNonNullItems, transformSorterToOrderString, } from '../helper'; +import { exportCSVWithFormattingRules } from '../helper/csv-util'; import { useUpdatableState } from '../hooks'; import { useBAIPaginationOptionState } from '../hooks/reactPaginationQueryOptions'; import BAIPropertyFilter from './BAIPropertyFilter'; @@ -21,14 +22,17 @@ import { DeleteOutlined, InfoCircleOutlined, LoadingOutlined, + MoreOutlined, ReloadOutlined, SettingOutlined, } from '@ant-design/icons'; import { App, Button, + Dropdown, Popconfirm, Radio, + TableColumnsType, Tag, Tooltip, Typography, @@ -150,6 +154,298 @@ const UserCredentialList: React.FC = () => { } `); + const columns: TableColumnsType = filterEmptyItem([ + { + key: 'user_id', + title: t('credential.UserID'), + dataIndex: 'email', + fixed: 'left', + sorter: true, + // TODO: user_id field in keypair_list is used as user's email, but sorting is done by email field + render: (value, record) => { + return record.user_id; + }, + }, + { + key: 'access_key', + title: t('credential.AccessKey'), + dataIndex: 'access_key', + sorter: true, + }, + { + key: 'is_admin', + title: t('credential.Permission'), + dataIndex: 'is_admin', + render: (isAdmin) => + isAdmin ? ( + <> + admin + user + + ) : ( + user + ), + sorter: true, + }, + { + key: 'key_age', + title: t('credential.KeyAge'), + dataIndex: 'created_at', + render: (createdAt) => { + return `${dayjs().diff(createdAt, 'day')}${t('credential.Days')}`; + }, + sorter: true, + }, + { + key: 'created_at', + title: t('credential.CreatedAt'), + dataIndex: 'created_at', + render: (createdAt) => dayjs(createdAt).format('lll'), + sorter: true, + }, + { + key: 'resource_policy', + title: t('credential.ResourcePolicy'), + dataIndex: 'resource_policy', + sorter: true, + }, + { + key: 'allocation', + title: t('credential.Allocation'), + render: (value, record) => { + return ( + + + {record.concurrency_used} + + {t('credential.Sessions')} + + + + {record.rate_limit} + + {t('credential.ReqPer15Min')} + + + + {record.num_queries} + + {t('credential.Queries')} + + + + ); + }, + }, + { + key: 'control', + title: t('general.Control'), + fixed: 'right', + render: (value, record) => { + return ( + +