diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts
index 2b0767b1..b1747839 100644
--- a/src/locales/en-US/models.ts
+++ b/src/locales/en-US/models.ts
@@ -181,5 +181,6 @@ export default {
'models.table.noselected': 'No users selected',
'models.table.users.all': 'All Users',
'models.table.users.selected': 'Selected Users',
- 'models.table.nouserFound': 'No users found'
+ 'models.table.nouserFound': 'No users found',
+ 'models.form.performance': 'Performance'
};
diff --git a/src/locales/ja-JP/models.ts b/src/locales/ja-JP/models.ts
index ca8c72b6..0f9d888f 100644
--- a/src/locales/ja-JP/models.ts
+++ b/src/locales/ja-JP/models.ts
@@ -178,7 +178,8 @@ export default {
'models.table.noselected': 'No users selected',
'models.table.users.all': 'All Users',
'models.table.users.selected': 'Selected Users',
- 'models.table.nouserFound': 'No users found'
+ 'models.table.nouserFound': 'No users found',
+ 'models.form.performance': 'Performance'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -200,5 +201,6 @@ export default {
// 16. 'models.table.nouserFound': 'No users found',
// 17. 'models.table.users.all': 'All Users',
// 18. 'models.table.users.selected': 'Selected Users',
-// 19. 'models.table.nouserFound': 'No users found'
+// 19. 'models.table.nouserFound': 'No users found',
+// 20. 'models.form.performance': 'Performance'
// ========== End of To-Do List ==========
diff --git a/src/locales/ru-RU/models.ts b/src/locales/ru-RU/models.ts
index 9a07cc69..166a8706 100644
--- a/src/locales/ru-RU/models.ts
+++ b/src/locales/ru-RU/models.ts
@@ -181,7 +181,8 @@ export default {
'models.table.noselected': 'No users selected',
'models.table.users.all': 'All users',
'models.table.users.selected': 'Selected users',
- 'models.table.nouserFound': 'No users found'
+ 'models.table.nouserFound': 'No users found',
+ 'models.form.performance': 'Performance'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -195,5 +196,6 @@ export default {
// 8. 'models.table.noselected': 'No users selected',
// 9. 'models.table.users.all': 'All users',
// 10. 'models.table.users.selected': 'Selected users',
-// 11. 'models.table.nouserFound': 'No users found'
+// 11. 'models.table.nouserFound': 'No users found',
+// 12. 'models.form.performance': 'Performance'
// ========== End of To-Do List ==========
diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts
index 73919256..6c44bab8 100644
--- a/src/locales/zh-CN/models.ts
+++ b/src/locales/zh-CN/models.ts
@@ -171,5 +171,6 @@ export default {
'models.table.noselected': '未选择用户',
'models.table.users.all': '所有用户',
'models.table.users.selected': '已选用户',
- 'models.table.nouserFound': '未找到用户'
+ 'models.table.nouserFound': '未找到用户',
+ 'models.form.performance': '性能'
};
diff --git a/src/pages/llmodels/components/instance-item.tsx b/src/pages/llmodels/components/instance-item.tsx
index b607b607..80ce785c 100644
--- a/src/pages/llmodels/components/instance-item.tsx
+++ b/src/pages/llmodels/components/instance-item.tsx
@@ -12,7 +12,6 @@ import useDownloadStream from '@/hooks/use-download-stream';
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
import { convertFileSize } from '@/utils';
import {
- CodeOutlined,
DeleteOutlined,
DownloadOutlined,
HddFilled,
@@ -273,12 +272,12 @@ const childActionList = [
],
icon:
},
- {
- label: 'Terminal',
- locale: false,
- key: 'terminal',
- icon:
- },
+ // {
+ // label: 'Terminal',
+ // locale: false,
+ // key: 'terminal',
+ // icon:
+ // },
{
label: 'common.button.downloadLog',
key: 'download',
diff --git a/src/pages/llmodels/components/search-model.tsx b/src/pages/llmodels/components/search-model.tsx
index 58c91e2b..d7589bb7 100644
--- a/src/pages/llmodels/components/search-model.tsx
+++ b/src/pages/llmodels/components/search-model.tsx
@@ -23,6 +23,7 @@ import SearchResult from './search-result';
const filterOptions = [
{ label: 'AWQ', value: 'awq' },
{ label: 'GPTQ', value: 'gptq' }
+ // { label: 'GGUF', value: 'gguf' }
];
const PaginationMain = styled(Pagination)`
.ant-pagination-slash {
@@ -532,13 +533,9 @@ const SearchModel: React.FC = (props) => {
{
- return (
-
- {intl.formatMessage({ id: 'model.deploy.sort' })}: {label}
-
- );
- }}
+ prefix={
+ {intl.formatMessage({ id: 'model.deploy.sort' })}:
+ }
options={modelFilesSortOptions}
size="middle"
style={{ width: '150px' }}
@@ -549,7 +546,7 @@ const SearchModel: React.FC = (props) => {
onChange={handleFilterChange}
options={filterOptions}
size="middle"
- placeholder="quantization type"
+ placeholder={intl.formatMessage({ id: 'common.input.type' })}
style={{ width: 150 }}
>
diff --git a/src/pages/resources/hooks/use-worker-columns.tsx b/src/pages/resources/hooks/use-worker-columns.tsx
index 9f811932..531b4072 100644
--- a/src/pages/resources/hooks/use-worker-columns.tsx
+++ b/src/pages/resources/hooks/use-worker-columns.tsx
@@ -9,7 +9,6 @@ import {
DeleteOutlined,
DownloadOutlined,
EditOutlined,
- FileTextOutlined,
InfoCircleOutlined
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
@@ -22,11 +21,11 @@ import { Filesystem, GPUDeviceItem, ListItem } from '../config/types';
const ActionList = [
{ label: 'common.button.edit', key: 'edit', icon: },
- {
- label: 'common.button.detail',
- key: 'details',
- icon:
- },
+ // {
+ // label: 'common.button.detail',
+ // key: 'details',
+ // icon:
+ // },
{
label: 'resources.worker.download.privatekey',
key: 'download_ssh_key',
diff --git a/src/pages/users/components/add-modal.tsx b/src/pages/users/components/add-modal.tsx
index b0a8fc01..7a87a74d 100644
--- a/src/pages/users/components/add-modal.tsx
+++ b/src/pages/users/components/add-modal.tsx
@@ -17,7 +17,7 @@ type AddModalProps = {
action: PageActionType;
open: boolean;
onOk: (values: FormData) => void;
- data?: ListItem;
+ data?: ListItem | null;
onCancel: () => void;
};
const AddModal: React.FC = ({
diff --git a/src/pages/users/hooks/use-users-columns.tsx b/src/pages/users/hooks/use-users-columns.tsx
new file mode 100644
index 00000000..264e645d
--- /dev/null
+++ b/src/pages/users/hooks/use-users-columns.tsx
@@ -0,0 +1,163 @@
+// columns.ts
+import AutoTooltip from '@/components/auto-tooltip';
+import DropdownButtons from '@/components/drop-down-buttons';
+import IconFont from '@/components/icon-font';
+import icons from '@/components/icon-font/icons';
+import { useIntl } from '@umijs/max';
+import { Tag } from 'antd';
+import type { SortOrder } from 'antd/es/table/interface';
+import { ColumnsType } from 'antd/lib/table';
+import dayjs from 'dayjs';
+import { useMemo } from 'react';
+import { ListItem } from '../config/types';
+
+interface ColumnsHookProps {
+ handleSelect: (val: string, record: ListItem) => void;
+ sortOrder: SortOrder;
+}
+
+const actionList: Global.ActionItem[] = [
+ {
+ label: 'common.button.edit',
+ key: 'edit',
+ icon: icons.EditOutlined
+ },
+ {
+ label: 'common.button.delete',
+ key: 'delete',
+ icon: icons.DeleteOutlined,
+ props: { danger: true }
+ }
+];
+
+const useUsersColumns = ({
+ handleSelect,
+ sortOrder
+}: ColumnsHookProps): ColumnsType => {
+ const intl = useIntl();
+
+ return useMemo(() => {
+ return [
+ {
+ title: intl.formatMessage({ id: 'common.table.name' }),
+ dataIndex: 'username',
+ key: 'username',
+ render: (text: string, record: ListItem) => (
+
+ {text}
+
+ )
+ },
+ {
+ title: intl.formatMessage({ id: 'users.table.role' }),
+ dataIndex: 'role',
+ key: 'role',
+ ellipsis: {
+ showTitle: false
+ },
+ render: (text: string, record: ListItem) => {
+ return record.is_admin ? (
+
+
+
+ {intl.formatMessage({ id: 'users.form.admin' })}
+
+
+ ) : (
+
+
+
+ {intl.formatMessage({ id: 'users.form.user' })}
+
+
+ );
+ }
+ },
+ {
+ title: intl.formatMessage({ id: 'users.form.fullname' }),
+ dataIndex: 'full_name',
+ key: 'full_name',
+ ellipsis: {
+ showTitle: false
+ },
+ render: (text: string, record: ListItem) => (
+
+ {text}
+
+ )
+ },
+ {
+ title: intl.formatMessage({ id: 'users.form.source' }),
+ dataIndex: 'source',
+ key: 'source',
+ ellipsis: {
+ showTitle: false
+ },
+ render: (text: string[], record: ListItem) => (
+
+ {text}
+
+ )
+ },
+ {
+ title: intl.formatMessage({ id: 'users.table.status' }),
+ dataIndex: 'is_active',
+ key: 'is_active',
+ ellipsis: {
+ showTitle: false
+ },
+ render: (text: string, record: ListItem) => {
+ return (
+ <>
+
+ {intl.formatMessage({
+ id: record.is_active
+ ? 'users.status.active'
+ : 'users.status.inactive'
+ })}
+
+ >
+ );
+ }
+ },
+ {
+ title: intl.formatMessage({ id: 'common.table.createTime' }),
+ dataIndex: 'created_at',
+ key: 'created_at',
+ defaultSortOrder: 'descend',
+ showSorterTooltip: false,
+ sortOrder,
+ sorter: false,
+ ellipsis: {
+ showTitle: false
+ },
+ render: (text: number) => (
+
+ {dayjs(text).format('YYYY-MM-DD HH:mm:ss')}
+
+ )
+ },
+ {
+ title: intl.formatMessage({ id: 'common.table.operation' }),
+ key: 'operation',
+ dataIndex: 'operation',
+ span: 3,
+ render: (text, record) => (
+ handleSelect(val, record)}
+ />
+ )
+ }
+ ];
+ }, [sortOrder, intl, handleSelect]);
+};
+
+export default useUsersColumns;
diff --git a/src/pages/users/index.tsx b/src/pages/users/index.tsx
index e013ce26..15ed07fd 100644
--- a/src/pages/users/index.tsx
+++ b/src/pages/users/index.tsx
@@ -1,40 +1,18 @@
-import AutoTooltip from '@/components/auto-tooltip';
import DeleteModal from '@/components/delete-modal';
-import DropdownButtons from '@/components/drop-down-buttons';
-import IconFont from '@/components/icon-font';
-import PageTools from '@/components/page-tools';
+import { FilterBar } from '@/components/page-tools';
import { PageAction } from '@/config';
-import HotKeys from '@/config/hotkeys';
import type { PageActionType } from '@/config/types';
import useTableFetch from '@/hooks/use-table-fetch';
-import {
- DeleteOutlined,
- EditOutlined,
- PlusOutlined,
- SearchOutlined,
- SyncOutlined
-} from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
-import {
- Button,
- ConfigProvider,
- Empty,
- Input,
- message,
- Space,
- Switch,
- Table,
- Tag
-} from 'antd';
-import dayjs from 'dayjs';
+import { useMemoizedFn } from 'ahooks';
+import { ConfigProvider, Empty, message, Switch, Table } from 'antd';
import { useState } from 'react';
-import { useHotkeys } from 'react-hotkeys-hook';
import styled from 'styled-components';
import { createUser, deleteUser, queryUsersList, updateUser } from './apis';
import AddModal from './components/add-modal';
import { FormData, ListItem } from './config/types';
-const { Column } = Table;
+import useUsersColumns from './hooks/use-users-columns';
const StyledSwitch = styled(Switch)`
.ant-switch-handle::before {
@@ -43,22 +21,6 @@ const StyledSwitch = styled(Switch)`
}
`;
-const ActionList = [
- {
- key: 'edit',
- label: 'common.button.edit',
- icon:
- },
- {
- key: 'delete',
- props: {
- danger: true
- },
- label: 'common.button.delete',
- icon:
- }
-];
-
const Users: React.FC = () => {
const {
dataSource,
@@ -80,65 +42,81 @@ const Users: React.FC = () => {
});
const intl = useIntl();
- const [openAddModal, setOpenAddModal] = useState(false);
-
- const [action, setAction] = useState(PageAction.CREATE);
- const [title, setTitle] = useState('');
- const [currentData, setCurrentData] = useState(
- undefined
- );
+ const [openAddModalStatus, setOpenAddModalStatus] = useState<{
+ action: PageActionType;
+ open: boolean;
+ title: string;
+ currentData?: ListItem | null;
+ }>({
+ action: PageAction.CREATE,
+ title: '',
+ open: false,
+ currentData: null
+ });
const handleAddUser = () => {
- setOpenAddModal(true);
- setAction(PageAction.CREATE);
- setTitle(intl.formatMessage({ id: 'users.form.create' }));
+ setOpenAddModalStatus({
+ action: PageAction.CREATE,
+ title: intl.formatMessage({ id: 'users.form.create' }),
+ open: true,
+ currentData: null
+ });
};
const handleModalOk = async (data: FormData) => {
const params = {
- ...currentData,
+ ...openAddModalStatus.currentData,
...data,
is_admin: data.is_admin === 'admin'
};
try {
- if (action === PageAction.EDIT) {
+ if (openAddModalStatus.action === PageAction.EDIT) {
await updateUser({
data: {
...params,
- id: currentData?.id
+ id: openAddModalStatus.currentData?.id
}
});
} else {
await createUser({ data: params });
}
fetchData();
- setOpenAddModal(false);
+ setOpenAddModalStatus({
+ ...openAddModalStatus,
+ open: false
+ });
message.success(intl.formatMessage({ id: 'common.message.success' }));
} catch (error) {
- setOpenAddModal(false);
+ setOpenAddModalStatus({ ...openAddModalStatus, open: false });
message.error(intl.formatMessage({ id: 'common.message.fail' }));
}
};
const handleModalCancel = () => {
console.log('handleModalCancel');
- setOpenAddModal(false);
+ setOpenAddModalStatus({
+ ...openAddModalStatus,
+ open: false,
+ currentData: null
+ });
};
const handleEditUser = (row: ListItem) => {
- setCurrentData(row);
- setOpenAddModal(true);
- setAction(PageAction.EDIT);
- setTitle(intl.formatMessage({ id: 'users.form.edit' }));
+ setOpenAddModalStatus({
+ title: intl.formatMessage({ id: 'users.form.edit' }),
+ action: PageAction.EDIT,
+ open: true,
+ currentData: row
+ });
};
- const handleSelect = (val: any, row: ListItem) => {
+ const handleSelect = useMemoizedFn((val: any, row: ListItem) => {
if (val === 'edit') {
handleEditUser(row);
} else if (val === 'delete') {
handleDelete({ ...row, name: row.username });
}
- };
+ });
const handleActiveChange = async (checked: boolean, row: ListItem) => {
try {
@@ -168,15 +146,10 @@ const Users: React.FC = () => {
return ;
};
- useHotkeys(
- HotKeys.CREATE,
- () => {
- handleAddUser();
- },
- {
- enabled: !openAddModal
- }
- );
+ const columns = useUsersColumns({
+ handleSelect,
+ sortOrder
+ });
return (
<>
@@ -191,56 +164,20 @@ const Users: React.FC = () => {
}}
extra={[]}
>
-
-
- }
- placeholder={intl.formatMessage({ id: 'common.filter.name' })}
- style={{ width: 300 }}
- allowClear
- onChange={handleNameChange}
- >
-
-
- }
- right={
-
-
- }
- danger
- onClick={handleDeleteBatch}
- disabled={!rowSelection.selectedRowKeys.length}
- >
-
- {intl?.formatMessage?.({ id: 'common.button.delete' })}
- {rowSelection.selectedRowKeys.length > 0 && (
- ({rowSelection.selectedRowKeys?.length})
- )}
-
-
-
- }
- >
+ marginTop={30}
+ buttonText={intl.formatMessage({ id: 'users.button.create' })}
+ handleSearch={handleSearch}
+ handleDeleteByBatch={handleDeleteBatch}
+ handleClickPrimary={handleAddUser}
+ handleInputChange={handleNameChange}
+ rowSelection={rowSelection}
+ width={{ input: 300 }}
+ >
{
hideOnSinglePage: queryParams.perPage === 10,
onChange: handlePageChange
}}
- >
- {
- return (
-
- {text}
-
- );
- }}
- />
- {
- return record.is_admin ? (
-
-
-
- {intl.formatMessage({ id: 'users.form.admin' })}
-
-
- ) : (
-
-
-
- {intl.formatMessage({ id: 'users.form.user' })}
-
-
- );
- }}
- />
- {
- return (
-
- {text}
-
- );
- }}
- />
- {
- return (
-
- {text}
-
- );
- }}
- />
- {
- return (
- <>
-
- {intl.formatMessage({
- id: record.is_active
- ? 'users.status.active'
- : 'users.status.inactive'
- })}
-
- >
- );
- }}
- />
- {
- return (
-
- {dayjs(text).format('YYYY-MM-DD HH:mm:ss')}
-
- );
- }}
- />
- {
- return (
- handleSelect(val, record)}
- >
- );
- }}
- />
-
+ >