Skip to content

Commit

Permalink
Feat: impl cronjob envs (#4821)
Browse files Browse the repository at this point in the history
* Feat: impl cronjob envs

* Fix: i18n Environment Variables
zijiren233 authored Jul 1, 2024
1 parent 7c509b1 commit 694ddb9
Showing 6 changed files with 150 additions and 10 deletions.
9 changes: 6 additions & 3 deletions frontend/providers/cronjob/public/locales/en/common.json
Original file line number Diff line number Diff line change
@@ -176,7 +176,8 @@
"Expansion and Contraction Launchpad": "Expansion and Contraction Launchpad",
"App Name": "App Name",
"Replicas": "Replicas",
"JobNamePlaceholder": "Starts with a letter and can contain only lowercase letters, digits, and hyphens (-)"
"JobNamePlaceholder": "Starts with a letter and can contain only lowercase letters, digits, and hyphens (-)",
"Environment Variables": "Environment Variables"
},
"every five minutes": "every five minutes",
"per hour": "per hour",
@@ -194,5 +195,7 @@
"Basic": "Basic",
"Username for the image registry": "Username for the image registry'",
"The password cannot be empty": "The password cannot be empty",
"Deploy": "Deploy"
}
"Deploy": "Deploy",
"Env Placeholder": "one per line, key and value separated by colon or equals sign, e.g.:\nmongoUrl=127.0.0.1:8000\nredisUrl:127.0.0.0:8001\n-env1 =test",
"Environment Variables": "Environment Variables"
}
10 changes: 7 additions & 3 deletions frontend/providers/cronjob/public/locales/zh/common.json
Original file line number Diff line number Diff line change
@@ -223,7 +223,8 @@
"Expansion and Contraction Launchpad": "扩缩容 Launchpad",
"App Name": "App 名称",
"Replicas": "副本数",
"JobNamePlaceholder": "以字母开头,只能包含小写字母、数字和连字符 (-)"
"JobNamePlaceholder": "以字母开头,只能包含小写字母、数字和连字符 (-)",
"Environment Variables": "环境变量"
},
"every five minutes": "每五分钟",
"per hour": "每小时",
@@ -239,5 +240,8 @@
"Failures": "失败数",
"Log": "日志",
"Username for the image registry": "用户名",
"The password cannot be empty": "密码不能为空"
}
"The password cannot be empty": "密码不能为空",
"Env Placeholder": "环境变量,每行一个,可用冒号或等号分隔,例如:\nmongoUrl=127.0.0.1:8000\nredisUrl:127.0.0.0:8001\n- env1=test",
"Edit Environment Variables": "编辑环境变量",
"Environment Variables": "环境变量"
}
5 changes: 5 additions & 0 deletions frontend/providers/cronjob/src/components/Icon/icons/edit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion frontend/providers/cronjob/src/components/Icon/index.tsx
Original file line number Diff line number Diff line change
@@ -29,7 +29,8 @@ const map = {
connection: require('./icons/connection.svg').default,
info: require('./icons/info.svg').default,
restore: require('./icons/restore.svg').default,
download: require('./icons/download.svg').default
download: require('./icons/download.svg').default,
edit: require('./icons/edit.svg').default
};

