From 634e9705a774d9a48c4f1970ff6341e1b5dd9b1e Mon Sep 17 00:00:00 2001 From: whyour Date: Fri, 4 Mar 2022 00:08:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=BB=E5=8A=A1=E8=AF=A6?= =?UTF-8?q?=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/crontab/detail.tsx | 165 +++++++++++++++++++++++++++++++++++ src/pages/crontab/index.less | 18 ++++ src/pages/crontab/index.tsx | 95 ++++++++++++-------- 3 files changed, 240 insertions(+), 38 deletions(-) create mode 100644 src/pages/crontab/detail.tsx diff --git a/src/pages/crontab/detail.tsx b/src/pages/crontab/detail.tsx new file mode 100644 index 00000000..c99e30d8 --- /dev/null +++ b/src/pages/crontab/detail.tsx @@ -0,0 +1,165 @@ +import React, { useEffect, useState } from 'react'; +import { + Modal, + message, + Input, + Form, + Button, + Card, + Tag, + Popover, + Divider, +} from 'antd'; +import { + ClockCircleOutlined, + CloseCircleOutlined, + FieldTimeOutlined, + Loading3QuartersOutlined, +} from '@ant-design/icons'; +import { CrontabStatus } from './index'; +import { diffTime } from '@/utils/date'; + +const contentList: any = { + log:

log content

, + script:

script content

, +}; + +const tabList = [ + { + key: 'log', + tab: '日志', + }, + { + key: 'script', + tab: '脚本', + }, +]; + +const language = navigator.language || navigator.languages[0]; + +const CronDetailModal = ({ + cron = {}, + handleCancel, + visible, +}: { + cron?: any; + visible: boolean; + handleCancel: (needUpdate?: boolean) => void; +}) => { + const [activeTabKey, setActiveTabKey] = useState('log'); + + const onTabChange = (key: string) => { + setActiveTabKey(key); + }; + + return ( + + {cron.name} + + {cron.labels?.length > 0 && + cron.labels[0] !== '' && + cron.labels?.map((label: string, i: number) => ( + + {label} + + ))} + + } + centered + visible={visible} + forceRender + footer={false} + onCancel={() => handleCancel()} + width={'80vw'} + bodyStyle={{ background: '#eee', padding: 12 }} + > +
+ +
+
状态
+
+ {(!cron.isDisabled || cron.status !== CrontabStatus.idle) && ( + <> + {cron.status === CrontabStatus.idle && ( + } color="default"> + 空闲中 + + )} + {cron.status === CrontabStatus.running && ( + } + color="processing" + > + 运行中 + + )} + {cron.status === CrontabStatus.queued && ( + } color="default"> + 队列中 + + )} + + )} + {cron.isDisabled === 1 && cron.status === CrontabStatus.idle && ( + } color="error"> + 已禁用 + + )} +
+
+
+
任务
+
{cron.command}
+
+
+
定时
+
{cron.schedule}
+
+
+
最后运行时间
+
+ {cron.last_execution_time + ? new Date(cron.last_execution_time * 1000) + .toLocaleString(language, { + hour12: false, + }) + .replace(' 24:', ' 00:') + : '-'} +
+
+
+
最后运行时长
+
+ {cron.last_running_time ? diffTime(cron.last_running_time) : '-'} +
+
+
+
下次运行时间
+
+ {cron.nextRunTime && + cron.nextRunTime + .toLocaleString(language, { + hour12: false, + }) + .replace(' 24:', ' 00:')} +
+
+
+ { + onTabChange(key); + }} + > + {contentList[activeTabKey]} + +
+
+ ); +}; + +export default CronDetailModal; diff --git a/src/pages/crontab/index.less b/src/pages/crontab/index.less index c33e54f8..6405f1ad 100644 --- a/src/pages/crontab/index.less +++ b/src/pages/crontab/index.less @@ -1,3 +1,21 @@ .ant-table-pagination.ant-pagination { margin-bottom: 0 !important; } + +.cron { + &:hover { + cursor: pointer; + } +} + +.cron-detail-info-item { + flex: auto; + + .cron-detail-info-title { + color: #888; + } + + .cron-detail-info-value { + margin-top: 18px; + } +} diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 428f4570..3b546297 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -33,6 +33,7 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import CronModal, { CronLabelModal } from './modal'; import CronLogModal from './logModal'; +import CronDetailModal from './detail'; import cron_parser from 'cron-parser'; import { diffTime } from '@/utils/date'; import { getTableScroll } from '@/utils/index'; @@ -42,7 +43,7 @@ import './index.less'; const { Text } = Typography; const { Search } = Input; -enum CrontabStatus { +export enum CrontabStatus { 'running', 'idle', 'disabled', @@ -84,7 +85,26 @@ const Crontab = ({ headerStyle, isPhone }: any) => { goToScriptManager(record); }} > - {record.name || record._id}{' '} + + {record.labels?.map((label: string, i: number) => ( + { + onSearch(`label:${label}`); + }} + > + {label} + + ))} + + } + > + {record.name || '-'} + {record.isPinned ? ( @@ -93,32 +113,6 @@ const Crontab = ({ headerStyle, isPhone }: any) => { '' )} - - {record.labels?.length > 0 && record.labels[0] !== '' ? ( - - {record.labels?.map((label: string, i: number) => ( - { - onSearch(`label:${label}`); - }} - > - {label} - - ))} - - } - > - {record.labels[0]} - - ) : ( - '' - )} - ), sorter: { @@ -316,7 +310,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => { {record.status === CrontabStatus.idle && ( { + onClick={(e) => { + e.stopPropagation(); runCron(record, index); }} > @@ -327,7 +322,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => { {record.status !== CrontabStatus.idle && ( { + onClick={(e) => { + e.stopPropagation(); stopCron(record, index); }} > @@ -337,7 +333,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => { )} { + onClick={(e) => { + e.stopPropagation(); setLogCron({ ...record, timestamp: Date.now() }); }} > @@ -354,7 +351,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => { const [value, setValue] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); - const [isLabelModalVisible, setisLabelModalVisible] = useState(false); + const [isLabelModalVisible, setIsLabelModalVisible] = useState(false); const [editedCron, setEditedCron] = useState(); const [searchText, setSearchText] = useState(''); const [isLogModalVisible, setIsLogModalVisible] = useState(false); @@ -363,6 +360,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => { const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(20); const [tableScrollHeight, setTableScrollHeight] = useState(); + const [isDetailModalVisible, setIsDetailModalVisible] = useState(false); + const [detailCron, setDetailCron] = useState(); const goToScriptManager = (record: any) => { const cmd = record.command.split(' ') as string[]; @@ -629,7 +628,12 @@ const Crontab = ({ headerStyle, isPhone }: any) => { arrow trigger={['click']} overlay={ - action(key, record, index)}> + { + domEvent.stopPropagation(); + action(key, record, index); + }} + > }> 编辑 @@ -659,7 +663,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => { } > - + e.stopPropagation()}> @@ -804,7 +808,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => { }; const getRowClassName = (record: any, index: number) => { - return record.isPinned ? 'pinned-cron' : ''; + return record.isPinned ? 'pinned-cron cron' : 'cron'; }; useEffect(() => { @@ -890,7 +894,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {