chore: models filter by category
This commit is contained in:
@@ -87,5 +87,6 @@ export default {
|
|||||||
'models.form.backend.voxbox': 'vox-box: For non-GGUF format audio models.',
|
'models.form.backend.voxbox': 'vox-box: For non-GGUF format audio models.',
|
||||||
'models.form.search.gguftips':
|
'models.form.search.gguftips':
|
||||||
'If using macOS or Windows as a worker, check GGUF (uncheck for audio models).',
|
'If using macOS or Windows as a worker, check GGUF (uncheck for audio models).',
|
||||||
'models.form.button.addlabel': 'Add Label'
|
'models.form.button.addlabel': 'Add Label',
|
||||||
|
'models.filter.category': 'Filter by Category'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -83,5 +83,6 @@ export default {
|
|||||||
'models.form.backend.voxbox': 'vox-box: 用于非 GGUF 格式的音频模型',
|
'models.form.backend.voxbox': 'vox-box: 用于非 GGUF 格式的音频模型',
|
||||||
'models.form.search.gguftips':
|
'models.form.search.gguftips':
|
||||||
'当 macOS 或 Windows 作 worker 时勾选 GGUF(搜索音频模型时取消勾选)',
|
'当 macOS 或 Windows 作 worker 时勾选 GGUF(搜索音频模型时取消勾选)',
|
||||||
'models.form.button.addlabel': '添加标签'
|
'models.form.button.addlabel': '添加标签',
|
||||||
|
'models.filter.category': '按类别筛选'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,11 +25,13 @@ export async function queryModelsList(
|
|||||||
params: Global.SearchParams,
|
params: Global.SearchParams,
|
||||||
options?: any
|
options?: any
|
||||||
) {
|
) {
|
||||||
return request<Global.PageResponse<ListItem>>(`${MODELS_API}`, {
|
return request<Global.PageResponse<ListItem>>(
|
||||||
methos: 'GET',
|
`${MODELS_API}?${qs.stringify(params)}`,
|
||||||
...options,
|
{
|
||||||
params
|
methos: 'GET',
|
||||||
});
|
...options
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function queryGPUList() {
|
export async function queryGPUList() {
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ const Catalog: React.FC = () => {
|
|||||||
source: modelSourceMap.huggingface_value
|
source: modelSourceMap.huggingface_value
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const categoryOptions = [...modelCategories.filter((item) => item.value)];
|
||||||
|
|
||||||
const fetchData = useCallback(async () => {
|
const fetchData = useCallback(async () => {
|
||||||
setDataSource((pre) => {
|
setDataSource((pre) => {
|
||||||
pre.loading = true;
|
pre.loading = true;
|
||||||
@@ -190,13 +192,13 @@ const Catalog: React.FC = () => {
|
|||||||
></Input>
|
></Input>
|
||||||
<Select
|
<Select
|
||||||
allowClear
|
allowClear
|
||||||
placeholder="Filter by category"
|
placeholder={intl.formatMessage({ id: 'models.filter.category' })}
|
||||||
style={{ width: 240 }}
|
style={{ width: 240 }}
|
||||||
size="large"
|
size="large"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
maxTagCount={1}
|
maxTagCount={1}
|
||||||
onChange={handleCategoryChange}
|
onChange={handleCategoryChange}
|
||||||
options={modelCategories.filter((item) => item.value)}
|
options={categoryOptions}
|
||||||
></Select>
|
></Select>
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import {
|
|||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
import { Access, useAccess, useIntl, useNavigate } from '@umijs/max';
|
import { Access, useAccess, useIntl, useNavigate } from '@umijs/max';
|
||||||
import { Button, Dropdown, Input, Space, Tag, message } from 'antd';
|
import { Button, Dropdown, Input, Select, Space, Tag, message } from 'antd';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
@@ -45,6 +45,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
InstanceRealLogStatus,
|
InstanceRealLogStatus,
|
||||||
getSourceRepoConfigValue,
|
getSourceRepoConfigValue,
|
||||||
|
modelCategories,
|
||||||
modelCategoriesMap,
|
modelCategoriesMap,
|
||||||
modelSourceMap
|
modelSourceMap
|
||||||
} from '../config';
|
} from '../config';
|
||||||
@@ -60,12 +61,14 @@ interface ModelsProps {
|
|||||||
handleShowSizeChange?: (page: number, size: number) => void;
|
handleShowSizeChange?: (page: number, size: number) => void;
|
||||||
handlePageChange: (page: number, pageSize: number | undefined) => void;
|
handlePageChange: (page: number, pageSize: number | undefined) => void;
|
||||||
handleDeleteSuccess: () => void;
|
handleDeleteSuccess: () => void;
|
||||||
|
handleCategoryChange: (val: any) => void;
|
||||||
onViewLogs: () => void;
|
onViewLogs: () => void;
|
||||||
onCancelViewLogs: () => void;
|
onCancelViewLogs: () => void;
|
||||||
queryParams: {
|
queryParams: {
|
||||||
page: number;
|
page: number;
|
||||||
perPage: number;
|
perPage: number;
|
||||||
query?: string;
|
query?: string;
|
||||||
|
categories?: string[];
|
||||||
};
|
};
|
||||||
deleteIds?: number[];
|
deleteIds?: number[];
|
||||||
gpuDeviceList: GPUDeviceItem[];
|
gpuDeviceList: GPUDeviceItem[];
|
||||||
@@ -113,6 +116,7 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
handleDeleteSuccess,
|
handleDeleteSuccess,
|
||||||
onViewLogs,
|
onViewLogs,
|
||||||
onCancelViewLogs,
|
onCancelViewLogs,
|
||||||
|
handleCategoryChange,
|
||||||
deleteIds,
|
deleteIds,
|
||||||
dataSource,
|
dataSource,
|
||||||
gpuDeviceList,
|
gpuDeviceList,
|
||||||
@@ -732,11 +736,23 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
<Space>
|
<Space>
|
||||||
<Input
|
<Input
|
||||||
placeholder={intl.formatMessage({ id: 'common.filter.name' })}
|
placeholder={intl.formatMessage({ id: 'common.filter.name' })}
|
||||||
style={{ width: 300 }}
|
style={{ width: 200 }}
|
||||||
size="large"
|
size="large"
|
||||||
allowClear
|
allowClear
|
||||||
onChange={handleNameChange}
|
onChange={handleNameChange}
|
||||||
></Input>
|
></Input>
|
||||||
|
<Select
|
||||||
|
allowClear
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'models.filter.category'
|
||||||
|
})}
|
||||||
|
style={{ width: 240 }}
|
||||||
|
size="large"
|
||||||
|
mode="multiple"
|
||||||
|
maxTagCount={1}
|
||||||
|
onChange={handleCategoryChange}
|
||||||
|
options={modelCategories.filter((item) => item.value)}
|
||||||
|
></Select>
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
style={{ color: 'var(--ant-color-text-tertiary)' }}
|
style={{ color: 'var(--ant-color-text-tertiary)' }}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
ListItem as WokerListItem
|
ListItem as WokerListItem
|
||||||
} from '@/pages/resources/config/types';
|
} from '@/pages/resources/config/types';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import qs from 'query-string';
|
||||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { MODELS_API, MODEL_INSTANCE_API, queryModelsList } from './apis';
|
import { MODELS_API, MODEL_INSTANCE_API, queryModelsList } from './apis';
|
||||||
import TableList from './components/table-list';
|
import TableList from './components/table-list';
|
||||||
@@ -38,7 +39,8 @@ const Models: React.FC = () => {
|
|||||||
const [queryParams, setQueryParams] = useState({
|
const [queryParams, setQueryParams] = useState({
|
||||||
page: 1,
|
page: 1,
|
||||||
perPage: 10,
|
perPage: 10,
|
||||||
search: ''
|
search: '',
|
||||||
|
categories: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const { updateChunkedList, cacheDataListRef, deletedIdsRef } =
|
const { updateChunkedList, cacheDataListRef, deletedIdsRef } =
|
||||||
@@ -128,10 +130,7 @@ const Models: React.FC = () => {
|
|||||||
chunkRequedtRef.current?.current?.cancel?.();
|
chunkRequedtRef.current?.current?.cancel?.();
|
||||||
try {
|
try {
|
||||||
chunkRequedtRef.current = setChunkRequest({
|
chunkRequedtRef.current = setChunkRequest({
|
||||||
url: `${MODELS_API}`,
|
url: `${MODELS_API}?${qs.stringify(_.pickBy(queryParams, (val: any) => !!val))}`,
|
||||||
params: {
|
|
||||||
..._.pickBy(queryParams, (val: any) => !!val)
|
|
||||||
},
|
|
||||||
handler: updateHandler
|
handler: updateHandler
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -191,6 +190,17 @@ const Models: React.FC = () => {
|
|||||||
|
|
||||||
const handleNameChange = useCallback(debounceUpdateFilter, [queryParams]);
|
const handleNameChange = useCallback(debounceUpdateFilter, [queryParams]);
|
||||||
|
|
||||||
|
const handleCategoryChange = useCallback(
|
||||||
|
(value: any) => {
|
||||||
|
setQueryParams({
|
||||||
|
...queryParams,
|
||||||
|
page: 1,
|
||||||
|
categories: value
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[queryParams]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getList();
|
getList();
|
||||||
return () => {
|
return () => {
|
||||||
@@ -242,6 +252,7 @@ const Models: React.FC = () => {
|
|||||||
<TableList
|
<TableList
|
||||||
dataSource={dataSource.dataList}
|
dataSource={dataSource.dataList}
|
||||||
handleNameChange={handleNameChange}
|
handleNameChange={handleNameChange}
|
||||||
|
handleCategoryChange={handleCategoryChange}
|
||||||
handleSearch={handleSearch}
|
handleSearch={handleSearch}
|
||||||
handlePageChange={handlePageChange}
|
handlePageChange={handlePageChange}
|
||||||
handleDeleteSuccess={fetchData}
|
handleDeleteSuccess={fetchData}
|
||||||
|
|||||||
Reference in New Issue
Block a user