From 4ba723732655d98290049e9eea4f3e5039f9fb22 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 6 Jan 2025 00:44:06 +0800 Subject: [PATCH] feat(ui): close confirm when changes not saved --- ui/.eslintrc.cjs | 6 + ui/src/components/DrawerForm.tsx | 12 +- ui/src/components/access/AccessEditForm.tsx | 4 +- .../notification/NotifyChannelEditForm.tsx | 4 +- .../components/workflow/WorkflowElement.tsx | 4 +- .../components/workflow/WorkflowElements.tsx | 5 +- .../components/workflow/WorkflowProvider.tsx | 7 - .../components/workflow/node/CommonNode.tsx | 213 ++++++++++++------ .../workflow/node/DeployNodeForm.tsx | 5 +- .../workflow/node/StartNodeForm.tsx | 2 + ui/src/components/workflow/panel/Panel.tsx | 41 ---- .../components/workflow/panel/PanelContext.ts | 34 --- .../workflow/panel/PanelProvider.tsx | 90 -------- ui/src/i18n/locales/en/nls.common.json | 1 + ui/src/i18n/locales/en/nls.workflow.json | 2 +- .../i18n/locales/en/nls.workflow.nodes.json | 2 + ui/src/i18n/locales/zh/nls.common.json | 1 + ui/src/i18n/locales/zh/nls.workflow.json | 2 +- .../i18n/locales/zh/nls.workflow.nodes.json | 2 + ui/src/pages/settings/SettingsSSLProvider.tsx | 4 +- ui/src/pages/workflows/WorkflowDetail.tsx | 4 +- ui/src/pages/workflows/WorkflowNew.tsx | 4 +- 22 files changed, 185 insertions(+), 264 deletions(-) delete mode 100644 ui/src/components/workflow/WorkflowProvider.tsx delete mode 100644 ui/src/components/workflow/panel/Panel.tsx delete mode 100644 ui/src/components/workflow/panel/PanelContext.ts delete mode 100644 ui/src/components/workflow/panel/PanelProvider.tsx diff --git a/ui/.eslintrc.cjs b/ui/.eslintrc.cjs index e96e20b7..6bd9b5fd 100644 --- a/ui/.eslintrc.cjs +++ b/ui/.eslintrc.cjs @@ -22,6 +22,12 @@ module.exports = { plugins: ["react-refresh"], rules: { "@typescript-eslint/consistent-type-imports": "error", + "@typescript-eslint/no-empty-object-type": [ + "error", + { + allowInterfaces: "with-single-extends", + }, + ], "@typescript-eslint/no-explicit-any": [ "warn", { diff --git a/ui/src/components/DrawerForm.tsx b/ui/src/components/DrawerForm.tsx index e9197cb0..bfacfd5f 100644 --- a/ui/src/components/DrawerForm.tsx +++ b/ui/src/components/DrawerForm.tsx @@ -71,6 +71,12 @@ const DrawerForm = = any>({ ...props, }; + const handleClose = () => { + if (formPending) return; + + setOpen(false); + }; + const handleOkClick = async () => { const ret = await submit(); if (ret != null && !ret) return; @@ -99,10 +105,10 @@ const DrawerForm = = any>({ footer={ } @@ -110,7 +116,7 @@ const DrawerForm = = any>({ title={title} width={width} {...drawerProps} - onClose={() => setOpen(false)} + onClose={handleClose} >
{children} diff --git a/ui/src/components/access/AccessEditForm.tsx b/ui/src/components/access/AccessEditForm.tsx index 76250932..325b71c3 100644 --- a/ui/src/components/access/AccessEditForm.tsx +++ b/ui/src/components/access/AccessEditForm.tsx @@ -67,7 +67,7 @@ const AccessEditForm = forwardRef(( const configProvider = Form.useWatch("provider", formInst); const [configFormInst] = Form.useForm(); const configFormName = useAntdFormName({ form: configFormInst, name: "accessEditConfigForm" }); - const configFormComponent = useMemo(() => { + const configFormEl = useMemo(() => { /* 注意:如果追加新的子组件,请保持以 ASCII 排序。 NOTICE: If you add new child component, please keep ASCII order. @@ -164,7 +164,7 @@ const AccessEditForm = forwardRef(( - {configFormComponent} + {configFormEl} ); diff --git a/ui/src/components/notification/NotifyChannelEditForm.tsx b/ui/src/components/notification/NotifyChannelEditForm.tsx index 2831e1e1..2fa9b5b3 100644 --- a/ui/src/components/notification/NotifyChannelEditForm.tsx +++ b/ui/src/components/notification/NotifyChannelEditForm.tsx @@ -36,7 +36,7 @@ const NotifyChannelEditForm = forwardRef { + const formFieldsEl = useMemo(() => { /* 注意:如果追加新的子组件,请保持以 ASCII 排序。 NOTICE: If you add new child component, please keep ASCII order. @@ -90,7 +90,7 @@ const NotifyChannelEditForm = forwardRef - {formFieldsComponent} + {formFieldsEl} ); } diff --git a/ui/src/components/workflow/WorkflowElement.tsx b/ui/src/components/workflow/WorkflowElement.tsx index 595ee4ce..4ec94e1e 100644 --- a/ui/src/components/workflow/WorkflowElement.tsx +++ b/ui/src/components/workflow/WorkflowElement.tsx @@ -15,7 +15,7 @@ export type WorkflowElementProps = { }; const WorkflowElement = ({ node, disabled, ...props }: WorkflowElementProps) => { - const nodeComponent = useMemo(() => { + const workflowNodeEl = useMemo(() => { switch (node.type) { case WorkflowNodeType.Start: case WorkflowNodeType.Apply: @@ -38,7 +38,7 @@ const WorkflowElement = ({ node, disabled, ...props }: WorkflowElementProps) => } }, [node, disabled, props]); - return <>{nodeComponent}; + return <>{workflowNodeEl}; }; export default memo(WorkflowElement); diff --git a/ui/src/components/workflow/WorkflowElements.tsx b/ui/src/components/workflow/WorkflowElements.tsx index 891ca507..3969b7fb 100644 --- a/ui/src/components/workflow/WorkflowElements.tsx +++ b/ui/src/components/workflow/WorkflowElements.tsx @@ -1,7 +1,6 @@ import { useMemo } from "react"; import WorkflowElement from "@/components/workflow/WorkflowElement"; -import WorkflowProvider from "@/components/workflow/WorkflowProvider"; import { type WorkflowNode, WorkflowNodeType, newNode } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; @@ -31,9 +30,7 @@ const WorkflowElements = ({ className, style, disabled }: WorkflowElementsProps) return (
-
- {elements} -
+
{elements}
); }; diff --git a/ui/src/components/workflow/WorkflowProvider.tsx b/ui/src/components/workflow/WorkflowProvider.tsx deleted file mode 100644 index 1b341f06..00000000 --- a/ui/src/components/workflow/WorkflowProvider.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { PanelProvider } from "./panel/PanelProvider"; - -const WorkflowProvider = ({ children }: { children: React.ReactNode }) => { - return {children}; -}; - -export default WorkflowProvider; diff --git a/ui/src/components/workflow/node/CommonNode.tsx b/ui/src/components/workflow/node/CommonNode.tsx index 35c485ec..76bf097c 100644 --- a/ui/src/components/workflow/node/CommonNode.tsx +++ b/ui/src/components/workflow/node/CommonNode.tsx @@ -1,8 +1,10 @@ -import { memo, useMemo } from "react"; +import { memo, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { CloseCircleOutlined as CloseCircleOutlinedIcon, EllipsisOutlined as EllipsisOutlinedIcon } from "@ant-design/icons"; -import { Avatar, Button, Card, Dropdown, Popover, Space, Typography } from "antd"; +import { useControllableValue } from "ahooks"; +import { Avatar, Button, Card, Drawer, Dropdown, Modal, Popover, Space, Typography } from "antd"; import { produce } from "immer"; +import { isEqual } from "radash"; import Show from "@/components/Show"; import { deployProvidersMap } from "@/domain/provider"; @@ -26,7 +28,6 @@ import ApplyNodeForm from "./ApplyNodeForm"; import DeployNodeForm from "./DeployNodeForm"; import NotifyNodeForm from "./NotifyNodeForm"; import StartNodeForm from "./StartNodeForm"; -import { usePanelContext } from "../panel/PanelContext"; export type CommonNodeProps = { node: WorkflowNode; @@ -36,42 +37,11 @@ export type CommonNodeProps = { const CommonNode = ({ node, disabled }: CommonNodeProps) => { const { t } = useTranslation(); - const { accesses } = useAccessesStore(useZustandShallowSelector("accesses")); - const { addEmail } = useContactEmailsStore(useZustandShallowSelector(["addEmail"])); const { updateNode, removeNode } = useWorkflowStore(useZustandShallowSelector(["updateNode", "removeNode"])); - const { confirm: confirmPanel } = usePanelContext(); - const { - form: formInst, - formPending, - formProps, - submit: submitForm, - } = useAntdForm({ - name: "workflowNodeForm", - onSubmit: async (values) => { - if (node.type === WorkflowNodeType.Apply) { - await addEmail(values.contactEmail); - await updateNode( - produce(node, (draft) => { - draft.config = { - provider: accesses.find((e) => e.id === values.providerAccessId)?.provider, - ...values, - }; - draft.validated = true; - }) - ); - } else { - await updateNode( - produce(node, (draft) => { - draft.config = { ...values }; - draft.validated = true; - }) - ); - } - }, - }); + const [drawerOpen, setDrawerOpen] = useState(false); - const nodeContentComponent = useMemo(() => { + const workflowNodeEl = useMemo(() => { if (!node.validated) { return {t("workflow_node.action.configure_node")}; } @@ -131,38 +101,8 @@ const CommonNode = ({ node, disabled }: CommonNodeProps) => { } }, [node]); - const panelBodyComponent = useMemo(() => { - const nodeFormProps = { - form: formInst, - formName: formProps.name, - disabled: disabled || formPending, - workflowNode: node, - }; - - switch (node.type) { - case WorkflowNodeType.Start: - return ; - case WorkflowNodeType.Apply: - return ; - case WorkflowNodeType.Deploy: - return ; - case WorkflowNodeType.Notify: - return ; - default: - console.warn(`[certimate] unsupported workflow node type: ${node.type}`); - return <> ; - } - }, [node, disabled, formInst, formPending, formProps]); - const handleNodeClick = () => { - confirmPanel({ - title: node.name, - children: panelBodyComponent, - okText: t("common.button.save"), - onOk: () => { - return submitForm(); - }, - }); + setDrawerOpen(true); }; const handleNodeNameBlur = (e: React.FocusEvent) => { @@ -226,13 +166,150 @@ const CommonNode = ({ node, disabled }: CommonNodeProps) => {
- {nodeContentComponent} + {workflowNodeEl}
+ + setDrawerOpen(open)} /> + + ); +}; + +type CommonNodeEditDrawerProps = CommonNodeProps & { + defaultOpen?: boolean; + open?: boolean; + onOpenChange?: (open: boolean) => void; +}; + +const CommonNodeEditDrawer = ({ node, disabled, ...props }: CommonNodeEditDrawerProps) => { + const { t } = useTranslation(); + + const [modalApi, ModelContextHolder] = Modal.useModal(); + + const [open, setOpen] = useControllableValue(props, { + valuePropName: "open", + defaultValuePropName: "defaultOpen", + trigger: "onOpenChange", + }); + + const { accesses } = useAccessesStore(useZustandShallowSelector("accesses")); + const { addEmail } = useContactEmailsStore(useZustandShallowSelector(["addEmail"])); + const { updateNode } = useWorkflowStore(useZustandShallowSelector(["updateNode"])); + + const { + form: formInst, + formPending, + formProps, + submit: submitForm, + } = useAntdForm({ + name: "workflowNodeForm", + onSubmit: async (values) => { + await sleep(5000); + if (node.type === WorkflowNodeType.Apply) { + await addEmail(values.contactEmail); + await updateNode( + produce(node, (draft) => { + draft.config = { + provider: accesses.find((e) => e.id === values.providerAccessId)?.provider, + ...values, + }; + draft.validated = true; + }) + ); + } else { + await updateNode( + produce(node, (draft) => { + draft.config = { ...values }; + draft.validated = true; + }) + ); + } + }, + }); + + const formEl = useMemo(() => { + const nodeFormProps = { + form: formInst, + formName: formProps.name, + disabled: disabled || formPending, + workflowNode: node, + }; + + switch (node.type) { + case WorkflowNodeType.Start: + return ; + case WorkflowNodeType.Apply: + return ; + case WorkflowNodeType.Deploy: + return ; + case WorkflowNodeType.Notify: + return ; + default: + console.warn(`[certimate] unsupported workflow node type: ${node.type}`); + return <> ; + } + }, [node, disabled, formInst, formPending, formProps]); + + const handleClose = () => { + if (formPending) return; + + const oldValues = Object.fromEntries(Object.entries(node.config ?? {}).filter(([_, value]) => value !== null && value !== undefined)); + const newValues = Object.fromEntries(Object.entries(formInst.getFieldsValue(true)).filter(([_, value]) => value !== null && value !== undefined)); + const changed = !isEqual(oldValues, newValues); + + const { promise, resolve, reject } = Promise.withResolvers(); + if (changed) { + modalApi.confirm({ + title: t("common.text.operation_confirm"), + content: t("workflow_node.unsaved_changes.confirm"), + onOk: () => resolve(void 0), + onCancel: () => reject(), + }); + } else { + resolve(void 0); + } + + promise.then(() => { + setOpen(false); + }); + }; + + const handleCancelClick = () => { + if (formPending) return; + + setOpen(false); + }; + + const handleOkClick = async () => { + await submitForm(); + setOpen(false); + }; + + return ( + <> + {ModelContextHolder} + + + + + + } + open={open} + title={node.name} + width={640} + onClose={handleClose} + > + {formEl} + ); }; diff --git a/ui/src/components/workflow/node/DeployNodeForm.tsx b/ui/src/components/workflow/node/DeployNodeForm.tsx index 7e278ff4..cee84e0a 100644 --- a/ui/src/components/workflow/node/DeployNodeForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeForm.tsx @@ -3,7 +3,6 @@ import { useTranslation } from "react-i18next"; import { PlusOutlined as PlusOutlinedIcon, QuestionCircleOutlined as QuestionCircleOutlinedIcon } from "@ant-design/icons"; import { Button, Divider, Form, type FormInstance, Select, Tooltip, Typography } from "antd"; import { createSchemaFieldRule } from "antd-zod"; -import { init } from "i18next"; import { z } from "zod"; import Show from "@/components/Show"; @@ -78,7 +77,7 @@ const DeployNodeForm = ({ form, formName, disabled, workflowNode, onValuesChange const fieldProvider = Form.useWatch("provider", { form: form, preserve: true }); - const formFieldsComponent = useMemo(() => { + const formFieldsEl = useMemo(() => { /* 注意:如果追加新的子组件,请保持以 ASCII 排序。 NOTICE: If you add new child component, please keep ASCII order. @@ -265,7 +264,7 @@ const DeployNodeForm = ({ form, formName, disabled, workflowNode, onValuesChange - {formFieldsComponent} + {formFieldsEl} ); diff --git a/ui/src/components/workflow/node/StartNodeForm.tsx b/ui/src/components/workflow/node/StartNodeForm.tsx index 1e8ba2b8..8d5e1a9c 100644 --- a/ui/src/components/workflow/node/StartNodeForm.tsx +++ b/ui/src/components/workflow/node/StartNodeForm.tsx @@ -64,6 +64,8 @@ const StartNodeForm = ({ form, formName, disabled, workflowNode, onValuesChange } else { form.setFieldValue("triggerCron", undefined); } + + onValuesChange?.(form.getFieldsValue(true)); }; const handleFormChange = (_: unknown, values: z.infer) => { diff --git a/ui/src/components/workflow/panel/Panel.tsx b/ui/src/components/workflow/panel/Panel.tsx deleted file mode 100644 index dd6d3eb9..00000000 --- a/ui/src/components/workflow/panel/Panel.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React, { useEffect } from "react"; -import { useControllableValue } from "ahooks"; -import { Drawer } from "antd"; - -export type PanelProps = { - children: React.ReactNode; - defaultOpen?: boolean; - extra?: React.ReactNode; - footer?: React.ReactNode; - open?: boolean; - title?: React.ReactNode; - onClose?: () => void | Promise; - onOpenChange?: (open: boolean) => void; -}; - -const Panel = ({ children, extra, footer, title, onClose, ...props }: PanelProps) => { - const [open, setOpen] = useControllableValue(props, { - valuePropName: "open", - defaultValuePropName: "defaultOpen", - trigger: "onOpenChange", - }); - - const handleClose = async () => { - try { - const ret = await onClose?.(); - if (ret != null && !ret) return; - - setOpen(false); - } catch { - return; - } - }; - - return ( - - {children} - - ); -}; - -export default Panel; diff --git a/ui/src/components/workflow/panel/PanelContext.ts b/ui/src/components/workflow/panel/PanelContext.ts deleted file mode 100644 index bc5a46a8..00000000 --- a/ui/src/components/workflow/panel/PanelContext.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { createContext, useContext } from "react"; -import { type ButtonProps } from "antd"; - -import { type PanelProps } from "./Panel"; - -export type ShowPanelOptions = Omit; -export type ShowPanelWithConfirmOptions = Omit & { - cancelButtonProps?: ButtonProps; - cancelText?: React.ReactNode; - okButtonProps?: ButtonProps; - okText?: React.ReactNode; - onCancel?: () => void; - onOk?: () => void | Promise; -}; - -export type PanelContextProps = { - open: boolean; - show: (options: ShowPanelOptions) => void; - confirm: (options: ShowPanelWithConfirmOptions) => void; - hide: () => void; -}; - -const PanelContext = createContext(undefined); - -export const usePanelContext = () => { - const context = useContext(PanelContext); - if (!context) { - throw new Error("`usePanelContext` must be used within `PanelProvider`"); - } - - return context; -}; - -export default PanelContext; diff --git a/ui/src/components/workflow/panel/PanelProvider.tsx b/ui/src/components/workflow/panel/PanelProvider.tsx deleted file mode 100644 index 16a87c69..00000000 --- a/ui/src/components/workflow/panel/PanelProvider.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { useState } from "react"; -import { useTranslation } from "react-i18next"; -import { Button, Space } from "antd"; - -import Panel from "./Panel"; -import PanelContext, { type ShowPanelOptions, type ShowPanelWithConfirmOptions } from "./PanelContext"; - -export const PanelProvider = ({ children }: { children: React.ReactNode }) => { - const { t } = useTranslation(); - - const [open, setOpen] = useState(false); - const [options, setOptions] = useState(); - - const showPanel = (options: ShowPanelOptions) => { - setOpen(true); - setOptions(options); - }; - - const showPanelWithConfirm = (options: ShowPanelWithConfirmOptions) => { - const updateOptionsFooter = (confirmLoading: boolean) => { - setOptions({ - ...options, - footer: ( - - - - - ), - onClose: () => Promise.resolve(!confirmLoading), - }); - }; - - showPanel(options); - updateOptionsFooter(false); - }; - - const hidePanel = () => { - setOpen(false); - setOptions(undefined); - }; - - const handleOpenChange = (open: boolean) => { - setOpen(open); - - if (!open) { - setOptions(undefined); - } - }; - - return ( - - {children} - - - {options?.children} - - - ); -}; diff --git a/ui/src/i18n/locales/en/nls.common.json b/ui/src/i18n/locales/en/nls.common.json index a99047cf..8d78fd6e 100644 --- a/ui/src/i18n/locales/en/nls.common.json +++ b/ui/src/i18n/locales/en/nls.common.json @@ -12,6 +12,7 @@ "common.text.copied": "Copied", "common.text.nodata": "No data available", + "common.text.operation_confirm": "Operation confirm", "common.text.operation_succeeded": "Operation succeeded", "common.text.operation_failed": "Operation failed", "common.text.request_error": "Request error", diff --git a/ui/src/i18n/locales/en/nls.workflow.json b/ui/src/i18n/locales/en/nls.workflow.json index 79036a81..27e5eb5e 100644 --- a/ui/src/i18n/locales/en/nls.workflow.json +++ b/ui/src/i18n/locales/en/nls.workflow.json @@ -49,6 +49,6 @@ "workflow.detail.orchestration.action.release.confirm": "Are you sure to release your changes?", "workflow.detail.orchestration.action.release.failed.uncompleted": "Please complete the orchestration first", "workflow.detail.orchestration.action.run": "Run", - "workflow.detail.orchestration.action.run.confirm": "There are unreleased changes, are you sure to run this workflow based on the latest released version?", + "workflow.detail.orchestration.action.run.confirm": "You have unreleased changes. Do you really want to run this workflow based on the latest released version?", "workflow.detail.runs.tab": "History runs" } diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index defe7b09..6bf2210f 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -5,6 +5,8 @@ "workflow_node.action.add_branch": "Add branch", "workflow_node.action.delete_branch": "Delete branch", + "workflow_node.unsaved_changes.confirm": "You have unsaved changes. Do you really want to close the panel and drop those changes?", + "workflow_node.start.label": "Start", "workflow_node.start.form.trigger.label": "Trigger", "workflow_node.start.form.trigger.placeholder": "Please select trigger", diff --git a/ui/src/i18n/locales/zh/nls.common.json b/ui/src/i18n/locales/zh/nls.common.json index 468c61b3..8eaee862 100644 --- a/ui/src/i18n/locales/zh/nls.common.json +++ b/ui/src/i18n/locales/zh/nls.common.json @@ -12,6 +12,7 @@ "common.text.copied": "已复制", "common.text.nodata": "暂无数据", + "common.text.operation_confirm": "操作确认", "common.text.operation_succeeded": "操作成功", "common.text.operation_failed": "操作失败", "common.text.request_error": "请求错误", diff --git a/ui/src/i18n/locales/zh/nls.workflow.json b/ui/src/i18n/locales/zh/nls.workflow.json index 5bf54898..80a8c2b4 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.json +++ b/ui/src/i18n/locales/zh/nls.workflow.json @@ -49,6 +49,6 @@ "workflow.detail.orchestration.action.release.confirm": "确定要发布更改吗?", "workflow.detail.orchestration.action.release.failed.uncompleted": "流程编排未完成,请检查是否有节点未配置", "workflow.detail.orchestration.action.run": "执行", - "workflow.detail.orchestration.action.run.confirm": "此工作流存在未发布的更改,将以最近一次发布的版本为准,确定要继续执行吗?", + "workflow.detail.orchestration.action.run.confirm": "你有尚未发布的更改。你确定要以最近一次发布的版本继续执行吗?", "workflow.detail.runs.tab": "执行历史" } diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index ff85f528..7d92ef68 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -5,6 +5,8 @@ "workflow_node.action.add_branch": "添加分支", "workflow_node.action.delete_branch": "删除分支", + "workflow_node.unsaved_changes.confirm": "你有尚未保存的更改。你确定要关闭面板吗?", + "workflow_node.start.label": "开始", "workflow_node.start.form.trigger.label": "触发方式", "workflow_node.start.form.trigger.placeholder": "请选择触发方式", diff --git a/ui/src/pages/settings/SettingsSSLProvider.tsx b/ui/src/pages/settings/SettingsSSLProvider.tsx index f9f71c0c..1314b086 100644 --- a/ui/src/pages/settings/SettingsSSLProvider.tsx +++ b/ui/src/pages/settings/SettingsSSLProvider.tsx @@ -227,7 +227,7 @@ const SettingsSSLProvider = () => { }, []); const [providerType, setProviderType] = useState(SSLPROVIDERS.LETS_ENCRYPT); - const providerFormComponent = useMemo(() => { + const providerFormEl = useMemo(() => { switch (providerType) { case SSLPROVIDERS.LETS_ENCRYPT: return ; @@ -286,7 +286,7 @@ const SettingsSSLProvider = () => { -
{providerFormComponent}
+
{providerFormEl}
); diff --git a/ui/src/pages/workflows/WorkflowDetail.tsx b/ui/src/pages/workflows/WorkflowDetail.tsx index aed9f7ac..7c67a5d0 100644 --- a/ui/src/pages/workflows/WorkflowDetail.tsx +++ b/ui/src/pages/workflows/WorkflowDetail.tsx @@ -309,7 +309,7 @@ const WorkflowBaseInfoModal = ({ trigger }: { trigger?: React.ReactNode }) => { form: formInst, formPending, formProps, - ...formApi + submit: submitForm, } = useAntdForm>({ initialValues: { name: workflow.name, description: workflow.description }, onSubmit: async (values) => { @@ -324,7 +324,7 @@ const WorkflowBaseInfoModal = ({ trigger }: { trigger?: React.ReactNode }) => { }); const handleFormFinish = async () => { - return formApi.submit(); + return submitForm(); }; return ( diff --git a/ui/src/pages/workflows/WorkflowNew.tsx b/ui/src/pages/workflows/WorkflowNew.tsx index 623fac68..fcdc7d14 100644 --- a/ui/src/pages/workflows/WorkflowNew.tsx +++ b/ui/src/pages/workflows/WorkflowNew.tsx @@ -49,7 +49,7 @@ const WorkflowNew = () => { form: formInst, formPending, formProps, - ...formApi + submit: submitForm, } = useAntdForm>({ onSubmit: async (values) => { try { @@ -97,7 +97,7 @@ const WorkflowNew = () => { }; const handleModalFormFinish = () => { - return formApi.submit(); + return submitForm(); }; return (