import { useEffect, useRef, useState } from "react"; import { useNavigate } from "react-router"; import InputText, { RefInputText } from "../ui/input/InputText"; import { useTranslation } from "react-i18next"; import InputGroup from "../ui/forms/InputGroup"; import EntityIcon from "../layouts/icons/EntityIcon"; import QuestionMarkFilledIcon from "../ui/icons/QuestionMarkFilledIcon"; import InputNumber from "../ui/input/InputNumber"; import InputCheckboxWithDescription from "../ui/input/InputCheckboxWithDescription"; import { Entity } from "@toolctrl/db/prisma-browser"; import FormGroup from "../ui/forms/FormGroup"; import { useAdminData } from "~/utils/data/useAdminData"; import StringUtils from "~/utils/shared/StringUtils"; import { DefaultVisibility } from "~/application/dtos/shared/DefaultVisibility"; import InputSelect from "../ui/input/InputSelect"; import VisibilityHelper from "~/utils/helpers/VisibilityHelper"; import Constants from "~/application/Constants"; import { DefaultEntityTypes } from "~/application/dtos/shared/DefaultEntityTypes"; import UrlUtils from "~/utils/app/UrlUtils"; import { adminPath, apiPath } from "~/utils/app/CanonicalUrlUtils"; import { useRootData } from "~/utils/data/useRootData"; interface Props { item?: Entity | null; } export default function EntityForm({ item }: Props) { const { t } = useTranslation(); const navigate = useNavigate(); const adminData = useAdminData(); const rootData = useRootData(); const inputName = useRef(null); const [title, setTitle] = useState(item?.title ?? ""); const [titlePlural, setTitlePlural] = useState(item?.titlePlural ?? ""); const [name, setName] = useState(item?.name ?? ""); const [type, setType] = useState(item?.type ?? DefaultEntityTypes.AppOnly); const [slug, setSlug] = useState(item?.slug ?? ""); const [icon, setIcon] = useState( item?.icon ?? ` ` ); const [order, setOrder] = useState( item?.order ?? (adminData.entities.length > 0 ? Math.max(...adminData.entities.map((o) => o.order)) : 0) + 1 ); const [prefix, setPrefix] = useState(item?.prefix ?? ""); const [isAutogenerated, setIsAutogenerated] = useState(item?.isAutogenerated ?? true); const [hasApi, setHasApi] = useState(item?.hasApi ?? true); const [active, setActive] = useState(item?.active ?? true); const [showInSidebar, setShowInSidebar] = useState(item?.showInSidebar ?? true); const [hasTags, setHasTags] = useState(item?.hasTags ?? true); const [hasComments, setHasComments] = useState(item?.hasComments ?? true); const [hasTasks, setHasTasks] = useState(item?.hasTasks ?? false); const [hasActivity, setHasActivity] = useState(item ? item.hasActivity : true); const [hasBulkDelete, setHasBulkDelete] = useState(item ? item.hasBulkDelete : false); const [hasViews, setHasViews] = useState(item ? item.hasViews : false); const [defaultVisibility, setDefaultVisibility] = useState(item?.defaultVisibility ?? Constants.DEFAULT_ROW_VISIBILITY); const [onCreated, setOnCreated] = useState(item?.onCreated ?? "redirectToOverview"); const [onEdit, setOnEdit] = useState(item?.onEdit ?? "editRoute"); const apiRowsPath = apiPath(`entities/${slug || "entity-name"}/rows`, { mode: "host-aware" }); const apiRowsUrl = rootData.apiBaseUrl ? new URL(apiRowsPath, rootData.apiBaseUrl).toString() : apiRowsPath; useEffect(() => { setTimeout(() => { inputName.current?.input.current?.focus(); }, 100); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // useEffect(() => { // if (!item) { // const slug = UrlUtils.slugify(t(titlePlural)); // setSlug(slug); // if (titlePlural.length >= 3) { // setPrefix(t(titlePlural).substring(0, 3).toUpperCase()); // } // } // // eslint-disable-next-line react-hooks/exhaustive-deps // }, [titlePlural]); return ( navigate(adminPath("entities", { mode: "host-aware" }))} editing={true} canDelete={false}>
{ if (!title.trim()) { const generateTitle = (str: string) => { return str .replace(/([a-z])([A-Z])/g, "$1 $2") // Insert space before capital letters .split(" ") // Split by spaces .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize the first letter of each word .join(" "); // Join the words back together }; const newTitle = generateTitle(name); if (newTitle) { setTitle(newTitle); setPrefix(t(newTitle).substring(0, 3).toUpperCase()); } } }} /> { const withoutStartingSlash = e?.toString().replace(/^\//, ""); setSlug(withoutStartingSlash); }} required autoComplete="off" help={t("models.entity.form.help.slug")} onBlur={() => { setSlug(UrlUtils.slugify(slug)); if (!titlePlural.trim()) { const words = slug.split(/[- ]/).map((w) => StringUtils.capitalize(w.toLowerCase())); setTitlePlural(words.join(" ")); } }} />
setType(e?.toString() ?? DefaultEntityTypes.AppOnly)} options={[ { name: t("models.entity.typeOptions.app"), value: DefaultEntityTypes.AppOnly }, { name: t("models.entity.typeOptions.admin"), value: DefaultEntityTypes.AdminOnly }, { name: t("models.entity.typeOptions.appAndAdmin"), value: DefaultEntityTypes.All }, { name: t("models.entity.typeOptions.system"), value: DefaultEntityTypes.System }, ]} required /> setPrefix(e.toString().toUpperCase())} minLength={2} maxLength={5} required help={t("models.entity.form.help.prefix")} /> {t("models.entity.form.iconHint")}
} button={
{icon ? ( ) : (
} />
setOnCreated(e?.toString() ?? "")} options={[ { value: "redirectToOverview", name: t("models.entity.form.onCreatedOptions.redirectToOverview") }, { value: "redirectToEdit", name: t("models.entity.form.onCreatedOptions.redirectToEdit") }, { value: "redirectToList", name: t("models.entity.form.onCreatedOptions.redirectToList") }, { value: "redirectToNew", name: t("models.entity.form.onCreatedOptions.redirectToNew") }, { value: "addAnother", name: t("models.entity.form.onCreatedOptions.addAnother") }, { value: "redirectToGroup", name: t("models.entity.form.onCreatedOptions.redirectToGroup") }, ]} /> setOnEdit(e?.toString() ?? "")} options={[ { value: "editRoute", name: t("models.entity.form.onEditOptions.editRoute") }, { value: "overviewRoute", name: t("models.entity.form.onEditOptions.overviewRoute") }, { value: "overviewAlwaysEditable", name: t("models.entity.form.onEditOptions.overviewAlwaysEditable") }, ]} />
); }