任务详情增加运行、禁用、置顶操作

This commit is contained in:
whyour 2022-04-24 17:45:50 +08:00
parent 1b893f35ba
commit 8bb8a29400
3 changed files with 261 additions and 30 deletions

View File

@ -0,0 +1,7 @@
import { createFromIconfontCN } from '@ant-design/icons';
const IconFont = createFromIconfontCN({
scriptUrl: ['//at.alicdn.com/t/font_3354854_pk18p04ny1a.js'],
});
export default IconFont;

View File

@ -10,6 +10,7 @@ import {
List, List,
Divider, Divider,
Typography, Typography,
Tooltip,
} from 'antd'; } from 'antd';
import { import {
ClockCircleOutlined, ClockCircleOutlined,
@ -17,6 +18,8 @@ import {
FieldTimeOutlined, FieldTimeOutlined,
Loading3QuartersOutlined, Loading3QuartersOutlined,
FileOutlined, FileOutlined,
PlayCircleOutlined,
PauseCircleOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { CrontabStatus } from './index'; import { CrontabStatus } from './index';
import { diffTime } from '@/utils/date'; import { diffTime } from '@/utils/date';
@ -24,6 +27,7 @@ import { request } from '@/utils/http';
import config from '@/utils/config'; import config from '@/utils/config';
import CronLogModal from './logModal'; import CronLogModal from './logModal';
import Editor from '@monaco-editor/react'; import Editor from '@monaco-editor/react';
import IconFont from '@/components/iconfont';
const { Text } = Typography; const { Text } = Typography;
@ -68,6 +72,7 @@ const CronDetailModal = ({
const [scriptInfo, setScriptInfo] = useState<any>({}); const [scriptInfo, setScriptInfo] = useState<any>({});
const [logUrl, setLogUrl] = useState(''); const [logUrl, setLogUrl] = useState('');
const [validTabs, setValidTabs] = useState(tabList); const [validTabs, setValidTabs] = useState(tabList);
const [currentCron, setCurrentCron] = useState<any>({});
const contentList: any = { const contentList: any = {
log: ( log: (
@ -103,7 +108,7 @@ const CronDetailModal = ({
}; };
const onClickItem = (item: LogItem) => { const onClickItem = (item: LogItem) => {
localStorage.setItem('logCron', cron.id); localStorage.setItem('logCron', currentCron.id);
setLogUrl(`${config.apiPrefix}logs/${item.directory}/${item.filename}`); setLogUrl(`${config.apiPrefix}logs/${item.directory}/${item.filename}`);
request request
.get(`${config.apiPrefix}logs/${item.directory}/${item.filename}`) .get(`${config.apiPrefix}logs/${item.directory}/${item.filename}`)
@ -196,8 +201,150 @@ const CronDetailModal = ({
}); });
}; };
const runCron = () => {
Modal.confirm({
title: '确认运行',
content: (
<>
{' '}
<Text style={{ wordBreak: 'break-all' }} type="warning">
{currentCron.name}
</Text>{' '}
</>
),
onOk() {
request
.put(`${config.apiPrefix}crons/run`, { data: [currentCron.id] })
.then((data: any) => {
if (data.code === 200) {
setCurrentCron({ ...currentCron, status: CrontabStatus.running });
setTimeout(() => {
getLogs();
}, 1000);
} else {
message.error(data);
}
});
},
onCancel() {
console.log('Cancel');
},
});
};
const stopCron = () => {
Modal.confirm({
title: '确认停止',
content: (
<>
{' '}
<Text style={{ wordBreak: 'break-all' }} type="warning">
{currentCron.name}
</Text>{' '}
</>
),
onOk() {
request
.put(`${config.apiPrefix}crons/stop`, { data: [currentCron.id] })
.then((data: any) => {
if (data.code === 200) {
setCurrentCron({ ...currentCron, status: CrontabStatus.idle });
} else {
message.error(data);
}
});
},
onCancel() {
console.log('Cancel');
},
});
};
const enabledOrDisabledCron = () => {
Modal.confirm({
title: `确认${currentCron.isDisabled === 1 ? '启用' : '禁用'}`,
content: (
<>
{currentCron.isDisabled === 1 ? '启用' : '禁用'}
{' '}
<Text style={{ wordBreak: 'break-all' }} type="warning">
{currentCron.name}
</Text>{' '}
</>
),
onOk() {
request
.put(
`${config.apiPrefix}crons/${
currentCron.isDisabled === 1 ? 'enable' : 'disable'
}`,
{
data: [currentCron.id],
},
)
.then((data: any) => {
if (data.code === 200) {
setCurrentCron({
...currentCron,
isDisabled: currentCron.isDisabled === 1 ? 0 : 1,
});
} else {
message.error(data);
}
});
},
onCancel() {
console.log('Cancel');
},
});
};
const pinOrUnPinCron = () => {
Modal.confirm({
title: `确认${currentCron.isPinned === 1 ? '取消置顶' : '置顶'}`,
content: (
<>
{currentCron.isPinned === 1 ? '取消置顶' : '置顶'}
{' '}
<Text style={{ wordBreak: 'break-all' }} type="warning">
{currentCron.name}
</Text>{' '}
</>
),
onOk() {
request
.put(
`${config.apiPrefix}crons/${
currentCron.isPinned === 1 ? 'unpin' : 'pin'
}`,
{
data: [currentCron.id],
},
)
.then((data: any) => {
if (data.code === 200) {
setCurrentCron({
...currentCron,
isPinned: currentCron.isPinned === 1 ? 0 : 1,
});
} else {
message.error(data);
}
});
},
onCancel() {
console.log('Cancel');
},
});
};
useEffect(() => { useEffect(() => {
if (cron && cron.id) { if (cron && cron.id) {
setCurrentCron(cron);
getLogs(); getLogs();
getScript(); getScript();
} }
@ -206,19 +353,76 @@ const CronDetailModal = ({
return ( return (
<Modal <Modal
title={ title={
<> <div className="crontab-title-wrapper">
<span>{cron.name}</span> <div>
{cron.labels?.length > 0 && cron.labels[0] !== '' && ( <span>{currentCron.name}</span>
<Divider type="vertical"></Divider> {currentCron.labels?.length > 0 && currentCron.labels[0] !== '' && (
)} <Divider type="vertical"></Divider>
{cron.labels?.length > 0 && )}
cron.labels[0] !== '' && {currentCron.labels?.length > 0 &&
cron.labels?.map((label: string, i: number) => ( currentCron.labels[0] !== '' &&
<Tag color="blue" style={{ marginRight: 5 }}> currentCron.labels?.map((label: string, i: number) => (
{label} <Tag color="blue" style={{ marginRight: 5 }}>
</Tag> {label}
))} </Tag>
</> ))}
</div>
<div className="operations">
<Tooltip
title={
currentCron.status === CrontabStatus.idle ? '运行' : '停止'
}
>
<Button
type="link"
icon={
currentCron.status === CrontabStatus.idle ? (
<PlayCircleOutlined />
) : (
<PauseCircleOutlined />
)
}
size="small"
onClick={
currentCron.status === CrontabStatus.idle ? runCron : stopCron
}
/>
</Tooltip>
<Tooltip title={currentCron.isDisabled === 1 ? '启用' : '禁用'}>
<Button
type="link"
icon={
<IconFont
type={
currentCron.isDisabled === 1
? 'ql-icon-qiyong'
: 'ql-icon-jinyong'
}
/>
}
size="small"
onClick={enabledOrDisabledCron}
/>
</Tooltip>
<Tooltip title={currentCron.isPinned === 1 ? '取消置顶' : '置顶'}>
<Button
type="link"
icon={
<IconFont
type={
currentCron.isPinned === 1
? 'ql-icon-quxiaozhiding'
: 'ql-icon-zhiding'
}
/>
}
size="small"
onClick={pinOrUnPinCron}
/>
</Tooltip>
</div>
</div>
} }
centered centered
visible={visible} visible={visible}
@ -232,21 +436,22 @@ const CronDetailModal = ({
<Card> <Card>
<div className="cron-detail-info-item"> <div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div> <div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">{cron.command}</div> <div className="cron-detail-info-value">{currentCron.command}</div>
</div> </div>
</Card> </Card>
<Card style={{ marginTop: 10 }}> <Card style={{ marginTop: 10 }}>
<div className="cron-detail-info-item"> <div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div> <div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value"> <div className="cron-detail-info-value">
{(!cron.isDisabled || cron.status !== CrontabStatus.idle) && ( {(!currentCron.isDisabled ||
currentCron.status !== CrontabStatus.idle) && (
<> <>
{cron.status === CrontabStatus.idle && ( {currentCron.status === CrontabStatus.idle && (
<Tag icon={<ClockCircleOutlined />} color="default"> <Tag icon={<ClockCircleOutlined />} color="default">
</Tag> </Tag>
)} )}
{cron.status === CrontabStatus.running && ( {currentCron.status === CrontabStatus.running && (
<Tag <Tag
icon={<Loading3QuartersOutlined spin />} icon={<Loading3QuartersOutlined spin />}
color="processing" color="processing"
@ -254,29 +459,30 @@ const CronDetailModal = ({
</Tag> </Tag>
)} )}
{cron.status === CrontabStatus.queued && ( {currentCron.status === CrontabStatus.queued && (
<Tag icon={<FieldTimeOutlined />} color="default"> <Tag icon={<FieldTimeOutlined />} color="default">
</Tag> </Tag>
)} )}
</> </>
)} )}
{cron.isDisabled === 1 && cron.status === CrontabStatus.idle && ( {currentCron.isDisabled === 1 &&
<Tag icon={<CloseCircleOutlined />} color="error"> currentCron.status === CrontabStatus.idle && (
<Tag icon={<CloseCircleOutlined />} color="error">
</Tag>
)} </Tag>
)}
</div> </div>
</div> </div>
<div className="cron-detail-info-item"> <div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div> <div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">{cron.schedule}</div> <div className="cron-detail-info-value">{currentCron.schedule}</div>
</div> </div>
<div className="cron-detail-info-item"> <div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div> <div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value"> <div className="cron-detail-info-value">
{cron.last_execution_time {currentCron.last_execution_time
? new Date(cron.last_execution_time * 1000) ? new Date(currentCron.last_execution_time * 1000)
.toLocaleString(language, { .toLocaleString(language, {
hour12: false, hour12: false,
}) })
@ -287,14 +493,16 @@ const CronDetailModal = ({
<div className="cron-detail-info-item"> <div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div> <div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value"> <div className="cron-detail-info-value">
{cron.last_running_time ? diffTime(cron.last_running_time) : '-'} {currentCron.last_running_time
? diffTime(currentCron.last_running_time)
: '-'}
</div> </div>
</div> </div>
<div className="cron-detail-info-item"> <div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div> <div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value"> <div className="cron-detail-info-value">
{cron.nextRunTime && {currentCron.nextRunTime &&
cron.nextRunTime currentCron.nextRunTime
.toLocaleString(language, { .toLocaleString(language, {
hour12: false, hour12: false,
}) })

View File

@ -77,6 +77,22 @@
margin-top: 12px; margin-top: 12px;
} }
} }
.crontab-title-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
margin-right: 32px;
.operations {
display: flex;
align-items: center;
.ant-btn:not(:first-child) {
margin-left: 8px;
}
}
}
} }
.log-item { .log-item {