chore: list actions
This commit is contained in:
@@ -2,7 +2,7 @@ import { createFromIconfontCN } from '@ant-design/icons';
|
|||||||
// import './iconfont/iconfont.js';
|
// import './iconfont/iconfont.js';
|
||||||
|
|
||||||
const IconFont = createFromIconfontCN({
|
const IconFont = createFromIconfontCN({
|
||||||
scriptUrl: '//at.alicdn.com/t/c/font_4613488_9wb9516md1k.js'
|
scriptUrl: '//at.alicdn.com/t/c/font_4613488_q6s2f01tf6l.js'
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IconFont;
|
export default IconFont;
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ interface WrapperProps {
|
|||||||
btnText?: string;
|
btnText?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onAdd?: () => void;
|
onAdd?: () => void;
|
||||||
|
styles?: {
|
||||||
|
wrapper?: React.CSSProperties;
|
||||||
|
};
|
||||||
button?: React.ReactNode;
|
button?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,11 +49,12 @@ const Wrapper: React.FC<WrapperProps> = ({
|
|||||||
onAdd,
|
onAdd,
|
||||||
btnText,
|
btnText,
|
||||||
disabled,
|
disabled,
|
||||||
button
|
button,
|
||||||
|
styles
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container style={styles?.wrapper}>
|
||||||
{label && (
|
{label && (
|
||||||
<span className="label">
|
<span className="label">
|
||||||
<LabelInfo
|
<LabelInfo
|
||||||
|
|||||||
@@ -1,8 +1,96 @@
|
|||||||
|
import Wrapper from '@/components/label-selector/wrapper';
|
||||||
|
import { DeleteOutlined } from '@ant-design/icons';
|
||||||
import { useHover } from 'ahooks';
|
import { useHover } from 'ahooks';
|
||||||
import { Popover } from 'antd';
|
import { Button, Divider, Flex, Input, Popover } from 'antd';
|
||||||
import { useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const ItemContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.seprator {
|
||||||
|
display: flex;
|
||||||
|
flex: none;
|
||||||
|
width: 12px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--ant-color-text-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 24px;
|
||||||
|
margin-left: 10px;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
interface MetadataListProps {
|
||||||
|
dataList: any[];
|
||||||
|
label: React.ReactNode;
|
||||||
|
description?: React.ReactNode;
|
||||||
|
disabled?: boolean;
|
||||||
|
btnText?: string;
|
||||||
|
onAdd?: () => void;
|
||||||
|
onDelete?: (index: number, item: any) => void;
|
||||||
|
children?: (item: any, index: number) => React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MetadataList: React.FC<MetadataListProps> = ({
|
||||||
|
dataList,
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
disabled,
|
||||||
|
btnText,
|
||||||
|
children,
|
||||||
|
onDelete,
|
||||||
|
onAdd
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Wrapper
|
||||||
|
label={label}
|
||||||
|
description={description}
|
||||||
|
onAdd={onAdd}
|
||||||
|
disabled={disabled}
|
||||||
|
btnText={btnText}
|
||||||
|
styles={{
|
||||||
|
wrapper: {
|
||||||
|
padding: 0,
|
||||||
|
border: 'none'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{dataList.map((item, index) => (
|
||||||
|
<ItemContainer key={index}>{children?.(item, index)}</ItemContainer>
|
||||||
|
))}
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DeleteWrapper = styled.span`
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--ant-color-text-tertiary);
|
||||||
|
&:hover {
|
||||||
|
color: var(--ant-color-error-text-hover);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Box = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
.ant-input-suffix {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.ant-input-suffix {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -24,15 +112,71 @@ const Container = styled.div`
|
|||||||
`;
|
`;
|
||||||
const CompareConditions: React.FC = () => {
|
const CompareConditions: React.FC = () => {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
const [filters, setFilters] = useState<string[]>([]);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const isHovering = useHover(containerRef);
|
const isHovering = useHover(containerRef);
|
||||||
|
|
||||||
|
const onAdd = () => {
|
||||||
|
setFilters((prev) => [...prev, '']);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDelete = (index: number, item: any) => {
|
||||||
|
setFilters((prev) => prev.filter((_, i) => i !== index));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOnChange = (value: string, index: number) => {
|
||||||
|
const newFilters = [...filters];
|
||||||
|
newFilters[index] = value;
|
||||||
|
setFilters(newFilters);
|
||||||
|
};
|
||||||
|
|
||||||
|
const FiltersDrop = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<MetadataList
|
||||||
|
dataList={filters}
|
||||||
|
onAdd={onAdd}
|
||||||
|
onDelete={onDelete}
|
||||||
|
btnText="Add Filter"
|
||||||
|
label=""
|
||||||
|
>
|
||||||
|
{(item, index) => (
|
||||||
|
<Box>
|
||||||
|
<Input
|
||||||
|
key={index}
|
||||||
|
value={item}
|
||||||
|
placeholder="enter a model name"
|
||||||
|
suffix={
|
||||||
|
filters.length > 1 ? (
|
||||||
|
<DeleteWrapper>
|
||||||
|
<DeleteOutlined onClick={() => onDelete?.(index, item)} />
|
||||||
|
</DeleteWrapper>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
onChange={(e) => handleOnChange(e.target.value, index)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</MetadataList>
|
||||||
|
<Divider style={{ margin: '12px 0' }} />
|
||||||
|
<Flex justify="end" gap={8}>
|
||||||
|
<Button size="middle" type="text">
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
|
<Button type="primary" size="middle">
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
trigger={'click'}
|
trigger={'click'}
|
||||||
content="Compare Conditions Content"
|
|
||||||
arrow={false}
|
arrow={false}
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
|
content={FiltersDrop()}
|
||||||
styles={{
|
styles={{
|
||||||
root: {
|
root: {
|
||||||
width: '240px'
|
width: '240px'
|
||||||
|
|||||||
Reference in New Issue
Block a user