UNPKG

alinea

Version:

[![npm](https://img.shields.io/npm/v/alinea.svg)](https://npmjs.org/package/alinea) [![install size](https://packagephobia.com/badge?p=alinea)](https://packagephobia.com/result?p=alinea)

241 lines (237 loc) 7.97 kB
import { useAtomValue, useSetAtom } from "../../../chunks/chunk-WF77DMLN.js"; import "../../../chunks/chunk-OBOPLPUQ.js"; import { useQuery } from "../../../chunks/chunk-DJKGEOOC.js"; import "../../../chunks/chunk-U5RRZUYZ.js"; // src/dashboard/view/entry/NewEntry.tsx import { Entry, EntryPhase, Type, createId, slugify, track, type } from "alinea/core"; import { entryChildrenDir, entryFileName, entryFilepath, entryUrl } from "alinea/core/EntryFilenames"; import { MutationType } from "alinea/core/Mutation"; import { createEntryRow } from "alinea/core/util/EntryRows"; import { generateKeyBetween } from "alinea/core/util/FractionalIndexing"; import { entries, fromEntries, keys } from "alinea/core/util/Objects"; import { dirname } from "alinea/core/util/Paths"; 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 { link } from "alinea/input/link"; import { select } from "alinea/input/select"; import { text } from "alinea/input/text"; import { Button, Loader, fromModule } from "alinea/ui"; import { Link } from "alinea/ui/Link"; import { Suspense, useMemo, useState } from "react"; import { changedEntriesAtom, graphAtom, useMutate } from "../../atoms/DbAtoms.js"; import { useConfig } from "../../hook/UseConfig.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 = fromModule(NewEntry_module_default); var parentData = { id: Entry.entryId, i18nId: Entry.i18nId, type: Entry.type, path: Entry.path, url: Entry.url, level: Entry.level, parent: Entry.parent, parentPaths({ parents }) { return parents().select(Entry.path); }, childrenIndex({ children }) { return children().select(Entry.index).orderBy(Entry.index.asc()).first(); } }; var titleField = text("Title", { autoFocus: true }); function NewEntryForm({ parentId }) { const config = useConfig(); const graph = useAtomValue(graphAtom); const { data: requestedParent } = useQuery( ["parent-req", parentId], async () => { return graph.preferDraft.get( Entry({ entryId: parentId }).select(parentData) ); }, { 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 locale = useLocale(); const mutate = useMutate(); const { name: workspace } = useWorkspace(); const containerTypes = entries(config.schema).filter(([, type2]) => { return Type.meta(type2).isContainer; }).map((pair) => pair[0]); const root = useRoot(); const parentField = useMemo( () => link.entry("Parent", { condition: Entry.type.isIn(containerTypes).and(Entry.workspace.is(workspace)).and(Entry.root.is(root.name)), initialValue: preselectedId ? { id: "parent", ref: "entry", type: "entry", entry: preselectedId } : void 0 }), [] ); const typeField = useMemo(() => { const result = select("Select type", {}); track.options(result, async (get) => { const types = []; const selectedParent = get(parentField); const parentId2 = selectedParent?.entry; if (!parentId2) { types.push(...root.contains ?? []); } else { const parent = await graph.preferDraft.get( Entry({ entryId: parentId2 }).select(parentData) ); const parentType = parent && config.schema[parent.type]; types.push( ...parentType && Type.meta(parentType).contains || keys(config.schema) ); } return { items: fromEntries( types.map((key) => { return [key, config.schema[key]]; }).filter((row) => row[1]).map(([key, type2]) => { return [key, Type.label(type2) || key]; }) ) }; }); return result; }, []); const [isCreating, setIsCreating] = useState(false); const updateEntries = useSetAtom(changedEntriesAtom); const formType = useMemo( () => type({ parent: parentField, title: titleField, type: typeField }), [] ); const form = useForm(formType); async function handleCreate(e) { e.preventDefault(); const { title, type: selected } = form.data(); if (!selected || !title) return; setIsCreating(true); const path = slugify(title); const entryId = createId(); const data = { workspace, root: root.name, locale: locale ?? null, path, phase: config.enableDrafts ? EntryPhase.Draft : EntryPhase.Published }; const parent = await graph.preferDraft.get( Entry({ entryId: parentId }).select(parentData) ); const parentPaths = parent ? parent.parentPaths.concat(parent.path) : []; const filePath = entryFilepath(config, data, parentPaths); const childrenDir = entryChildrenDir(config, data, parentPaths); const parentDir = dirname(filePath); const entryType = config.schema[selected]; const url = entryUrl(entryType, { ...data, parentPaths }); const entry = await createEntryRow(config, { entryId, ...data, filePath, type: selected, path, title, url, index: generateKeyBetween(null, parent?.childrenIndex || null), parent: parent?.id ?? null, seeded: false, level: parent ? parent.level + 1 : 0, parentDir, childrenDir, i18nId: root.i18n ? createId() : entryId, modifiedAt: Date.now(), active: true, main: false, data: { title, path }, searchableText: "" }); return mutate({ type: MutationType.Create, entryId: entry.entryId, entry, file: entryFileName(config, data, parentPaths) }).then(() => { setIsCreating(false); navigate(nav.entry({ entryId: entry.i18nId })); if (parent) updateEntries([parent.i18nId]); }); } 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 };