mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-24 15:43:24 +08:00
修改定时任务添加标签交互
This commit is contained in:
parent
c0d401e296
commit
2bd8e49302
|
@ -53,7 +53,7 @@
|
||||||
"sequelize": "^6.17.0",
|
"sequelize": "^6.17.0",
|
||||||
"serve-handler": "^6.1.3",
|
"serve-handler": "^6.1.3",
|
||||||
"sockjs": "^0.3.24",
|
"sockjs": "^0.3.24",
|
||||||
"sqlite3": "npm:@louislam/sqlite3@^6.0.1",
|
"sqlite3": "npm:@louislam/sqlite3@^15.0.3",
|
||||||
"toad-scheduler": "^1.6.0",
|
"toad-scheduler": "^1.6.0",
|
||||||
"typedi": "^0.10.0",
|
"typedi": "^0.10.0",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
|
|
110
src/components/tag.tsx
Normal file
110
src/components/tag.tsx
Normal file
|
@ -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<string[]>([]);
|
||||||
|
const saveInputRef = useRef<any>();
|
||||||
|
|
||||||
|
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 = (
|
||||||
|
<Tag
|
||||||
|
closable
|
||||||
|
onClose={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleClose(tag);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tag}
|
||||||
|
</Tag>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<span key={tag} style={{ display: 'inline-block', marginBottom: 8 }}>
|
||||||
|
{tagElem}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (inputVisible && saveInputRef) {
|
||||||
|
saveInputRef.current.focus();
|
||||||
|
}
|
||||||
|
}, [inputVisible]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (value) {
|
||||||
|
setTags(value);
|
||||||
|
}
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TweenOneGroup
|
||||||
|
enter={{
|
||||||
|
scale: 0.8,
|
||||||
|
opacity: 0,
|
||||||
|
type: 'from',
|
||||||
|
duration: 100,
|
||||||
|
}}
|
||||||
|
leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
|
||||||
|
appear={false}
|
||||||
|
>
|
||||||
|
{tagChild}
|
||||||
|
</TweenOneGroup>
|
||||||
|
{inputVisible && (
|
||||||
|
<Input
|
||||||
|
ref={saveInputRef}
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
style={{ width: 78 }}
|
||||||
|
value={inputValue}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
onBlur={handleInputConfirm}
|
||||||
|
onPressEnter={handleInputConfirm}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!inputVisible && (
|
||||||
|
<Tag
|
||||||
|
onClick={showInput}
|
||||||
|
style={{ borderStyle: 'dashed', cursor: 'pointer' }}
|
||||||
|
>
|
||||||
|
<PlusOutlined /> 新建
|
||||||
|
</Tag>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditableTagGroup;
|
|
@ -3,6 +3,7 @@ import { Modal, message, Input, Form, Button } from 'antd';
|
||||||
import { request } from '@/utils/http';
|
import { request } from '@/utils/http';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
import cronParse from 'cron-parser';
|
import cronParse from 'cron-parser';
|
||||||
|
import EditableTagGroup from '@/components/tag';
|
||||||
|
|
||||||
const CronModal = ({
|
const CronModal = ({
|
||||||
cron,
|
cron,
|
||||||
|
@ -20,11 +21,6 @@ const CronModal = ({
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const method = cron ? 'put' : 'post';
|
const method = cron ? 'put' : 'post';
|
||||||
const payload = { ...values };
|
const payload = { ...values };
|
||||||
if (typeof payload.labels === 'string') {
|
|
||||||
payload.labels = values.labels.split(/,|,/);
|
|
||||||
} else if (!payload.labels) {
|
|
||||||
payload.labels = [];
|
|
||||||
}
|
|
||||||
if (cron) {
|
if (cron) {
|
||||||
payload.id = cron.id;
|
payload.id = cron.id;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +89,7 @@ const CronModal = ({
|
||||||
{ required: true },
|
{ required: true },
|
||||||
{
|
{
|
||||||
validator: (rule, value) => {
|
validator: (rule, value) => {
|
||||||
if (cronParse.parseExpression(value).hasNext()) {
|
if (!value || cronParse.parseExpression(value).hasNext()) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject('Cron表达式格式有误');
|
return Promise.reject('Cron表达式格式有误');
|
||||||
|
@ -105,7 +101,7 @@ const CronModal = ({
|
||||||
<Input placeholder="秒(可选) 分 时 天 月 周" />
|
<Input placeholder="秒(可选) 分 时 天 月 周" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="labels" label="标签">
|
<Form.Item name="labels" label="标签">
|
||||||
<Input placeholder="请输入任务标签" />
|
<EditableTagGroup />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -128,9 +124,6 @@ const CronLabelModal = ({
|
||||||
form
|
form
|
||||||
.validateFields()
|
.validateFields()
|
||||||
.then(async (values) => {
|
.then(async (values) => {
|
||||||
if (typeof values.labels === 'string') {
|
|
||||||
values.labels = values.labels.split(/,|,/);
|
|
||||||
}
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const payload = { ids, labels: values.labels };
|
const payload = { ids, labels: values.labels };
|
||||||
const { code, data } = await request[action](
|
const { code, data } = await request[action](
|
||||||
|
@ -179,7 +172,7 @@ const CronLabelModal = ({
|
||||||
>
|
>
|
||||||
<Form form={form} layout="vertical" name="form_in_label_modal">
|
<Form form={form} layout="vertical" name="form_in_label_modal">
|
||||||
<Form.Item name="labels" label="标签">
|
<Form.Item name="labels" label="标签">
|
||||||
<Input placeholder="请输入任务标签" />
|
<EditableTagGroup />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user