Compare commits

...

4 Commits

Author SHA1 Message Date
whyour
1c18668bad 修复文件下载参数 2025-05-22 00:09:19 +08:00
whyour
f94582b68d 修复查询 python 依赖存在逻辑 2025-05-21 01:25:24 +08:00
whyour
eb1c00984c 修复任务视图状态包含筛选 2025-05-20 23:40:18 +08:00
whyour
1a185f5682 修复创建脚本可能失败 2025-05-20 01:00:08 +08:00
32 changed files with 252 additions and 303 deletions

View File

@ -232,7 +232,7 @@ export default (app: Router) => {
celebrate({ celebrate({
body: Joi.object({ body: Joi.object({
filename: Joi.string().required(), filename: Joi.string().required(),
path: Joi.string().allow(''), path: Joi.string().optional().allow(''),
}), }),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
@ -241,6 +241,9 @@ export default (app: Router) => {
filename: string; filename: string;
path: string; path: string;
}; };
if (!path) {
path = '';
}
const scriptService = Container.get(ScriptService); const scriptService = Container.get(ScriptService);
const filePath = scriptService.checkFilePath(path, filename); const filePath = scriptService.checkFilePath(path, filename);
if (!filePath) { if (!filePath) {

View File

@ -514,6 +514,20 @@ export async function setSystemTimezone(timezone: string): Promise<boolean> {
} }
} }
export function getGetCommand(type: DependenceTypes, name: string): string {
const baseCommands = {
[DependenceTypes.nodejs]: `pnpm ls -g | grep "${name}" | head -1`,
[DependenceTypes.python3]: `python3 -c "import importlib;pkg=importlib.import_module('${name}');print(getattr(pkg, '__version__', 'inner package'))"`,
[DependenceTypes.linux]: `apk info -es ${name}`,
};
let command = baseCommands[type];
return type === DependenceTypes.python3
? command
: `${command} ${name.trim()}`;
}
export function getInstallCommand(type: DependenceTypes, name: string): string { export function getInstallCommand(type: DependenceTypes, name: string): string {
const baseCommands = { const baseCommands = {
[DependenceTypes.nodejs]: 'pnpm add -g', [DependenceTypes.nodejs]: 'pnpm add -g',

View File

@ -41,12 +41,6 @@ export enum DependenceTypes {
'linux', 'linux',
} }
export enum GetDependenceCommandTypes {
'pnpm ls -g ',
'pip3 show --disable-pip-version-check',
'apk info -es',
}
export enum versionDependenceCommandTypes { export enum versionDependenceCommandTypes {
'@', '@',
'==', '==',

View File

@ -116,7 +116,9 @@ export default async () => {
`Neither content nor source specified for ${item.target}`, `Neither content nor source specified for ${item.target}`,
); );
} }
const content = item.content || (await fs.readFile(item.source!)); const content =
item.content ||
(await fs.readFile(item.source!, { encoding: 'utf-8' }));
await writeFileWithLock(item.target, content); await writeFileWithLock(item.target, content);
} }
} }

View File

@ -215,14 +215,24 @@ export default class CronService {
operate2 = Op.and; operate2 = Op.and;
break; break;
case 'In': case 'In':
q[Op.or] = [ if (
{ property === 'status' &&
[property]: Array.isArray(value) ? value : [value], !value.includes(CrontabStatus.disabled)
}, ) {
property === 'status' && value.includes(2) q[Op.and] = [
? { isDisabled: 1 } { [property]: Array.isArray(value) ? value : [value] },
: {}, { isDisabled: 0 },
]; ];
} else {
q[Op.or] = [
{
[property]: Array.isArray(value) ? value : [value],
},
property === 'status' && value.includes(CrontabStatus.disabled)
? { isDisabled: 1 }
: {},
];
}
break; break;
case 'Nin': case 'Nin':
q[Op.and] = [ q[Op.and] = [
@ -560,7 +570,10 @@ export default class CronService {
if (logFileExist) { if (logFileExist) {
return await getFileContentByName(`${absolutePath}`); return await getFileContentByName(`${absolutePath}`);
} else { } else {
return '任务未运行'; return typeof doc.status === 'number' &&
[CrontabStatus.queued, CrontabStatus.running].includes(doc.status)
? '运行中...'
: '任务空闲中';
} }
} }

View File

@ -6,7 +6,6 @@ import {
DependenceStatus, DependenceStatus,
DependenceTypes, DependenceTypes,
DependenceModel, DependenceModel,
GetDependenceCommandTypes,
versionDependenceCommandTypes, versionDependenceCommandTypes,
} from '../data/dependence'; } from '../data/dependence';
import { spawn } from 'cross-spawn'; import { spawn } from 'cross-spawn';
@ -19,6 +18,7 @@ import {
promiseExecSuccess, promiseExecSuccess,
getInstallCommand, getInstallCommand,
getUninstallCommand, getUninstallCommand,
getGetCommand,
} from '../config/util'; } from '../config/util';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import taskLimit from '../shared/pLimit'; import taskLimit from '../shared/pLimit';
@ -252,7 +252,7 @@ export default class DependenceService {
// 判断是否已经安装过依赖 // 判断是否已经安装过依赖
if (isInstall && !force) { if (isInstall && !force) {
const getCommandPrefix = GetDependenceCommandTypes[dependency.type]; const getCommand = getGetCommand(dependency.type, depName);
const depVersionStr = versionDependenceCommandTypes[dependency.type]; const depVersionStr = versionDependenceCommandTypes[dependency.type];
let depVersion = ''; let depVersion = '';
if (depName.includes(depVersionStr)) { if (depName.includes(depVersionStr)) {
@ -269,13 +269,7 @@ export default class DependenceService {
const isLinuxDependence = dependency.type === DependenceTypes.linux; const isLinuxDependence = dependency.type === DependenceTypes.linux;
const isPythonDependence = const isPythonDependence =
dependency.type === DependenceTypes.python3; dependency.type === DependenceTypes.python3;
const depInfo = ( const depInfo = (await promiseExecSuccess(getCommand))
await promiseExecSuccess(
isNodeDependence
? `${getCommandPrefix} | grep "${depName}" | head -1`
: `${getCommandPrefix} ${depName}`,
)
)
.replace(/\s{2,}/, ' ') .replace(/\s{2,}/, ' ')
.replace(/\s+$/, ''); .replace(/\s+$/, '');

View File

@ -13,7 +13,7 @@ function getUniqueLockPath(filePath: string) {
export async function writeFileWithLock( export async function writeFileWithLock(
filePath: string, filePath: string,
content: string | Buffer, content: string,
options: Parameters<typeof writeFile>[2] = {}, options: Parameters<typeof writeFile>[2] = {},
) { ) {
if (typeof options === 'string') { if (typeof options === 'string') {

View File

@ -56,12 +56,10 @@ interface LogItem {
const CronDetailModal = ({ const CronDetailModal = ({
cron = {}, cron = {},
handleCancel, handleCancel,
visible,
theme, theme,
isPhone, isPhone,
}: { }: {
cron?: any; cron?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void; handleCancel: (needUpdate?: boolean) => void;
theme: string; theme: string;
isPhone: boolean; isPhone: boolean;
@ -440,7 +438,7 @@ const CronDetailModal = ({
</div> </div>
} }
centered centered
open={visible} open={true}
forceRender forceRender
footer={false} footer={false}
onCancel={() => handleCancel()} onCancel={() => handleCancel()}
@ -559,15 +557,16 @@ const CronDetailModal = ({
{contentList[activeTabKey]} {contentList[activeTabKey]}
</Card> </Card>
</div> </div>
<CronLogModal {isLogModalVisible && (
visible={isLogModalVisible} <CronLogModal
handleCancel={() => { handleCancel={() => {
setIsLogModalVisible(false); setIsLogModalVisible(false);
}} }}
cron={cron} cron={cron}
data={log} data={log}
logUrl={logUrl} logUrl={logUrl}
/> />
)}
</Modal> </Modal>
); );
}; };

View File

@ -1037,55 +1037,58 @@ const Crontab = () => {
components={isPhone || pageConf.size < 50 ? undefined : vt} components={isPhone || pageConf.size < 50 ? undefined : vt}
/> />
</div> </div>
<CronLogModal {isLogModalVisible && (
visible={isLogModalVisible} <CronLogModal
handleCancel={() => { handleCancel={() => {
getCronDetail(logCron); getCronDetail(logCron);
setIsLogModalVisible(false); setIsLogModalVisible(false);
}} }}
cron={logCron} cron={logCron}
/> />
<CronModal )}
visible={isModalVisible} {isModalVisible && (
handleCancel={handleCancel} <CronModal handleCancel={handleCancel} cron={editedCron} />
cron={editedCron} )}
/> {isLabelModalVisible && (
<CronLabelModal <CronLabelModal
visible={isLabelModalVisible} handleCancel={(needUpdate?: boolean) => {
handleCancel={(needUpdate?: boolean) => { setIsLabelModalVisible(false);
setIsLabelModalVisible(false); if (needUpdate) {
if (needUpdate) { getCrons();
getCrons(); }
} }}
}} ids={selectedRowIds}
ids={selectedRowIds} />
/> )}
<CronDetailModal {isDetailModalVisible && (
visible={isDetailModalVisible} <CronDetailModal
handleCancel={() => { handleCancel={() => {
setIsDetailModalVisible(false); setIsDetailModalVisible(false);
}} }}
cron={detailCron} cron={detailCron}
theme={theme} theme={theme}
isPhone={isPhone} isPhone={isPhone}
/> />
<ViewCreateModal )}
visible={isCreateViewModalVisible} {isCreateViewModalVisible && (
handleCancel={(data) => { <ViewCreateModal
setIsCreateViewModalVisible(false); handleCancel={(data) => {
getCronViews(); setIsCreateViewModalVisible(false);
}} getCronViews();
/> }}
<ViewManageModal />
cronViews={cronViews} )}
visible={isViewManageModalVisible} {isViewManageModalVisible && (
handleCancel={() => { <ViewManageModal
setIsViewManageModalVisible(false); cronViews={cronViews}
}} handleCancel={() => {
cronViewChange={(data) => { setIsViewManageModalVisible(false);
getCronViews(); }}
}} cronViewChange={(data) => {
/> getCronViews();
}}
/>
)}
</PageContainer> </PageContainer>
); );
}; };

View File

@ -25,12 +25,10 @@ const { Countdown } = Statistic;
const CronLogModal = ({ const CronLogModal = ({
cron, cron,
handleCancel, handleCancel,
visible,
data, data,
logUrl, logUrl,
}: { }: {
cron?: any; cron?: any;
visible: boolean;
handleCancel: () => void; handleCancel: () => void;
data?: string; data?: string;
logUrl?: string; logUrl?: string;
@ -120,11 +118,10 @@ const CronLogModal = ({
}; };
useEffect(() => { useEffect(() => {
if (cron && cron.id && visible) { if (cron && cron.id) {
getCronLog(true); getCronLog(true);
scrollInfoRef.current.down = true;
} }
}, [cron, visible]); }, [cron]);
useEffect(() => { useEffect(() => {
if (data) { if (data) {
@ -139,7 +136,7 @@ const CronLogModal = ({
return ( return (
<Modal <Modal
title={titleElement()} title={titleElement()}
open={visible} open={true}
centered centered
className="log-modal" className="log-modal"
forceRender forceRender

View File

@ -12,10 +12,8 @@ import { ScheduleType } from './type';
const CronModal = ({ const CronModal = ({
cron, cron,
handleCancel, handleCancel,
visible,
}: { }: {
cron?: any; cron?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void; handleCancel: (needUpdate?: boolean) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -58,11 +56,6 @@ const CronModal = ({
} }
}; };
useEffect(() => {
form.resetFields();
setScheduleType(getScheduleType(cron?.schedule));
}, [cron, visible]);
const handleScheduleTypeChange = (type: ScheduleType) => { const handleScheduleTypeChange = (type: ScheduleType) => {
setScheduleType(type); setScheduleType(type);
form.setFieldValue('schedule', ''); form.setFieldValue('schedule', '');
@ -146,7 +139,7 @@ const CronModal = ({
return ( return (
<Modal <Modal
title={cron?.id ? intl.get('编辑任务') : intl.get('创建任务')} title={cron?.id ? intl.get('编辑任务') : intl.get('创建任务')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}
@ -251,10 +244,8 @@ const CronModal = ({
const CronLabelModal = ({ const CronLabelModal = ({
ids, ids,
handleCancel, handleCancel,
visible,
}: { }: {
ids: Array<string>; ids: Array<string>;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void; handleCancel: (needUpdate?: boolean) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -290,10 +281,6 @@ const CronLabelModal = ({
}); });
}; };
useEffect(() => {
form.resetFields();
}, [ids, visible]);
const buttons = [ const buttons = [
<Button onClick={() => handleCancel(false)}>{intl.get('取消')}</Button>, <Button onClick={() => handleCancel(false)}>{intl.get('取消')}</Button>,
<Button type="primary" danger onClick={() => update('delete')}> <Button type="primary" danger onClick={() => update('delete')}>
@ -307,7 +294,7 @@ const CronLabelModal = ({
return ( return (
<Modal <Modal
title={intl.get('批量修改标签')} title={intl.get('批量修改标签')}
open={visible} open={true}
footer={buttons} footer={buttons}
centered centered
maskClosable={false} maskClosable={false}

View File

@ -56,10 +56,8 @@ enum ViewFilterRelation {
const ViewCreateModal = ({ const ViewCreateModal = ({
view, view,
handleCancel, handleCancel,
visible,
}: { }: {
view?: any; view?: any;
visible: boolean;
handleCancel: (param?: any) => void; handleCancel: (param?: any) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -101,17 +99,6 @@ const ViewCreateModal = ({
} }
}; };
useEffect(() => {
if (!view) {
form.resetFields();
}
form.setFieldsValue(
view || {
filters: [{ property: 'command' }],
},
);
}, [view, visible]);
const OperationElement = ({ name, ...others }: { name: number }) => { const OperationElement = ({ name, ...others }: { name: number }) => {
const property = form.getFieldValue(['filters', name, 'property']); const property = form.getFieldValue(['filters', name, 'property']);
return ( return (
@ -172,7 +159,7 @@ const ViewCreateModal = ({
return ( return (
<Modal <Modal
title={view ? intl.get('编辑视图') : intl.get('创建视图')} title={view ? intl.get('编辑视图') : intl.get('创建视图')}
open={visible} open={true}
forceRender forceRender
width={580} width={580}
centered centered
@ -190,7 +177,16 @@ const ViewCreateModal = ({
onCancel={() => handleCancel()} onCancel={() => handleCancel()}
confirmLoading={loading} confirmLoading={loading}
> >
<Form form={form} layout="vertical" name="env_modal"> <Form
form={form}
layout="vertical"
initialValues={
view || {
filters: [{ property: 'command' }],
}
}
name="env_modal"
>
<Form.Item <Form.Item
name="name" name="name"
label={intl.get('视图名称')} label={intl.get('视图名称')}

View File

@ -68,11 +68,9 @@ const DragableBodyRow = ({
const ViewManageModal = ({ const ViewManageModal = ({
cronViews, cronViews,
handleCancel, handleCancel,
visible,
cronViewChange, cronViewChange,
}: { }: {
cronViews: any[]; cronViews: any[];
visible: boolean;
handleCancel: () => void; handleCancel: () => void;
cronViewChange: (data?: any) => void; cronViewChange: (data?: any) => void;
}) => { }) => {
@ -218,7 +216,7 @@ const ViewManageModal = ({
return ( return (
<Modal <Modal
title={intl.get('视图管理')} title={intl.get('视图管理')}
open={visible} open={true}
centered centered
width={620} width={620}
onCancel={() => handleCancel()} onCancel={() => handleCancel()}
@ -263,14 +261,15 @@ const ViewManageModal = ({
}} }}
/> />
</DndProvider> </DndProvider>
<ViewCreateModal {isCreateViewModalVisible && (
view={editedView} <ViewCreateModal
visible={isCreateViewModalVisible} view={editedView}
handleCancel={(data) => { handleCancel={(data) => {
setIsCreateViewModalVisible(false); setIsCreateViewModalVisible(false);
cronViewChange(data); cronViewChange(data);
}} }}
/> />
)}
</Modal> </Modal>
); );
}; };

View File

@ -618,15 +618,15 @@ const Dependence = () => {
]} ]}
/> />
{children} {children}
<DependenceModal {isModalVisible && (
visible={isModalVisible} <DependenceModal
handleCancel={handleCancel} handleCancel={handleCancel}
dependence={editedDependence} dependence={editedDependence}
defaultType={type} defaultType={type}
/> />
{logDependence && ( )}
{logDependence && isLogModalVisible && (
<DependenceLogModal <DependenceLogModal
visible={isLogModalVisible}
handleCancel={(needRemove?: boolean) => { handleCancel={(needRemove?: boolean) => {
setIsLogModalVisible(false); setIsLogModalVisible(false);
if (needRemove) { if (needRemove) {

View File

@ -15,10 +15,8 @@ import { Status } from './type';
const DependenceLogModal = ({ const DependenceLogModal = ({
dependence, dependence,
handleCancel, handleCancel,
visible,
}: { }: {
dependence?: any; dependence?: any;
visible: boolean;
handleCancel: (needRemove?: boolean) => void; handleCancel: (needRemove?: boolean) => void;
}) => { }) => {
const [value, setValue] = useState<string>(''); const [value, setValue] = useState<string>('');
@ -128,7 +126,7 @@ const DependenceLogModal = ({
return ( return (
<Modal <Modal
title={titleElement()} title={titleElement()}
open={visible} open={true}
centered centered
className="log-modal" className="log-modal"
forceRender forceRender

View File

@ -14,11 +14,9 @@ enum DependenceTypes {
const DependenceModal = ({ const DependenceModal = ({
dependence, dependence,
handleCancel, handleCancel,
visible,
defaultType, defaultType,
}: { }: {
dependence?: any; dependence?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void; handleCancel: (cks?: any[]) => void;
defaultType: string; defaultType: string;
}) => { }) => {
@ -61,14 +59,10 @@ const DependenceModal = ({
} }
}; };
useEffect(() => {
form.resetFields();
}, [dependence, visible]);
return ( return (
<Modal <Modal
title={dependence ? intl.get('编辑依赖') : intl.get('创建依赖')} title={dependence ? intl.get('编辑依赖') : intl.get('创建依赖')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const EditNameModal = ({ const EditNameModal = ({
ids, ids,
handleCancel, handleCancel,
visible,
}: { }: {
ids?: string[]; ids?: string[];
visible: boolean;
handleCancel: () => void; handleCancel: () => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -34,14 +32,10 @@ const EditNameModal = ({
} }
}; };
useEffect(() => {
form.resetFields();
}, [ids, visible]);
return ( return (
<Modal <Modal
title={intl.get('修改环境变量名称')} title={intl.get('修改环境变量名称')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}

View File

@ -616,16 +616,15 @@ const Env = () => {
/> />
</DndProvider> </DndProvider>
</div> </div>
<EnvModal {isModalVisible && (
visible={isModalVisible} <EnvModal handleCancel={handleCancel} env={editedEnv} />
handleCancel={handleCancel} )}
env={editedEnv} {isEditNameModalVisible && (
/> <EditNameModal
<EditNameModal handleCancel={handleEditNameCancel}
visible={isEditNameModalVisible} ids={selectedRowIds}
handleCancel={handleEditNameCancel} />
ids={selectedRowIds} )}
/>
</PageContainer> </PageContainer>
); );
}; };

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const EnvModal = ({ const EnvModal = ({
env, env,
handleCancel, handleCancel,
visible,
}: { }: {
env?: any; env?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void; handleCancel: (cks?: any[]) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -55,14 +53,10 @@ const EnvModal = ({
} }
}; };
useEffect(() => {
form.resetFields();
}, [env, visible]);
return ( return (
<Modal <Modal
title={env ? intl.get('编辑变量') : intl.get('创建变量')} title={env ? intl.get('编辑变量') : intl.get('创建变量')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}

View File

@ -14,6 +14,17 @@ const Error = () => {
const [data, setData] = useState(intl.get('暂无日志')); const [data, setData] = useState(intl.get('暂无日志'));
const retryTimes = useRef(1); const retryTimes = useRef(1);
const loopStatus = (message: string) => {
if (retryTimes.current > 3) {
setData(message);
return;
}
retryTimes.current += 1;
setTimeout(() => {
getHealthStatus(false);
}, 3000);
};
const getHealthStatus = (needLoading: boolean = true) => { const getHealthStatus = (needLoading: boolean = true) => {
needLoading && setLoading(true); needLoading && setLoading(true);
request request
@ -27,19 +38,15 @@ const Error = () => {
} }
return; return;
} }
if (retryTimes.current > 3) {
setData(error?.details); loopStatus(error?.details);
return;
}
retryTimes.current += 1;
setTimeout(() => {
getHealthStatus(false);
}, 3000);
}) })
.catch((error) => { .catch((error) => {
const responseStatus = error.response.status; const responseStatus = error.response.status;
if (responseStatus === 401) { if (responseStatus === 401) {
history.push('/login'); history.push('/login');
} else {
loopStatus(error.response?.message || error?.message);
} }
}) })
.finally(() => needLoading && setLoading(false)); .finally(() => needLoading && setLoading(false));

View File

@ -25,11 +25,9 @@ const EditModal = ({
currentNode, currentNode,
content, content,
handleCancel, handleCancel,
visible,
}: { }: {
treeData?: any; treeData?: any;
content?: string; content?: string;
visible: boolean;
currentNode: any; currentNode: any;
handleCancel: () => void; handleCancel: () => void;
}) => { }) => {
@ -223,7 +221,7 @@ const EditModal = ({
width={'100%'} width={'100%'}
headerStyle={{ padding: '11px 24px' }} headerStyle={{ padding: '11px 24px' }}
onClose={cancel} onClose={cancel}
open={visible} open={true}
> >
{/* @ts-ignore */} {/* @ts-ignore */}
<SplitPane <SplitPane
@ -256,24 +254,26 @@ const EditModal = ({
<Ansi>{log}</Ansi> <Ansi>{log}</Ansi>
</pre> </pre>
</SplitPane> </SplitPane>
<SaveModal {saveModalVisible && (
visible={saveModalVisible} <SaveModal
handleCancel={() => { handleCancel={() => {
setSaveModalVisible(false); setSaveModalVisible(false);
}} }}
file={{ file={{
content: content:
editorRef.current && editorRef.current &&
editorRef.current.getValue().replace(/\r\n/g, '\n'), editorRef.current.getValue().replace(/\r\n/g, '\n'),
...cNode, ...cNode,
}} }}
/> />
<SettingModal )}
visible={settingModalVisible} {settingModalVisible && (
handleCancel={() => { <SettingModal
setSettingModalVisible(false); handleCancel={() => {
}} setSettingModalVisible(false);
/> }}
/>
)}
</Drawer> </Drawer>
); );
}; };

View File

@ -19,9 +19,7 @@ const { Option } = Select;
const EditScriptNameModal = ({ const EditScriptNameModal = ({
handleCancel, handleCancel,
treeData, treeData,
visible,
}: { }: {
visible: boolean;
treeData: any[]; treeData: any[];
handleCancel: (file?: { handleCancel: (file?: {
filename: string; filename: string;
@ -53,7 +51,7 @@ const EditScriptNameModal = ({
directory ? intl.get('创建文件夹成功') : intl.get('创建文件成功'), directory ? intl.get('创建文件夹成功') : intl.get('创建文件成功'),
); );
const key = path ? `${path}/` : ''; const key = path ? `${path}/` : '';
const filename = file ? file.name : (directory || inputFilename); const filename = file ? file.name : directory || inputFilename;
handleCancel({ handleCancel({
filename, filename,
path, path,
@ -95,14 +93,10 @@ const EditScriptNameModal = ({
setDirs(dirs); setDirs(dirs);
}, [treeData]); }, [treeData]);
useEffect(() => {
form.resetFields();
}, [visible]);
return ( return (
<Modal <Modal
title={intl.get('创建')} title={intl.get('创建')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}

View File

@ -710,9 +710,8 @@ const Script = () => {
}} }}
/> />
)} )}
{isLogModalVisible && ( {isLogModalVisible && isLogModalVisible && (
<EditModal <EditModal
visible={isLogModalVisible}
treeData={data} treeData={data}
currentNode={currentNode} currentNode={currentNode}
content={value} content={value}
@ -721,16 +720,18 @@ const Script = () => {
}} }}
/> />
)} )}
<EditScriptNameModal {isAddFileModalVisible && (
visible={isAddFileModalVisible} <EditScriptNameModal
treeData={data} treeData={data}
handleCancel={addFileModalClose} handleCancel={addFileModalClose}
/> />
<RenameModal )}
visible={isRenameFileModalVisible} {isRenameFileModalVisible && (
handleCancel={handleRenameFileCancel} <RenameModal
currentNode={currentNode} handleCancel={handleRenameFileCancel}
/> currentNode={currentNode}
/>
)}
</div> </div>
</PageContainer> </PageContainer>
); );

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const RenameModal = ({ const RenameModal = ({
currentNode, currentNode,
handleCancel, handleCancel,
visible,
}: { }: {
currentNode?: any; currentNode?: any;
visible: boolean;
handleCancel: () => void; handleCancel: () => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -38,14 +36,10 @@ const RenameModal = ({
} }
}; };
useEffect(() => {
form.resetFields();
}, [currentNode, visible]);
return ( return (
<Modal <Modal
title={intl.get('重命名')} title={intl.get('重命名')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const SaveModal = ({ const SaveModal = ({
file, file,
handleCancel, handleCancel,
visible,
}: { }: {
file?: any; file?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void; handleCancel: (cks?: any[]) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -32,15 +30,10 @@ const SaveModal = ({
}); });
}; };
useEffect(() => {
form.resetFields();
setLoading(false);
}, [file, visible]);
return ( return (
<Modal <Modal
title={intl.get('保存文件')} title={intl.get('保存文件')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const SettingModal = ({ const SettingModal = ({
file, file,
handleCancel, handleCancel,
visible,
}: { }: {
file?: any; file?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void; handleCancel: (cks?: any[]) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -30,15 +28,10 @@ const SettingModal = ({
}); });
}; };
useEffect(() => {
form.resetFields();
setLoading(false);
}, [file, visible]);
return ( return (
<Modal <Modal
title={intl.get('运行设置')} title={intl.get('运行设置')}
open={visible} open={true}
forceRender forceRender
centered centered
onCancel={() => handleCancel()} onCancel={() => handleCancel()}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const AppModal = ({ const AppModal = ({
app, app,
handleCancel, handleCancel,
visible,
}: { }: {
app?: any; app?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void; handleCancel: (needUpdate?: boolean) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -41,14 +39,10 @@ const AppModal = ({
} }
}; };
useEffect(() => {
form.resetFields();
}, [app, visible]);
return ( return (
<Modal <Modal
title={app ? intl.get('编辑应用') : intl.get('创建应用')} title={app ? intl.get('编辑应用') : intl.get('创建应用')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}

View File

@ -363,11 +363,9 @@ const Setting = () => {
]} ]}
/> />
</div> </div>
<AppModal {isModalVisible && (
visible={isModalVisible} <AppModal handleCancel={handleCancel} app={editedApp} />
handleCancel={handleCancel} )}
app={editedApp}
/>
</PageContainer> </PageContainer>
); );
}; };

View File

@ -579,18 +579,20 @@ const Subscription = () => {
loading={loading} loading={loading}
rowClassName={getRowClassName} rowClassName={getRowClassName}
/> />
<SubscriptionModal {isModalVisible && (
visible={isModalVisible} <SubscriptionModal
handleCancel={handleCancel} handleCancel={handleCancel}
subscription={editedSubscription} subscription={editedSubscription}
/> />
<SubscriptionLogModal )}
visible={isLogModalVisible} {isLogModalVisible && (
handleCancel={() => { <SubscriptionLogModal
setIsLogModalVisible(false); handleCancel={() => {
}} setIsLogModalVisible(false);
subscription={logSubscription} }}
/> subscription={logSubscription}
/>
)}
</PageContainer> </PageContainer>
); );
}; };

View File

@ -14,12 +14,10 @@ import Ansi from 'ansi-to-react';
const SubscriptionLogModal = ({ const SubscriptionLogModal = ({
subscription, subscription,
handleCancel, handleCancel,
visible,
data, data,
logUrl, logUrl,
}: { }: {
subscription?: any; subscription?: any;
visible: boolean;
handleCancel: () => void; handleCancel: () => void;
data?: string; data?: string;
logUrl?: string; logUrl?: string;
@ -79,10 +77,10 @@ const SubscriptionLogModal = ({
}; };
useEffect(() => { useEffect(() => {
if (subscription && subscription.id && visible) { if (subscription && subscription.id) {
getCronLog(true); getCronLog(true);
} }
}, [subscription, visible]); }, [subscription]);
useEffect(() => { useEffect(() => {
if (data) { if (data) {
@ -97,7 +95,7 @@ const SubscriptionLogModal = ({
return ( return (
<Modal <Modal
title={titleElement()} title={titleElement()}
open={visible} open={true}
centered centered
className="log-modal" className="log-modal"
forceRender forceRender

View File

@ -22,17 +22,19 @@ const fileUrlRegx = /([^\/\:]+\/[^\/\.]+)\.[a-z]+$/;
const SubscriptionModal = ({ const SubscriptionModal = ({
subscription, subscription,
handleCancel, handleCancel,
visible,
}: { }: {
subscription?: any; subscription?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void; handleCancel: (needUpdate?: boolean) => void;
}) => { }) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [type, setType] = useState('public-repo'); const [type, setType] = useState(subscription?.type || 'public-repo');
const [scheduleType, setScheduleType] = useState('crontab'); const [scheduleType, setScheduleType] = useState(
const [pullType, setPullType] = useState<'ssh-key' | 'user-pwd'>('ssh-key'); subscription?.schedule_type || 'crontab',
);
const [pullType, setPullType] = useState<'ssh-key' | 'user-pwd'>(
subscription?.pull_type || 'ssh-key',
);
const handleOk = async (values: any) => { const handleOk = async (values: any) => {
setLoading(true); setLoading(true);
@ -255,29 +257,17 @@ const SubscriptionModal = ({
}; };
useEffect(() => { useEffect(() => {
if (visible) { window.addEventListener('paste', onPaste);
window.addEventListener('paste', onPaste);
} else {
window.removeEventListener('paste', onPaste);
}
}, [visible]);
useEffect(() => { return () => {
form.setFieldsValue( window.removeEventListener('paste', onPaste);
{ ...subscription, ...formatParams(subscription) } || {}, };
); }, []);
setType((subscription && subscription.type) || 'public-repo');
setScheduleType((subscription && subscription.schedule_type) || 'crontab');
setPullType((subscription && subscription.pull_type) || 'ssh-key');
if (!subscription) {
form.resetFields();
}
}, [subscription, visible]);
return ( return (
<Modal <Modal
title={subscription ? intl.get('编辑订阅') : intl.get('创建订阅')} title={subscription ? intl.get('编辑订阅') : intl.get('创建订阅')}
open={visible} open={true}
forceRender forceRender
centered centered
maskClosable={false} maskClosable={false}
@ -294,7 +284,12 @@ const SubscriptionModal = ({
onCancel={() => handleCancel()} onCancel={() => handleCancel()}
confirmLoading={loading} confirmLoading={loading}
> >
<Form form={form} name="form_in_modal" layout="vertical"> <Form
form={form}
name="form_in_modal"
layout="vertical"
initialValues={{ ...subscription, ...formatParams(subscription) }}
>
<Form.Item <Form.Item
name="name" name="name"
label={intl.get('名称')} label={intl.get('名称')}

View File

@ -14,7 +14,7 @@ export interface IResponseData {
code?: number; code?: number;
data?: any; data?: any;
message?: string; message?: string;
errors?: any[]; error?: any;
} }
export type Override< export type Override<