refactor: table filters ux
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
import BaseSelect from '@/components/seal-form/base/select';
|
||||
import { FiltersButton } from '@/components/page-tools';
|
||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||
import { SearchOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
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;
|
||||
@@ -13,12 +12,18 @@ export interface RightActionsProps {
|
||||
handleQueryChange: (value: any, option?: any) => void;
|
||||
modelList?: Global.BaseOption<number, { categories: string[] }>[];
|
||||
datasetList?: Global.BaseOption<string | number>[];
|
||||
toggleFilters: () => void;
|
||||
count?: number;
|
||||
onClear: () => void;
|
||||
}
|
||||
|
||||
const RightActions: React.FC<RightActionsProps> = ({
|
||||
handleInputChange,
|
||||
handleSearch,
|
||||
handleQueryChange,
|
||||
toggleFilters,
|
||||
count,
|
||||
onClear,
|
||||
modelList,
|
||||
datasetList
|
||||
}) => {
|
||||
@@ -44,6 +49,11 @@ const RightActions: React.FC<RightActionsProps> = ({
|
||||
|
||||
return (
|
||||
<Space>
|
||||
<FiltersButton
|
||||
onClick={toggleFilters}
|
||||
count={count}
|
||||
onClear={onClear}
|
||||
></FiltersButton>
|
||||
<Input
|
||||
prefix={
|
||||
<SearchOutlined
|
||||
@@ -53,11 +63,11 @@ const RightActions: React.FC<RightActionsProps> = ({
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'common.filter.name'
|
||||
})}
|
||||
style={{ width: 200 }}
|
||||
style={{ width: 300 }}
|
||||
allowClear
|
||||
onChange={handleInputChange}
|
||||
></Input>
|
||||
<Input
|
||||
{/* <Input
|
||||
prefix={
|
||||
<SearchOutlined
|
||||
style={{ color: 'var(--ant-color-text-placeholder)' }}
|
||||
@@ -107,7 +117,7 @@ const RightActions: React.FC<RightActionsProps> = ({
|
||||
page: 1
|
||||
})
|
||||
}
|
||||
></BaseSelect>
|
||||
></BaseSelect> */}
|
||||
<Button
|
||||
type="text"
|
||||
style={{ color: 'var(--ant-color-text-tertiary)' }}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import BaseSelect from '@/components/seal-form/base/select';
|
||||
import FilterForm from '@/pages/_components/filter-form';
|
||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form, Input } from 'antd';
|
||||
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { profileOptions } from '../config';
|
||||
|
||||
const Content = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
const Label = styled.span`
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
margin-block: 12px 8px;
|
||||
color: var(--ant-color-text-tertiary);
|
||||
`;
|
||||
|
||||
interface FilterFormContentProps {
|
||||
clusterList?: Global.BaseOption<number>[];
|
||||
initialValues?: any;
|
||||
open?: boolean;
|
||||
ref?: any;
|
||||
modelList?: Global.BaseOption<number, { categories: string[] }>[];
|
||||
onClose?: () => void;
|
||||
onClear?: () => void;
|
||||
onValuesChange: (values: any) => void;
|
||||
}
|
||||
|
||||
const FilterFormContent: React.FC<FilterFormContentProps> = forwardRef(
|
||||
(
|
||||
{ initialValues, onClose, onClear, onValuesChange, open, modelList },
|
||||
ref
|
||||
) => {
|
||||
const intl = useIntl();
|
||||
const filterRef = useRef<any>(null);
|
||||
|
||||
const handleOnValuesChange = (changedValues: any, allValues: any) => {
|
||||
onValuesChange?.(allValues);
|
||||
};
|
||||
|
||||
const modelOptions = modelList
|
||||
?.filter((item) => {
|
||||
return item.categories?.includes(modelCategoriesMap.llm);
|
||||
})
|
||||
.map((item) => ({
|
||||
label: item.label,
|
||||
value: item.label
|
||||
}));
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
reset: () => {
|
||||
filterRef.current?.reset();
|
||||
}
|
||||
}));
|
||||
|
||||
return (
|
||||
<FilterForm
|
||||
ref={filterRef}
|
||||
width={232}
|
||||
contentHeight={'calc(100vh - 122px)'}
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
onClear={onClear}
|
||||
onValuesChange={handleOnValuesChange}
|
||||
initialValues={initialValues}
|
||||
styles={{
|
||||
container: {
|
||||
paddingInline: '0 8px',
|
||||
marginLeft: '-8px'
|
||||
},
|
||||
wrapper: {
|
||||
marginRight: open ? 24 : 0,
|
||||
marginTop: '-24px'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Content>
|
||||
<Label style={{ marginTop: 0 }}>GPU</Label>
|
||||
<Form.Item name="gpu_summary" noStyle>
|
||||
<Input
|
||||
prefix={
|
||||
<SearchOutlined
|
||||
style={{ color: 'var(--ant-color-text-placeholder)' }}
|
||||
></SearchOutlined>
|
||||
}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'benchmark.table.filter.bygpu'
|
||||
})}
|
||||
allowClear
|
||||
></Input>
|
||||
</Form.Item>
|
||||
<Label>{intl.formatMessage({ id: 'benchmark.form.profile' })}</Label>
|
||||
<Form.Item noStyle name="profile">
|
||||
<BaseSelect
|
||||
allowClear
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'benchmark.table.filter.byProfile'
|
||||
})}
|
||||
options={[
|
||||
...profileOptions,
|
||||
{
|
||||
label: 'backend.custom',
|
||||
locale: true,
|
||||
value: 'Custom'
|
||||
}
|
||||
].map((item) => ({
|
||||
label: item.locale
|
||||
? intl.formatMessage({ id: item.label })
|
||||
: item.label,
|
||||
value: item.value
|
||||
}))}
|
||||
></BaseSelect>
|
||||
</Form.Item>
|
||||
<Label>{intl.formatMessage({ id: 'benchmark.table.model' })}</Label>
|
||||
<Form.Item noStyle name="model_name">
|
||||
{/* <PillButtonGroup
|
||||
options={modelCategories.filter((item) => item.value)}
|
||||
></PillButtonGroup> */}
|
||||
<BaseSelect
|
||||
allowClear
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'benchmark.table.filter.bymodel'
|
||||
})}
|
||||
options={modelOptions}
|
||||
></BaseSelect>
|
||||
</Form.Item>
|
||||
</Content>
|
||||
</FilterForm>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default FilterFormContent;
|
||||
@@ -7,10 +7,10 @@ import useTableFetch from '@/hooks/use-table-fetch';
|
||||
import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-benchmark';
|
||||
import { useQueryModelList } from '@/pages/llmodels/services/use-query-model-list';
|
||||
import { useIntl, useNavigate } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { useMemoizedFn, useToggle } from 'ahooks';
|
||||
import { ConfigProvider, Table, message } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import NoResult from '../_components/no-result';
|
||||
import PageBox from '../_components/page-box';
|
||||
import { useQueryClusterList } from '../cluster-management/services/use-query-cluster-list';
|
||||
@@ -26,6 +26,7 @@ import LeftActions from './components/left-actions';
|
||||
import RightActions from './components/right-actions';
|
||||
import ViewLogsModal from './components/view-logs-modal';
|
||||
import { FormData, BenchmarkListItem as ListItem } from './config/types';
|
||||
import Filters from './filters';
|
||||
import useBenchmarkColumns from './hooks/use-benchmark-columns';
|
||||
import useColumnSettings from './hooks/use-column-settings';
|
||||
import useCreateBenchmark from './hooks/use-create-benchmark';
|
||||
@@ -86,6 +87,9 @@ const Benchmark: React.FC = () => {
|
||||
clusterList,
|
||||
profileOptions: profilesOptions
|
||||
});
|
||||
const [filtersVisible, { toggle: toggleFilters }] = useToggle();
|
||||
const filterRef = useRef<any>(null);
|
||||
const [filterValues, setFilterValues] = useState<any>({});
|
||||
|
||||
useEffect(() => {
|
||||
fetchModelList({ page: -1 });
|
||||
@@ -205,9 +209,38 @@ const Benchmark: React.FC = () => {
|
||||
exportData(rowSelection.selectedRowKeys);
|
||||
};
|
||||
|
||||
const handleOnFilterChange = (filters: any) => {
|
||||
handleQueryChange({
|
||||
page: 1,
|
||||
...filters
|
||||
});
|
||||
|
||||
setFilterValues(filters);
|
||||
};
|
||||
|
||||
const handleOnClearFilters = () => {
|
||||
filterRef.current?.reset();
|
||||
};
|
||||
|
||||
const filtersCount = Object.values(filterValues).filter(
|
||||
(value) => value !== undefined && value !== null && value !== ''
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageBox>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start'
|
||||
}}
|
||||
>
|
||||
<Filters
|
||||
ref={filterRef}
|
||||
open={filtersVisible}
|
||||
onValuesChange={handleOnFilterChange}
|
||||
onClose={toggleFilters}
|
||||
onClear={handleOnClearFilters}
|
||||
></Filters>
|
||||
<PageBox style={{ flex: 1 }}>
|
||||
<FilterBar
|
||||
showSelect={false}
|
||||
marginBottom={22}
|
||||
@@ -223,6 +256,9 @@ const Benchmark: React.FC = () => {
|
||||
handleSearch={handleSearch}
|
||||
handleQueryChange={handleQueryChange}
|
||||
handleInputChange={handleNameChange}
|
||||
count={filtersCount.length}
|
||||
toggleFilters={toggleFilters}
|
||||
onClear={handleOnClearFilters}
|
||||
></LeftActions>
|
||||
}
|
||||
right={
|
||||
@@ -284,7 +320,7 @@ const Benchmark: React.FC = () => {
|
||||
onCancel={closeViewLogsModal}
|
||||
></ViewLogsModal>
|
||||
<DeleteModal ref={modalRef}></DeleteModal>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user