From 06e92c6bc0bb0833d7f37576951fa1aceba738c6 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 15 Oct 2025 17:24:15 +0800 Subject: [PATCH] feat(ui): add default workflow designer layout setting --- .../components/workflow/designer/Designer.tsx | 14 ++++--- ui/src/hooks/useAppSettings.ts | 9 ++++- ui/src/i18n/locales/en/nls.settings.json | 5 +++ ui/src/i18n/locales/zh/nls.settings.json | 5 +++ ui/src/pages/settings/SettingsAppearance.tsx | 40 ++++++++++++++++++- .../pages/workflows/WorkflowDetailDesign.tsx | 18 ++++++++- 6 files changed, 81 insertions(+), 10 deletions(-) diff --git a/ui/src/components/workflow/designer/Designer.tsx b/ui/src/components/workflow/designer/Designer.tsx index 52b7483ab..7eea4b14a 100644 --- a/ui/src/components/workflow/designer/Designer.tsx +++ b/ui/src/components/workflow/designer/Designer.tsx @@ -4,12 +4,12 @@ import { EditorRenderer, EditorState, FixedLayoutEditorProvider, + FlowLayoutDefault, type FixedLayoutPluginContext, type FixedLayoutProps, type FlowDocumentJSON, type FlowNodeEntity, FlowTextKey, - getNodeForm, } from "@flowgram.ai/fixed-layout-editor"; import { createMinimapPlugin } from "@flowgram.ai/minimap-plugin"; import "@flowgram.ai/fixed-layout-editor/index.css"; @@ -139,9 +139,11 @@ const Designer = forwardRef( rendered.current = true; // 画布初始化后向下滚动一点,露出可能被 Alert 遮挡的部分 - setTimeout(() => { - ctx.playground.config.scroll({ scrollY: -80 }); - }, 1); + if (defaultLayout === FlowLayoutDefault.VERTICAL_FIXED_LAYOUT) { + setTimeout(() => { + ctx.playground.config.scroll({ scrollY: -80 }); + }, 1); + } }, }), [defaultEditorState, defaultLayout, initialData, readonly, onDocumentChange, themeToken] @@ -195,12 +197,12 @@ const Designer = forwardRef( node = flowgramEditorRef.current!.document.getNode(node)!; } - const form = getNodeForm(node); + const form = node.form; return form ? form.validate().then((res) => res && !form.state.invalid) : Promise.resolve(true); }, validateAllNodes() { const nodes = flowgramEditorRef.current!.document.getAllNodes(); - const forms = nodes.map((node) => getNodeForm(node)).filter((form) => form != null); + const forms = nodes.map((node) => node.form).filter((form) => form != null); return Promise.allSettled(forms.map((form) => form.validate())).then((res) => forms.every((form, index) => res[index] && !form.state.invalid)); }, }; diff --git a/ui/src/hooks/useAppSettings.ts b/ui/src/hooks/useAppSettings.ts index 4f203e8b3..4fef05244 100644 --- a/ui/src/hooks/useAppSettings.ts +++ b/ui/src/hooks/useAppSettings.ts @@ -7,8 +7,14 @@ if (!localStorage.getItem(LOCAL_STORAGE_KEY)) { } type AppSettings = { - // 每页显示的默认条目数 + /** + * 每页显示的默认条目数。 + */ defaultPerPage?: number; + /** + * 工作流默认布局。 + */ + defaultWorkflowLayout?: "horizontal" | "vertical"; }; export type UseAppSettingsReturns = { @@ -26,6 +32,7 @@ const useAppSettings = (): UseAppSettingsReturns => { defaultValue: {}, }); state.defaultPerPage ??= 15; + state.defaultWorkflowLayout ??= "vertical"; const resetState = useCallback(() => { localStorage.removeItem(LOCAL_STORAGE_KEY); diff --git a/ui/src/i18n/locales/en/nls.settings.json b/ui/src/i18n/locales/en/nls.settings.json index 29789404c..6cff94790 100644 --- a/ui/src/i18n/locales/en/nls.settings.json +++ b/ui/src/i18n/locales/en/nls.settings.json @@ -29,6 +29,11 @@ "settings.appearance.pagination.form.default_per_page.label": "Default items per page", "settings.appearance.pagination.form.default_per_page.placeholder": "Please enter default items per page", "settings.appearance.pagination.form.default_per_page.unit": "items per page", + "settings.appearance.workflow.title": "Workflow", + "settings.appearance.workflow.form.default_designer_layout.label": "Default designer layout", + "settings.appearance.workflow.form.default_designer_layout.placeholder": "Please select default designer layout", + "settings.appearance.workflow.form.default_designer_layout.option.horizontal": "Horizontal layout", + "settings.appearance.workflow.form.default_designer_layout.option.vertical": "Vertical layout", "settings.sslprovider.tab": "Certificate authority", "settings.sslprovider.ca.title": "System-wide CA", diff --git a/ui/src/i18n/locales/zh/nls.settings.json b/ui/src/i18n/locales/zh/nls.settings.json index a59c39da7..10a353e93 100644 --- a/ui/src/i18n/locales/zh/nls.settings.json +++ b/ui/src/i18n/locales/zh/nls.settings.json @@ -29,6 +29,11 @@ "settings.appearance.pagination.form.default_per_page.label": "列表页默认显示数量", "settings.appearance.pagination.form.default_per_page.placeholder": "请输入列表页默认显示数量", "settings.appearance.pagination.form.default_per_page.unit": "条每页", + "settings.appearance.workflow.title": "工作流", + "settings.appearance.workflow.form.default_designer_layout.label": "编辑器默认布局", + "settings.appearance.workflow.form.default_designer_layout.placeholder": "请选择编辑器默认布局", + "settings.appearance.workflow.form.default_designer_layout.option.horizontal": "水平布局", + "settings.appearance.workflow.form.default_designer_layout.option.vertical": "垂直布局", "settings.sslprovider.tab": "证书颁发机构", "settings.sslprovider.ca.title": "全局证书颁发机构", diff --git a/ui/src/pages/settings/SettingsAppearance.tsx b/ui/src/pages/settings/SettingsAppearance.tsx index ee427afea..f28be5c53 100644 --- a/ui/src/pages/settings/SettingsAppearance.tsx +++ b/ui/src/pages/settings/SettingsAppearance.tsx @@ -24,6 +24,11 @@ const SettingsAppearance = () => {

{t("settings.appearance.pagination.title")}

+ + + +

{t("settings.appearance.workflow.title")}

+ ); }; @@ -105,7 +110,7 @@ const SettingsAppearancePagination = ({ className, style }: { className?: string const { appSettings: globalAppSettings, setAppSettings: setGlobalAppSettings } = useAppSettings(); - const handleChange = (value: number) => { + const handleChange = (value: (typeof globalAppSettings)["defaultPerPage"]) => { setGlobalAppSettings( produce(globalAppSettings, (draft) => { draft.defaultPerPage = value; @@ -133,4 +138,37 @@ const SettingsAppearancePagination = ({ className, style }: { className?: string ); }; +const SettingsAppearanceWorkflow = ({ className, style }: { className?: string; style?: React.CSSProperties }) => { + const { t } = useTranslation(); + + const { appSettings: globalAppSettings, setAppSettings: setGlobalAppSettings } = useAppSettings(); + + const handleChange = (value: (typeof globalAppSettings)["defaultWorkflowLayout"]) => { + setGlobalAppSettings( + produce(globalAppSettings, (draft) => { + draft.defaultWorkflowLayout = value; + }) + ); + }; + + return ( +
+
+ +