mirror of
https://github.com/certimate-go/certimate.git
synced 2026-06-19 21:03:27 +08:00
Merge pull request #917 from fudiwei/dev
This commit is contained in:
commit
cbbabc42ac
1259
ui/package-lock.json
generated
1259
ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,26 +9,24 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.0.0",
|
||||
"@ant-design/pro-components": "^2.8.10",
|
||||
"@codemirror/lang-json": "^6.0.2",
|
||||
"@codemirror/lang-yaml": "^6.1.2",
|
||||
"@codemirror/language": "^6.11.2",
|
||||
"@codemirror/legacy-modes": "^6.5.1",
|
||||
"@flowgram.ai/document": "^0.3.4",
|
||||
"@flowgram.ai/fixed-layout-editor": "^0.3.4",
|
||||
"@flowgram.ai/minimap-plugin": "^0.3.4",
|
||||
"@flowgram.ai/document": "^0.3.5",
|
||||
"@flowgram.ai/fixed-layout-editor": "^0.3.5",
|
||||
"@flowgram.ai/minimap-plugin": "^0.3.5",
|
||||
"@tabler/icons-react": "^3.34.1",
|
||||
"@uiw/codemirror-extensions-basic-setup": "^4.24.2",
|
||||
"@uiw/codemirror-theme-vscode": "^4.24.2",
|
||||
"@uiw/react-codemirror": "^4.24.2",
|
||||
"ahooks": "^3.9.0",
|
||||
"antd": "^5.26.7",
|
||||
"antd": "^5.27.0",
|
||||
"antd-zod": "^7.0.0",
|
||||
"clsx": "^2.1.1",
|
||||
"cron-parser": "^5.3.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"i18next": "^25.3.2",
|
||||
"i18next": "^25.3.4",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"immer": "^10.1.1",
|
||||
"nanoid": "^5.1.5",
|
||||
@ -40,7 +38,7 @@
|
||||
"react-i18next": "^15.6.1",
|
||||
"react-router-dom": "^7.8.0",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"zod": "^4.0.16",
|
||||
"zod": "^4.0.17",
|
||||
"zustand": "^5.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -67,7 +65,7 @@
|
||||
"prettier": "^3.6.2",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.39.0",
|
||||
"typescript-eslint": "^8.39.1",
|
||||
"vite": "^6.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,9 +10,7 @@ export interface AppDocumentLinkButtonProps {
|
||||
showIcon?: boolean;
|
||||
}
|
||||
|
||||
const AppDocumentLinkButton = (props: AppDocumentLinkButtonProps) => {
|
||||
const { className, style, showIcon = true } = props;
|
||||
|
||||
const AppDocumentLinkButton = ({ className, style, showIcon = true }: AppDocumentLinkButtonProps) => {
|
||||
const { i18n, t } = useTranslation();
|
||||
|
||||
const handleDocumentClick = () => {
|
||||
|
||||
@ -30,9 +30,7 @@ export interface AppLocaleDropdownProps {
|
||||
trigger?: DropdownProps["trigger"];
|
||||
}
|
||||
|
||||
const AppLocaleDropdown = (props: AppLocaleDropdownProps) => {
|
||||
const { children, trigger = ["click"] } = props;
|
||||
|
||||
const AppLocaleDropdown = ({ children, trigger = ["click"] }: AppLocaleDropdownProps) => {
|
||||
const items = useAppLocaleMenuItems();
|
||||
|
||||
return (
|
||||
@ -62,9 +60,7 @@ export interface AppLocaleLinkButtonProps {
|
||||
showIcon?: boolean;
|
||||
}
|
||||
|
||||
const AppLocaleLinkButton = (props: AppLocaleLinkButtonProps) => {
|
||||
const { className, style, showIcon = true } = props;
|
||||
|
||||
const AppLocaleLinkButton = ({ className, style, showIcon = true }: AppLocaleLinkButtonProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
|
||||
@ -39,9 +39,7 @@ export interface AppThemeDropdownProps {
|
||||
trigger?: DropdownProps["trigger"];
|
||||
}
|
||||
|
||||
const AppThemeDropdown = (props: AppThemeDropdownProps) => {
|
||||
const { children, trigger = ["click"] } = props;
|
||||
|
||||
const AppThemeDropdown = ({ children, trigger = ["click"] }: AppThemeDropdownProps) => {
|
||||
const items = useAppThemeMenuItems();
|
||||
|
||||
return (
|
||||
@ -65,9 +63,7 @@ export interface AppThemeLinkButtonProps {
|
||||
showIcon?: boolean;
|
||||
}
|
||||
|
||||
const AppThemeLinkButton = (props: AppThemeLinkButtonProps) => {
|
||||
const { className, style, showIcon = true } = props;
|
||||
|
||||
const AppThemeLinkButton = ({ className, style, showIcon = true }: AppThemeLinkButtonProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { themeMode } = useBrowserTheme();
|
||||
|
||||
@ -25,7 +25,7 @@ export interface AppVersionBadgeProps {
|
||||
}
|
||||
|
||||
const AppVersionBadge = ({ className, style, children }: AppVersionBadgeProps) => {
|
||||
const { hasNewVersion } = useVersionChecker();
|
||||
const { hasUpdate } = useVersionChecker();
|
||||
|
||||
return (
|
||||
<Badge
|
||||
@ -34,7 +34,7 @@ const AppVersionBadge = ({ className, style, children }: AppVersionBadgeProps) =
|
||||
styles={{
|
||||
indicator: { transform: "scale(0.75) translate(50%, -50%)" },
|
||||
}}
|
||||
count={hasNewVersion ? "NEW" : void 0}
|
||||
count={hasUpdate ? "NEW" : void 0}
|
||||
>
|
||||
{children}
|
||||
</Badge>
|
||||
|
||||
@ -16,10 +16,12 @@ const Tips = ({ className, style, message }: TipsProps) => {
|
||||
style={style}
|
||||
message={
|
||||
<Flex gap="small">
|
||||
<div>
|
||||
<IconBulb size="1.5em" color={themeToken.colorInfo} />
|
||||
<div style={{ marginTop: "1px" }}>
|
||||
<IconBulb size={18} color={themeToken.colorInfo} />
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>
|
||||
<Typography.Text>{message}</Typography.Text>
|
||||
</div>
|
||||
<Typography.Text>{message}</Typography.Text>
|
||||
</Flex>
|
||||
}
|
||||
type="info"
|
||||
|
||||
@ -139,12 +139,6 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
console.warn(`[certimate] unsupported provider usage: '${usage}'`);
|
||||
}
|
||||
}, [usage]);
|
||||
const providerTooltip = useMemo(() => {
|
||||
switch (usage) {
|
||||
case "dns-hosting":
|
||||
return <span dangerouslySetInnerHTML={{ __html: t("access.form.provider.tooltip") }}></span>;
|
||||
}
|
||||
}, [usage]);
|
||||
|
||||
const fieldProvider = Form.useWatch<z.infer<typeof formSchema>["provider"]>("provider", formInst);
|
||||
const [fieldProviderPicked, setFieldProviderPicked] = useState<string>(initialValues?.provider); // bugfix: Form.useWatch 在条件渲染下不生效,这里用单独的变量存放 Picker 组件选择的值
|
||||
@ -378,7 +372,12 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
|
||||
<Input placeholder={t("access.form.name.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="provider" label={t("access.form.provider.label")} rules={[formRule]} tooltip={providerTooltip}>
|
||||
<Form.Item
|
||||
name="provider"
|
||||
label={t("access.form.provider.label")}
|
||||
extra={usage === "dns-hosting" ? <span dangerouslySetInnerHTML={{ __html: t("access.form.provider.help") }}></span> : null}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<AccessProviderSelect
|
||||
disabled={mode !== "create"}
|
||||
placeholder={t("access.form.provider.placeholder")}
|
||||
|
||||
@ -58,6 +58,7 @@ const AccessFormDiscordBotConfig = ({ form: formInst, formName, disabled, initia
|
||||
<Form.Item
|
||||
name="channelId"
|
||||
label={t("access.form.discordbot_channel_id.label")}
|
||||
extra={t("access.form.discordbot_channel_id.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.discordbot_channel_id.tooltip") }}></span>}
|
||||
>
|
||||
|
||||
@ -117,7 +117,12 @@ const AccessFormEmailConfig = ({ form: formInst, formName, disabled, initialValu
|
||||
<Input allowClear placeholder={t("access.form.email_sender_name.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="receiverAddress" label={t("access.form.email_receiver_address.label")} rules={[formRule]}>
|
||||
<Form.Item
|
||||
name="receiverAddress"
|
||||
label={t("access.form.email_receiver_address.label")}
|
||||
extra={t("access.form.email_receiver_address.help")}
|
||||
rules={[formRule]}
|
||||
>
|
||||
<Input type="email" allowClear placeholder={t("access.form.email_receiver_address.placeholder")} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
@ -67,6 +67,7 @@ const AccessFormMattermostConfig = ({ form: formInst, formName, disabled, initia
|
||||
<Form.Item
|
||||
name="channelId"
|
||||
label={t("access.form.mattermost_channel_id.label")}
|
||||
extra={t("access.form.mattermost_channel_id.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.mattermost_channel_id.tooltip") }}></span>}
|
||||
>
|
||||
|
||||
@ -135,17 +135,14 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
||||
</div>
|
||||
|
||||
<Form.Item name="authMethod" label={t("access.form.ssh_auth_method.label")} rules={[formRule]}>
|
||||
<Select placeholder={t("access.form.ssh_auth_method.placeholder")}>
|
||||
<Select.Option key={AUTH_METHOD_NONE} value={AUTH_METHOD_NONE}>
|
||||
{t("access.form.ssh_auth_method.option.none.label")}
|
||||
</Select.Option>
|
||||
<Select.Option key={AUTH_METHOD_PASSWORD} value={AUTH_METHOD_PASSWORD}>
|
||||
{t("access.form.ssh_auth_method.option.password.label")}
|
||||
</Select.Option>
|
||||
<Select.Option key={AUTH_METHOD_KEY} value={AUTH_METHOD_KEY}>
|
||||
{t("access.form.ssh_auth_method.option.key.label")}
|
||||
</Select.Option>
|
||||
</Select>
|
||||
<Select
|
||||
options={[AUTH_METHOD_NONE, AUTH_METHOD_PASSWORD, AUTH_METHOD_KEY].map((s) => ({
|
||||
key: s,
|
||||
label: t(`access.form.ssh_auth_method.option.${s}.label`),
|
||||
value: s,
|
||||
}))}
|
||||
placeholder={t("access.form.ssh_auth_method.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="username" label={t("access.form.ssh_username.label")} rules={[formRule]}>
|
||||
|
||||
@ -58,6 +58,7 @@ const AccessFormSlackBotConfig = ({ form: formInst, formName, disabled, initialV
|
||||
<Form.Item
|
||||
name="channelId"
|
||||
label={t("access.form.slackbot_channel_id.label")}
|
||||
extra={t("access.form.slackbot_channel_id.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.slackbot_channel_id.tooltip") }}></span>}
|
||||
>
|
||||
|
||||
@ -65,6 +65,7 @@ const AccessFormTelegramBotConfig = ({ form: formInst, formName, disabled, initi
|
||||
<Form.Item
|
||||
name="chatId"
|
||||
label={t("access.form.telegrambot_chat_id.label")}
|
||||
extra={t("access.form.telegrambot_chat_id.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.telegrambot_chat_id.tooltip") }}></span>}
|
||||
>
|
||||
|
||||
@ -305,76 +305,62 @@ const AccessFormWebhookConfig = ({ form: formInst, formName, disabled, initialVa
|
||||
</Form.Item>
|
||||
|
||||
<Show when={!usage || usage === "deployment"}>
|
||||
<Form.Item noStyle>
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("access.form.webhook_data_for_deployment.label")}</span>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<Button size="small" type="link" onClick={handlePresetDataForDeploymentClick}>
|
||||
{t("access.form.webhook_preset_data.button")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="dataForDeployment" rules={[formRule]}>
|
||||
<Form.Item className="relative" label={t("access.form.webhook_data.label")} extra={t("access.form.webhook_data.help")}>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<Button size="small" type="link" onClick={handlePresetDataForDeploymentClick}>
|
||||
{t("access.form.webhook_preset_data.button")}
|
||||
</Button>
|
||||
</div>
|
||||
<Form.Item name="dataForDeployment" noStyle rules={[formRule]}>
|
||||
<CodeInput
|
||||
height="auto"
|
||||
minHeight="64px"
|
||||
maxHeight="256px"
|
||||
language="json"
|
||||
placeholder={t("access.form.webhook_data_for_deployment.placeholder")}
|
||||
placeholder={t("access.form.webhook_data.placeholder")}
|
||||
onBlur={handleWebhookDataForDeploymentBlur}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Tips message={<span dangerouslySetInnerHTML={{ __html: t("access.form.webhook_data_for_deployment.guide") }}></span>} />
|
||||
<Tips message={<span dangerouslySetInnerHTML={{ __html: t("access.form.webhook_data.guide_for_deployment") }}></span>} />
|
||||
</Form.Item>
|
||||
</Show>
|
||||
|
||||
<Show when={!usage || usage === "notification"}>
|
||||
<Form.Item noStyle>
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("access.form.webhook_data_for_notification.label")}</span>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: ["bark", "ntfy", "gotify", "pushover", "pushplus", "serverchan3", "serverchanturbo", "common"].map((key) => ({
|
||||
key,
|
||||
label: <span dangerouslySetInnerHTML={{ __html: t(`access.form.webhook_preset_data.option.${key}.label`) }}></span>,
|
||||
onClick: () => handlePresetDataForNotificationClick(key),
|
||||
})),
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
<Button size="small" type="link">
|
||||
{t("access.form.webhook_preset_data.button")}
|
||||
<IconChevronDown size="1.25em" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="dataForNotification" rules={[formRule]}>
|
||||
<Form.Item className="relative" label={t("access.form.webhook_data.label")} extra={t("access.form.webhook_data.help")}>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: ["bark", "ntfy", "gotify", "pushover", "pushplus", "serverchan3", "serverchanturbo", "common"].map((key) => ({
|
||||
key,
|
||||
label: <span dangerouslySetInnerHTML={{ __html: t(`access.form.webhook_preset_data.option.${key}.label`) }}></span>,
|
||||
onClick: () => handlePresetDataForNotificationClick(key),
|
||||
})),
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
<Button size="small" type="link">
|
||||
{t("access.form.webhook_preset_data.button")}
|
||||
<IconChevronDown size="1.25em" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<Form.Item name="dataForNotification" noStyle rules={[formRule]}>
|
||||
<CodeInput
|
||||
height="auto"
|
||||
minHeight="64px"
|
||||
maxHeight="256px"
|
||||
language="json"
|
||||
placeholder={t("access.form.webhook_data_for_notification.placeholder")}
|
||||
placeholder={t("access.form.webhook_data.placeholder")}
|
||||
onBlur={handleWebhookDataForNotificationBlur}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Tips message={<span dangerouslySetInnerHTML={{ __html: t("access.form.webhook_data_for_notification.guide") }}></span>} />
|
||||
<Tips message={<span dangerouslySetInnerHTML={{ __html: t("access.form.webhook_data.guide_for_notification") }}></span>} />
|
||||
</Form.Item>
|
||||
</Show>
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ const AccessSelect = ({ onFilter, ...props }: AccessTypeSelectProps) => {
|
||||
|
||||
const { accesses, loadedAtOnce, fetchAccesses } = useAccessesStore(useZustandShallowSelector(["accesses", "loadedAtOnce", "fetchAccesses"]));
|
||||
useEffect(() => {
|
||||
fetchAccesses();
|
||||
fetchAccesses(false);
|
||||
}, []);
|
||||
|
||||
const [options, setOptions] = useState<Array<{ key: string; value: string; label: string; data: AccessModel }>>([]);
|
||||
|
||||
@ -59,9 +59,8 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => {
|
||||
<Input value={data.keyAlgorithm} variant="filled" placeholder="" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<div className="mb-2 flex w-full items-center justify-between">
|
||||
<label>{t("certificate.props.certificate")}</label>
|
||||
<Form.Item label={t("certificate.props.certificate")}>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<Tooltip title={t("common.button.copy")}>
|
||||
<CopyToClipboard
|
||||
text={data.certificate}
|
||||
@ -76,9 +75,8 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => {
|
||||
<Input.TextArea value={data.certificate} variant="filled" autoSize={{ minRows: 5, maxRows: 5 }} readOnly />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<div className="mb-2 flex w-full items-center justify-between">
|
||||
<label>{t("certificate.props.private_key")}</label>
|
||||
<Form.Item label={t("certificate.props.private_key")}>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<Tooltip title={t("common.button.copy")}>
|
||||
<CopyToClipboard
|
||||
text={data.privateKey}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useSize } from "ahooks";
|
||||
import { Avatar, Card, Empty, Input, type InputRef, Tag, Typography } from "antd";
|
||||
import { Avatar, Card, Empty, Input, type InputRef, Tag, Tooltip, Typography } from "antd";
|
||||
|
||||
import Show from "@/components/Show";
|
||||
import { ACCESS_USAGES, type AccessProvider, type AccessUsageType, accessProvidersMap } from "@/domain/provider";
|
||||
@ -18,9 +18,7 @@ export interface AccessProviderPickerProps {
|
||||
onSelect?: (value: string) => void;
|
||||
}
|
||||
|
||||
const AccessProviderPicker = ({ className, style, autoFocus, placeholder, showOptionTags, onFilter, onSelect, ...props }: AccessProviderPickerProps) => {
|
||||
const { gap = "middle" } = props;
|
||||
|
||||
const AccessProviderPicker = ({ className, style, autoFocus, gap = "middle", placeholder, showOptionTags, onFilter, onSelect }: AccessProviderPickerProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
@ -99,7 +97,7 @@ const AccessProviderPicker = ({ className, style, autoFocus, placeholder, showOp
|
||||
return (
|
||||
<div key={provider.type}>
|
||||
<Card
|
||||
className={mergeCls("h-20 w-full overflow-hidden shadow", provider.builtin ? " cursor-not-allowed" : "")}
|
||||
className={mergeCls("w-full overflow-hidden shadow", provider.builtin ? " cursor-not-allowed" : "", showOptionTagAnyhow ? "h-32" : "h-28")}
|
||||
styles={{ body: { height: "100%", padding: "0.5rem 1rem" } }}
|
||||
hoverable
|
||||
onClick={() => {
|
||||
@ -110,14 +108,18 @@ const AccessProviderPicker = ({ className, style, autoFocus, placeholder, showOp
|
||||
handleProviderTypeSelect(provider.type);
|
||||
}}
|
||||
>
|
||||
<div className="flex size-full items-center gap-4 overflow-hidden">
|
||||
<Avatar className="bg-stone-100" icon={<img src={provider.icon} />} shape="square" size={28} />
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<div className={mergeCls("max-w-full", showOptionTagAnyhow ? "mb-1 truncate" : "line-clamp-2")}>
|
||||
<Typography.Text type={provider.builtin ? "secondary" : void 0}>{t(provider.name) || "\u00A0"}</Typography.Text>
|
||||
<div className="flex size-full flex-col items-center justify-center gap-3 overflow-hidden p-2">
|
||||
<div className="flex items-center justify-center">
|
||||
<Avatar className="bg-stone-100" icon={<img src={provider.icon} />} shape="square" size={32} />
|
||||
</div>
|
||||
<div className="w-full overflow-hidden text-center">
|
||||
<div className={mergeCls("w-full truncate", { "mb-1": showOptionTagAnyhow })}>
|
||||
<Tooltip title={t(provider.name)} mouseEnterDelay={1}>
|
||||
<Typography.Text type={provider.builtin ? "secondary" : void 0}>{t(provider.name) || "\u00A0"}</Typography.Text>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Show when={showOptionTagAnyhow}>
|
||||
<div className="origin-left scale-80 whitespace-nowrap">
|
||||
<div className="origin-top scale-80 whitespace-nowrap" style={{ marginInlineEnd: "-8px" }}>
|
||||
<Show when={provider.builtin}>
|
||||
<Tag>{t("access.props.provider.builtin")}</Tag>
|
||||
</Show>
|
||||
|
||||
@ -33,7 +33,7 @@ const CAProviderSelect = ({ onFilter, ...props }: CAProviderSelectProps) => {
|
||||
temp.unshift({
|
||||
key: "",
|
||||
value: "",
|
||||
label: t("provider.text.default_ca_provider.label"),
|
||||
label: t("provider.text.default_ca_provider"),
|
||||
data: {} as CAProvider,
|
||||
});
|
||||
|
||||
@ -45,7 +45,7 @@ const CAProviderSelect = ({ onFilter, ...props }: CAProviderSelectProps) => {
|
||||
return (
|
||||
<div className="flex items-center gap-2 truncate overflow-hidden">
|
||||
<Typography.Text className="italic" ellipsis italic>
|
||||
{t("provider.text.default_ca_provider.label")}
|
||||
{t("provider.text.default_ca_provider")}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useSize } from "ahooks";
|
||||
import { Avatar, Card, Empty, Flex, Input, type InputRef, Tabs, Tooltip, Typography } from "antd";
|
||||
import { Avatar, Card, Checkbox, Empty, Flex, Input, type InputRef, Tabs, Tooltip, Typography } from "antd";
|
||||
|
||||
import Show from "@/components/Show";
|
||||
import { DEPLOYMENT_CATEGORIES, type DeploymentProvider, deploymentProvidersMap } from "@/domain/provider";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { useAccessesStore } from "@/stores/access";
|
||||
import { mergeCls } from "@/utils/css";
|
||||
|
||||
export interface DeploymentProviderPickerProps {
|
||||
@ -17,14 +19,19 @@ export interface DeploymentProviderPickerProps {
|
||||
onSelect?: (value: string) => void;
|
||||
}
|
||||
|
||||
const DeploymentProviderPicker = ({ className, style, autoFocus, onFilter, placeholder, onSelect, ...props }: DeploymentProviderPickerProps) => {
|
||||
const { gap = "middle" } = props;
|
||||
|
||||
const DeploymentProviderPicker = ({ className, style, autoFocus, gap = "middle", placeholder, onFilter, onSelect }: DeploymentProviderPickerProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { accesses, fetchAccesses } = useAccessesStore(useZustandShallowSelector(["accesses", "fetchAccesses"]));
|
||||
useEffect(() => {
|
||||
fetchAccesses(false);
|
||||
}, []);
|
||||
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const wrapperSize = useSize(wrapperRef);
|
||||
|
||||
const [isAvailableOnly, setIsAvailableOnly] = useState(true);
|
||||
|
||||
const [category, setCategory] = useState<string>(DEPLOYMENT_CATEGORIES.ALL);
|
||||
|
||||
const [keyword, setKeyword] = useState<string>();
|
||||
@ -44,6 +51,13 @@ const DeploymentProviderPicker = ({ className, style, autoFocus, onFilter, place
|
||||
|
||||
return true;
|
||||
})
|
||||
.filter((provider) => {
|
||||
if (isAvailableOnly) {
|
||||
return provider.builtin || accesses.some((access) => access.provider === provider.provider);
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.filter((provider) => {
|
||||
if (category && category !== DEPLOYMENT_CATEGORIES.ALL) {
|
||||
return provider.category === category;
|
||||
@ -59,7 +73,7 @@ const DeploymentProviderPicker = ({ className, style, autoFocus, onFilter, place
|
||||
|
||||
return true;
|
||||
});
|
||||
}, [onFilter, category, keyword]);
|
||||
}, [onFilter, accesses, isAvailableOnly, category, keyword]);
|
||||
const providerCols = useMemo(() => {
|
||||
if (!wrapperSize) {
|
||||
return 1;
|
||||
@ -77,6 +91,14 @@ const DeploymentProviderPicker = ({ className, style, autoFocus, onFilter, place
|
||||
<div className={className} style={style} ref={wrapperRef}>
|
||||
<Input.Search ref={keywordInputRef} placeholder={placeholder ?? t("common.text.search")} onChange={(e) => setKeyword(e.target.value.trim())} />
|
||||
|
||||
<div className="mt-4">
|
||||
<Flex justify="end">
|
||||
<Checkbox checked={isAvailableOnly} onClick={() => setIsAvailableOnly(!isAvailableOnly)}>
|
||||
{t("provider.text.show_available_hosting_provider_only")}
|
||||
</Checkbox>
|
||||
</Flex>
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<Flex>
|
||||
<Tabs
|
||||
@ -126,16 +148,16 @@ const DeploymentProviderPicker = ({ className, style, autoFocus, onFilter, place
|
||||
handleProviderTypeSelect(provider.type);
|
||||
}}
|
||||
>
|
||||
<Tooltip title={t(provider.name)} mouseEnterDelay={1}>
|
||||
<div className="flex size-full items-center gap-4 overflow-hidden">
|
||||
<Avatar className="bg-stone-100" icon={<img src={provider.icon} />} shape="square" size={28} />
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<div className="line-clamp-2 max-w-full">
|
||||
<div className="flex size-full items-center gap-4 overflow-hidden">
|
||||
<Avatar className="bg-stone-100" icon={<img src={provider.icon} />} shape="square" size={28} />
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<div className="line-clamp-2 max-w-full">
|
||||
<Tooltip title={t(provider.name)} mouseEnterDelay={1}>
|
||||
<Typography.Text>{t(provider.name) || "\u00A0"}</Typography.Text>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -15,6 +15,10 @@ import StartNode from "./node/StartNode";
|
||||
import UnknownNode from "./node/UnknownNode";
|
||||
import UploadNode from "./node/UploadNode";
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export interface WorkflowElementProps {
|
||||
node: WorkflowNode;
|
||||
disabled?: boolean;
|
||||
|
||||
@ -5,6 +5,10 @@ import { WorkflowNodeType, newNode } from "@/domain/workflow";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export interface WorkflowElementsProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
|
||||
@ -5,6 +5,10 @@ import { Button, Card, Typography } from "antd";
|
||||
import WorkflowElements from "@/components/workflow/WorkflowElements";
|
||||
import { mergeCls } from "@/utils/css";
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export interface WorkflowElementsProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
|
||||
@ -17,7 +17,7 @@ import { listByWorkflowRunId as listLogsByWorkflowRunId } from "@/repository/wor
|
||||
import { mergeCls } from "@/utils/css";
|
||||
import { getErrMsg } from "@/utils/error";
|
||||
|
||||
import WorkflowStatusIcon from "./WorkflowStatusIcon";
|
||||
import WorkflowStatus from "./WorkflowStatus";
|
||||
|
||||
export interface WorkflowRunDetailProps {
|
||||
className?: string;
|
||||
@ -88,34 +88,6 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
|
||||
const [showTimestamp, setShowTimestamp] = useState(true);
|
||||
const [showWhitespace, setShowWhitespace] = useState(true);
|
||||
|
||||
const renderBadge = () => {
|
||||
let color: string | undefined;
|
||||
|
||||
switch (runStatus) {
|
||||
case WORKFLOW_RUN_STATUSES.PENDING:
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.RUNNING:
|
||||
color = themeToken.colorInfo;
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.SUCCEEDED:
|
||||
color = themeToken.colorSuccess;
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.FAILED:
|
||||
color = themeToken.colorError;
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.CANCELED:
|
||||
color = themeToken.colorWarning;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex gap="small" style={{ color: color }}>
|
||||
<WorkflowStatusIcon size="1.25em" status={runStatus} />
|
||||
{t(`workflow_run.props.status.${runStatus}`)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const renderRecord = (record: Log) => {
|
||||
let message = <>{record.message}</>;
|
||||
if (record.data != null && Object.keys(record.data).length > 0) {
|
||||
@ -189,7 +161,9 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
|
||||
<Typography.Title level={5}>{t("workflow_run.logs")}</Typography.Title>
|
||||
<div className="rounded-md bg-black text-stone-200">
|
||||
<div className="flex items-center gap-2 p-4">
|
||||
<div className="grow overflow-hidden">{renderBadge()}</div>
|
||||
<div className="grow overflow-hidden">
|
||||
<WorkflowStatus value={runStatus} />
|
||||
</div>
|
||||
<div>
|
||||
<Dropdown
|
||||
menu={{
|
||||
|
||||
153
ui/src/components/workflow/WorkflowStatus.tsx
Normal file
153
ui/src/components/workflow/WorkflowStatus.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
IconCircleCheck,
|
||||
IconCircleCheckFilled,
|
||||
IconCircleDashed,
|
||||
IconCircleOff,
|
||||
IconCircleX,
|
||||
IconCircleXFilled,
|
||||
IconClock,
|
||||
IconClockFilled,
|
||||
IconLoader3,
|
||||
} from "@tabler/icons-react";
|
||||
import { Typography, theme } from "antd";
|
||||
|
||||
import { WORKFLOW_RUN_STATUSES, type WorkflorRunStatusType } from "@/domain/workflowRun";
|
||||
import { mergeCls } from "@/utils/css";
|
||||
|
||||
const useColor = (value: WorkflorRunStatusType | string, defaultColor?: string | false) => {
|
||||
const { token: themeToken } = theme.useToken();
|
||||
|
||||
switch (value) {
|
||||
case WORKFLOW_RUN_STATUSES.PENDING:
|
||||
if (defaultColor == null || !defaultColor) {
|
||||
return themeToken.colorTextSecondary;
|
||||
}
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.RUNNING:
|
||||
if (defaultColor == null || !defaultColor) {
|
||||
return themeToken.colorInfo;
|
||||
}
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.SUCCEEDED:
|
||||
if (defaultColor == null || !defaultColor) {
|
||||
return themeToken.colorSuccess;
|
||||
}
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.FAILED:
|
||||
if (defaultColor == null || !defaultColor) {
|
||||
return themeToken.colorError;
|
||||
}
|
||||
break;
|
||||
case WORKFLOW_RUN_STATUSES.CANCELED:
|
||||
if (defaultColor == null || !defaultColor) {
|
||||
return themeToken.colorWarning;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (defaultColor == null || !defaultColor) {
|
||||
return themeToken.colorTextSecondary;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return defaultColor;
|
||||
};
|
||||
|
||||
export interface WorkflowStatusIconProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
color?: string | false;
|
||||
size?: number | string;
|
||||
type?: "filled" | "outlined";
|
||||
value: WorkflorRunStatusType | string;
|
||||
}
|
||||
|
||||
const WorkflowStatusIcon = ({ className, style, size = "1.25em", type = "outlined", value, ...props }: WorkflowStatusIconProps) => {
|
||||
const color = useColor(value, props.color);
|
||||
|
||||
switch (value) {
|
||||
case WORKFLOW_RUN_STATUSES.PENDING:
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
{type === "filled" ? <IconClockFilled color={color} size={size} /> : <IconClock color={color} size={size} />}
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.RUNNING:
|
||||
return (
|
||||
<span className={mergeCls("anticon", "animate-spin", className)} style={style} role="img">
|
||||
<IconLoader3 color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.SUCCEEDED:
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
{type === "filled" ? <IconCircleCheckFilled color={color} size={size} /> : <IconCircleCheck color={color} size={size} />}
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.FAILED:
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
{type === "filled" ? <IconCircleXFilled color={color} size={size} /> : <IconCircleX color={color} size={size} />}
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.CANCELED:
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
<IconCircleOff color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
<IconCircleDashed color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export interface WorkflowStatusProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
children?: React.ReactNode;
|
||||
color?: string | false;
|
||||
showIcon?: boolean;
|
||||
type?: WorkflowStatusIconProps["type"];
|
||||
value: WorkflorRunStatusType | string;
|
||||
}
|
||||
|
||||
const WorkflowStatus = ({ className, style, children, showIcon = true, type, value, ...props }: WorkflowStatusProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const color = useColor(value, props.color);
|
||||
|
||||
const renderIcon = () => (showIcon ? <WorkflowStatusIcon type={type} value={value} /> : null);
|
||||
|
||||
switch (value) {
|
||||
case WORKFLOW_RUN_STATUSES.PENDING:
|
||||
case WORKFLOW_RUN_STATUSES.RUNNING:
|
||||
case WORKFLOW_RUN_STATUSES.SUCCEEDED:
|
||||
case WORKFLOW_RUN_STATUSES.FAILED:
|
||||
case WORKFLOW_RUN_STATUSES.CANCELED:
|
||||
return (
|
||||
<Typography.Text className={className} style={style}>
|
||||
<div className="flex items-center gap-2">
|
||||
{renderIcon()}
|
||||
{children != null ? children : <span style={{ color: color }}>{t(`workflow_run.props.status.${value.toLowerCase()}`)}</span>}
|
||||
</div>
|
||||
</Typography.Text>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<Typography.Text className={className} style={style}>
|
||||
<div className="flex items-center gap-2">{children != null ? children : <></>}</div>
|
||||
</Typography.Text>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const _default = Object.assign(WorkflowStatus, {
|
||||
Icon: WorkflowStatusIcon,
|
||||
});
|
||||
|
||||
export default _default;
|
||||
@ -1,78 +0,0 @@
|
||||
import { IconCircleCheck, IconCircleDashed, IconCircleOff, IconCircleX, IconClock, IconLoader3 } from "@tabler/icons-react";
|
||||
import { theme } from "antd";
|
||||
|
||||
import { WORKFLOW_RUN_STATUSES } from "@/domain/workflowRun";
|
||||
import { mergeCls } from "@/utils/css";
|
||||
|
||||
export interface WorkflowStatusIconProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
color?: string | true;
|
||||
size?: number | string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
const WorkflowStatusIcon = ({ className, style, color, status, ...props }: WorkflowStatusIconProps) => {
|
||||
const { size = "1em" } = props;
|
||||
|
||||
const { token: themeToken } = theme.useToken();
|
||||
|
||||
switch (status) {
|
||||
case WORKFLOW_RUN_STATUSES.PENDING:
|
||||
if (color === true) {
|
||||
color = themeToken.colorTextSecondary;
|
||||
}
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
<IconClock color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.RUNNING:
|
||||
if (color === true) {
|
||||
color = themeToken.colorInfo;
|
||||
}
|
||||
return (
|
||||
<span className={mergeCls("anticon", "animate-spin", className)} style={style} role="img">
|
||||
<IconLoader3 color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.SUCCEEDED:
|
||||
if (color === true) {
|
||||
color = themeToken.colorSuccess;
|
||||
}
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
<IconCircleCheck color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.FAILED:
|
||||
if (color === true) {
|
||||
color = themeToken.colorError;
|
||||
}
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
<IconCircleX color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.CANCELED:
|
||||
if (color === true) {
|
||||
color = themeToken.colorWarning;
|
||||
}
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
<IconCircleOff color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
default:
|
||||
if (color === true) {
|
||||
color = themeToken.colorTextSecondary;
|
||||
}
|
||||
return (
|
||||
<span className={mergeCls("anticon", className)} style={style} role="img">
|
||||
<IconCircleDashed color={color} size={size} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default WorkflowStatusIcon;
|
||||
@ -1,55 +0,0 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Tag } from "antd";
|
||||
|
||||
import { WORKFLOW_RUN_STATUSES } from "@/domain/workflowRun";
|
||||
|
||||
import WorkflowStatusIcon from "./WorkflowStatusIcon";
|
||||
|
||||
export interface WorkflowStatusTagProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
status: string;
|
||||
}
|
||||
|
||||
const WorkflowStatusTag = ({ className, style, status }: WorkflowStatusTagProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const Icon = <WorkflowStatusIcon status={status} />;
|
||||
|
||||
switch (status) {
|
||||
case WORKFLOW_RUN_STATUSES.PENDING:
|
||||
return (
|
||||
<Tag className={className} style={style} icon={Icon}>
|
||||
{t("workflow_run.props.status.pending")}
|
||||
</Tag>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.RUNNING:
|
||||
return (
|
||||
<Tag className={className} style={style} color="var(--color-info)" icon={Icon}>
|
||||
{t("workflow_run.props.status.running")}
|
||||
</Tag>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.SUCCEEDED:
|
||||
return (
|
||||
<Tag className={className} style={style} color="var(--color-success)" icon={Icon}>
|
||||
{t("workflow_run.props.status.succeeded")}
|
||||
</Tag>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.FAILED:
|
||||
return (
|
||||
<Tag className={className} style={style} color="var(--color-error)" icon={Icon}>
|
||||
{t("workflow_run.props.status.failed")}
|
||||
</Tag>
|
||||
);
|
||||
case WORKFLOW_RUN_STATUSES.CANCELED:
|
||||
return (
|
||||
<Tag className={className} style={style} color="var(--color-warning)" icon={Icon}>
|
||||
{t("workflow_run.props.status.canceled")}
|
||||
</Tag>
|
||||
);
|
||||
default:
|
||||
return <></>;
|
||||
}
|
||||
};
|
||||
|
||||
export default WorkflowStatusTag;
|
||||
@ -14,14 +14,14 @@ import { createMinimapPlugin } from "@flowgram.ai/minimap-plugin";
|
||||
import "@flowgram.ai/fixed-layout-editor/index.css";
|
||||
import { theme } from "antd";
|
||||
|
||||
import { getFlowComponents } from "./components";
|
||||
import { EditorContextProvider } from "./EditorContext";
|
||||
import { DegisnerContextProvider } from "./DesignerContext";
|
||||
import { getAllElements } from "./elements";
|
||||
import NodeRender from "./NodeRender";
|
||||
import { getFlowNodeRegistries } from "./nodes";
|
||||
import { getAllNodeRegistries } from "./nodes";
|
||||
import { BranchNode } from "./nodes/_shared";
|
||||
import "./flowgram.css";
|
||||
|
||||
export interface EditorProps {
|
||||
export interface DesignerProps {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
children?: React.ReactNode;
|
||||
@ -30,12 +30,12 @@ export interface EditorProps {
|
||||
onNodeClick?: (ctx: FixedLayoutPluginContext, node: FlowNodeEntity) => void;
|
||||
}
|
||||
|
||||
export interface EditorInstance extends FixedLayoutPluginContext {
|
||||
export interface DesignerInstance extends FixedLayoutPluginContext {
|
||||
validateNode(node: string | FlowNodeEntity): Promise<boolean>;
|
||||
validateAllNodes(): Promise<boolean>;
|
||||
}
|
||||
|
||||
const Editor = forwardRef<EditorInstance, EditorProps>(({ className, style, children, initialData, readonly, onNodeClick }, ref) => {
|
||||
const Designer = forwardRef<DesignerInstance, DesignerProps>(({ className, style, children, initialData, readonly, onNodeClick }, ref) => {
|
||||
const { token: themeToken } = theme.useToken();
|
||||
|
||||
const flowgramEditorRef = useRef<FixedLayoutPluginContext>(null);
|
||||
@ -80,16 +80,16 @@ const Editor = forwardRef<EditorInstance, EditorProps>(({ className, style, chil
|
||||
},
|
||||
|
||||
materials: {
|
||||
components: getFlowComponents(),
|
||||
components: getAllElements(),
|
||||
renderTexts: {
|
||||
[FlowTextKey.TRY_START_TEXT]: "Try",
|
||||
[FlowTextKey.TRY_END_TEXT]: "Finally",
|
||||
[FlowTextKey.TRY_END_TEXT]: "Then",
|
||||
[FlowTextKey.CATCH_TEXT]: "Catch",
|
||||
},
|
||||
renderDefaultNode: NodeRender,
|
||||
},
|
||||
|
||||
nodeRegistries: getFlowNodeRegistries(),
|
||||
nodeRegistries: getAllNodeRegistries(),
|
||||
|
||||
getNodeDefaultRegistry(type) {
|
||||
return {
|
||||
@ -172,12 +172,12 @@ const Editor = forwardRef<EditorInstance, EditorProps>(({ className, style, chil
|
||||
|
||||
return (
|
||||
<FixedLayoutEditorProvider ref={flowgramEditorRef} {...flowgramEditorProps}>
|
||||
<EditorContextProvider value={{ onNodeClick: (node) => onNodeClick?.(flowgramEditorRef.current!, node) }}>
|
||||
<DegisnerContextProvider value={{ onNodeClick: (node) => onNodeClick?.(flowgramEditorRef.current!, node) }}>
|
||||
<EditorRenderer className={className} style={style} />
|
||||
{children}
|
||||
</EditorContextProvider>
|
||||
</DegisnerContextProvider>
|
||||
</FixedLayoutEditorProvider>
|
||||
);
|
||||
});
|
||||
|
||||
export default Editor;
|
||||
export default Designer;
|
||||
20
ui/src/components/workflow/designer/DesignerContext.ts
Normal file
20
ui/src/components/workflow/designer/DesignerContext.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { createContext, useContext } from "react";
|
||||
import { type FlowNodeEntity } from "@flowgram.ai/fixed-layout-editor";
|
||||
|
||||
export type DesignerContextType = {
|
||||
onNodeClick: (node: FlowNodeEntity) => void;
|
||||
};
|
||||
|
||||
export const DesignerContext = createContext<DesignerContextType>({
|
||||
onNodeClick: () => {},
|
||||
});
|
||||
|
||||
export const DegisnerContextProvider = DesignerContext.Provider;
|
||||
|
||||
export const useDesignerContext = () => {
|
||||
const context = useContext(DesignerContext);
|
||||
if (!context) {
|
||||
throw new Error("`DesignerContext` must be used within a `DesignerContextProvider`");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@ -1,20 +0,0 @@
|
||||
import { createContext, useContext } from "react";
|
||||
import { type FlowNodeEntity } from "@flowgram.ai/fixed-layout-editor";
|
||||
|
||||
export type NodeRenderContextType = {
|
||||
onNodeClick: (node: FlowNodeEntity) => void;
|
||||
};
|
||||
|
||||
export const EditorContext = createContext<NodeRenderContextType>({
|
||||
onNodeClick: () => {},
|
||||
});
|
||||
|
||||
export const EditorContextProvider = EditorContext.Provider;
|
||||
|
||||
export const useEditorContext = () => {
|
||||
const context = useContext(EditorContext);
|
||||
if (!context) {
|
||||
throw new Error("`EditorContext` must be used within a `EditorContextProvider`");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@ -22,9 +22,7 @@ export interface NodeDrawerProps {
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
const NodeDrawer = (_: NodeDrawerProps) => {
|
||||
const { node, trigger, ...props } = _;
|
||||
|
||||
const NodeDrawer = ({ node, trigger, ...props }: NodeDrawerProps) => {
|
||||
const [open, setOpen] = useControllableValue<boolean>(props, {
|
||||
valuePropName: "open",
|
||||
defaultValuePropName: "defaultOpen",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { type NodeRenderProps, useClientContext, useNodeRender, useRefresh } from "@flowgram.ai/fixed-layout-editor";
|
||||
|
||||
import { useEditorContext } from "./EditorContext";
|
||||
import { useDesignerContext } from "./DesignerContext";
|
||||
import { NodeRenderContextProvider } from "./NodeRenderContext";
|
||||
import { type NodeRegistry } from "./nodes/typings";
|
||||
|
||||
@ -14,6 +14,8 @@ const Node = (_: NodeProps) => {
|
||||
|
||||
const nodeRender = useNodeRender();
|
||||
|
||||
const designer = useDesignerContext();
|
||||
|
||||
useEffect(() => {
|
||||
const d = ctx.document.originTree.onTreeChange(() => refresh());
|
||||
return () => d.dispose();
|
||||
@ -28,11 +30,10 @@ const Node = (_: NodeProps) => {
|
||||
};
|
||||
}, [nodeRender.form]);
|
||||
|
||||
const { onNodeClick } = useEditorContext();
|
||||
const handleNodeClick = () => {
|
||||
const node = nodeRender.node;
|
||||
if (node.getNodeRegistry<NodeRegistry>().meta?.clickable) {
|
||||
onNodeClick?.(node);
|
||||
designer.onNodeClick?.(node);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
import { type AdderProps as FlowgramAdderProps, useClientContext } from "@flowgram.ai/fixed-layout-editor";
|
||||
|
||||
import { IconPlus } from "@tabler/icons-react";
|
||||
import { Button, Dropdown } from "antd";
|
||||
|
||||
import { getFlowNodeRegistries } from "../nodes";
|
||||
|
||||
export interface AdderProps extends FlowgramAdderProps {}
|
||||
|
||||
const Adder = ({ from, hoverActivated }: AdderProps) => {
|
||||
const ctx = useClientContext();
|
||||
const { operation, playground } = ctx;
|
||||
|
||||
const menuItems = getFlowNodeRegistries()
|
||||
.filter((registry) => {
|
||||
if (registry.meta?.addDisable != null) {
|
||||
return !registry.meta.addDisable;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.filter((registry) => {
|
||||
if (registry.canAdd != null) {
|
||||
return registry.canAdd(ctx, from);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((registry) => {
|
||||
const Icon = registry.meta?.icon;
|
||||
|
||||
return {
|
||||
key: registry.type,
|
||||
label: registry.meta?.labelText ?? registry.type,
|
||||
icon: <span className="anticon scale-125">{Icon && <Icon size="1em" />}</span>,
|
||||
onClick: () => {
|
||||
const block = operation.addFromNode(from, registry.onAdd!(ctx, from));
|
||||
|
||||
setTimeout(() => {
|
||||
playground.scrollToView({
|
||||
bounds: block.bounds,
|
||||
scrollToCenter: true,
|
||||
});
|
||||
}, 1);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return playground.config.readonlyOrDisabled ? null : (
|
||||
<div className="relative">
|
||||
<Dropdown menu={{ items: menuItems }} placement="bottomRight" trigger={["click"]}>
|
||||
{hoverActivated ? (
|
||||
<Button icon={<IconPlus size="1em" stroke={3} />} shape="circle" size="small" type="primary" />
|
||||
) : (
|
||||
<div className="size-2 rounded-full bg-primary opacity-75"></div>
|
||||
)}
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Adder;
|
||||
82
ui/src/components/workflow/designer/elements/Adder.tsx
Normal file
82
ui/src/components/workflow/designer/elements/Adder.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { type AdderProps as FlowgramAdderProps, useClientContext } from "@flowgram.ai/fixed-layout-editor";
|
||||
|
||||
import { IconPlus } from "@tabler/icons-react";
|
||||
import { Button, Dropdown, type MenuProps } from "antd";
|
||||
|
||||
import { getAllNodeRegistries } from "../nodes";
|
||||
|
||||
export interface AdderProps extends FlowgramAdderProps {}
|
||||
|
||||
const Adder = ({ from, hoverActivated }: AdderProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const ctx = useClientContext();
|
||||
const { operation, playground } = ctx;
|
||||
|
||||
const [menuOpen, setMenuOpen] = useState(false); // 使用受控组件,避免下拉菜单展开时鼠标移出而产生的布局抖动
|
||||
const menuItems = getAllNodeRegistries()
|
||||
.filter((registry) => {
|
||||
if (registry.meta?.addDisable != null) {
|
||||
return !registry.meta.addDisable;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.filter((registry) => {
|
||||
if (registry.canAdd != null) {
|
||||
return registry.canAdd(ctx, from);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.reduce(
|
||||
(acc, registry) => {
|
||||
let group = acc.find((item) => item!.key === registry.kindType);
|
||||
if (!group) {
|
||||
group = {
|
||||
key: registry.kindType,
|
||||
type: "group",
|
||||
label: registry.kindType ? t(`workflow_node.kind.${registry.kindType}`) : null,
|
||||
children: [],
|
||||
};
|
||||
acc.push(group);
|
||||
}
|
||||
|
||||
if (group.type === "group") {
|
||||
const NodeIcon = registry.meta?.icon;
|
||||
group.children!.push({
|
||||
key: registry.type,
|
||||
label: registry.meta?.labelText ?? registry.type,
|
||||
icon: <span className="anticon scale-125">{NodeIcon && <NodeIcon size="1em" />}</span>,
|
||||
onClick: () => {
|
||||
const block = operation.addFromNode(from, registry.onAdd!(ctx, from));
|
||||
|
||||
setTimeout(() => {
|
||||
playground.scrollToView({
|
||||
bounds: block.bounds,
|
||||
scrollToCenter: true,
|
||||
});
|
||||
}, 1);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
[] as Required<MenuProps>["items"]
|
||||
);
|
||||
|
||||
return playground.config.readonlyOrDisabled ? null : (
|
||||
<div className="relative">
|
||||
<Dropdown menu={{ items: menuItems }} placement="bottomRight" trigger={["click"]} open={menuOpen} onOpenChange={setMenuOpen}>
|
||||
{hoverActivated || menuOpen ? (
|
||||
<Button icon={<IconPlus size="1em" stroke={3} />} shape="circle" size="small" type="primary" />
|
||||
) : (
|
||||
<div className="size-2 rounded-full bg-primary opacity-75"></div>
|
||||
)}
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Adder;
|
||||
@ -9,7 +9,7 @@ import DragNode from "./DragNode";
|
||||
import Null from "./Null";
|
||||
import TryCatchCollapse from "./TryCatchCollapse";
|
||||
|
||||
export const getFlowComponents = () => {
|
||||
export const getAllElements = () => {
|
||||
return {
|
||||
[FlowRendererKey.ADDER]: Adder,
|
||||
[FlowRendererKey.BRANCH_ADDER]: BranchAdder,
|
||||
@ -13,8 +13,7 @@ export interface BizApplyNodeConfigDrawerProps {
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
const BizApplyNodeConfigDrawer = (_: BizApplyNodeConfigDrawerProps) => {
|
||||
const { node, ...props } = _;
|
||||
const BizApplyNodeConfigDrawer = ({ node, ...props }: BizApplyNodeConfigDrawerProps) => {
|
||||
if (node.flowNodeType !== NodeType.BizApply) {
|
||||
console.warn(`[certimate] current workflow node type is not: ${NodeType.BizApply}`);
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import { memo, useEffect, useMemo, useState } from "react";
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
import { QuestionCircleOutlined as IconQuestionCircleOutlined } from "@ant-design/icons";
|
||||
import { type FlowNodeEntity, getNodeForm } from "@flowgram.ai/fixed-layout-editor";
|
||||
import { IconChevronRight, IconCircleMinus, IconPlus } from "@tabler/icons-react";
|
||||
import { useControllableValue } from "ahooks";
|
||||
import { type AnchorProps, AutoComplete, Button, Divider, Flex, Form, type FormInstance, Input, InputNumber, Select, Switch, Tooltip, Typography } from "antd";
|
||||
import { type AnchorProps, AutoComplete, Button, Divider, Flex, Form, type FormInstance, Input, InputNumber, Select, Switch, Typography } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
@ -150,12 +149,7 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
<NodeFormContextProvider value={{ node }}>
|
||||
<Form {...formProps} clearOnDestroy={true} form={formInst} layout="vertical" preserve={false} scrollToFirstError>
|
||||
<div id="parameters" data-anchor="parameters">
|
||||
<Form.Item
|
||||
name="domains"
|
||||
label={t("workflow_node.apply.form.domains.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.domains.tooltip") }}></span>}
|
||||
>
|
||||
<Form.Item name="domains" label={t("workflow_node.apply.form.domains.label")} extra={t("workflow_node.apply.form.domains.help")} rules={[formRule]}>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.apply.form.domains.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.apply.form.domains.placeholder")}
|
||||
@ -171,7 +165,7 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.contact_email.tooltip") }}></span>}
|
||||
>
|
||||
<EmailInput placeholder={t("workflow_node.apply.form.contact_email.placeholder")} />
|
||||
<InternalEmailInput placeholder={t("workflow_node.apply.form.contact_email.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="challengeType" label={t("workflow_node.apply.form.challenge_type.label")} rules={[formRule]} hidden>
|
||||
@ -200,39 +194,31 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item noStyle>
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("workflow_node.apply.form.provider_access.label")}</span>
|
||||
<Tooltip title={t("workflow_node.apply.form.provider_access.tooltip")}>
|
||||
<Typography.Text className="ms-1" type="secondary">
|
||||
<IconQuestionCircleOutlined />
|
||||
</Typography.Text>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<AccessEditDrawer
|
||||
mode="create"
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.apply.form.provider_access.button")}
|
||||
<IconPlus size="1.25em" />
|
||||
</Button>
|
||||
}
|
||||
usage="dns"
|
||||
afterSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (provider?.usages?.includes(ACCESS_USAGES.DNS)) {
|
||||
formInst.setFieldValue("providerAccessId", record.id);
|
||||
handleProviderAccessSelect(record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="providerAccessId" rules={[formRule]}>
|
||||
<Form.Item
|
||||
className="relative"
|
||||
label={t("workflow_node.apply.form.provider_access.label")}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.provider_access.tooltip") }}></span>}
|
||||
>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<AccessEditDrawer
|
||||
mode="create"
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.apply.form.provider_access.button")}
|
||||
<IconPlus size="1.25em" />
|
||||
</Button>
|
||||
}
|
||||
usage="dns"
|
||||
afterSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (provider?.usages?.includes(ACCESS_USAGES.DNS)) {
|
||||
formInst.setFieldValue("providerAccessId", record.id);
|
||||
handleProviderAccessSelect(record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Form.Item name="providerAccessId" rules={[formRule]} noStyle>
|
||||
<AccessSelect
|
||||
placeholder={t("workflow_node.apply.form.provider_access.placeholder")}
|
||||
showSearch
|
||||
@ -259,25 +245,18 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
</Typography.Text>
|
||||
</Divider>
|
||||
|
||||
<Form.Item noStyle>
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("workflow_node.apply.form.ca_provider.label")}</span>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<Show when={!fieldCAProvider}>
|
||||
<Link className="ant-typography" to="/settings/ssl-provider" target="_blank">
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.apply.form.ca_provider.button")}
|
||||
<IconChevronRight size="1.25em" />
|
||||
</Button>
|
||||
</Link>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="caProvider" rules={[formRule]}>
|
||||
<Form.Item className="relative" label={t("workflow_node.apply.form.ca_provider.label")}>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<Show when={!fieldCAProvider}>
|
||||
<Link className="ant-typography" to="/settings/ssl-provider" target="_blank">
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.apply.form.ca_provider.button")}
|
||||
<IconChevronRight size="1.25em" />
|
||||
</Button>
|
||||
</Link>
|
||||
</Show>
|
||||
</div>
|
||||
<Form.Item name="caProvider" noStyle rules={[formRule]}>
|
||||
<CAProviderSelect
|
||||
allowClear
|
||||
placeholder={t("workflow_node.apply.form.ca_provider.placeholder")}
|
||||
@ -288,34 +267,27 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item hidden={!showCAProviderAccess} noStyle>
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("workflow_node.apply.form.ca_provider_access.label")}</span>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<AccessEditDrawer
|
||||
data={{ provider: caProvidersMap.get(fieldCAProvider!)?.provider }}
|
||||
mode="create"
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.apply.form.ca_provider_access.button")}
|
||||
<IconChevronRight size="1.25em" />
|
||||
</Button>
|
||||
}
|
||||
usage="ca"
|
||||
afterSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (provider?.usages?.includes(ACCESS_USAGES.CA)) {
|
||||
formInst.setFieldValue("caProviderAccessId", record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="caProviderAccessId" rules={[formRule]}>
|
||||
<Form.Item label={t("workflow_node.apply.form.ca_provider_access.label")} hidden={!showCAProviderAccess}>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<AccessEditDrawer
|
||||
data={{ provider: caProvidersMap.get(fieldCAProvider!)?.provider }}
|
||||
mode="create"
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.apply.form.ca_provider_access.button")}
|
||||
<IconChevronRight size="1.25em" />
|
||||
</Button>
|
||||
}
|
||||
usage="ca"
|
||||
afterSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (provider?.usages?.includes(ACCESS_USAGES.CA)) {
|
||||
formInst.setFieldValue("caProviderAccessId", record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Form.Item name="caProviderAccessId" noStyle rules={[formRule]}>
|
||||
<AccessSelect
|
||||
placeholder={t("workflow_node.apply.form.ca_provider_access.placeholder")}
|
||||
showSearch
|
||||
@ -412,6 +384,7 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
<Form.Item
|
||||
name="dnsTTL"
|
||||
label={t("workflow_node.apply.form.dns_ttl.label")}
|
||||
extra={t("workflow_node.apply.form.dns_ttl.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.dns_ttl.tooltip") }}></span>}
|
||||
>
|
||||
@ -475,11 +448,11 @@ const BizApplyNodeConfigForm = ({ node, ...props }: BizApplyNodeConfigFormProps)
|
||||
);
|
||||
};
|
||||
|
||||
const EmailInput = memo(
|
||||
const InternalEmailInput = memo(
|
||||
({ disabled, placeholder, ...props }: { disabled?: boolean; placeholder?: string; value?: string; onChange?: (value: string) => void }) => {
|
||||
const { emails, fetchEmails, removeEmail } = useContactEmailsStore();
|
||||
useEffect(() => {
|
||||
fetchEmails();
|
||||
fetchEmails(false);
|
||||
}, []);
|
||||
|
||||
const [value, setValue] = useControllableValue<string>(props, {
|
||||
@ -550,7 +523,7 @@ const EmailInput = memo(
|
||||
}
|
||||
);
|
||||
|
||||
const getAnchorItems = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }): Required<AnchorProps>["items"] => {
|
||||
const getAnchorItems = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }): Required<AnchorProps>["items"] => {
|
||||
const { t } = i18n;
|
||||
|
||||
return ["parameters", "certificate", "advanced", "strategy"].map((key) => ({
|
||||
@ -569,7 +542,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -47,7 +47,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -36,7 +36,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -36,7 +36,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -36,7 +36,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -36,7 +36,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -13,8 +13,7 @@ export interface BizDeployNodeConfigDrawerProps {
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
const BizDeployNodeConfigDrawer = (_: BizDeployNodeConfigDrawerProps) => {
|
||||
const { node, ...props } = _;
|
||||
const BizDeployNodeConfigDrawer = ({ node, ...props }: BizDeployNodeConfigDrawerProps) => {
|
||||
if (node.flowNodeType !== NodeType.BizDeploy) {
|
||||
console.warn(`[certimate] current workflow node type is not: ${NodeType.BizDeploy}`);
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { QuestionCircleOutlined as IconQuestionCircleOutlined } from "@ant-design/icons";
|
||||
import { type FlowNodeEntity, getNodeForm } from "@flowgram.ai/fixed-layout-editor";
|
||||
import { IconPlus } from "@tabler/icons-react";
|
||||
import { type AnchorProps, Button, Divider, Flex, Form, type FormInstance, Select, Switch, Tooltip, Typography, theme } from "antd";
|
||||
import { type AnchorProps, Button, Divider, Flex, Form, type FormInstance, Select, Switch, Typography, theme } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
@ -415,39 +414,32 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item hidden={!showProviderAccess} noStyle>
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("workflow_node.deploy.form.provider_access.label")}</span>
|
||||
<Tooltip title={t("workflow_node.deploy.form.provider_access.tooltip")}>
|
||||
<Typography.Text className="ms-1" type="secondary">
|
||||
<IconQuestionCircleOutlined />
|
||||
</Typography.Text>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<AccessEditDrawer
|
||||
data={{ provider: deploymentProvidersMap.get(fieldProvider!)?.provider }}
|
||||
mode="create"
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.deploy.form.provider_access.button")}
|
||||
<IconPlus size="1.25em" />
|
||||
</Button>
|
||||
}
|
||||
usage="hosting"
|
||||
afterSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (provider?.usages?.includes(ACCESS_USAGES.HOSTING)) {
|
||||
formInst.setFieldValue("providerAccessId", record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="providerAccessId" rules={[formRule]}>
|
||||
<Form.Item
|
||||
className="relative"
|
||||
hidden={!showProviderAccess}
|
||||
label={t("workflow_node.deploy.form.provider_access.label")}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.provider_access.tooltip") }}></span>}
|
||||
>
|
||||
<div className="absolute -top-[6px] right-0 -translate-y-full">
|
||||
<AccessEditDrawer
|
||||
data={{ provider: deploymentProvidersMap.get(fieldProvider!)?.provider }}
|
||||
mode="create"
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.deploy.form.provider_access.button")}
|
||||
<IconPlus size="1.25em" />
|
||||
</Button>
|
||||
}
|
||||
usage="hosting"
|
||||
afterSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (provider?.usages?.includes(ACCESS_USAGES.HOSTING)) {
|
||||
formInst.setFieldValue("providerAccessId", record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Form.Item name="providerAccessId" rules={[formRule]} noStyle>
|
||||
<AccessSelect
|
||||
placeholder={t("workflow_node.deploy.form.provider_access.placeholder")}
|
||||
showSearch
|
||||
@ -465,8 +457,8 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp
|
||||
<Form.Item
|
||||
name="certificate"
|
||||
label={t("workflow_node.deploy.form.certificate.label")}
|
||||
extra={t("workflow_node.deploy.form.certificate.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.certificate.tooltip") }}></span>}
|
||||
>
|
||||
<Select
|
||||
labelRender={({ label, value }) => {
|
||||
@ -525,7 +517,7 @@ const BizDeployNodeConfigForm = ({ node, ...props }: BizDeployNodeConfigFormProp
|
||||
);
|
||||
};
|
||||
|
||||
const getAnchorItems = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }): Required<AnchorProps>["items"] => {
|
||||
const getAnchorItems = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }): Required<AnchorProps>["items"] => {
|
||||
const { t } = i18n;
|
||||
|
||||
return ["parameters", "deployment", "strategy"].map((key) => ({
|
||||
@ -543,7 +535,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -35,7 +35,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t: _ } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -29,6 +29,7 @@ const BizDeployNodeConfigFormProvider1PanelSite = () => {
|
||||
name={[parentNamePath, "nodeName"]}
|
||||
initialValue={initialValues.nodeName}
|
||||
label={t("workflow_node.deploy.form.1panel_site_node_name.label")}
|
||||
extra={t("workflow_node.deploy.form.1panel_site_node_name.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.1panel_site_node_name.tooltip") }}></span>}
|
||||
>
|
||||
@ -84,7 +85,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -58,7 +58,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -31,8 +31,8 @@ const BizDeployNodeConfigFormProviderAWSACM = () => {
|
||||
name={[parentNamePath, "certificateArn"]}
|
||||
initialValue={initialValues.certificateArn}
|
||||
label={t("workflow_node.deploy.form.aws_acm_certificate_arn.label")}
|
||||
extra={t("workflow_node.deploy.form.aws_acm_certificate_arn.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aws_acm_certificate_arn.tooltip") }}></span>}
|
||||
>
|
||||
<Input allowClear placeholder={t("workflow_node.deploy.form.aws_acm_certificate_arn.placeholder")} />
|
||||
</Form.Item>
|
||||
@ -46,7 +46,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -62,7 +62,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -47,7 +47,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -81,6 +81,7 @@ const BizDeployNodeConfigFormProviderAliyunALB = () => {
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.aliyun_alb_snidomain.label")}
|
||||
extra={t("workflow_node.deploy.form.aliyun_alb_snidomain.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_alb_snidomain.tooltip") }}></span>}
|
||||
>
|
||||
@ -98,7 +99,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -95,7 +95,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -36,7 +36,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { getI18n, useTranslation } from "react-i18next";
|
||||
import { Alert, Form, Input } from "antd";
|
||||
import { Form, Input } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import MultipleSplitValueInput from "@/components/MultipleSplitValueInput";
|
||||
import Tips from "@/components/Tips";
|
||||
|
||||
import { useFormNestedFieldsContext } from "./_context";
|
||||
|
||||
@ -22,30 +23,31 @@ const BizDeployNodeConfigFormProviderAliyunCASDeploy = () => {
|
||||
return (
|
||||
<>
|
||||
<Form.Item>
|
||||
<Alert type="info" message={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_cas_deploy.guide") }}></span>} />
|
||||
<Tips message={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_casdeploy.guide") }}></span>} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "region"]}
|
||||
initialValue={initialValues.region}
|
||||
label={t("workflow_node.deploy.form.aliyun_cas_deploy_region.label")}
|
||||
label={t("workflow_node.deploy.form.aliyun_casdeploy_region.label")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_cas_deploy_region.tooltip") }}></span>}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_casdeploy_region.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder")} />
|
||||
<Input placeholder={t("workflow_node.deploy.form.aliyun_casdeploy_region.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name={[parentNamePath, "resourceIds"]}
|
||||
initialValue={initialValues.resourceIds}
|
||||
label={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.label")}
|
||||
label={t("workflow_node.deploy.form.aliyun_casdeploy_resource_ids.label")}
|
||||
extra={t("workflow_node.deploy.form.aliyun_casdeploy_resource_ids.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.tooltip") }}></span>}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_casdeploy_resource_ids.tooltip") }}></span>}
|
||||
>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.multiple_input_modal.placeholder")}
|
||||
modalTitle={t("workflow_node.deploy.form.aliyun_casdeploy_resource_ids.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_casdeploy_resource_ids.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.aliyun_casdeploy_resource_ids.multiple_input_modal.placeholder")}
|
||||
separator={MULTIPLE_INPUT_SEPARATOR}
|
||||
splitOptions={{ removeEmpty: true, trimSpace: true }}
|
||||
/>
|
||||
@ -54,14 +56,15 @@ const BizDeployNodeConfigFormProviderAliyunCASDeploy = () => {
|
||||
<Form.Item
|
||||
name={[parentNamePath, "contactIds"]}
|
||||
initialValue={initialValues.contactIds}
|
||||
label={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.label")}
|
||||
label={t("workflow_node.deploy.form.aliyun_casdeploy_contact_ids.label")}
|
||||
extra={t("workflow_node.deploy.form.aliyun_casdeploy_contact_ids.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.tooltip") }}></span>}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_casdeploy_contact_ids.tooltip") }}></span>}
|
||||
>
|
||||
<MultipleSplitValueInput
|
||||
modalTitle={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.multiple_input_modal.placeholder")}
|
||||
modalTitle={t("workflow_node.deploy.form.aliyun_casdeploy_contact_ids.multiple_input_modal.title")}
|
||||
placeholder={t("workflow_node.deploy.form.aliyun_casdeploy_contact_ids.placeholder")}
|
||||
placeholderInModal={t("workflow_node.deploy.form.aliyun_casdeploy_contact_ids.multiple_input_modal.placeholder")}
|
||||
separator={MULTIPLE_INPUT_SEPARATOR}
|
||||
splitOptions={{ removeEmpty: true, trimSpace: true }}
|
||||
/>
|
||||
@ -77,17 +80,17 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
region: z.string().nonempty(t("workflow_node.deploy.form.aliyun_cas_deploy_region.placeholder")),
|
||||
region: z.string().nonempty(t("workflow_node.deploy.form.aliyun_casdeploy_region.placeholder")),
|
||||
resourceIds: z.string().refine((v) => {
|
||||
if (!v) return false;
|
||||
return String(v)
|
||||
.split(MULTIPLE_INPUT_SEPARATOR)
|
||||
.every((e) => /^[1-9]\d*$/.test(e));
|
||||
}, t("workflow_node.deploy.form.aliyun_cas_deploy_resource_ids.errmsg.invalid")),
|
||||
}, t("workflow_node.deploy.form.aliyun_casdeploy_resource_ids.errmsg.invalid")),
|
||||
contactIds: z
|
||||
.string()
|
||||
.nullish()
|
||||
@ -96,7 +99,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) =
|
||||
return String(v)
|
||||
.split(MULTIPLE_INPUT_SEPARATOR)
|
||||
.every((e) => /^[1-9]\d*$/.test(e));
|
||||
}, t("workflow_node.deploy.form.aliyun_cas_deploy_contact_ids.errmsg.invalid")),
|
||||
}, t("workflow_node.deploy.form.aliyun_casdeploy_contact_ids.errmsg.invalid")),
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -79,6 +79,7 @@ const BizDeployNodeConfigFormProviderAliyunCLB = () => {
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.aliyun_clb_snidomain.label")}
|
||||
extra={t("workflow_node.deploy.form.aliyun_clb_snidomain.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_clb_snidomain.tooltip") }}></span>}
|
||||
>
|
||||
@ -98,7 +99,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -49,7 +49,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -47,7 +47,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -66,7 +66,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -69,6 +69,7 @@ const BizDeployNodeConfigFormProviderAliyunGA = () => {
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.aliyun_ga_snidomain.label")}
|
||||
extra={t("workflow_node.deploy.form.aliyun_ga_snidomain.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_ga_snidomain.tooltip") }}></span>}
|
||||
>
|
||||
@ -86,7 +87,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -49,7 +49,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -85,7 +85,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -60,7 +60,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -49,7 +49,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -56,6 +56,7 @@ const BizDeployNodeConfigFormProviderAliyunWAF = () => {
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.aliyun_waf_domain.label")}
|
||||
extra={t("workflow_node.deploy.form.aliyun_waf_domain.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_waf_domain.tooltip") }}></span>}
|
||||
>
|
||||
@ -73,7 +74,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -31,8 +31,8 @@ const BizDeployNodeConfigFormProviderAzureKeyVault = () => {
|
||||
name={[parentNamePath, "certificateName"]}
|
||||
initialValue={initialValues.certificateName}
|
||||
label={t("workflow_node.deploy.form.azure_keyvault_certificate_name.label")}
|
||||
extra={t("workflow_node.deploy.form.azure_keyvault_certificate_name.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.azure_keyvault_certificate_name.tooltip") }}></span>}
|
||||
>
|
||||
<Input placeholder={t("workflow_node.deploy.form.azure_keyvault_certificate_name.placeholder")} />
|
||||
</Form.Item>
|
||||
@ -46,7 +46,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -79,6 +79,7 @@ const BizDeployNodeConfigFormProviderBaiduCloudAppBLB = () => {
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.baiducloud_appblb_snidomain.label")}
|
||||
extra={t("workflow_node.deploy.form.baiducloud_appblb_snidomain.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.baiducloud_appblb_snidomain.tooltip") }}></span>}
|
||||
>
|
||||
@ -98,7 +99,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -79,6 +79,7 @@ const BizDeployNodeConfigFormProviderBaiduCloudBLB = () => {
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.baiducloud_blb_snidomain.label")}
|
||||
extra={t("workflow_node.deploy.form.baiducloud_blb_snidomain.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.baiducloud_blb_snidomain.tooltip") }}></span>}
|
||||
>
|
||||
@ -98,7 +99,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -33,6 +33,7 @@ const BizDeployNodeConfigFormProviderBaishanCDN = () => {
|
||||
name={[parentNamePath, "certificateId"]}
|
||||
initialValue={initialValues.certificateId}
|
||||
label={t("workflow_node.deploy.form.baishan_cdn_certificate_id.label")}
|
||||
extra={t("workflow_node.deploy.form.baishan_cdn_certificate_id.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.baishan_cdn_certificate_id.tooltip") }}></span>}
|
||||
>
|
||||
@ -48,7 +49,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -35,7 +35,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t: _ } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -61,6 +61,7 @@ const BizDeployNodeConfigFormProviderBaotaPanelSite = () => {
|
||||
name={[parentNamePath, "siteNames"]}
|
||||
initialValue={initialValues.siteNames}
|
||||
label={t("workflow_node.deploy.form.baotapanel_site_names.label")}
|
||||
extra={t("workflow_node.deploy.form.baotapanel_site_names.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.baotapanel_site_names.tooltip") }}></span>}
|
||||
>
|
||||
@ -83,7 +84,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -48,7 +48,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -48,7 +48,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -85,7 +85,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -74,7 +74,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -36,7 +36,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -58,7 +58,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -31,6 +31,7 @@ const BizDeployNodeConfigFormProviderGcoreCDN = () => {
|
||||
name={[parentNamePath, "certificateId"]}
|
||||
initialValue={initialValues.certificateId}
|
||||
label={t("workflow_node.deploy.form.gcore_cdn_certificate_id.label")}
|
||||
extra={t("workflow_node.deploy.form.gcore_cdn_certificate_id.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.gcore_cdn_certificate_id.tooltip") }}></span>}
|
||||
>
|
||||
@ -46,7 +47,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -58,7 +58,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -49,7 +49,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -101,7 +101,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -89,7 +89,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -81,6 +81,7 @@ const BizDeployNodeConfigFormProviderJDCloudALB = () => {
|
||||
name={[parentNamePath, "domain"]}
|
||||
initialValue={initialValues.domain}
|
||||
label={t("workflow_node.deploy.form.jdcloud_alb_snidomain.label")}
|
||||
extra={t("workflow_node.deploy.form.jdcloud_alb_snidomain.help")}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.jdcloud_alb_snidomain.tooltip") }}></span>}
|
||||
>
|
||||
@ -98,7 +99,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
@ -38,7 +38,7 @@ const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
|
||||
};
|
||||
};
|
||||
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
|
||||
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
|
||||
const { t } = i18n;
|
||||
|
||||
return z.object({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user