From 9696e0bcce994dc72621c2f4e2a70ed77aa03f43 Mon Sep 17 00:00:00 2001 From: Colin Dawson Date: Tue, 10 Feb 2026 21:50:35 +0000 Subject: [PATCH] Started working on the ability to add workflow templates --- public/locales/en/common.json | 4 +- src/App.tsx | 9 ++ .../WorkflowTemplateDetails.tsx | 151 ++++++++++++++++++ .../components/GeneralTab.tsx | 49 ++++++ .../services/WorkflowTemplateService.ts | 4 + 5 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/modules/manager/workflowTemplates/WorkflowTemplateDetails.tsx create mode 100644 src/modules/manager/workflowTemplates/components/GeneralTab.tsx diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 53473d8..6ba6377 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -7,6 +7,7 @@ "AddDomain": "Add Domain", "Address": "Address", "AddUser": "Add User", + "AddWorkflowTemplate": "Add Workflow Template", "Admin": "Admin", "Allowed": "Allowed", "AnEmailWithPasswordResetLinkHasBeenSent": "An email with a password reset link has been sent.", @@ -55,7 +56,7 @@ "e-suiteLogo": "e-suite logo", "Edit": "Edit", "EditDomain": "Edit Domain", - "EditUser": "Edit User", + "EditWorkflowTemplate": "Edit Workflow Template", "EFlowAppId": "e-flow AppId", "EFlowCategoryId": "e-flow CategoryId", "EFlowHostname": "e-flow hostname", @@ -201,6 +202,7 @@ "ValidIssuer": "Valid Issuer", "Version": "Version", "VersionCannotBeNull": "Version cannot be null", + "WorkflowTemplateName": "Workflow Template Name", "WorkflowTemplates": "Workflow Templates", "Year": "Year", "YourProfileSettingsHaveBeenSaved": "Your profile settings have been saved" diff --git a/src/App.tsx b/src/App.tsx index 654ebe6..9e9f92d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -45,6 +45,7 @@ import SsoManager from "./modules/manager/ssoManager/ssoManager"; import SsoProviderDetails from "./modules/manager/ssoManager/SsoProviderDetails"; import { Namespaces } from "./i18n/i18n"; import WorkflowTemplateManager from "./modules/manager/workflowTemplates/WorkflowTemplateManager"; +import WorkflowTemplateDetails from "./modules/manager/workflowTemplates/WorkflowTemplateDetails"; function GetSecureRoutes() { const { t } = useTranslation(); @@ -371,6 +372,14 @@ function GetSecureRoutes() { } /> + + + + } + /> = ({ + editMode, +}) => { + const { t } = useTranslation(); + const { userId } = useParams<{ userId: string }>(); + + // useForm promoted to the parent + const form = useForm({ + loaded: false, + data: { + name: "", + } as CreateWorkflowTemplateVersion, + errors: {}, + redirect: "", + }); + + const heading = editMode + ? t("EditWorkflowTemplate") + : t("AddWorkflowTemplate"); + + // ----------------------------- + // Joi schema (same pattern as original GeneralTab) + // ----------------------------- + form.schema = { + name: Joi.string().required().max(450).label(t("WorkflowTemplateName")), + }; + + // ----------------------------- + // Load existing template (edit mode) + // ----------------------------- + useEffect(() => { + const load = async () => { + const newData: CreateWorkflowTemplateVersion = { ...form.state.data }; + + if (editMode && userId) { + try { + const loadedData = await templateVersionsService.getTemplateVersion( + BigInt(userId), + ); + + if (loadedData) { + newData.name = loadedData.name ?? ""; + } + } catch (ex: any) { + form.handleGeneralError(ex); + } + } + + form.setState({ ...form.state, loaded: true, data: newData }); + }; + + load(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [editMode, userId]); + + // ----------------------------- + // Save handler (called by useForm.handleSubmit) + // ----------------------------- + const doSubmit = async (buttonName: string) => { + try { + const { name } = form.state.data; + + if (editMode) { + await templateVersionsService.putTemplateVersion({ name }); + toast.info(t("WorkflowTemplateEdited")); + } else { + await templateVersionsService.postTemplateVersion({ name }); + toast.info(t("WorkflowTemplateAdded")); + } + + if (buttonName === "save") { + form.setState({ ...form.state, redirect: "/workflowTemplates" }); + } + } catch (ex: any) { + form.handleGeneralError(ex); + } + }; + + const handleSubmit = (e: React.FormEvent) => { + form.handleSubmit(e, doSubmit); + }; + + const { loaded, redirect, errors, data } = form.state; + if (redirect) return ; + + // ----------------------------- + // Tabs + // ----------------------------- + const tabs = [ + + + , + + +
Tasks editor coming soon…
+
, + + +
Fields editor coming soon…
+
, + + +
Visual Flow editor coming soon…
+
, + ]; + + return ( + +
+
+

{heading}

+ +
+ {editMode && renderButton(t("Save"), errors, "apply")} + {renderButton(t("SaveAndClose"), errors, "save")} +
+ + {renderError("_general", errors)} + + {tabs} +
+
+
+ ); +}; + +export default WorkflowTemplateDetails; diff --git a/src/modules/manager/workflowTemplates/components/GeneralTab.tsx b/src/modules/manager/workflowTemplates/components/GeneralTab.tsx new file mode 100644 index 0000000..90df9fb --- /dev/null +++ b/src/modules/manager/workflowTemplates/components/GeneralTab.tsx @@ -0,0 +1,49 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { Namespaces } from "../../../../i18n/i18n"; +import { InputType } from "../../../../components/common/Input"; +import { + renderInput, + renderError, +} from "../../../../components/common/formHelpers"; +import { WorkflowTemplateDraft } from "../WorkflowTemplateDetails"; + +interface GeneralTabProps { + data: WorkflowTemplateDraft; + errors: Record; + isEditMode: boolean; + onFieldChange: (e: React.ChangeEvent) => void; +} + +const GeneralTab: React.FC = ({ + data, + errors, + onFieldChange, +}) => { + const { t } = useTranslation(); + + const labelName = t("WorkflowTemplateName"); + + return ( +
+ {renderError("_general", errors)} + + {renderInput( + "name", + labelName, + data, + errors, + InputType.text, + false, + "", + "", + 0, + true, + undefined, + onFieldChange, + )} +
+ ); +}; + +export default GeneralTab; diff --git a/src/modules/manager/workflowTemplates/services/WorkflowTemplateService.ts b/src/modules/manager/workflowTemplates/services/WorkflowTemplateService.ts index 86a0ee2..fbecbce 100644 --- a/src/modules/manager/workflowTemplates/services/WorkflowTemplateService.ts +++ b/src/modules/manager/workflowTemplates/services/WorkflowTemplateService.ts @@ -25,6 +25,10 @@ export type ReadWorkflowTemplateVersion = { status: string; }; +export type CreateWorkflowTemplateVersion = { + name: string; +}; + export async function getTemplates( page: number, pageSize: number,