const MyIcon = ({
100 changes: 100 additions & 0 deletions frontend/providers/cronjob/src/pages/job/edit/components/EditEnvs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, { useState, useCallback } from 'react';
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
Button,
Textarea,
Box
} from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import { CronJobEditType } from '@/types/job';

const EditEnvs = ({
defaultEnv = [],
successCb,
onClose
}: {
defaultEnv: CronJobEditType['envs'];
successCb: (e: { key: string; value: string }[]) => void;
onClose: () => void;
}) => {
const { t } = useTranslation();
const [inputVal, setInputVal] = useState(
defaultEnv
.filter((item) => !item.valueFrom) // Only env that is not valuefrom can be edited
.map((item) => `${item.key}=${item.value}`)
.join('\n')
);

const onSubmit = useCallback(() => {
const lines = inputVal.split('\n').filter((item) => item);
const result = lines
.map((str) => {
// replace special symbol
str = str.trim();
if (/^-\s*/.test(str)) {
str = str.replace(/^-\s*/, '');
}
if (str.includes('=')) {
const i = str.indexOf('=');
return [str.slice(0, i), str.slice(i + 1)];
} else if (str.includes(':')) {
const i = str.indexOf(':');
return [str.slice(0, i), str.slice(i + 1)];
}
return '';
})
.filter((item) => item)
.map((item) => {
// remove quotation
const key = item[0].replace(/^['"]|['"]$/g, '').trim();
const value = item[1].replace(/^['"]|['"]$/g, '').trim();

return {
key,
value
};
});

// concat valueFrom env
successCb([...defaultEnv.filter((item) => item.valueFrom), ...result]);
onClose();
}, [defaultEnv, inputVal, onClose, successCb]);

return (
<Modal isOpen onClose={onClose} lockFocusAcrossFrames={false}>
<ModalOverlay />
<ModalContent maxH={'90vh'} maxW={'90vw'} minW={'530px'} w={'auto'}>
<ModalHeader>{t('Edit Environment Variables')}</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Box fontSize={'14px'} fontWeight={500} color={'messenger.900'} mb={'8px'}>
{t('Environment Variables')}
</Box>
<Textarea
h={'350px'}
maxH={'100%'}
value={inputVal}
resize={'both'}
placeholder={t('Env Placeholder') || ''}
overflowX={'auto'}
whiteSpace={inputVal === '' ? 'pre-wrap' : 'nowrap'}
onChange={(e) => setInputVal(e.target.value)}
/>
</ModalBody>
<ModalFooter>
<Button w={'88px'} onClick={onSubmit}>
{t('Confirm')}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
};

export default EditEnvs;
33 changes: 30 additions & 3 deletions frontend/providers/cronjob/src/pages/job/edit/components/Form.tsx
Original file line number Diff line number Diff line change
@@ -19,17 +19,19 @@ import {
NumberInput,
NumberInputField,
NumberInputStepper,
Switch,
Text
Text,
Button,
useDisclosure
} from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import { throttle } from 'lodash';
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from 'react';
import { Controller, UseFormReturn } from 'react-hook-form';
import { Controller, UseFormReturn, useFieldArray } from 'react-hook-form';
import Cron from './Cron';
import Label from './Label';
import EditEnvs from './EditEnvs';

const Form = ({ formHook }: { formHook: UseFormReturn<CronJobEditType, any> }) => {
if (!formHook) return null;
@@ -38,6 +40,7 @@ const Form = ({ formHook }: { formHook: UseFormReturn<CronJobEditType, any> }) =
const { name } = router.query as QueryType;
const isEdit = useMemo(() => !!name, [name]);
const { data: launchpadApps, refetch } = useQuery(['getLaunchpadApps'], getMyApps);
const { isOpen: isEditEnvs, onOpen: onOpenEditEnvs, onClose: onCloseEditEnvs } = useDisclosure();

const {
register,
@@ -55,6 +58,11 @@ const Form = ({ formHook }: { formHook: UseFormReturn<CronJobEditType, any> }) =
}
];

const { fields: envs, replace: replaceEnvs } = useFieldArray({
control,
name: 'envs'
});

const [activeNav, setActiveNav] = useState(navList[0].id);

// listen scroll and set activeNav
@@ -349,8 +357,27 @@ const Form = ({ formHook }: { formHook: UseFormReturn<CronJobEditType, any> }) =
/>
</Box>
</FormControl>
<Box pl="80px" mb={'18px'}>
<Label w={80}>{t('Form.Environment Variables')}</Label>
<Button
w={'300px'}
variant={'outline'}
fontSize={'base'}
leftIcon={<MyIcon name="edit" width={'16px'} fill={'#485264'} />}
onClick={onOpenEditEnvs}
>
{t('Edit Environment Variables')}
</Button>
</Box>
</>
)}
{isEditEnvs && (
<EditEnvs
defaultEnv={envs}
onClose={onCloseEditEnvs}
successCb={(e) => replaceEnvs(e)}
/>
)}
{/* cronjob type Launchpad */}
{getValues('jobType') === 'launchpad' && (
<>

0 comments on commit 694ddb9

Please sign in to comment.