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 OverlayScroller from '@/components/overlay-scroller';
import { FilterOutlined } from '@ant-design/icons'; import { CloseCircleFilled, FilterOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Form, Popover } from 'antd'; import { Badge, Button, Form, Popover } from 'antd';
import React, { useState } from 'react'; import React, { useState } from 'react';
import styled from 'styled-components'; 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< const FilterForm: React.FC<
React.PropsWithChildren & { React.PropsWithChildren & {
width?: number; width?: number;
@@ -40,12 +70,12 @@ const FilterForm: React.FC<
width = 300, width = 300,
contentHeight = 400, contentHeight = 400,
initialValues = {}, initialValues = {},
hasFilters = false,
onClose, onClose,
onValuesChange onValuesChange
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [hasFilters, setHasFilters] = useState(false);
const [form] = Form.useForm(); const [form] = Form.useForm();
const handleToggle = () => { const handleToggle = () => {
@@ -60,6 +90,7 @@ const FilterForm: React.FC<
form.resetFields(Object.keys(initialValues)); form.resetFields(Object.keys(initialValues));
onValuesChange?.({}, initialValues); onValuesChange?.({}, initialValues);
setOpen(false); setOpen(false);
setHasFilters(false);
}; };
const handleOnClose = () => { const handleOnClose = () => {
@@ -67,6 +98,14 @@ const FilterForm: React.FC<
onClose?.(); 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 ( return (
<Popover <Popover
open={open} open={open}
@@ -84,7 +123,7 @@ const FilterForm: React.FC<
}} }}
> >
<Form <Form
onValuesChange={onValuesChange} onValuesChange={handleOnValuesChange}
initialValues={initialValues} initialValues={initialValues}
form={form} 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> </Popover>
); );
}; };
+3 -2
View File
@@ -59,6 +59,7 @@ import {
ModelInstanceListItem, ModelInstanceListItem,
SourceType SourceType
} from '../config/types'; } from '../config/types';
import Filters from '../filters';
import useEditDeployment from '../hooks/use-edit-deployment'; import useEditDeployment from '../hooks/use-edit-deployment';
import useFilterStatus from '../hooks/use-filter-status'; import useFilterStatus from '../hooks/use-filter-status';
import useFormInitialValues from '../hooks/use-form-initial-values'; import useFormInitialValues from '../hooks/use-form-initial-values';
@@ -649,7 +650,7 @@ const Models: React.FC<ModelsProps> = ({
options={statusOptions} options={statusOptions}
onChange={handleStatusChange} onChange={handleStatusChange}
></BaseSelect> ></BaseSelect>
{/* <Filters <Filters
initialValues={{ initialValues={{
cluster_id: undefined, cluster_id: undefined,
state: undefined, state: undefined,
@@ -657,7 +658,7 @@ const Models: React.FC<ModelsProps> = ({
}} }}
clusterList={clusterList} clusterList={clusterList}
onValuesChange={onFilterChange} onValuesChange={onFilterChange}
></Filters> */} ></Filters>
<Button <Button
type="text" type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }} 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 FilterForm from '@/pages/_components/filter-form';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Form } from 'antd'; import { Form } from 'antd';
import _ from 'lodash';
import styled from 'styled-components'; import styled from 'styled-components';
import { modelCategories } from '../config'; import { modelCategories } from '../config';
import useFilterStatus from '../hooks/use-filter-status'; import useFilterStatus from '../hooks/use-filter-status';
@@ -25,12 +24,10 @@ const FilterFormContent: React.FC<FilterFormContentProps> = ({
onValuesChange onValuesChange
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const form = Form.useFormInstance();
const { labelRender, optionRender, statusOptions } = useFilterStatus(); const { labelRender, optionRender, statusOptions } = useFilterStatus();
const handleOnValuesChange = (changedValues: any, allValues: any) => { const handleOnValuesChange = (changedValues: any, allValues: any) => {
const query = _.pickBy(allValues, (value: any) => !!value); onValuesChange?.(allValues);
onValuesChange?.(query);
}; };
return ( return (