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 { GeneralIdRef, MakeGeneralIdRef } from "../../../utils/GeneralIdRef"; import glossariesService, { CustomFieldValue, Glossary, SystemGlossaries, } from "./services/glossaryService"; import { CustomField } from "../customfields/services/customFieldsService"; import Loading from "../../../components/common/Loading"; import { renderError, renderButton, renderInput, renderCustomFields, renderCustomFieldsEditor, } from "../../../components/common/formHelpers"; import { useFormWithGuard } from "../../../components/common/useFormRouter"; interface GlossariesDetailsProps { editMode?: boolean; } const GlossariesDetails: React.FC = ({ editMode = false, }) => { const { glossaryId } = useParams<{ glossaryId: string }>(); const { t } = useTranslation(Namespaces.Common); const labelName = t("Name"); const labelChildCustomFieldDefinition = t("CustomFieldForChildEntries"); const labelApply = t("Save"); const labelSave = t("SaveAndClose"); const form = useFormWithGuard({ loaded: false, data: { id: undefined, guid: undefined, name: "", parent: undefined, childCustomFieldDefinition: [], }, errors: {}, redirect: "", }); form.schema = { id: Joi.optional(), guid: Joi.optional(), name: Joi.string().required().max(450).label(labelName), parent: Joi.optional(), childCustomFieldDefinition: Joi.optional().label( labelChildCustomFieldDefinition, ), }; useEffect(() => { const loadData = async () => { const newData = { ...form.state.data }; if (editMode) { const generalIdRef = MakeGeneralIdRef(BigInt(glossaryId!)); try { const loadedData = await glossariesService.getGlossaryItem(generalIdRef); if (loadedData) { newData.name = loadedData.name; newData.parent = loadedData.parent; newData.id = loadedData.id; newData.guid = loadedData.guid; newData.childCustomFieldDefinition = loadedData.childCustomFieldDefinition ?? []; const parentGlossary = newData.parent as Glossary | undefined; form.setCustomFieldValues( newData, loadedData.customFieldValues, parentGlossary?.childCustomFieldDefinition ?? [], ); } } catch (ex: any) { form.handleGeneralError(ex); } } else { const generalIdRef = MakeGeneralIdRef(BigInt(glossaryId!)); try { const loadedData = await glossariesService.getGlossaryItem(generalIdRef); if (loadedData) { newData.parent = loadedData; } } catch (ex: any) { form.handleGeneralError(ex); } } form.setState({ loaded: true, data: newData, customFields: (newData.parent as Glossary | undefined) ?.childCustomFieldDefinition, }); }; loadData(); }, [glossaryId, editMode]); // eslint-disable-line react-hooks/exhaustive-deps const handleAdd = (customfield: CustomField) => { const newData = { ...form.state.data }; const childDefs = (newData.childCustomFieldDefinition as CustomField[]) ?? []; childDefs.push(customfield); newData.childCustomFieldDefinition = childDefs; form.setState({ data: newData }); }; const handleDelete = (fieldToDelete: CustomField) => { const newData = { ...form.state.data }; if (fieldToDelete) { const childDefs = (newData.childCustomFieldDefinition as CustomField[]) ?? []; newData.childCustomFieldDefinition = childDefs.filter( (x) => x !== fieldToDelete, ); } form.setState({ data: newData }); }; const doSubmit = async (buttonName: string) => { try { const { id, guid, name, parent, childCustomFieldDefinition } = form.state.data; const nameStr = typeof name === "string" ? name : ""; const parentGlossary = parent as Glossary | undefined; const childDefs = (childCustomFieldDefinition as CustomField[]) ?? []; const idValue = typeof id === "bigint" ? id : undefined; const guidValue = typeof guid === "string" ? guid : undefined; const customfieldValues = form.CustomFieldValues(); if (editMode) { const generalIdRef = MakeGeneralIdRef(idValue, guidValue); const response = await glossariesService.putGlossaryItem( generalIdRef, parentGlossary ? MakeGeneralIdRef(parentGlossary.id, parentGlossary.guid) : undefined, nameStr, childDefs, customfieldValues, ); if (response) { toast.info(t("GlossaryItemEdited")); } } else { const generalIdRef = parentGlossary ? MakeGeneralIdRef(parentGlossary.id, parentGlossary.guid) : SystemGlossaries; const response = await glossariesService.postGlossaryItem( generalIdRef, nameStr, childDefs, customfieldValues, ); if (response) { toast.info(t("NewGlossaryItemAdded")); } } const navigateId = parentGlossary ? parentGlossary.id.toString() : ""; if (buttonName === "save") form.setState({ redirect: "/glossaries/" + navigateId }); form.markAsSaved(); } catch (ex: any) { form.handleGeneralError(ex); } }; const handleSubmit = (e: React.FormEvent) => { form.handleSubmit(e, doSubmit); }; const { loaded, redirect, data } = form.state; if (redirect) return ; let mode = t("Add"); if (editMode) mode = t("Edit"); const parentGlossary = data.parent as Glossary | undefined; const handleCustomFieldChange = ( e: React.ChangeEvent, ) => { if (e.target instanceof HTMLTextAreaElement) { form.handleTextAreaChange(e as React.ChangeEvent); } else { form.handleCustomFieldChange(e as React.ChangeEvent); } }; const getCustomFieldType = ( field: CustomFieldValue, customFields: CustomField[], ) => { return form.getCustomFieldType(field as any, customFields); }; const handleCustomFieldPickerChange = ( name: string, value: GeneralIdRef | CustomFieldValue[], ) => { if (Array.isArray(value)) { form.handleGlossaryPickerChange(name, value); } else { form.handlePickerChange(name, value as GeneralIdRef); } }; return (

{mode} {t("GlossaryItem")}

{renderError("_general", form.state.errors)} {renderInput( "name", labelName, form.state.data, form.state.errors, InputType.text, false, "", "", 0, true, undefined, form.handleChange, )} {renderCustomFields( parentGlossary?.childCustomFieldDefinition, form.state.data, form.state.errors, handleCustomFieldChange, handleCustomFieldPickerChange, getCustomFieldType, )}
{renderCustomFieldsEditor( "childCustomFieldDefinition", labelChildCustomFieldDefinition, form.state.data, form.state.errors, (data.childCustomFieldDefinition as CustomField[]) ?? [], handleAdd, handleDelete, )}
{editMode && renderButton(labelApply, form.state.errors, "apply")} {renderButton(labelSave, form.state.errors, "save")}
); }; export default GlossariesDetails;