feat: filter form for table

This commit is contained in:
jialin
2026-02-10 10:25:02 +08:00
parent 90e212a1b2
commit ba11689029
3 changed files with 68 additions and 11 deletions
+64 -5
View File
@@ -1,7 +1,7 @@
import OverlayScroller from '@/components/overlay-scroller';
import { FilterOutlined } from '@ant-design/icons';
import { CloseCircleFilled, FilterOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Form, Popover } from 'antd';
import { Badge, Button, Form, Popover } from 'antd';
import React, { useState } from 'react';
import styled from 'styled-components';
@@ -26,6 +26,36 @@ const Container = styled.div`
}
`;
const ButtonWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
position: relative;
.badge {
position: absolute;
top: 4px;
right: 4px;
}
.close-btn {
position: absolute;
display: none;
top: -4px;
right: -4px;
font-size: 12px;
border-radius: 50%;
color: var(--ant-color-text-quaternary);
background-color: var(--ant-color-bg-container);
&:hover {
color: var(--ant-color-text-tertiary);
}
}
&:hover {
.close-btn {
display: block;
}
}
`;
const FilterForm: React.FC<
React.PropsWithChildren & {
width?: number;
@@ -40,12 +70,12 @@ const FilterForm: React.FC<
width = 300,
contentHeight = 400,
initialValues = {},
hasFilters = false,
onClose,
onValuesChange
}) => {
const intl = useIntl();
const [open, setOpen] = useState(false);
const [hasFilters, setHasFilters] = useState(false);
const [form] = Form.useForm();
const handleToggle = () => {
@@ -60,6 +90,7 @@ const FilterForm: React.FC<
form.resetFields(Object.keys(initialValues));
onValuesChange?.({}, initialValues);
setOpen(false);
setHasFilters(false);
};
const handleOnClose = () => {
@@ -67,6 +98,14 @@ const FilterForm: React.FC<
onClose?.();
};
const handleOnValuesChange = (changedValues: any, allValues: any) => {
onValuesChange?.(changedValues, allValues);
const hasActiveFilters = Object.values(allValues).some(
(value) => value !== undefined && value !== null && value !== ''
);
setHasFilters(hasActiveFilters);
};
return (
<Popover
open={open}
@@ -84,7 +123,7 @@ const FilterForm: React.FC<
}}
>
<Form
onValuesChange={onValuesChange}
onValuesChange={handleOnValuesChange}
initialValues={initialValues}
form={form}
>
@@ -113,7 +152,27 @@ const FilterForm: React.FC<
}
}}
>
<Button onClick={handleToggle} icon={<FilterOutlined />}></Button>
<ButtonWrapper>
<Button icon={<FilterOutlined />} onClick={handleToggle}></Button>
{hasFilters && (
<Badge
dot
color={'var(--ant-color-primary-text-hover)'}
className="badge"
/>
)}
{hasFilters && (
<span className="close-btn">
<CloseCircleFilled
style={{ fontSize: 12 }}
onClick={(e) => {
e.stopPropagation();
handleOnReset();
}}
/>
</span>
)}
</ButtonWrapper>
</Popover>
);
};
+3 -2
View File
@@ -59,6 +59,7 @@ import {
ModelInstanceListItem,
SourceType
} from '../config/types';
import Filters from '../filters';
import useEditDeployment from '../hooks/use-edit-deployment';
import useFilterStatus from '../hooks/use-filter-status';
import useFormInitialValues from '../hooks/use-form-initial-values';
@@ -649,7 +650,7 @@ const Models: React.FC<ModelsProps> = ({
options={statusOptions}
onChange={handleStatusChange}
></BaseSelect>
{/* <Filters
<Filters
initialValues={{
cluster_id: undefined,
state: undefined,
@@ -657,7 +658,7 @@ const Models: React.FC<ModelsProps> = ({
}}
clusterList={clusterList}
onValuesChange={onFilterChange}
></Filters> */}
></Filters>
<Button
type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }}
+1 -4
View File
@@ -2,7 +2,6 @@ import BaseSelect from '@/components/seal-form/base/select';
import FilterForm from '@/pages/_components/filter-form';
import { useIntl } from '@umijs/max';
import { Form } from 'antd';
import _ from 'lodash';
import styled from 'styled-components';
import { modelCategories } from '../config';
import useFilterStatus from '../hooks/use-filter-status';
@@ -25,12 +24,10 @@ const FilterFormContent: React.FC<FilterFormContentProps> = ({
onValuesChange
}) => {
const intl = useIntl();
const form = Form.useFormInstance();
const { labelRender, optionRender, statusOptions } = useFilterStatus();
const handleOnValuesChange = (changedValues: any, allValues: any) => {
const query = _.pickBy(allValues, (value: any) => !!value);
onValuesChange?.(query);
onValuesChange?.(allValues);
};
return (