UNPKG

alinea

Version:
275 lines (271 loc) 9.5 kB
import { dist_default } from "../../../chunks/chunk-A5O3N2GS.js"; import { useAtomValue } from "../../../chunks/chunk-TOJF2G3X.js"; import "../../../chunks/chunk-WJ67RR7S.js"; import { useQuery } from "../../../chunks/chunk-YWCPLD22.js"; import "../../../chunks/chunk-NZLE2WMY.js"; // src/dashboard/view/entry/NewEntry.tsx import { Entry } from "alinea/core/Entry"; import { createId } from "alinea/core/Id"; import { Reference } from "alinea/core/Reference"; import { Schema } from "alinea/core/Schema"; import { track } from "alinea/core/Tracker"; import { Type, type } from "alinea/core/Type"; import { entries, fromEntries, keys } from "alinea/core/util/Objects"; import { slugify } from "alinea/core/util/Slugs"; import { useForm } from "alinea/dashboard/atoms/FormAtoms"; import { InputForm } from "alinea/dashboard/editor/InputForm"; import { useLocation, useNavigate } from "alinea/dashboard/util/HashRouter"; import { Modal } from "alinea/dashboard/view/Modal"; import { EntryLink, entry } from "alinea/field/link"; import { select } from "alinea/field/select"; import { text } from "alinea/field/text"; import { entryPicker } from "alinea/picker/entry/EntryPicker"; import { EntryReference } from "alinea/picker/entry/EntryReference"; import { parents } from "alinea/query"; import { Button, Loader } from "alinea/ui"; import { Link } from "alinea/ui/Link"; import { Suspense, useEffect, useMemo, useState } from "react"; import { useConfig } from "../../hook/UseConfig.js"; import { useDb } from "../../hook/UseDb.js"; import { useLocale } from "../../hook/UseLocale.js"; import { useNav } from "../../hook/UseNav.js"; import { useRoot } from "../../hook/UseRoot.js"; import { useWorkspace } from "../../hook/UseWorkspace.js"; // src/dashboard/view/entry/NewEntry.module.scss var NewEntry_module_default = { "root": "alinea-NewEntry", "root-header": "alinea-NewEntry-header", "rootHeader": "alinea-NewEntry-header", "root-footer": "alinea-NewEntry-footer", "rootFooter": "alinea-NewEntry-footer", "root-footer-link": "alinea-NewEntry-footer-link", "rootFooterLink": "alinea-NewEntry-footer-link", "form": "alinea-NewEntry-form", "is-loading": "alinea-NewEntry-is-loading", "isLoading": "alinea-NewEntry-is-loading" }; // src/dashboard/view/entry/NewEntry.tsx import { jsx, jsxs } from "react/jsx-runtime"; var styles = dist_default(NewEntry_module_default); var parentData = { id: Entry.id, type: Entry.type, path: Entry.path, url: Entry.url, level: Entry.level, parent: Entry.parentId, parentPaths: parents({ select: Entry.path }) }; var titleField = text("Title", { autoFocus: true }); function NewEntryForm({ parentId }) { const config = useConfig(); const locale = useLocale(); const db = useDb(); const { data: requestedParent } = useQuery( ["parent-req", parentId], async () => { return parentId ? db.first({ select: parentData, id: parentId, locale, status: "preferDraft" }) : null; }, { suspense: true, keepPreviousData: true, staleTime: 0 } ); const preselectedId = requestedParent && (Type.isContainer(config.schema[requestedParent.type]) ? requestedParent.id : requestedParent.parent); const { pathname } = useLocation(); const nav = useNav(); const navigate = useNavigate(); const { name: workspace } = useWorkspace(); const containerTypes = entries(config.schema).filter(([, type2]) => { return Type.isContainer(type2); }).map((pair) => pair[0]); const root = useRoot(); const parentField = useMemo(() => { return entry("Parent", { location: { workspace, root: root.name }, condition: { _type: { in: containerTypes } }, enableNavigation: true, initialValue: preselectedId ? { [Reference.id]: "parent", [Reference.type]: "entry", [EntryReference.entry]: preselectedId } : void 0 }); }, []); async function allowedTypes(parentId2) { if (!parentId2) { return root.contains ? Schema.contained(config.schema, root.contains) : keys(config.schema); } const parent = parentId2 ? await db.get({ select: parentData, id: parentId2, status: "preferDraft" }) : null; const parentType = parent && config.schema[parent.type]; if (parentType) return Schema.contained(config.schema, Type.contains(parentType)); return keys(config.schema); } const typeField = useMemo(() => { const typeField2 = select("Select type", { options: {} }); return track.options(typeField2, async (get) => { const selectedParent2 = get(parentField); const parentId2 = selectedParent2?.[EntryReference.entry]; const types = await allowedTypes(parentId2); return { options: fromEntries( types.map((key) => { return [key, config.schema[key]]; }).filter((row) => row[1]).map(([key, type2]) => { return [key, Type.label(type2) || key]; }) ) }; }); }, []); const insertOrderField = useMemo(() => { const insertOrderField2 = select( "Insert order", { initialValue: "last", options: { first: "At the top of the list", last: "At the bottom of the list" } } ); return track.options(insertOrderField2, async (get) => { const selectedParent2 = get(parentField); const parentId2 = selectedParent2?.[EntryReference.entry]; const parent = await db.first({ select: { type: Entry.type }, id: parentId2, status: "preferDraft" }); const parentType = parent && config.schema[parent.type]; const parentInsertOrder = parentType && Type.insertOrder(parentType); return { hidden: parentInsertOrder !== "free" }; }); }, []); const copyFromField = useMemo(() => { const copyFromField2 = entry("Copy content from"); return track.options(copyFromField2, (get) => { const type2 = get(typeField); return { readOnly: !type2, pickers: { entry: entryPicker({ condition: { _type: type2 }, title: "Copy content from", max: 1, selection: EntryLink }) } }; }); }, []); const [isCreating, setIsCreating] = useState(false); const formType = useMemo( () => type("New entry", { fields: { parent: parentField, title: titleField, type: typeField, order: insertOrderField, copyFrom: copyFromField } }), [] ); const form = useForm(formType); const parentAtoms = form.fieldInfo(parentField); const typeAtoms = form.fieldInfo(typeField); const copyFromAtoms = form.fieldInfo(copyFromField); const selectedType = useAtomValue(typeAtoms.value); const selectedParent = useAtomValue(parentAtoms.value); useEffect(() => { allowedTypes(selectedParent?.[EntryReference.entry]).then((types) => { if (types.length > 0) typeAtoms.mutator(types[0]); }); }, [selectedParent]); useEffect(() => { copyFromAtoms.mutator.replace(void 0); }, [selectedType]); async function handleCreate(e) { e.preventDefault(); const { title, type: selected } = form.data(); if (isCreating || !selected || !title) return; setIsCreating(true); const path = slugify(title); const id = createId(); const parentId2 = form.data().parent?.[EntryReference.entry]; const entryType = config.schema[selected]; const copyFrom = form.data().copyFrom?.[EntryReference.entry]; const entryData = copyFrom ? await db.first({ select: Entry.data, id: copyFrom, locale, status: "preferPublished" }) : Type.initialValue(entryType); const parent = parentId2 ? await db.first({ id: parentId2 }) : void 0; const parentType = parent && config.schema[parent._type]; const parentInsertOrder = parentType && Type.insertOrder(parentType); return db.create({ type: entryType, id, insertOrder: !parentInsertOrder || parentInsertOrder === "free" ? form.data().order : parentInsertOrder, parentId: parentId2, locale, root: root.name, workspace, status: config.enableDrafts ? "draft" : "published", set: { ...entryData, title, path } }).then((entry2) => { navigate(nav.entry({ id: entry2._id })); }).finally(() => { setIsCreating(false); }); } return /* @__PURE__ */ jsxs( "form", { onSubmit: handleCreate, className: styles.form({ loading: isCreating }), children: [ isCreating && /* @__PURE__ */ jsx(Loader, { absolute: true }), /* @__PURE__ */ jsx(InputForm, { border: false, form }), /* @__PURE__ */ jsxs("div", { className: styles.root.footer(), children: [ /* @__PURE__ */ jsx(Link, { href: pathname, className: styles.root.footer.link(), children: "Cancel" }), /* @__PURE__ */ jsx(Button, { children: "Create" }) ] }) ] } ); } function NewEntry({ parentId }) { const navigate = useNavigate(); const { pathname } = useLocation(); function handleClose() { navigate(pathname); } return /* @__PURE__ */ jsx(Modal, { open: true, onClose: handleClose, className: styles.root(), children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loader, {}), children: /* @__PURE__ */ jsx(NewEntryForm, { parentId }) }) }); } export { NewEntry };