mirror of
https://github.com/woodchen-ink/certimate.git
synced 2025-07-18 17:31:55 +08:00
feat(ui): TextFileInput
This commit is contained in:
parent
355059df3c
commit
04abf9dd76
51
ui/src/components/TextFileInput.tsx
Normal file
51
ui/src/components/TextFileInput.tsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { type ChangeEvent, useRef } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { UploadOutlined as UploadOutlinedIcon } from "@ant-design/icons";
|
||||||
|
import { Button, type ButtonProps, Input, Space, type UploadProps } from "antd";
|
||||||
|
import { type TextAreaProps } from "antd/es/input/TextArea";
|
||||||
|
|
||||||
|
import { mergeCls } from "@/utils/css";
|
||||||
|
import { readFileContent } from "@/utils/file";
|
||||||
|
|
||||||
|
export interface TextFileInputProps extends Omit<TextAreaProps, "onChange"> {
|
||||||
|
accept?: UploadProps["accept"];
|
||||||
|
uploadButtonProps?: Omit<ButtonProps, "disabled" | "onClick">;
|
||||||
|
uploadText?: string;
|
||||||
|
onChange?: (value: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TextFileInput = ({ className, style, accept, disabled, readOnly, uploadText, uploadButtonProps, onChange, ...props }: TextFileInputProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
const handleButtonClick = () => {
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { files } = e.target as HTMLInputElement;
|
||||||
|
if (files?.length) {
|
||||||
|
const value = await readFileContent(files[0]);
|
||||||
|
onChange?.(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space className={mergeCls("w-full", className)} style={style} direction="vertical" size="small">
|
||||||
|
<Input.TextArea {...props} disabled={disabled} readOnly={readOnly} onChange={(e) => onChange?.(e.target.value)} />
|
||||||
|
{!readOnly && (
|
||||||
|
<>
|
||||||
|
<Button {...uploadButtonProps} block disabled={disabled} icon={<UploadOutlinedIcon />} onClick={handleButtonClick}>
|
||||||
|
{uploadText ?? t("common.text.import_from_file")}
|
||||||
|
</Button>
|
||||||
|
<input ref={fileInputRef} type="file" style={{ display: "none" }} accept={accept} onChange={handleFileChange} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TextFileInput;
|
@ -1,12 +1,10 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { UploadOutlined as UploadOutlinedIcon } from "@ant-design/icons";
|
import { Form, type FormInstance } from "antd";
|
||||||
import { Button, Form, type FormInstance, Input, Upload, type UploadFile, type UploadProps } from "antd";
|
|
||||||
import { createSchemaFieldRule } from "antd-zod";
|
import { createSchemaFieldRule } from "antd-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import TextFileInput from "@/components/TextFileInput";
|
||||||
import { type AccessConfigForKubernetes } from "@/domain/access";
|
import { type AccessConfigForKubernetes } from "@/domain/access";
|
||||||
import { readFileContent } from "@/utils/file";
|
|
||||||
|
|
||||||
type AccessFormKubernetesConfigFieldValues = Nullish<AccessConfigForKubernetes>;
|
type AccessFormKubernetesConfigFieldValues = Nullish<AccessConfigForKubernetes>;
|
||||||
|
|
||||||
@ -34,24 +32,6 @@ const AccessFormKubernetesConfig = ({ form: formInst, formName, disabled, initia
|
|||||||
});
|
});
|
||||||
const formRule = createSchemaFieldRule(formSchema);
|
const formRule = createSchemaFieldRule(formSchema);
|
||||||
|
|
||||||
const fieldKubeConfig = Form.useWatch("kubeConfig", formInst);
|
|
||||||
const [fieldKubeFileList, setFieldKubeFileList] = useState<UploadFile[]>([]);
|
|
||||||
useEffect(() => {
|
|
||||||
setFieldKubeFileList(initialValues?.kubeConfig?.trim() ? [{ uid: "-1", name: "kubeconfig", status: "done" }] : []);
|
|
||||||
}, [initialValues?.kubeConfig]);
|
|
||||||
|
|
||||||
const handleKubeFileChange: UploadProps["onChange"] = async ({ file }) => {
|
|
||||||
if (file && file.status !== "removed") {
|
|
||||||
formInst.setFieldValue("kubeConfig", await readFileContent(file.originFileObj ?? (file as unknown as File)));
|
|
||||||
setFieldKubeFileList([file]);
|
|
||||||
} else {
|
|
||||||
formInst.setFieldValue("kubeConfig", "");
|
|
||||||
setFieldKubeFileList([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
onValuesChange?.(formInst.getFieldsValue(true));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||||
onValuesChange?.(values);
|
onValuesChange?.(values);
|
||||||
};
|
};
|
||||||
@ -65,16 +45,13 @@ const AccessFormKubernetesConfig = ({ form: formInst, formName, disabled, initia
|
|||||||
name={formName}
|
name={formName}
|
||||||
onValuesChange={handleFormChange}
|
onValuesChange={handleFormChange}
|
||||||
>
|
>
|
||||||
<Form.Item name="kubeConfig" noStyle rules={[formRule]}>
|
|
||||||
<Input.TextArea autoComplete="new-password" hidden placeholder={t("access.form.k8s_kubeconfig.placeholder")} value={fieldKubeConfig} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
name="kubeConfig"
|
||||||
label={t("access.form.k8s_kubeconfig.label")}
|
label={t("access.form.k8s_kubeconfig.label")}
|
||||||
|
rules={[formRule]}
|
||||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.k8s_kubeconfig.tooltip") }}></span>}
|
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.k8s_kubeconfig.tooltip") }}></span>}
|
||||||
>
|
>
|
||||||
<Upload beforeUpload={() => false} fileList={fieldKubeFileList} maxCount={1} onChange={handleKubeFileChange}>
|
<TextFileInput allowClear autoSize={{ minRows: 3, maxRows: 10 }} placeholder={t("access.form.k8s_kubeconfig.placeholder")} />
|
||||||
<Button icon={<UploadOutlinedIcon />}>{t("access.form.k8s_kubeconfig.upload")}</Button>
|
|
||||||
</Upload>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { UploadOutlined as UploadOutlinedIcon } from "@ant-design/icons";
|
import { Form, type FormInstance, Input, InputNumber } from "antd";
|
||||||
import { Button, Form, type FormInstance, Input, InputNumber, Upload, type UploadFile, type UploadProps } from "antd";
|
|
||||||
import { createSchemaFieldRule } from "antd-zod";
|
import { createSchemaFieldRule } from "antd-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import TextFileInput from "@/components/TextFileInput";
|
||||||
import { type AccessConfigForSSH } from "@/domain/access";
|
import { type AccessConfigForSSH } from "@/domain/access";
|
||||||
import { readFileContent } from "@/utils/file";
|
|
||||||
import { validDomainName, validIPv4Address, validIPv6Address, validPortNumber } from "@/utils/validators";
|
import { validDomainName, validIPv4Address, validIPv6Address, validPortNumber } from "@/utils/validators";
|
||||||
|
|
||||||
type AccessFormSSHConfigFieldValues = Nullish<AccessConfigForSSH>;
|
type AccessFormSSHConfigFieldValues = Nullish<AccessConfigForSSH>;
|
||||||
@ -59,24 +57,6 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
});
|
});
|
||||||
const formRule = createSchemaFieldRule(formSchema);
|
const formRule = createSchemaFieldRule(formSchema);
|
||||||
|
|
||||||
const fieldKey = Form.useWatch("key", formInst);
|
|
||||||
const [fieldKeyFileList, setFieldKeyFileList] = useState<UploadFile[]>([]);
|
|
||||||
useEffect(() => {
|
|
||||||
setFieldKeyFileList(initialValues?.key?.trim() ? [{ uid: "-1", name: "sshkey", status: "done" }] : []);
|
|
||||||
}, [initialValues?.key]);
|
|
||||||
|
|
||||||
const handleKeyFileChange: UploadProps["onChange"] = async ({ file }) => {
|
|
||||||
if (file && file.status !== "removed") {
|
|
||||||
formInst.setFieldValue("key", await readFileContent(file.originFileObj ?? (file as unknown as File)));
|
|
||||||
setFieldKeyFileList([file]);
|
|
||||||
} else {
|
|
||||||
formInst.setFieldValue("key", "");
|
|
||||||
setFieldKeyFileList([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
onValuesChange?.(formInst.getFieldsValue(true));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||||
onValuesChange?.(values);
|
onValuesChange?.(values);
|
||||||
};
|
};
|
||||||
@ -104,48 +84,36 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex space-x-2">
|
<Form.Item name="username" label={t("access.form.ssh_username.label")} rules={[formRule]}>
|
||||||
<div className="w-1/2">
|
<Input autoComplete="new-password" placeholder={t("access.form.ssh_username.placeholder")} />
|
||||||
<Form.Item name="username" label={t("access.form.ssh_username.label")} rules={[formRule]}>
|
</Form.Item>
|
||||||
<Input autoComplete="new-password" placeholder={t("access.form.ssh_username.placeholder")} />
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="w-1/2">
|
<Form.Item
|
||||||
<Form.Item
|
name="password"
|
||||||
name="password"
|
label={t("access.form.ssh_password.label")}
|
||||||
label={t("access.form.ssh_password.label")}
|
rules={[formRule]}
|
||||||
rules={[formRule]}
|
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.ssh_password.tooltip") }}></span>}
|
||||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.ssh_password.tooltip") }}></span>}
|
>
|
||||||
>
|
<Input.Password allowClear autoComplete="new-password" placeholder={t("access.form.ssh_password.placeholder")} />
|
||||||
<Input.Password autoComplete="new-password" placeholder={t("access.form.ssh_password.placeholder")} />
|
</Form.Item>
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex space-x-2">
|
<Form.Item
|
||||||
<div className="w-1/2">
|
name="key"
|
||||||
<Form.Item name="key" noStyle rules={[formRule]}>
|
label={t("access.form.ssh_key.label")}
|
||||||
<Input.TextArea autoComplete="new-password" hidden placeholder={t("access.form.ssh_key.placeholder")} value={fieldKey} />
|
rules={[formRule]}
|
||||||
</Form.Item>
|
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.ssh_key.tooltip") }}></span>}
|
||||||
<Form.Item label={t("access.form.ssh_key.label")} tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.ssh_key.tooltip") }}></span>}>
|
>
|
||||||
<Upload beforeUpload={() => false} fileList={fieldKeyFileList} maxCount={1} onChange={handleKeyFileChange}>
|
<TextFileInput allowClear autoSize={{ minRows: 1, maxRows: 5 }} placeholder={t("access.form.ssh_key.placeholder")} />
|
||||||
<Button icon={<UploadOutlinedIcon />}>{t("access.form.ssh_key.upload")}</Button>
|
</Form.Item>
|
||||||
</Upload>
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="w-1/2">
|
<Form.Item
|
||||||
<Form.Item
|
name="keyPassphrase"
|
||||||
name="keyPassphrase"
|
label={t("access.form.ssh_key_passphrase.label")}
|
||||||
label={t("access.form.ssh_key_passphrase.label")}
|
rules={[formRule]}
|
||||||
rules={[formRule]}
|
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.ssh_key_passphrase.tooltip") }}></span>}
|
||||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.ssh_key_passphrase.tooltip") }}></span>}
|
>
|
||||||
>
|
<Input.Password allowClear autoComplete="new-password" placeholder={t("access.form.ssh_key_passphrase.placeholder")} />
|
||||||
<Input.Password autoComplete="new-password" placeholder={t("access.form.ssh_key_passphrase.placeholder")} />
|
</Form.Item>
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -177,7 +177,7 @@ const NotifyNodeConfigForm = forwardRef<NotifyNodeConfigFormInstance, NotifyNode
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item name="message" label={t("workflow_node.notify.form.message.label")} rules={[formRule]}>
|
<Form.Item name="message" label={t("workflow_node.notify.form.message.label")} rules={[formRule]}>
|
||||||
<Input.TextArea autoSize={{ minRows: 3, maxRows: 5 }} placeholder={t("workflow_node.notify.form.message.placeholder")} />
|
<Input.TextArea autoSize={{ minRows: 3, maxRows: 10 }} placeholder={t("workflow_node.notify.form.message.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item className="mb-0" htmlFor="null">
|
<Form.Item className="mb-0" htmlFor="null">
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import { forwardRef, memo, useImperativeHandle } from "react";
|
import { forwardRef, memo, useImperativeHandle } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { UploadOutlined as UploadOutlinedIcon } from "@ant-design/icons";
|
import { Form, type FormInstance, Input } from "antd";
|
||||||
import { Button, Form, type FormInstance, Input, Upload, type UploadProps } from "antd";
|
|
||||||
import { createSchemaFieldRule } from "antd-zod";
|
import { createSchemaFieldRule } from "antd-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { validateCertificate, validatePrivateKey } from "@/api/certificates";
|
import { validateCertificate, validatePrivateKey } from "@/api/certificates";
|
||||||
|
import TextFileInput from "@/components/TextFileInput";
|
||||||
import { type WorkflowNodeConfigForUpload } from "@/domain/workflow";
|
import { type WorkflowNodeConfigForUpload } from "@/domain/workflow";
|
||||||
import { useAntdForm } from "@/hooks";
|
import { useAntdForm } from "@/hooks";
|
||||||
import { getErrMsg } from "@/utils/error";
|
import { getErrMsg } from "@/utils/error";
|
||||||
import { readFileContent } from "@/utils/file";
|
|
||||||
|
|
||||||
type UploadNodeConfigFormFieldValues = Partial<WorkflowNodeConfigForUpload>;
|
type UploadNodeConfigFormFieldValues = Partial<WorkflowNodeConfigForUpload>;
|
||||||
|
|
||||||
@ -70,65 +69,53 @@ const UploadNodeConfigForm = forwardRef<UploadNodeConfigFormInstance, UploadNode
|
|||||||
} as UploadNodeConfigFormInstance;
|
} as UploadNodeConfigFormInstance;
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCertificateFileChange: UploadProps["onChange"] = async ({ file }) => {
|
const handleCertificateChange = async (value: string) => {
|
||||||
if (file && file.status !== "removed") {
|
try {
|
||||||
const certificate = await readFileContent(file.originFileObj ?? (file as unknown as File));
|
const resp = await validateCertificate(value);
|
||||||
|
formInst.setFields([
|
||||||
try {
|
{
|
||||||
const resp = await validateCertificate(certificate);
|
name: "domains",
|
||||||
formInst.setFields([
|
value: resp.data.domains,
|
||||||
{
|
},
|
||||||
name: "domains",
|
{
|
||||||
value: resp.data.domains,
|
name: "certificate",
|
||||||
},
|
value: value,
|
||||||
{
|
},
|
||||||
name: "certificate",
|
]);
|
||||||
value: certificate,
|
} catch (e) {
|
||||||
},
|
formInst.setFields([
|
||||||
]);
|
{
|
||||||
} catch (e) {
|
name: "domains",
|
||||||
formInst.setFields([
|
value: "",
|
||||||
{
|
},
|
||||||
name: "domains",
|
{
|
||||||
value: "",
|
name: "certificate",
|
||||||
},
|
value: value,
|
||||||
{
|
errors: [getErrMsg(e)],
|
||||||
name: "certificate",
|
},
|
||||||
value: "",
|
]);
|
||||||
errors: [getErrMsg(e)],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
formInst.setFieldValue("certificate", "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onValuesChange?.(formInst.getFieldsValue(true));
|
onValuesChange?.(formInst.getFieldsValue(true));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePrivateKeyFileChange: UploadProps["onChange"] = async ({ file }) => {
|
const handlePrivateKeyChange = async (value: string) => {
|
||||||
if (file && file.status !== "removed") {
|
try {
|
||||||
const privateKey = await readFileContent(file.originFileObj ?? (file as unknown as File));
|
await validatePrivateKey(value);
|
||||||
|
formInst.setFields([
|
||||||
try {
|
{
|
||||||
await validatePrivateKey(privateKey);
|
name: "privateKey",
|
||||||
formInst.setFields([
|
value: value,
|
||||||
{
|
},
|
||||||
name: "privateKey",
|
]);
|
||||||
value: privateKey,
|
} catch (e) {
|
||||||
},
|
formInst.setFields([
|
||||||
]);
|
{
|
||||||
} catch (e) {
|
name: "privateKey",
|
||||||
formInst.setFields([
|
value: value,
|
||||||
{
|
errors: [getErrMsg(e)],
|
||||||
name: "privateKey",
|
},
|
||||||
value: "",
|
]);
|
||||||
errors: [getErrMsg(e)],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
formInst.setFieldValue("privateKey", "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onValuesChange?.(formInst.getFieldsValue(true));
|
onValuesChange?.(formInst.getFieldsValue(true));
|
||||||
@ -141,23 +128,19 @@ const UploadNodeConfigForm = forwardRef<UploadNodeConfigFormInstance, UploadNode
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item name="certificate" label={t("workflow_node.upload.form.certificate.label")} rules={[formRule]}>
|
<Form.Item name="certificate" label={t("workflow_node.upload.form.certificate.label")} rules={[formRule]}>
|
||||||
<Input.TextArea readOnly autoSize={{ minRows: 5, maxRows: 5 }} placeholder={t("workflow_node.upload.form.certificate.placeholder")} />
|
<TextFileInput
|
||||||
</Form.Item>
|
autoSize={{ minRows: 3, maxRows: 10 }}
|
||||||
|
placeholder={t("workflow_node.upload.form.certificate.placeholder")}
|
||||||
<Form.Item>
|
onChange={handleCertificateChange}
|
||||||
<Upload beforeUpload={() => false} maxCount={1} onChange={handleCertificateFileChange}>
|
/>
|
||||||
<Button icon={<UploadOutlinedIcon />}>{t("workflow_node.upload.form.certificate.button")}</Button>
|
|
||||||
</Upload>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item name="privateKey" label={t("workflow_node.upload.form.private_key.label")} rules={[formRule]}>
|
<Form.Item name="privateKey" label={t("workflow_node.upload.form.private_key.label")} rules={[formRule]}>
|
||||||
<Input.TextArea readOnly autoSize={{ minRows: 5, maxRows: 5 }} placeholder={t("workflow_node.upload.form.private_key.placeholder")} />
|
<TextFileInput
|
||||||
</Form.Item>
|
autoSize={{ minRows: 3, maxRows: 10 }}
|
||||||
|
placeholder={t("workflow_node.upload.form.private_key.placeholder")}
|
||||||
<Form.Item>
|
onChange={handlePrivateKeyChange}
|
||||||
<Upload beforeUpload={() => false} maxCount={1} onChange={handlePrivateKeyFileChange}>
|
/>
|
||||||
<Button icon={<UploadOutlinedIcon />}>{t("workflow_node.upload.form.private_key.button")}</Button>
|
|
||||||
</Upload>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
@ -230,7 +230,6 @@
|
|||||||
"access.form.jdcloud_access_key_secret.tooltip": "For more information, see <a href=\"https://docs.jdcloud.com/en/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/en/account-management/accesskey-management</a>",
|
"access.form.jdcloud_access_key_secret.tooltip": "For more information, see <a href=\"https://docs.jdcloud.com/en/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/en/account-management/accesskey-management</a>",
|
||||||
"access.form.k8s_kubeconfig.label": "KubeConfig",
|
"access.form.k8s_kubeconfig.label": "KubeConfig",
|
||||||
"access.form.k8s_kubeconfig.placeholder": "Please enter KubeConfig file",
|
"access.form.k8s_kubeconfig.placeholder": "Please enter KubeConfig file",
|
||||||
"access.form.k8s_kubeconfig.upload": "Choose File ...",
|
|
||||||
"access.form.k8s_kubeconfig.tooltip": "For more information, see <a href=\"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>Leave it blank to use the Pod's ServiceAccount.",
|
"access.form.k8s_kubeconfig.tooltip": "For more information, see <a href=\"https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>Leave it blank to use the Pod's ServiceAccount.",
|
||||||
"access.form.larkbot_webhook_url.label": "Lark bot Webhook URL",
|
"access.form.larkbot_webhook_url.label": "Lark bot Webhook URL",
|
||||||
"access.form.larkbot_webhook_url.placeholder": "Please enter Lark bot Webhook URL",
|
"access.form.larkbot_webhook_url.placeholder": "Please enter Lark bot Webhook URL",
|
||||||
@ -315,7 +314,6 @@
|
|||||||
"access.form.ssh_password.tooltip": "Required when using password to connect to SSH.",
|
"access.form.ssh_password.tooltip": "Required when using password to connect to SSH.",
|
||||||
"access.form.ssh_key.label": "SSH key (Optional)",
|
"access.form.ssh_key.label": "SSH key (Optional)",
|
||||||
"access.form.ssh_key.placeholder": "Please enter SSH key",
|
"access.form.ssh_key.placeholder": "Please enter SSH key",
|
||||||
"access.form.ssh_key.upload": "Choose file ...",
|
|
||||||
"access.form.ssh_key.tooltip": "Required when using key to connect to SSH.",
|
"access.form.ssh_key.tooltip": "Required when using key to connect to SSH.",
|
||||||
"access.form.ssh_key_passphrase.label": "SSH key passphrase (Optional)",
|
"access.form.ssh_key_passphrase.label": "SSH key passphrase (Optional)",
|
||||||
"access.form.ssh_key_passphrase.placeholder": "Please enter SSH key passphrase",
|
"access.form.ssh_key_passphrase.placeholder": "Please enter SSH key passphrase",
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"common.button.submit": "Submit",
|
"common.button.submit": "Submit",
|
||||||
|
|
||||||
"common.text.copied": "Copied",
|
"common.text.copied": "Copied",
|
||||||
|
"common.text.import_from_file": "Import from file ...",
|
||||||
"common.text.nodata": "No data available",
|
"common.text.nodata": "No data available",
|
||||||
"common.text.operation_confirm": "Operation confirm",
|
"common.text.operation_confirm": "Operation confirm",
|
||||||
"common.text.operation_succeeded": "Operation succeeded",
|
"common.text.operation_succeeded": "Operation succeeded",
|
||||||
|
@ -732,10 +732,8 @@
|
|||||||
"workflow_node.upload.form.domains.placholder": "Please select certificate file",
|
"workflow_node.upload.form.domains.placholder": "Please select certificate file",
|
||||||
"workflow_node.upload.form.certificate.label": "Certificate (PEM format)",
|
"workflow_node.upload.form.certificate.label": "Certificate (PEM format)",
|
||||||
"workflow_node.upload.form.certificate.placeholder": "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
|
"workflow_node.upload.form.certificate.placeholder": "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
|
||||||
"workflow_node.upload.form.certificate.button": "Choose file ...",
|
|
||||||
"workflow_node.upload.form.private_key.label": "Private key (PEM format)",
|
"workflow_node.upload.form.private_key.label": "Private key (PEM format)",
|
||||||
"workflow_node.upload.form.private_key.placeholder": "-----BEGIN (RSA|EC) PRIVATE KEY-----...-----END(RSA|EC) PRIVATE KEY-----",
|
"workflow_node.upload.form.private_key.placeholder": "-----BEGIN (RSA|EC) PRIVATE KEY-----...-----END(RSA|EC) PRIVATE KEY-----",
|
||||||
"workflow_node.upload.form.private_key.button": "Choose file ...",
|
|
||||||
|
|
||||||
"workflow_node.notify.label": "Notification",
|
"workflow_node.notify.label": "Notification",
|
||||||
"workflow_node.notify.form.subject.label": "Subject",
|
"workflow_node.notify.form.subject.label": "Subject",
|
||||||
|
@ -223,8 +223,7 @@
|
|||||||
"access.form.jdcloud_access_key_secret.placeholder": "请输入京东云 AccessKeySecret",
|
"access.form.jdcloud_access_key_secret.placeholder": "请输入京东云 AccessKeySecret",
|
||||||
"access.form.jdcloud_access_key_secret.tooltip": "这是什么?请参阅 <a href=\"https://docs.jdcloud.com/cn/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/cn/account-management/accesskey-management</a>",
|
"access.form.jdcloud_access_key_secret.tooltip": "这是什么?请参阅 <a href=\"https://docs.jdcloud.com/cn/account-management/accesskey-management\" target=\"_blank\">https://docs.jdcloud.com/cn/account-management/accesskey-management</a>",
|
||||||
"access.form.k8s_kubeconfig.label": "KubeConfig",
|
"access.form.k8s_kubeconfig.label": "KubeConfig",
|
||||||
"access.form.k8s_kubeconfig.placeholder": "请选择 KubeConfig 文件",
|
"access.form.k8s_kubeconfig.placeholder": "请输入 KubeConfig 文件内容",
|
||||||
"access.form.k8s_kubeconfig.upload": "选择文件",
|
|
||||||
"access.form.k8s_kubeconfig.tooltip": "这是什么?请参阅 <a href=\"https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>为空时,将使用 Pod 的 ServiceAccount 作为凭证。",
|
"access.form.k8s_kubeconfig.tooltip": "这是什么?请参阅 <a href=\"https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/\" target=\"_blank\">https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/</a><br><br>为空时,将使用 Pod 的 ServiceAccount 作为凭证。",
|
||||||
"access.form.larkbot_webhook_url.label": "飞书群机器人 Webhook 地址",
|
"access.form.larkbot_webhook_url.label": "飞书群机器人 Webhook 地址",
|
||||||
"access.form.larkbot_webhook_url.placeholder": "请输入飞书群机器人 Webhook 地址",
|
"access.form.larkbot_webhook_url.placeholder": "请输入飞书群机器人 Webhook 地址",
|
||||||
@ -308,8 +307,7 @@
|
|||||||
"access.form.ssh_password.placeholder": "请输入密码",
|
"access.form.ssh_password.placeholder": "请输入密码",
|
||||||
"access.form.ssh_password.tooltip": "使用密码连接到 SSH 时必填。<br>该字段与密钥文件字段二选一,如果同时填写优先使用 SSH 密钥登录。",
|
"access.form.ssh_password.tooltip": "使用密码连接到 SSH 时必填。<br>该字段与密钥文件字段二选一,如果同时填写优先使用 SSH 密钥登录。",
|
||||||
"access.form.ssh_key.label": "SSH 密钥(可选)",
|
"access.form.ssh_key.label": "SSH 密钥(可选)",
|
||||||
"access.form.ssh_key.placeholder": "请输入 SSH 密钥文件",
|
"access.form.ssh_key.placeholder": "请输入 SSH 密钥文件内容",
|
||||||
"access.form.ssh_key.upload": "选择文件",
|
|
||||||
"access.form.ssh_key.tooltip": "使用 SSH 密钥连接到 SSH 时必填。<br>该字段与密码字段二选一,如果同时填写优先使用 SSH 密钥登录。",
|
"access.form.ssh_key.tooltip": "使用 SSH 密钥连接到 SSH 时必填。<br>该字段与密码字段二选一,如果同时填写优先使用 SSH 密钥登录。",
|
||||||
"access.form.ssh_key_passphrase.label": "SSH 密钥口令(可选)",
|
"access.form.ssh_key_passphrase.label": "SSH 密钥口令(可选)",
|
||||||
"access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令",
|
"access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令",
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"common.button.submit": "提交",
|
"common.button.submit": "提交",
|
||||||
|
|
||||||
"common.text.copied": "已复制",
|
"common.text.copied": "已复制",
|
||||||
|
"common.text.import_from_file": "从文件导入 ……",
|
||||||
"common.text.nodata": "暂无数据",
|
"common.text.nodata": "暂无数据",
|
||||||
"common.text.operation_confirm": "操作确认",
|
"common.text.operation_confirm": "操作确认",
|
||||||
"common.text.operation_succeeded": "操作成功",
|
"common.text.operation_succeeded": "操作成功",
|
||||||
|
@ -731,10 +731,8 @@
|
|||||||
"workflow_node.upload.form.domains.placeholder": "上传证书文件后显示",
|
"workflow_node.upload.form.domains.placeholder": "上传证书文件后显示",
|
||||||
"workflow_node.upload.form.certificate.label": "证书文件(PEM 格式)",
|
"workflow_node.upload.form.certificate.label": "证书文件(PEM 格式)",
|
||||||
"workflow_node.upload.form.certificate.placeholder": "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
|
"workflow_node.upload.form.certificate.placeholder": "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
|
||||||
"workflow_node.upload.form.certificate.button": "选择文件",
|
|
||||||
"workflow_node.upload.form.private_key.label": "私钥文件(PEM 格式)",
|
"workflow_node.upload.form.private_key.label": "私钥文件(PEM 格式)",
|
||||||
"workflow_node.upload.form.private_key.placeholder": "-----BEGIN (RSA|EC) PRIVATE KEY-----...-----END(RSA|EC) PRIVATE KEY-----",
|
"workflow_node.upload.form.private_key.placeholder": "-----BEGIN (RSA|EC) PRIVATE KEY-----...-----END(RSA|EC) PRIVATE KEY-----",
|
||||||
"workflow_node.upload.form.private_key.button": "选择文件",
|
|
||||||
|
|
||||||
"workflow_node.notify.label": "推送通知",
|
"workflow_node.notify.label": "推送通知",
|
||||||
"workflow_node.notify.form.subject.label": "通知主题",
|
"workflow_node.notify.form.subject.label": "通知主题",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user