fix: flatten all filters in table list

This commit is contained in:
jialin
2026-06-10 15:37:27 +08:00
committed by jialin
parent ded270ff25
commit 98a6b19298
11 changed files with 108 additions and 109 deletions
+3 -3
View File
@@ -37,10 +37,10 @@ export default {
'Stress test for long-context handling. Evaluates KV cache behavior, memory usage, and backend stability.',
'benchmark.form.profile.heavy.tips':
'Decode-heavy generation benchmark. Measures sustained decoding speed and output token throughput.',
'benchmark.table.filter.bygpu': 'Filter by GPU',
'benchmark.table.filter.bymodel': 'Filter by Model',
'benchmark.table.filter.bygpu': 'Search by GPU',
'benchmark.table.filter.bymodel': 'Search by model',
'benchmark.table.filter.bydataset': 'Filter by Dataset',
'benchmark.table.filter.byProfile': 'Filter by Profile',
'benchmark.table.filter.byProfile': 'Filter by profile',
'benchmark.table.avg': 'Avg',
'benchmark.table.columnSettings': 'Column Settings',
'benchmark.detail.summary.results': 'Test Results',
+2 -2
View File
@@ -37,8 +37,8 @@ export default {
'Stress test for long-context handling. Evaluates KV cache behavior, memory usage, and backend stability.',
'benchmark.form.profile.heavy.tips':
'Decode-heavy generation benchmark. Measures sustained decoding speed and output token throughput.',
'benchmark.table.filter.bygpu': 'Filter by GPU',
'benchmark.table.filter.bymodel': 'Filter by Model',
'benchmark.table.filter.bygpu': 'GPU 検索',
'benchmark.table.filter.bymodel': 'モデル検索',
'benchmark.table.filter.bydataset': 'Filter by Dataset',
'benchmark.table.filter.byProfile': 'Filter by Profile',
'benchmark.table.avg': 'Avg',
+2 -2
View File
@@ -37,8 +37,8 @@ export default {
'Stress test for long-context handling. Evaluates KV cache behavior, memory usage, and backend stability.',
'benchmark.form.profile.heavy.tips':
'Decode-heavy generation benchmark. Measures sustained decoding speed and output token throughput.',
'benchmark.table.filter.bygpu': 'Filter by GPU',
'benchmark.table.filter.bymodel': 'Filter by Model',
'benchmark.table.filter.bygpu': 'Поиск GPU',
'benchmark.table.filter.bymodel': 'Поиск модели',
'benchmark.table.filter.bydataset': 'Filter by Dataset',
'benchmark.table.filter.byProfile': 'Filter by Profile',
'benchmark.table.avg': 'Avg',
+2 -2
View File
@@ -37,8 +37,8 @@ export default {
'Uzun bağlam işleme için stres testi. KV önbellek davranışını, bellek kullanımını ve altyapı kararlılığını değerlendirir.',
'benchmark.form.profile.heavy.tips':
'Çözümleme ağırlıklı üretim kıyaslaması. Sürekli çözümleme hızını ve çıkış token verimini ölçer.',
'benchmark.table.filter.bygpu': "GPU'ya göre filtrele",
'benchmark.table.filter.bymodel': 'Modele göre filtrele',
'benchmark.table.filter.bygpu': 'GPU ara',
'benchmark.table.filter.bymodel': 'Model ara',
'benchmark.table.filter.bydataset': 'Veri Kümesine göre filtrele',
'benchmark.table.filter.byProfile': 'Profile göre filtrele',
'benchmark.table.avg': 'Ort.',
+2 -2
View File
@@ -37,8 +37,8 @@ export default {
'长上下文压力测试。评估 KV Cache 行为、内存占用及后端稳定性。',
'benchmark.form.profile.heavy.tips':
'以解码为主的生成测试。衡量持续解码速度与输出 Token 吞吐能力。',
'benchmark.table.filter.bygpu': 'GPU 过滤',
'benchmark.table.filter.bymodel': '模型过滤',
'benchmark.table.filter.bygpu': 'GPU 查询',
'benchmark.table.filter.bymodel': '模型查询',
'benchmark.table.filter.bydataset': '按数据集过滤',
'benchmark.table.filter.byProfile': '按模式过滤',
'benchmark.table.avg': '均值',
+1 -1
View File
@@ -261,7 +261,7 @@ export default {
'common.button.terminal': '终端',
'common.button.addItem': '添加项',
'common.help.default': '默认: {content}',
'common.filter.status': '按状态筛选',
'common.filter.status': '按状态过滤',
'common.form.rule.selectInput': '请选择或输入{name}',
'common.tag.experimental': '实验性',
'common.title.example': '示例',
+1 -1
View File
@@ -99,7 +99,7 @@ export default {
'models.form.search.gguftips':
'当 macOS 或 Windows 作节点时勾选 GGUF(搜索语音模型时取消勾选)',
'models.form.button.addlabel': '添加标签',
'models.filter.category': '按类别筛选',
'models.filter.category': '按类别过滤',
'models.list.more.logs': '查看更多',
'models.catalog.release.date': '发布日期',
'models.localpath.gguf.tips.title': 'GGUF 格式模型',
+23 -31
View File
@@ -1,10 +1,10 @@
import { modelCategoriesMap } from '@/pages/llmodels/config';
import { SearchOutlined, SyncOutlined } from '@ant-design/icons';
import { FiltersButton } from '@gpustack/core-ui';
import { BaseSelect } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Button, Input, Space } from 'antd';
import _ from 'lodash';
import React from 'react';
import { profileOptions } from '../config';
export interface RightActionsProps {
handleInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
@@ -38,22 +38,15 @@ const RightActions: React.FC<RightActionsProps> = ({
const handleGPUChange = debounceUpdateFilter;
const modelOptions = modelList
?.filter((item) => {
return item.categories?.includes(modelCategoriesMap.llm);
})
.map((item) => ({
label: item.label,
value: item.label
}));
const handleSearchByModelDebounce = _.debounce((value: any) => {
handleQueryChange({
page: 1,
model_name: value
});
}, 350);
return (
<Space>
<FiltersButton
onClick={toggleFilters}
count={count}
onClear={onClear}
></FiltersButton>
<Input
prefix={
<SearchOutlined
@@ -63,11 +56,24 @@ const RightActions: React.FC<RightActionsProps> = ({
placeholder={intl.formatMessage({
id: 'common.filter.name'
})}
style={{ width: 300 }}
style={{ width: 200 }}
allowClear
onChange={handleInputChange}
></Input>
{/* <Input
<Input
prefix={
<SearchOutlined
style={{ color: 'var(--ant-color-text-placeholder)' }}
></SearchOutlined>
}
placeholder={intl.formatMessage({
id: 'benchmark.table.filter.bymodel'
})}
style={{ width: 180 }}
allowClear
onChange={handleSearchByModelDebounce}
></Input>
<Input
prefix={
<SearchOutlined
style={{ color: 'var(--ant-color-text-placeholder)' }}
@@ -104,20 +110,6 @@ const RightActions: React.FC<RightActionsProps> = ({
})
}
></BaseSelect>
<BaseSelect
allowClear
placeholder={intl.formatMessage({
id: 'benchmark.table.filter.bymodel'
})}
style={{ width: 180 }}
options={modelOptions}
onChange={(value, option) =>
handleQueryChange({
model_name: value,
page: 1
})
}
></BaseSelect> */}
<Button
type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }}
+5 -28
View File
@@ -22,7 +22,7 @@ import {
TableOrder
} from '@gpustack/core-ui';
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
import { useMemoizedFn, useToggle } from 'ahooks';
import { useMemoizedFn } from 'ahooks';
import { Button, Space, message } from 'antd';
import { useAtom } from 'jotai';
import _ from 'lodash';
@@ -54,14 +54,13 @@ import {
ModelInstanceListItem,
SourceType
} from '../config/types';
import Filters from '../filters';
import useEditDeployment from '../hooks/use-edit-deployment';
import useModelsColumns from '../hooks/use-models-columns';
import useViewInstanceLogs from '../hooks/use-view-instance-logs';
import LeftFilters from '../instance-view/left-filters';
import DeployModal from './deployment/deploy-modal';
import UpdateModelModal from './deployment/update-modal';
import Instances from './instance/instances';
import LeftFilters from './left-filters';
import ViewLogsModal from './view-logs-modal';
interface ModelsProps {
handleSearch: (params?: any) => void;
@@ -124,15 +123,13 @@ const Models: React.FC<ModelsProps> = ({
onTableSort,
onStatusChange,
onDeleteInstanceFromCache,
onFilterChange,
sortOrder,
deleteIds,
dataSource,
queryParams,
loading,
loadend,
total,
filterValues = {}
total
}) => {
const { generateFormValues, clusterList, workerList } =
useDeploymentsContext();
@@ -180,8 +177,6 @@ const Models: React.FC<ModelsProps> = ({
source: modelSourceMap.huggingface_value as SourceType
});
const modalRef = useRef<any>(null);
const [filtersVisible, { toggle: toggleFilters }] = useToggle();
const filterRef = useRef<any>(null);
useEffect(() => {
if (deleteIds?.length) {
@@ -550,14 +545,6 @@ const Models: React.FC<ModelsProps> = ({
}
});
const handleOnClearFilters = () => {
filterRef.current?.reset();
};
const filtersCount = Object.values(filterValues).filter(
(value) => value !== undefined && value !== null && value !== ''
);
useEffect(() => {
if (modelsSession.source && loadend) {
handleClickDropdown({
@@ -576,29 +563,19 @@ const Models: React.FC<ModelsProps> = ({
alignItems: 'flex-start'
}}
>
<Filters
ref={filterRef}
open={filtersVisible}
onValuesChange={onFilterChange}
clusterList={clusterList}
onClose={toggleFilters}
onClear={handleOnClearFilters}
></Filters>
<div style={{ flex: 1, padding: '24px' }}>
<PageTools
marginBottom={22}
marginTop={0}
left={
<LeftFilters
count={filtersCount.length}
toggleFilters={toggleFilters}
onClear={handleOnClearFilters}
showCategory
showWorker={false}
handleNameChange={handleNameChange}
handleClusterChange={handleClusterChange}
handleCategoryChange={handleCategoryChange}
handleStatusChange={onStatusChange}
handleSearch={handleSearch}
onFilterChange={onFilterChange}
clusterList={clusterList}
></LeftFilters>
}
@@ -20,6 +20,21 @@ import useQueryModelList from '../services/use-query-model-list';
import LeftFilters from './left-filters';
import useInstanceColumns from './use-instance-columns';
const filterOptions = {
optionList: [
{
label: 'Running',
value: 'running',
color: 'var(--ant-color-success)'
},
{
label: 'Error',
value: 'error',
color: 'var(--ant-color-error)'
}
]
};
const InstanceView = forwardRef((props, ref) => {
const {
dataSource,
@@ -150,6 +165,7 @@ const InstanceView = forwardRef((props, ref) => {
handleSearch={handleSearch}
clusterList={clusterList}
workerList={workerList}
filterOptions={filterOptions}
></LeftFilters>
}
></FilterBar>
@@ -4,15 +4,26 @@ import { BaseSelect } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Button, Input, Space } from 'antd';
import React from 'react';
import { categoryOptions } from '../config';
import useFilterStatus from '../hooks/use-filter-status';
interface LeftFiltersProps {
handleNameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
handleClusterChange: (value: number) => void;
handleStatusChange: (value: string) => void;
handleWorkerChange: (value: number) => void;
handleWorkerChange?: (value: number) => void;
handleCategoryChange?: (value: string) => void;
handleSearch: () => void;
clusterList: Global.BaseOption<number>[];
workerList: workerListItem[];
workerList?: workerListItem[];
showWorker?: boolean;
showCategory?: boolean;
filterOptions?: {
optionList: {
label: string;
value: string;
color: string;
}[];
};
}
const LeftFilters: React.FC<LeftFiltersProps> = (props) => {
@@ -21,29 +32,16 @@ const LeftFilters: React.FC<LeftFiltersProps> = (props) => {
handleClusterChange,
handleStatusChange,
handleWorkerChange,
handleCategoryChange,
handleSearch,
clusterList,
workerList
workerList = [],
showWorker = true,
showCategory = false,
filterOptions
} = props;
const { labelRender, optionRender, statusOptions } = useFilterStatus({
optionList: [
{
label: 'Running',
value: 'running',
color: 'var(--ant-color-success)'
},
{
label: 'Error',
value: 'error',
color: 'var(--ant-color-error)'
}
// {
// label: 'Provisioning',
// value: 'provisioning',
// color: 'var(--ant-blue-5)'
// }
]
});
const { labelRender, optionRender, statusOptions } =
useFilterStatus(filterOptions);
const intl = useIntl();
return (
@@ -72,21 +70,37 @@ const LeftFilters: React.FC<LeftFiltersProps> = (props) => {
onChange={handleClusterChange}
options={clusterList}
></BaseSelect>
<BaseSelect
allowClear
showSearch={false}
placeholder={intl.formatMessage({
id: 'resources.filter.worker'
})}
style={{ width: 160 }}
size="large"
maxTagCount={1}
onChange={handleWorkerChange}
options={workerList.map((worker) => ({
label: worker.name,
value: worker.id
}))}
></BaseSelect>
{showCategory && (
<BaseSelect
allowClear
showSearch={false}
placeholder={intl.formatMessage({
id: 'models.filter.category'
})}
style={{ width: 160 }}
size="large"
maxTagCount={1}
onChange={handleCategoryChange}
options={categoryOptions}
></BaseSelect>
)}
{showWorker && (
<BaseSelect
allowClear
showSearch={false}
placeholder={intl.formatMessage({
id: 'resources.filter.worker'
})}
style={{ width: 160 }}
size="large"
maxTagCount={1}
onChange={handleWorkerChange}
options={workerList.map((worker) => ({
label: worker.name,
value: worker.id
}))}
></BaseSelect>
)}
<BaseSelect
allowClear
showSearch={false}