增加任务详情

This commit is contained in:
whyour 2022-03-04 00:08:33 +08:00
parent c959cec738
commit 634e9705a7
3 changed files with 240 additions and 38 deletions

View File

@ -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: <p>log content</p>,
script: <p>script content</p>,
};
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 (
<Modal
title={
<>
<span>{cron.name}</span>
<Divider type="vertical"></Divider>
{cron.labels?.length > 0 &&
cron.labels[0] !== '' &&
cron.labels?.map((label: string, i: number) => (
<Tag color="blue" style={{ marginRight: 5 }}>
{label}
</Tag>
))}
</>
}
centered
visible={visible}
forceRender
footer={false}
onCancel={() => handleCancel()}
width={'80vw'}
bodyStyle={{ background: '#eee', padding: 12 }}
>
<div style={{ height: '70vh', overflowY: 'auto' }}>
<Card bodyStyle={{ display: 'flex', justifyContent: 'space-between' }}>
<div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">
{(!cron.isDisabled || cron.status !== CrontabStatus.idle) && (
<>
{cron.status === CrontabStatus.idle && (
<Tag icon={<ClockCircleOutlined />} color="default">
</Tag>
)}
{cron.status === CrontabStatus.running && (
<Tag
icon={<Loading3QuartersOutlined spin />}
color="processing"
>
</Tag>
)}
{cron.status === CrontabStatus.queued && (
<Tag icon={<FieldTimeOutlined />} color="default">
</Tag>
)}
</>
)}
{cron.isDisabled === 1 && cron.status === CrontabStatus.idle && (
<Tag icon={<CloseCircleOutlined />} color="error">
</Tag>
)}
</div>
</div>
<div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">{cron.command}</div>
</div>
<div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">{cron.schedule}</div>
</div>
<div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">
{cron.last_execution_time
? new Date(cron.last_execution_time * 1000)
.toLocaleString(language, {
hour12: false,
})
.replace(' 24:', ' 00:')
: '-'}
</div>
</div>
<div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">
{cron.last_running_time ? diffTime(cron.last_running_time) : '-'}
</div>
</div>
<div className="cron-detail-info-item">
<div className="cron-detail-info-title"></div>
<div className="cron-detail-info-value">
{cron.nextRunTime &&
cron.nextRunTime
.toLocaleString(language, {
hour12: false,
})
.replace(' 24:', ' 00:')}
</div>
</div>
</Card>
<Card
style={{ marginTop: 16 }}
tabList={tabList}
activeTabKey={activeTabKey}
onTabChange={(key) => {
onTabChange(key);
}}
>
{contentList[activeTabKey]}
</Card>
</div>
</Modal>
);
};
export default CronDetailModal;

View File

@ -1,3 +1,21 @@
.ant-table-pagination.ant-pagination { .ant-table-pagination.ant-pagination {
margin-bottom: 0 !important; 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;
}
}

View File

