You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
5.7 KiB
TypeScript

/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-07 14:02:00
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-14 15:31:03
* @FilePath: \general-ai-manage\src\components\CategorizeUpdate\index.tsx
* @Description:
* @
* 1.
* 2.
*
*/
import { PlusOutlined } from '@ant-design/icons';
import { ModalForm, ProForm } from '@ant-design/pro-components';
import type { InputRef } from 'antd';
import { Flex, Form, Input, Tag, Tooltip } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { proFormSmallModelWidth } from '../../../config/defaultForm';
type CategorizeUpdateProps = {
visible: boolean;
values: Record<string, any>;
apiSource: () => any;
handleModal: (arg1: any) => void;
modalFormProps: Record<string, any>; // {categorizeFormProps , categorizeModelProps}
};
const tagInputStyle: React.CSSProperties = {
width: 64,
height: 22,
marginInlineEnd: 8,
verticalAlign: 'top',
};
// TODO 整体样式需要按UI图调整 交互在确认时要把tags赋值给form
const CategorizeUpdate: React.FC<CategorizeUpdateProps> = (props) => {
const [form] = Form.useForm<Record<string, any>>();
const [tags, setTags] = useState<string[]>([]);
const [inputVisible, setInputVisible] = useState(false);
const [inputValue, setInputValue] = useState('');
const [editInputIndex, setEditInputIndex] = useState(-1);
const [editInputValue, setEditInputValue] = useState('');
const inputRef = useRef<InputRef>(null);
const editInputRef = useRef<InputRef>(null);
async function loadData() {
const { data } = await props.apiSource();
const finalList = [];
data?.results?.forEach((v: Record<string, any>) => {
finalList.push(v.name);
});
setTags(finalList);
}
useEffect(() => {
if (inputVisible) {
inputRef.current?.focus();
}
}, [inputVisible]);
useEffect(() => {
editInputRef.current?.focus();
}, [editInputValue]);
useEffect(() => {
if (props.visible) {
loadData();
}
}, [props.visible]);
const handleClose = (removedTag: string) => {
const newTags = tags.filter((tag) => tag !== removedTag);
console.log(newTags);
setTags(newTags);
};
const showInput = () => {
setInputVisible(true);
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
const handleInputConfirm = () => {
if (inputValue && !tags.includes(inputValue)) {
setTags([...tags, inputValue]);
}
setInputVisible(false);
setInputValue('');
};
const handleEditInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setEditInputValue(e.target.value);
};
const handleEditInputConfirm = () => {
const newTags = [...tags];
newTags[editInputIndex] = editInputValue;
setTags(newTags);
setEditInputIndex(-1);
setEditInputValue('');
};
const tagPlusStyle: React.CSSProperties = {
height: 22,
background: '#FFFFFF',
border: '1px solid #154DDD',
color: '#154DDD',
// borderStyle: 'dashed',
};
return (
<ModalForm<Record<string, any>>
className="gn_form gn_categorize_update"
width={proFormSmallModelWidth}
{...props?.modalFormProps?.categorizeModelProps}
open={props.visible}
form={form}
modalProps={{
destroyOnClose: true,
onCancel: () => props.handleModal(),
}}
initialValues={props.values}
submitTimeout={2000}
onFinish={async (values) => {
console.log(values, 'add_finish_values');
props.handleModal(form.getFieldsValue());
return true;
}}
>
<ProForm.Item {...props?.modalFormProps?.categorizeFormProps}>
<Flex gap="16px 0" wrap="wrap">
{tags.map<React.ReactNode>((tag, index) => {
if (editInputIndex === index) {
return (
<Input
ref={editInputRef}
key={tag}
size="small"
style={tagInputStyle}
value={editInputValue}
onChange={handleEditInputChange}
onBlur={handleEditInputConfirm}
onPressEnter={handleEditInputConfirm}
/>
);
}
const isLongTag = tag.length > 20;
const tagElem = (
<Tag
key={tag}
closable={true}
style={{ userSelect: 'none' }}
onClose={() => handleClose(tag)}
>
<span
onDoubleClick={(e) => {
if (index !== 0) {
setEditInputIndex(index);
setEditInputValue(tag);
e.preventDefault();
}
}}
>
{isLongTag ? `${tag.slice(0, 20)}...` : tag}
</span>
</Tag>
);
return isLongTag ? (
<Tooltip title={tag} key={tag}>
{tagElem}
</Tooltip>
) : (
tagElem
);
})}
{inputVisible ? (
<Input
ref={inputRef}
type="text"
size="small"
style={tagInputStyle}
value={inputValue}
onChange={handleInputChange}
onBlur={handleInputConfirm}
onPressEnter={handleInputConfirm}
/>
) : (
<Tag style={tagPlusStyle} icon={<PlusOutlined />} onClick={showInput}>
</Tag>
)}
</Flex>
</ProForm.Item>
</ModalForm>
);
};
export default CategorizeUpdate;