302 lines
8.8 KiB
TypeScript
302 lines
8.8 KiB
TypeScript
import Joi from "joi";
|
|
import React, { useEffect, useRef, useState, useCallback } 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 { useForm } from "../../../components/common/useForm";
|
|
import { InputType } from "../../../components/common/Input";
|
|
import Loading from "../../../components/common/Loading";
|
|
import TemplateFiller, {
|
|
TemplateFillerHandle,
|
|
} from "../../../components/common/TemplateFiller";
|
|
import { GeneralIdRef, MakeGeneralIdRef } from "../../../utils/GeneralIdRef";
|
|
import {
|
|
CustomFieldValue,
|
|
PrintSpecificationsGlossary,
|
|
} from "../glossary/services/glossaryService";
|
|
import specificationService from "./services/specificationService";
|
|
import {
|
|
renderInput,
|
|
renderButton,
|
|
renderError,
|
|
renderGlossaryPicker,
|
|
} from "../../../components/common/formHelpers";
|
|
|
|
interface SpecificationsDetailsProps {
|
|
editMode?: boolean;
|
|
}
|
|
|
|
const SpecificationsDetails: React.FC<SpecificationsDetailsProps> = ({
|
|
editMode = false,
|
|
}) => {
|
|
const { organisationId, siteId, specificationId } = useParams<{
|
|
organisationId: string;
|
|
siteId: string;
|
|
specificationId?: string;
|
|
}>();
|
|
const { t } = useTranslation<typeof Namespaces.Common>();
|
|
const TemplateFillerRef = useRef<TemplateFillerHandle>(null);
|
|
|
|
const labelName = t("Name");
|
|
const labelPrintSpecification = t("PrintSpecification");
|
|
const labelSigmaId = t("SigmaId");
|
|
const labelApply = t("Save");
|
|
const labelSave = t("SaveAndClose");
|
|
|
|
const form = useForm({
|
|
loaded: false,
|
|
data: {
|
|
name: "",
|
|
sigmaId: null as bigint | null,
|
|
printSpecifications: [] as CustomFieldValue[],
|
|
formInstanceId: undefined,
|
|
},
|
|
errors: {},
|
|
redirect: "",
|
|
});
|
|
|
|
const [formTemplate, setFormTemplate] = useState<GeneralIdRef | undefined>(
|
|
undefined,
|
|
);
|
|
const [hasErrors, setHasErrors] = useState(false);
|
|
|
|
form.schema = {
|
|
name: Joi.string().required().max(450).label(labelName),
|
|
printSpecifications: Joi.optional(),
|
|
formInstanceId: Joi.optional(),
|
|
sigmaId: Joi.number().allow(null).label(labelSigmaId),
|
|
};
|
|
|
|
const isEditMode = () => editMode;
|
|
|
|
const loadFormTemplate = useCallback(
|
|
async (printSpecifications?: GeneralIdRef) => {
|
|
const { data } = form.state;
|
|
const printSpecArray =
|
|
(data.printSpecifications as CustomFieldValue[]) || [];
|
|
|
|
if (printSpecArray && printSpecArray.length > 0) {
|
|
if (
|
|
((printSpecArray[0] as CustomFieldValue).value as GeneralIdRef).id ===
|
|
BigInt(0)
|
|
) {
|
|
data.printSpecifications = undefined;
|
|
}
|
|
}
|
|
|
|
let template;
|
|
if (!printSpecArray || printSpecArray.length === 0) {
|
|
template = undefined;
|
|
} else {
|
|
template = await specificationService.GetTemplateForPrintSpec(
|
|
(printSpecArray[0] as CustomFieldValue).value as GeneralIdRef,
|
|
);
|
|
}
|
|
if (template) {
|
|
setFormTemplate(template);
|
|
form.setState({ loaded: true });
|
|
} else {
|
|
form.setState({ loaded: false });
|
|
}
|
|
},
|
|
[form],
|
|
);
|
|
|
|
const handleValidationChanged = useCallback(() => {
|
|
const templateFiller = TemplateFillerRef.current;
|
|
let templateErrors: boolean = false;
|
|
if (templateFiller) templateErrors = templateFiller.hasValidationErrors();
|
|
setHasErrors(templateErrors);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const loadData = async () => {
|
|
if (specificationId !== undefined) {
|
|
try {
|
|
const loadedData = await specificationService.GetSSpecification(
|
|
BigInt(specificationId),
|
|
);
|
|
if (loadedData) {
|
|
const newData = { ...form.state.data };
|
|
newData.name = loadedData.name;
|
|
newData.formInstanceId = loadedData.formInstanceId;
|
|
form.setState({ loaded: true, data: newData });
|
|
} else {
|
|
form.setState({ loaded: false });
|
|
}
|
|
} catch (ex: any) {
|
|
form.handleGeneralError(ex);
|
|
}
|
|
}
|
|
|
|
if (!editMode) {
|
|
form.setState({ loaded: true });
|
|
}
|
|
};
|
|
|
|
loadData();
|
|
}, [specificationId, editMode]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
useEffect(() => {
|
|
const { printSpecifications } = form.state.data;
|
|
const printSpecArray = (printSpecifications as CustomFieldValue[]) || [];
|
|
if (printSpecArray && printSpecArray.length > 0) {
|
|
loadFormTemplate(
|
|
(printSpecArray[0] as CustomFieldValue).value as GeneralIdRef,
|
|
);
|
|
}
|
|
}, [form.state.data.printSpecifications, loadFormTemplate, form]);
|
|
|
|
const doSubmit = async (buttonName: string) => {
|
|
try {
|
|
const { name, formInstanceId, sigmaId } = form.state.data;
|
|
const nameStr = typeof name === "string" ? name : "";
|
|
const sigmaIdValue =
|
|
sigmaId === null || sigmaId === undefined || sigmaId === ""
|
|
? null
|
|
: typeof sigmaId === "bigint"
|
|
? sigmaId
|
|
: BigInt(sigmaId as string | number);
|
|
const siteIdGeneralIdRef = MakeGeneralIdRef(
|
|
siteId ? BigInt(siteId) : undefined,
|
|
);
|
|
const templateFiller = TemplateFillerRef.current!;
|
|
|
|
if (isEditMode()) {
|
|
await templateFiller.Save();
|
|
const specificationIdGeneralIdRef = MakeGeneralIdRef(
|
|
specificationId ? BigInt(specificationId) : undefined,
|
|
);
|
|
const response = await specificationService.PutSpecification(
|
|
specificationIdGeneralIdRef,
|
|
siteIdGeneralIdRef,
|
|
nameStr,
|
|
formInstanceId as GeneralIdRef,
|
|
sigmaIdValue,
|
|
);
|
|
if (response) {
|
|
toast.info(t("SpecificationsEdited"));
|
|
}
|
|
} else {
|
|
const newFormInstanceId = await templateFiller.Save();
|
|
if (!newFormInstanceId) {
|
|
toast.error(t("FailedToSaveFormInstance"));
|
|
return;
|
|
}
|
|
|
|
const response = await specificationService.PostSpecification(
|
|
siteIdGeneralIdRef,
|
|
nameStr,
|
|
newFormInstanceId!,
|
|
sigmaIdValue,
|
|
);
|
|
if (response) {
|
|
toast.info(t("NewSpecificationsAdded"));
|
|
}
|
|
}
|
|
|
|
if (buttonName === "save") {
|
|
form.setState({
|
|
redirect: "/Specifications/" + organisationId + "/" + siteId,
|
|
});
|
|
}
|
|
} catch (ex: any) {
|
|
form.handleGeneralError(ex);
|
|
}
|
|
};
|
|
|
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
|
form.handleSubmit(e, doSubmit);
|
|
};
|
|
|
|
const { loaded, redirect } = form.state;
|
|
if (redirect && redirect !== "") return <Navigate to={redirect} />;
|
|
|
|
const mode = isEditMode() ? t("Edit") : t("Add");
|
|
|
|
return (
|
|
<Loading loaded={loaded}>
|
|
<h1>
|
|
{mode} {t("Specifications")}
|
|
</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,
|
|
)}
|
|
{renderInput(
|
|
"sigmaId",
|
|
labelSigmaId,
|
|
form.state.data,
|
|
form.state.errors,
|
|
InputType.number,
|
|
false,
|
|
"",
|
|
"",
|
|
0,
|
|
false,
|
|
undefined,
|
|
form.handleChange,
|
|
)}
|
|
{!isEditMode() &&
|
|
renderGlossaryPicker(
|
|
true,
|
|
"printSpecifications",
|
|
labelPrintSpecification,
|
|
form.state.data,
|
|
form.state.errors,
|
|
1,
|
|
PrintSpecificationsGlossary,
|
|
form.handleGlossaryPickerChange,
|
|
)}
|
|
|
|
<TemplateFiller
|
|
templateId={formTemplate}
|
|
formInstanceId={
|
|
form.state.data.formInstanceId as GeneralIdRef | undefined
|
|
}
|
|
ref={TemplateFillerRef}
|
|
onValidationChanged={handleValidationChanged}
|
|
/>
|
|
|
|
<br />
|
|
{isEditMode() &&
|
|
renderButton(
|
|
labelApply,
|
|
form.state.errors,
|
|
"apply",
|
|
undefined,
|
|
undefined,
|
|
Object.keys(form.state.errors).length === 0 && !hasErrors,
|
|
undefined,
|
|
true,
|
|
)}
|
|
{renderButton(
|
|
labelSave,
|
|
form.state.errors,
|
|
"save",
|
|
undefined,
|
|
undefined,
|
|
Object.keys(form.state.errors).length === 0 && !hasErrors,
|
|
undefined,
|
|
true,
|
|
)}
|
|
</form>
|
|
</Loading>
|
|
);
|
|
};
|
|
|
|
export default SpecificationsDetails;
|