@ -33,6 +33,7 @@ import { PageContainer } from '@ant-design/pro-layout';
import { request } from '@/utils/http'; import { request } from '@/utils/http';
import CronModal, { CronLabelModal } from './modal'; import CronModal, { CronLabelModal } from './modal';
import CronLogModal from './logModal'; import CronLogModal from './logModal';
import CronDetailModal from './detail';
import cron_parser from 'cron-parser'; import cron_parser from 'cron-parser';
import { diffTime } from '@/utils/date'; import { diffTime } from '@/utils/date';
import { getTableScroll } from '@/utils/index'; import { getTableScroll } from '@/utils/index';
@ -42,7 +43,7 @@ import './index.less';
const { Text } = Typography; const { Text } = Typography;
const { Search } = Input; const { Search } = Input;
enum CrontabStatus { export enum CrontabStatus {
'running', 'running',
'idle', 'idle',
'disabled', 'disabled',
@ -84,17 +85,6 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
goToScriptManager(record); goToScriptManager(record);
}} }}
> >
{record.name || record._id}{' '}
{record.isPinned ? (
<span>
<PushpinOutlined />
</span>
) : (
''
)}
</a>
<span>
{record.labels?.length > 0 && record.labels[0] !== '' ? (
<Popover <Popover
placement="right" placement="right"
trigger={isPhone ? 'click' : 'hover'} trigger={isPhone ? 'click' : 'hover'}
@ -113,12 +103,16 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
</div> </div>
} }
> >
<Tag color="blue">{record.labels[0]}</Tag> {record.name || '-'}
</Popover> </Popover>
{record.isPinned ? (
<span>
<PushpinOutlined />
</span>
) : ( ) : (
'' ''
)} )}
</span> </a>
</> </>
), ),
sorter: { sorter: {
@ -316,7 +310,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
{record.status === CrontabStatus.idle && ( {record.status === CrontabStatus.idle && (
<Tooltip title={isPc ? '运行' : ''}> <Tooltip title={isPc ? '运行' : ''}>
<a <a
onClick={() => { onClick={(e) => {
e.stopPropagation();
runCron(record, index); runCron(record, index);
}} }}
> >
@ -327,7 +322,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
{record.status !== CrontabStatus.idle && ( {record.status !== CrontabStatus.idle && (
<Tooltip title={isPc ? '停止' : ''}> <Tooltip title={isPc ? '停止' : ''}>
<a <a
onClick={() => { onClick={(e) => {
e.stopPropagation();
stopCron(record, index); stopCron(record, index);
}} }}
> >
@ -337,7 +333,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
)} )}
<Tooltip title={isPc ? '日志' : ''}> <Tooltip title={isPc ? '日志' : ''}>
<a <a
onClick={() => { onClick={(e) => {
e.stopPropagation();
setLogCron({ ...record, timestamp: Date.now() }); setLogCron({ ...record, timestamp: Date.now() });
}} }}
> >
@ -354,7 +351,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
const [value, setValue] = useState<any[]>([]); const [value, setValue] = useState<any[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [isLabelModalVisible, setisLabelModalVisible] = useState(false); const [isLabelModalVisible, setIsLabelModalVisible] = useState(false);
const [editedCron, setEditedCron] = useState(); const [editedCron, setEditedCron] = useState();
const [searchText, setSearchText] = useState(''); const [searchText, setSearchText] = useState('');
const [isLogModalVisible, setIsLogModalVisible] = useState(false); const [isLogModalVisible, setIsLogModalVisible] = useState(false);
@ -363,6 +360,8 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(20); const [pageSize, setPageSize] = useState(20);
const [tableScrollHeight, setTableScrollHeight] = useState<number>(); const [tableScrollHeight, setTableScrollHeight] = useState<number>();
const [isDetailModalVisible, setIsDetailModalVisible] = useState(false);
const [detailCron, setDetailCron] = useState<any>();
const goToScriptManager = (record: any) => { const goToScriptManager = (record: any) => {
const cmd = record.command.split(' ') as string[]; const cmd = record.command.split(' ') as string[];
@ -629,7 +628,12 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
arrow arrow
trigger={['click']} trigger={['click']}
overlay={ overlay={
<Menu onClick={({ key }) => action(key, record, index)}> <Menu
onClick={({ key, domEvent }) => {
domEvent.stopPropagation();
action(key, record, index);
}}
>
<Menu.Item key="edit" icon={<EditOutlined />}> <Menu.Item key="edit" icon={<EditOutlined />}>
</Menu.Item> </Menu.Item>
@ -659,7 +663,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
</Menu> </Menu>
} }
> >
<a> <a onClick={(e) => e.stopPropagation()}>
<EllipsisOutlined /> <EllipsisOutlined />
</a> </a>
</Dropdown> </Dropdown>
@ -804,7 +808,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
}; };
const getRowClassName = (record: any, index: number) => { const getRowClassName = (record: any, index: number) => {
return record.isPinned ? 'pinned-cron' : ''; return record.isPinned ? 'pinned-cron cron' : 'cron';
}; };
useEffect(() => { useEffect(() => {
@ -890,7 +894,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
</Button> </Button>
<Button <Button
type="primary" type="primary"
onClick={() => setisLabelModalVisible(true)} onClick={() => setIsLabelModalVisible(true)}
style={{ marginLeft: 8, marginRight: 8 }} style={{ marginLeft: 8, marginRight: 8 }}
> >
@ -912,7 +916,15 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
defaultPageSize: 20, defaultPageSize: 20,
showTotal: (total: number, range: number[]) => showTotal: (total: number, range: number[]) =>
`${range[0]}-${range[1]} 条/总共 ${total}`, `${range[0]}-${range[1]} 条/总共 ${total}`,
pageSizeOptions: [10, 20, 50, 100, 200, 500, 1000], pageSizeOptions: [20, 100, 500, 1000] as any,
}}
onRow={(record) => {
return {
onClick: (event) => {
setDetailCron(record);
setIsDetailModalVisible(true);
},
};
}} }}
dataSource={value} dataSource={value}
rowKey="id" rowKey="id"
@ -938,13 +950,20 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
<CronLabelModal <CronLabelModal
visible={isLabelModalVisible} visible={isLabelModalVisible}
handleCancel={(needUpdate?: boolean) => { handleCancel={(needUpdate?: boolean) => {
setisLabelModalVisible(false); setIsLabelModalVisible(false);
if (needUpdate) { if (needUpdate) {
getCrons(); getCrons();
} }
}} }}
ids={selectedRowIds} ids={selectedRowIds}
/> />
<CronDetailModal
visible={isDetailModalVisible}
handleCancel={() => {
setIsDetailModalVisible(false);
}}
cron={detailCron}
/>
</PageContainer> </PageContainer>
); );
}; };