feat: filter form for table
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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)' }}
|
||||
|
||||
@@ -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 (
|
||||
|
||||
Reference in New Issue
Block a user