webui/src/modules/manager/forms/FormsDetails.tsx

148 lines
4.1 KiB
TypeScript

import Joi from "joi";
import React, { useEffect } from "react";
import { Navigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import { useTranslation } from "react-i18next";
import { Namespaces } from "../../../i18n/i18n";
import { InputType } from "../../../components/common/Input";
import { MakeGeneralIdRef } from "../../../utils/GeneralIdRef";
import formsService from "./services/formsService";
import {
renderError,
renderButton,
renderInput,
renderTemplateEditor,
} from "../../../components/common/formHelpers";
import { useFormWithGuard } from "../../../components/common/useFormRouter";
const FormsDetails: React.FC<{ editMode?: boolean }> = ({
editMode = false,
}) => {
const { formId } = useParams<{ formId: string }>();
const { t } = useTranslation(Namespaces.Common);
const labelName = t("Name");
const labelDefinition = t("Definition");
const labelApply = t("Save");
const labelSave = t("SaveAndClose");
const form = useFormWithGuard({
loaded: false,
data: {
name: "",
definition: "",
},
errors: {},
redirect: "",
});
form.schema = {
name: Joi.string().required().max(450).label(labelName),
definition: Joi.string().required().label(labelDefinition),
};
useEffect(() => {
const loadData = async () => {
if (formId !== undefined) {
try {
const loadedData = await formsService.getForm(BigInt(formId));
if (loadedData) {
const newData = { ...form.state.data };
newData.name = loadedData.name;
newData.definition = loadedData.definition;
form.setState({ loaded: true, data: newData });
} else {
form.setState({ loaded: false });
}
} catch (ex: any) {
form.handleGeneralError(ex);
}
}
if (!editMode) form.setState({ loaded: true });
};
loadData();
}, [formId, editMode]); // eslint-disable-line react-hooks/exhaustive-deps
const doSubmit = async (buttonName: string) => {
try {
const { name, definition } = form.state.data;
const nameStr = typeof name === "string" ? name : "";
const definitionStr = typeof definition === "string" ? definition : "";
if (editMode) {
var generalIdRef = MakeGeneralIdRef(BigInt(formId!));
const response = await formsService.putForm(
generalIdRef,
nameStr,
definitionStr,
);
if (response) {
toast.info(t("FormTemplateEdited"));
}
} else {
const response = await formsService.postForm(nameStr, definitionStr);
if (response) {
toast.info(t("NewFormTemplateAdded"));
}
}
if (buttonName === "save") form.setState({ redirect: "/forms" });
form.markAsSaved();
} catch (ex: any) {
form.handleGeneralError(ex);
}
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
form.handleSubmit(e, doSubmit);
};
const { loaded, redirect } = form.state;
if (redirect) return <Navigate to={redirect} />;
let mode = t("Add");
if (editMode) mode = t("Edit");
return (
<>
<h1>
{mode} {t("FormTemplate")}
</h1>
<form onSubmit={handleSubmit}>
{renderError("_general", form.state.errors)}
{renderInput(
"name",
labelName,
form.state.data,
form.state.errors,
InputType.text,
false,
"",
"",
0,
true,
undefined,
form.handleChange,
)}
{renderTemplateEditor(
"form-editor",
"definition",
labelDefinition,
form.state.data,
true,
form.handleTemplateEditorChange,
)}
{editMode && renderButton(labelApply, form.state.errors, "apply")}
{renderButton(labelSave, form.state.errors, "save")}
</form>
</>
);
};
export default FormsDetails;