From 22d097aa0818a0abdecd104a9f2e2238d3a22e31 Mon Sep 17 00:00:00 2001 From: whyour Date: Sun, 1 May 2022 13:51:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=B7=BB=E5=8A=A0=E6=A0=87=E7=AD=BE=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/components/tag.tsx | 110 ++++++++++++++++++++++++++++++++++++ src/pages/crontab/modal.tsx | 15 ++--- 3 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 src/components/tag.tsx diff --git a/package.json b/package.json index 6376fd46..38e12e97 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "sequelize": "^6.17.0", "serve-handler": "^6.1.3", "sockjs": "^0.3.24", - "sqlite3": "npm:@louislam/sqlite3@^6.0.1", + "sqlite3": "npm:@louislam/sqlite3@^15.0.3", "toad-scheduler": "^1.6.0", "typedi": "^0.10.0", "uuid": "^8.3.2", diff --git a/src/components/tag.tsx b/src/components/tag.tsx new file mode 100644 index 00000000..c62066fb --- /dev/null +++ b/src/components/tag.tsx @@ -0,0 +1,110 @@ +import { Tag, Input } from 'antd'; +import { TweenOneGroup } from 'rc-tween-one'; +import { PlusOutlined } from '@ant-design/icons'; +import { useEffect, useRef, useState } from 'react'; + +const EditableTagGroup = ({ + value, + onChange, +}: { + value?: string[]; + onChange?: (tags: string[]) => void; +}) => { + const [inputValue, setInputValue] = useState(''); + const [inputVisible, setInputVisible] = useState(false); + const [tags, setTags] = useState([]); + const saveInputRef = useRef(); + + const handleClose = (removedTag: string) => { + const _tags = tags.filter((tag) => tag !== removedTag); + setTags(_tags); + onChange?.(_tags); + }; + + const showInput = () => { + setInputVisible(true); + }; + + const handleInputChange = (e) => { + setInputValue(e.target.value); + }; + + const handleInputConfirm = () => { + if (inputValue && !tags.includes(inputValue)) { + setTags([...tags, inputValue]); + onChange?.([...tags, inputValue]); + } + setInputVisible(false); + setInputValue(''); + }; + + const tagChild = tags.map((tag) => { + const tagElem = ( + { + e.preventDefault(); + handleClose(tag); + }} + > + {tag} + + ); + return ( + + {tagElem} + + ); + }); + + useEffect(() => { + if (inputVisible && saveInputRef) { + saveInputRef.current.focus(); + } + }, [inputVisible]); + + useEffect(() => { + if (value) { + setTags(value); + } + }, [value]); + + return ( + <> + + {tagChild} + + {inputVisible && ( + + )} + {!inputVisible && ( + + 新建 + + )} + + ); +}; + +export default EditableTagGroup; diff --git a/src/pages/crontab/modal.tsx b/src/pages/crontab/modal.tsx index e067d68c..e56b1cbe 100644 --- a/src/pages/crontab/modal.tsx +++ b/src/pages/crontab/modal.tsx @@ -3,6 +3,7 @@ import { Modal, message, Input, Form, Button } from 'antd'; import { request } from '@/utils/http'; import config from '@/utils/config'; import cronParse from 'cron-parser'; +import EditableTagGroup from '@/components/tag'; const CronModal = ({ cron, @@ -20,11 +21,6 @@ const CronModal = ({ setLoading(true); const method = cron ? 'put' : 'post'; const payload = { ...values }; - if (typeof payload.labels === 'string') { - payload.labels = values.labels.split(/,|,/); - } else if (!payload.labels) { - payload.labels = []; - } if (cron) { payload.id = cron.id; } @@ -93,7 +89,7 @@ const CronModal = ({ { required: true }, { validator: (rule, value) => { - if (cronParse.parseExpression(value).hasNext()) { + if (!value || cronParse.parseExpression(value).hasNext()) { return Promise.resolve(); } else { return Promise.reject('Cron表达式格式有误'); @@ -105,7 +101,7 @@ const CronModal = ({ - + @@ -128,9 +124,6 @@ const CronLabelModal = ({ form .validateFields() .then(async (values) => { - if (typeof values.labels === 'string') { - values.labels = values.labels.split(/,|,/); - } setLoading(true); const payload = { ids, labels: values.labels }; const { code, data } = await request[action]( @@ -179,7 +172,7 @@ const CronLabelModal = ({ >
- +