mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36:06 +08:00
修复定时任务排序
This commit is contained in:
parent
918d68d140
commit
3b3d45da29
|
@ -28,7 +28,7 @@ export default (app: Router) => {
|
||||||
celebrate({
|
celebrate({
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
name: Joi.string().required(),
|
name: Joi.string().required(),
|
||||||
sorts: Joi.string().required(),
|
sorts: Joi.string().optional(),
|
||||||
filters: Joi.string().optional(),
|
filters: Joi.string().optional(),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
@ -107,6 +107,8 @@ export default (app: Router) => {
|
||||||
searchText: Joi.string().required().allow(''),
|
searchText: Joi.string().required().allow(''),
|
||||||
page: Joi.string().required(),
|
page: Joi.string().required(),
|
||||||
size: Joi.string().required(),
|
size: Joi.string().required(),
|
||||||
|
sortField: Joi.string().optional(),
|
||||||
|
sortType: Joi.string().optional(),
|
||||||
t: Joi.string().required(),
|
t: Joi.string().required(),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -117,10 +117,14 @@ export default class CronService {
|
||||||
searchText: string;
|
searchText: string;
|
||||||
page: string;
|
page: string;
|
||||||
size: string;
|
size: string;
|
||||||
|
sortField: string;
|
||||||
|
sortType: string;
|
||||||
}): Promise<{ data: Crontab[]; total: number }> {
|
}): Promise<{ data: Crontab[]; total: number }> {
|
||||||
const searchText = params?.searchText;
|
const searchText = params?.searchText;
|
||||||
const page = Number(params?.page || '0');
|
const page = Number(params?.page || '0');
|
||||||
const size = Number(params?.size || '0');
|
const size = Number(params?.size || '0');
|
||||||
|
const sortField = params?.sortField || '';
|
||||||
|
const sortType = params?.sortType || '';
|
||||||
|
|
||||||
let query = {};
|
let query = {};
|
||||||
if (searchText) {
|
if (searchText) {
|
||||||
|
@ -166,14 +170,18 @@ export default class CronService {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let order = [
|
||||||
|
['isPinned', 'DESC'],
|
||||||
|
['isDisabled', 'ASC'],
|
||||||
|
['status', 'ASC'],
|
||||||
|
['createdAt', 'DESC'],
|
||||||
|
];
|
||||||
|
if (sortType && sortField) {
|
||||||
|
order.unshift([sortField, sortType]);
|
||||||
|
}
|
||||||
let condition: any = {
|
let condition: any = {
|
||||||
where: query,
|
where: query,
|
||||||
order: [
|
order: order,
|
||||||
['isPinned', 'DESC'],
|
|
||||||
['isDisabled', 'ASC'],
|
|
||||||
['status', 'ASC'],
|
|
||||||
['createdAt', 'DESC'],
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
if (page && size) {
|
if (page && size) {
|
||||||
condition.offset = (page - 1) * size;
|
condition.offset = (page - 1) * size;
|
||||||
|
@ -298,11 +306,13 @@ export default class CronService {
|
||||||
if (!cmdStr.includes('task ') && !cmdStr.includes('ql ')) {
|
if (!cmdStr.includes('task ') && !cmdStr.includes('ql ')) {
|
||||||
cmdStr = `task ${cmdStr}`;
|
cmdStr = `task ${cmdStr}`;
|
||||||
}
|
}
|
||||||
if (cmdStr.endsWith('.js')
|
if (
|
||||||
|| cmdStr.endsWith('.py')
|
cmdStr.endsWith('.js') ||
|
||||||
|| cmdStr.endsWith('.pyc')
|
cmdStr.endsWith('.py') ||
|
||||||
|| cmdStr.endsWith('.sh')
|
cmdStr.endsWith('.pyc') ||
|
||||||
|| cmdStr.endsWith('.ts')) {
|
cmdStr.endsWith('.sh') ||
|
||||||
|
cmdStr.endsWith('.ts')
|
||||||
|
) {
|
||||||
cmdStr = `${cmdStr} now`;
|
cmdStr = `${cmdStr} now`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,3 +126,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.view-create-modal-filters {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.ant-space-item:nth-child(3) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
Input,
|
Input,
|
||||||
Popover,
|
Popover,
|
||||||
Tabs,
|
Tabs,
|
||||||
|
TablePaginationConfig,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import {
|
import {
|
||||||
ClockCircleOutlined,
|
ClockCircleOutlined,
|
||||||
|
@ -46,6 +47,8 @@ import { history } from 'umi';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
import ViewCreateModal from './viewCreateModal';
|
import ViewCreateModal from './viewCreateModal';
|
||||||
import ViewManageModal from './viewManageModal';
|
import ViewManageModal from './viewManageModal';
|
||||||
|
import pagination from 'antd/lib/pagination';
|
||||||
|
import { FilterValue, SorterResult } from 'antd/lib/table/interface';
|
||||||
|
|
||||||
const { Text, Paragraph } = Typography;
|
const { Text, Paragraph } = Typography;
|
||||||
const { Search } = Input;
|
const { Search } = Input;
|
||||||
|
@ -130,7 +133,6 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
),
|
),
|
||||||
sorter: {
|
sorter: {
|
||||||
compare: (a: any, b: any) => a?.name?.localeCompare(b?.name),
|
compare: (a: any, b: any) => a?.name?.localeCompare(b?.name),
|
||||||
multiple: 2,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -155,7 +157,6 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
},
|
},
|
||||||
sorter: {
|
sorter: {
|
||||||
compare: (a: any, b: any) => a.command.localeCompare(b.command),
|
compare: (a: any, b: any) => a.command.localeCompare(b.command),
|
||||||
multiple: 3,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -166,7 +167,6 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
align: 'center' as const,
|
align: 'center' as const,
|
||||||
sorter: {
|
sorter: {
|
||||||
compare: (a: any, b: any) => a.schedule.localeCompare(b.schedule),
|
compare: (a: any, b: any) => a.schedule.localeCompare(b.schedule),
|
||||||
multiple: 1,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -353,9 +353,11 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
const [isLogModalVisible, setIsLogModalVisible] = useState(false);
|
const [isLogModalVisible, setIsLogModalVisible] = useState(false);
|
||||||
const [logCron, setLogCron] = useState<any>();
|
const [logCron, setLogCron] = useState<any>();
|
||||||
const [selectedRowIds, setSelectedRowIds] = useState<string[]>([]);
|
const [selectedRowIds, setSelectedRowIds] = useState<string[]>([]);
|
||||||
const [pageConf, setPageConf] = useState<{ page: number; size: number }>(
|
const [pageConf, setPageConf] = useState<{
|
||||||
{} as any,
|
page: number;
|
||||||
);
|
size: number;
|
||||||
|
sorter: any;
|
||||||
|
}>({} as any);
|
||||||
const [tableScrollHeight, setTableScrollHeight] = useState<number>();
|
const [tableScrollHeight, setTableScrollHeight] = useState<number>();
|
||||||
const [isDetailModalVisible, setIsDetailModalVisible] = useState(false);
|
const [isDetailModalVisible, setIsDetailModalVisible] = useState(false);
|
||||||
const [detailCron, setDetailCron] = useState<any>();
|
const [detailCron, setDetailCron] = useState<any>();
|
||||||
|
@ -365,6 +367,7 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
useState(false);
|
useState(false);
|
||||||
const [isViewManageModalVisible, setIsViewManageModalVisible] =
|
const [isViewManageModalVisible, setIsViewManageModalVisible] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
const [cronViews, setCronViews] = useState<any[]>([]);
|
||||||
|
|
||||||
const goToScriptManager = (record: any) => {
|
const goToScriptManager = (record: any) => {
|
||||||
const cmd = record.command.split(' ') as string[];
|
const cmd = record.command.split(' ') as string[];
|
||||||
|
@ -386,10 +389,15 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
|
|
||||||
const getCrons = () => {
|
const getCrons = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
const { page, size, sorter } = pageConf;
|
||||||
|
let url = `${config.apiPrefix}crons?searchText=${searchText}&page=${page}&size=${size}`;
|
||||||
|
if (sorter && sorter.field) {
|
||||||
|
url += `&sortField=${sorter.field}&sortType=${
|
||||||
|
sorter.order === 'ascend' ? 'ASC' : 'DESC'
|
||||||
|
}`;
|
||||||
|
}
|
||||||
request
|
request
|
||||||
.get(
|
.get(url)
|
||||||
`${config.apiPrefix}crons?searchText=${searchText}&page=${pageConf.page}&size=${pageConf.size}`,
|
|
||||||
)
|
|
||||||
.then((_data: any) => {
|
.then((_data: any) => {
|
||||||
const { data, total } = _data.data;
|
const { data, total } = _data.data;
|
||||||
setValue(
|
setValue(
|
||||||
|
@ -791,8 +799,13 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPageChange = (page: number, pageSize: number | undefined) => {
|
const onPageChange = (
|
||||||
setPageConf({ page, size: pageSize as number });
|
pagination: TablePaginationConfig,
|
||||||
|
filters: Record<string, FilterValue | null>,
|
||||||
|
sorter: SorterResult<any> | SorterResult<any>[],
|
||||||
|
) => {
|
||||||
|
const { current, pageSize } = pagination;
|
||||||
|
setPageConf({ page: current as number, size: pageSize as number, sorter });
|
||||||
localStorage.setItem('pageSize', String(pageSize));
|
localStorage.setItem('pageSize', String(pageSize));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -821,10 +834,12 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
setPageConf({
|
setPageConf({
|
||||||
page: 1,
|
page: 1,
|
||||||
size: parseInt(localStorage.getItem('pageSize') || '20'),
|
size: parseInt(localStorage.getItem('pageSize') || '20'),
|
||||||
|
sorter: {},
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setTableScrollHeight(getTableScroll());
|
setTableScrollHeight(getTableScroll());
|
||||||
});
|
});
|
||||||
|
getCronViews();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const panelContent = (
|
const panelContent = (
|
||||||
|
@ -889,7 +904,6 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
columns={columns}
|
columns={columns}
|
||||||
pagination={{
|
pagination={{
|
||||||
current: pageConf.page,
|
current: pageConf.page,
|
||||||
onChange: onPageChange,
|
|
||||||
pageSize: pageConf.size,
|
pageSize: pageConf.size,
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
simple: isPhone,
|
simple: isPhone,
|
||||||
|
@ -915,6 +929,7 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
loading={loading}
|
loading={loading}
|
||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
rowClassName={getRowClassName}
|
rowClassName={getRowClassName}
|
||||||
|
onChange={onPageChange}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -940,11 +955,11 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
viewAction(key);
|
viewAction(key);
|
||||||
}}
|
}}
|
||||||
items={[
|
items={[
|
||||||
{
|
...[...cronViews].slice(5).map((x) => ({
|
||||||
label: 'Clicking me will not close the menu.',
|
label: x.name,
|
||||||
key: '1',
|
key: x.id,
|
||||||
icon: <UnorderedListOutlined />,
|
icon: <UnorderedListOutlined />,
|
||||||
},
|
})),
|
||||||
{
|
{
|
||||||
type: 'divider',
|
type: 'divider',
|
||||||
},
|
},
|
||||||
|
@ -962,6 +977,18 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getCronViews = () => {
|
||||||
|
setLoading(true);
|
||||||
|
request
|
||||||
|
.get(`${config.apiPrefix}crons/views`)
|
||||||
|
.then((data: any) => {
|
||||||
|
setCronViews(data.data);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainer
|
||||||
className="ql-container-wrapper crontab-wrapper ql-container-wrapper-has-tab"
|
className="ql-container-wrapper crontab-wrapper ql-container-wrapper-has-tab"
|
||||||
|
@ -1005,6 +1032,11 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
<Tabs.TabPane tab="全部任务" key="all">
|
<Tabs.TabPane tab="全部任务" key="all">
|
||||||
{panelContent}
|
{panelContent}
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
|
{[...cronViews].slice(0, 5).map((x) => (
|
||||||
|
<Tabs.TabPane tab={x.name} key={x.id}>
|
||||||
|
{panelContent}
|
||||||
|
</Tabs.TabPane>
|
||||||
|
))}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<CronLogModal
|
<CronLogModal
|
||||||
visible={isLogModalVisible}
|
visible={isLogModalVisible}
|
||||||
|
|
|
@ -1,7 +1,30 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Modal, message, Input, Form, Statistic, Button } from 'antd';
|
import {
|
||||||
|
Modal,
|
||||||
|
message,
|
||||||
|
Input,
|
||||||
|
Form,
|
||||||
|
Statistic,
|
||||||
|
Button,
|
||||||
|
Space,
|
||||||
|
Select,
|
||||||
|
} from 'antd';
|
||||||
import { request } from '@/utils/http';
|
import { request } from '@/utils/http';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
|
const PROPERTIES = [
|
||||||
|
{ name: '命令', value: 'command' },
|
||||||
|
{ name: '名称', value: 'name' },
|
||||||
|
{ name: '定时规则', value: 'schedule' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const OPERATIONS = [
|
||||||
|
{ name: '包含', value: 'contains' },
|
||||||
|
{ name: '不包含', value: 'noncontains' },
|
||||||
|
// { name: '属于', value: 'belong' },
|
||||||
|
// { name: '不属于', value: 'nonbelong' },
|
||||||
|
];
|
||||||
|
|
||||||
const ViewCreateModal = ({
|
const ViewCreateModal = ({
|
||||||
view,
|
view,
|
||||||
|
@ -17,19 +40,12 @@ const ViewCreateModal = ({
|
||||||
|
|
||||||
const handleOk = async (values: any) => {
|
const handleOk = async (values: any) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const { value, name } = values;
|
|
||||||
const method = view ? 'put' : 'post';
|
const method = view ? 'put' : 'post';
|
||||||
let payload;
|
|
||||||
if (!view) {
|
|
||||||
payload = [{ value, name }];
|
|
||||||
} else {
|
|
||||||
payload = { ...values, id: view.id };
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const { code, data } = await request[method](
|
const { code, data } = await request[method](
|
||||||
`${config.apiPrefix}crons/views`,
|
`${config.apiPrefix}crons/views`,
|
||||||
{
|
{
|
||||||
data: payload,
|
data: values,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (code !== 200) {
|
if (code !== 200) {
|
||||||
|
@ -44,13 +60,37 @@ const ViewCreateModal = ({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
|
form.setFieldsValue({
|
||||||
|
filters: [{ property: 'command', operation: 'contains' }],
|
||||||
|
});
|
||||||
}, [view, visible]);
|
}, [view, visible]);
|
||||||
|
|
||||||
|
const operationElement = (
|
||||||
|
<Select style={{ width: 80 }}>
|
||||||
|
{OPERATIONS.map((x) => (
|
||||||
|
<Select.Option key={x.name} value={x.value}>
|
||||||
|
{x.name}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
|
||||||
|
const propertyElement = (
|
||||||
|
<Select style={{ width: 100 }}>
|
||||||
|
{PROPERTIES.map((x) => (
|
||||||
|
<Select.Option key={x.name} value={x.value}>
|
||||||
|
{x.name}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={view ? '编辑视图' : '新建视图'}
|
title={view ? '编辑视图' : '新建视图'}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
forceRender
|
forceRender
|
||||||
|
width={580}
|
||||||
centered
|
centered
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
|
@ -74,6 +114,58 @@ const ViewCreateModal = ({
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入视图名称" />
|
<Input placeholder="请输入视图名称" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.List name="filters">
|
||||||
|
{(fields, { add, remove }) => (
|
||||||
|
<>
|
||||||
|
{fields.map(({ key, name, ...restField }, index) => (
|
||||||
|
<Form.Item
|
||||||
|
label={index === 0 ? '筛选条件' : ''}
|
||||||
|
required={true}
|
||||||
|
key={key}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
|
<Space className="view-create-modal-filters" align="baseline">
|
||||||
|
<Form.Item
|
||||||
|
{...restField}
|
||||||
|
name={[name, 'property']}
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
>
|
||||||
|
{propertyElement}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
{...restField}
|
||||||
|
name={[name, 'operation']}
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
>
|
||||||
|
{operationElement}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
{...restField}
|
||||||
|
name={[name, 'value']}
|
||||||
|
rules={[{ required: true, message: '请输入内容' }]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
{index !== 0 && (
|
||||||
|
<MinusCircleOutlined onClick={() => remove(name)} />
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
</Form.Item>
|
||||||
|
))}
|
||||||
|
<Form.Item>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
onClick={() =>
|
||||||
|
add({ property: 'command', operation: 'contains' })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<PlusOutlined />
|
||||||
|
新增筛选条件
|
||||||
|
</a>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form.List>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { Modal, message, Space, Table, Tag, Typography } from 'antd';
|
import { Modal, message, Space, Table, Tag, Typography, Button } from 'antd';
|
||||||
import { request } from '@/utils/http';
|
import { request } from '@/utils/http';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
import { DeleteOutlined, EditOutlined } from '@ant-design/icons';
|
import { DeleteOutlined, EditOutlined } from '@ant-design/icons';
|
||||||
|
@ -7,6 +7,7 @@ import { PageLoading } from '@ant-design/pro-layout';
|
||||||
import Paragraph from 'antd/lib/skeleton/Paragraph';
|
import Paragraph from 'antd/lib/skeleton/Paragraph';
|
||||||
import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
|
import ViewCreateModal from './viewCreateModal';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
@ -69,6 +70,7 @@ const ViewManageModal = ({
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
align: 'center' as const,
|
align: 'center' as const,
|
||||||
|
width: 70,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '显示',
|
title: '显示',
|
||||||
|
@ -101,6 +103,8 @@ const ViewManageModal = ({
|
||||||
];
|
];
|
||||||
const [list, setList] = useState<any[]>([]);
|
const [list, setList] = useState<any[]>([]);
|
||||||
const [loading, setLoading] = useState<any>(true);
|
const [loading, setLoading] = useState<any>(true);
|
||||||
|
const [isCreateViewModalVisible, setIsCreateViewModalVisible] =
|
||||||
|
useState<boolean>(false);
|
||||||
|
|
||||||
const editView = (record: any, index: number) => {
|
const editView = (record: any, index: number) => {
|
||||||
// setEditedEnv(record);
|
// setEditedEnv(record);
|
||||||
|
@ -190,11 +194,22 @@ const ViewManageModal = ({
|
||||||
title="视图管理"
|
title="视图管理"
|
||||||
visible={visible}
|
visible={visible}
|
||||||
centered
|
centered
|
||||||
|
width={620}
|
||||||
onCancel={() => handleCancel()}
|
onCancel={() => handleCancel()}
|
||||||
className="view-manage-modal"
|
className="view-manage-modal"
|
||||||
forceRender
|
forceRender
|
||||||
footer={false}
|
footer={false}
|
||||||
|
maskClosable={false}
|
||||||
>
|
>
|
||||||
|
<Space style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||||
|
<Button
|
||||||
|
key="2"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setIsCreateViewModalVisible(true)}
|
||||||
|
>
|
||||||
|
新建视图
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<PageLoading />
|
<PageLoading />
|
||||||
) : (
|
) : (
|
||||||
|
@ -216,6 +231,12 @@ const ViewManageModal = ({
|
||||||
/>
|
/>
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
)}
|
)}
|
||||||
|
<ViewCreateModal
|
||||||
|
visible={isCreateViewModalVisible}
|
||||||
|
handleCancel={() => {
|
||||||
|
setIsCreateViewModalVisible(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user