Now able to edit a workflow template version

This commit is contained in:
Colin Dawson 2026-03-02 23:58:05 +00:00
parent 574f254dca
commit 6f328afbf2
4 changed files with 67 additions and 47 deletions

View File

@ -380,6 +380,14 @@ function GetSecureRoutes() {
</Mainframe> </Mainframe>
} }
/> />
<Route
path="/workflowTemplates/:workflowTemplateId"
element={
<Mainframe title={t("WorkflowTemplates")}>
<WorkflowTemplateDetails editMode={true} />
</Mainframe>
}
/>
<Route <Route
path="/workflowTemplates" path="/workflowTemplates"
element={ element={

View File

@ -7,6 +7,7 @@ import GeneralTab from "./components/GeneralTab";
import { Navigate, useParams } from "react-router-dom"; import { Navigate, useParams } from "react-router-dom";
import templateVersionsService, { import templateVersionsService, {
CreateWorkflowTemplateVersion, CreateWorkflowTemplateVersion,
ReadWorkflowTemplateVersion,
TaskDefinition, TaskDefinition,
} from "./services/WorkflowTemplateService"; } from "./services/WorkflowTemplateService";
import Loading from "../../../components/common/Loading"; import Loading from "../../../components/common/Loading";
@ -27,7 +28,7 @@ const WorkflowTemplateDetails: React.FC<{ editMode: boolean }> = ({
editMode, editMode,
}) => { }) => {
const { t } = useTranslation(Namespaces.Common); const { t } = useTranslation(Namespaces.Common);
const { userId } = useParams<{ userId: string }>(); const { workflowTemplateId } = useParams<{ workflowTemplateId: string }>();
const [activeTab, setActiveTab] = React.useState("general"); const [activeTab, setActiveTab] = React.useState("general");
const [taskValidation, setTaskValidation] = useState<Record<string, boolean>>( const [taskValidation, setTaskValidation] = useState<Record<string, boolean>>(
@ -43,7 +44,7 @@ const WorkflowTemplateDetails: React.FC<{ editMode: boolean }> = ({
activityNameTemplate: "", activityNameTemplate: "",
description: "", description: "",
tasks: [] as TaskDefinition[], tasks: [] as TaskDefinition[],
} as CreateWorkflowTemplateVersion, } as CreateWorkflowTemplateVersion | ReadWorkflowTemplateVersion,
errors: {}, errors: {},
redirect: "", redirect: "",
}); });
@ -67,38 +68,46 @@ const WorkflowTemplateDetails: React.FC<{ editMode: boolean }> = ({
description: Joi.string().required().allow("").label(t("Description")), description: Joi.string().required().allow("").label(t("Description")),
domainId: Joi.required(), domainId: Joi.required(),
tasks: Joi.array().required(), tasks: Joi.array().required(),
deleted: Joi.boolean().optional(),
guid: Joi.string().optional(),
id: Joi.number().optional(),
lastUpdated: Joi.date().optional(),
version: Joi.number().optional(),
workflowId: Joi.optional(),
};
const load = async () => {
let newData: CreateWorkflowTemplateVersion | ReadWorkflowTemplateVersion = {
...form.state.data,
};
if (editMode && workflowTemplateId) {
try {
const loadedData = await templateVersionsService.getTemplateVersion(
BigInt(workflowTemplateId),
);
if (loadedData) {
newData = loadedData;
}
} catch (ex: any) {
form.handleGeneralError(ex);
}
} else {
const user = authentication.getCurrentUser();
newData.domainId = MakeGeneralIdRef(user?.domainid);
}
form.setState({ ...form.state, loaded: true, data: newData });
}; };
// ----------------------------- // -----------------------------
// Load existing template (edit mode) // Load existing template (edit mode)
// ----------------------------- // -----------------------------
useEffect(() => { useEffect(() => {
const load = async () => {
const newData: CreateWorkflowTemplateVersion = { ...form.state.data };
if (editMode && userId) {
try {
const loadedData = await templateVersionsService.getTemplateVersion(
BigInt(userId),
);
if (loadedData) {
newData.workflowName = loadedData.workflowName ?? "";
}
} catch (ex: any) {
form.handleGeneralError(ex);
}
} else {
const user = authentication.getCurrentUser();
newData.domainId = MakeGeneralIdRef(user?.domainid);
}
form.setState({ ...form.state, loaded: true, data: newData });
};
load(); load();
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [editMode, userId]); }, [editMode, workflowTemplateId]);
// ----------------------------- // -----------------------------
// Save handler (called by useForm.handleSubmit) // Save handler (called by useForm.handleSubmit)
@ -109,10 +118,10 @@ const WorkflowTemplateDetails: React.FC<{ editMode: boolean }> = ({
var json = JSON.stringify(data); var json = JSON.stringify(data);
console.log("Submitting workflow template:", json);
if (editMode) { if (editMode) {
//await templateVersionsService.putTemplateVersion({ name }); await templateVersionsService.putTemplateVersion(
data as ReadWorkflowTemplateVersion,
);
toast.info(t("WorkflowTemplateEdited")); toast.info(t("WorkflowTemplateEdited"));
} else { } else {
await templateVersionsService.postTemplateVersion( await templateVersionsService.postTemplateVersion(
@ -126,6 +135,7 @@ const WorkflowTemplateDetails: React.FC<{ editMode: boolean }> = ({
} }
form.markAsSaved(); form.markAsSaved();
load();
} catch (ex: any) { } catch (ex: any) {
form.handleGeneralError(ex); form.handleGeneralError(ex);
} }

View File

@ -17,15 +17,17 @@ export type ReadWorkflowTemplate = {
version: bigint; version: bigint;
}; };
export type ReadWorkflowTemplateVersion = { export interface ReadWorkflowTemplateVersion extends FormData {
id: bigint; id: bigint;
guid?: string; guid: string;
workflowId: GeneralIdRef;
name: string;
domainId: GeneralIdRef;
activityNameTemplate: string; activityNameTemplate: string;
domainId: GeneralIdRef;
version: bigint;
workflowId: GeneralIdRef;
workflowName: string;
description: string; description: string;
}; tasks: TaskDefinition[];
}
export interface TaskDefinition<TConfig = Record<string, unknown>> { export interface TaskDefinition<TConfig = Record<string, unknown>> {
type: string; type: string;
@ -94,8 +96,11 @@ export async function getTemplateVersions(
return response?.data; return response?.data;
} }
export async function getTemplateVersion(id?: bigint, guid?: string) { export async function getTemplateVersion(
const params = MakeGeneralIdRefParams(id, guid); workflowTemplateId: bigint,
guid?: string,
): Promise<ReadWorkflowTemplateVersion> {
const params = MakeGeneralIdRefParams(workflowTemplateId, guid);
const response = await httpService.get<ReadWorkflowTemplateVersion>( const response = await httpService.get<ReadWorkflowTemplateVersion>(
apiEndpoint + "/templateVersion?" + params, apiEndpoint + "/templateVersion?" + params,
@ -111,17 +116,9 @@ export async function postTemplateVersion(
} }
export async function putTemplateVersion( export async function putTemplateVersion(
id: GeneralIdRef, data: ReadWorkflowTemplateVersion,
name: string,
address: string,
status: string,
): Promise<any> { ): Promise<any> {
return await httpService.put(apiEndpoint + "/templateVersion", { return await httpService.put(apiEndpoint + "/templateVersion", data);
GeneralIdRef: id,
name,
address,
status,
});
} }
export async function deleteTemplateVersion( export async function deleteTemplateVersion(

View File

@ -75,6 +75,7 @@ export function Get<T>(url: string, config?: any): any {
}) })
.catch((error) => { .catch((error) => {
toast.error(error.message); toast.error(error.message);
throw error;
}); });
} }
@ -86,6 +87,7 @@ export function Post<T>(url: string, data?: any, config?: any): any {
}) })
.catch((error) => { .catch((error) => {
toast.error(error.message); toast.error(error.message);
throw error;
}); });
} }
@ -97,6 +99,7 @@ export function Put<T>(url: string, data?: any, config?: any): any {
}) })
.catch((error) => { .catch((error) => {
toast.error(error.message); toast.error(error.message);
throw error;
}); });
} }
@ -108,6 +111,7 @@ export function Patch<T>(url: string, data?: any, config?: any): any {
}) })
.catch((error) => { .catch((error) => {
toast.error(error.message); toast.error(error.message);
throw error;
}); });
} }
@ -119,6 +123,7 @@ export function Delete<T>(url: string, config?: any): any {
}) })
.catch((error) => { .catch((error) => {
toast.error(error.message); toast.error(error.message);
throw error;
}); });
} }