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)

220 lines (216 loc) 9.76 kB
import { useAtomValue, useSetAtom } from "../../chunks/chunk-WF77DMLN.js"; import "../../chunks/chunk-OBOPLPUQ.js"; import "../../chunks/chunk-U5RRZUYZ.js"; // src/dashboard/view/EntryEdit.tsx import { EntryPhase, Section, Type } from "alinea/core"; import { FormProvider } from "alinea/dashboard"; import { InputForm } from "alinea/dashboard/editor/InputForm"; import { Modal } from "alinea/dashboard/view/Modal"; import { TabsHeader, TabsSection } from "alinea/input/tabs/Tabs.browser"; import { Button, HStack, Stack, VStack, fromModule } from "alinea/ui"; import { Main } from "alinea/ui/Main"; import { Statusbar } from "alinea/ui/Statusbar"; import { Tabs } from "alinea/ui/Tabs"; import { IcOutlineTableRows } from "alinea/ui/icons/IcOutlineTableRows"; import { IcRoundInsertDriveFile } from "alinea/ui/icons/IcRoundInsertDriveFile"; import { IcRoundTranslate } from "alinea/ui/icons/IcRoundTranslate"; import { useEffect, useRef } from "react"; import { useRouteBlocker } from "../atoms/RouterAtoms.js"; import { useConfig } from "../hook/UseConfig.js"; import { useDashboard } from "../hook/UseDashboard.js"; import { EntryEditorProvider } from "../hook/UseEntryEditor.js"; import { useLocale } from "../hook/UseLocale.js"; import { useNav } from "../hook/UseNav.js"; import { SuspenseBoundary } from "../util/SuspenseBoundary.js"; // src/dashboard/view/EntryEdit.module.scss var EntryEdit_module_default = { "root": "alinea-EntryEdit", "root-tabs": "alinea-EntryEdit-tabs", "rootTabs": "alinea-EntryEdit-tabs" }; // src/dashboard/view/EntryEdit.tsx import { useSidebar } from "./Sidebar.js"; import { EntryDiff } from "./diff/EntryDiff.js"; import { EditMode } from "./entry/EditModeToggle.js"; import { EntryHeader } from "./entry/EntryHeader.js"; import { EntryHistory } from "./entry/EntryHistory.js"; import { EntryNotice } from "./entry/EntryNotice.js"; import { EntryPreview } from "./entry/EntryPreview.js"; import { EntryTitle } from "./entry/EntryTitle.js"; import { FieldToolbar } from "./entry/FieldToolbar.js"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var styles = fromModule(EntryEdit_module_default); function ShowChanges({ editor }) { const draftEntry = useAtomValue(editor.draftEntry); const hasChanges = useAtomValue(editor.hasChanges); const compareTo = hasChanges ? editor.activeVersion : editor.phases[editor.availablePhases.find((phase) => phase !== EntryPhase.Draft)]; return /* @__PURE__ */ jsx(EntryDiff, { entryA: compareTo, entryB: draftEntry }); } function EntryEdit({ editor }) { const { alineaDev } = useDashboard(); const locale = useLocale(); const { preview, enableDrafts } = useConfig(); const { isPreviewOpen } = useSidebar(); const nav = useNav(); const mode = useAtomValue(editor.editMode); const hasChanges = useAtomValue(editor.hasChanges); const selectedPhase = useAtomValue(editor.selectedPhase); const ref = useRef(null); useEffect(() => { ref.current?.scrollTo({ top: 0 }); }, [editor.entryId, mode, selectedPhase]); const untranslated = locale && locale !== editor.activeVersion.locale; const { isBlocking, nextRoute, confirm, cancel } = useRouteBlocker( "Are you sure you want to discard changes?", !untranslated && hasChanges ); const isNavigationChange = nextRoute?.data.editor?.entryId !== editor.entryId; const form = useAtomValue(editor.form); const saveDraft = useSetAtom(editor.saveDraft); const publishDraft = useSetAtom(editor.publishDraft); const publishEdits = useSetAtom(editor.publishEdits); const discardEdits = useSetAtom(editor.discardEdits); const showHistory = useAtomValue(editor.showHistory); const saveTranslation = useSetAtom(editor.saveTranslation); const previewRevision = useAtomValue(editor.previewRevision); const translate = () => saveTranslation(locale); useEffect(() => { function listener(e) { if (e.ctrlKey && e.key === "s") { e.preventDefault(); if (previewRevision) { alert("todo"); return; } if (untranslated && hasChanges) { translate(); } else if (enableDrafts) { if (hasChanges) saveDraft(); else if (selectedPhase === EntryPhase.Draft) publishDraft(); } else { if (hasChanges) publishEdits(); } } } document.addEventListener("keydown", listener); return () => { document.removeEventListener("keydown", listener); }; }, [editor, hasChanges, saveDraft, enableDrafts]); const sections = Type.sections(editor.type); const hasRootTabs = sections.length === 1 && sections[0][Section.Data] instanceof TabsSection; const tabs = hasRootTabs && sections[0][Section.Data]; const visibleTypes = tabs && tabs.types.filter((type) => !Type.meta(type).isHidden); useEffect(() => { if (isBlocking && !isNavigationChange) confirm?.(); }, [isBlocking, isNavigationChange, confirm]); return /* @__PURE__ */ jsxs(Fragment, { children: [ alineaDev && /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(Statusbar.Slot, { children: /* @__PURE__ */ jsxs(Statusbar.Status, { children: [ "File path: ", editor.activeVersion.filePath ] }) }), /* @__PURE__ */ jsx(Statusbar.Slot, { children: /* @__PURE__ */ jsxs(Statusbar.Status, { children: [ "Parent dir: ", editor.activeVersion.parentDir ] }) }), /* @__PURE__ */ jsx(Statusbar.Slot, { children: /* @__PURE__ */ jsxs(Statusbar.Status, { children: [ "Children dir: ", editor.activeVersion.childrenDir ] }) }), /* @__PURE__ */ jsx(Statusbar.Slot, { children: /* @__PURE__ */ jsxs(Statusbar.Status, { children: [ "Url: ", editor.activeVersion.url ] }) }), /* @__PURE__ */ jsx(Statusbar.Slot, { children: /* @__PURE__ */ jsx(Statusbar.Status, { icon: IcRoundInsertDriveFile, children: editor.activeVersion.fileHash }) }), /* @__PURE__ */ jsx(Statusbar.Slot, { children: /* @__PURE__ */ jsx(Statusbar.Status, { icon: IcOutlineTableRows, children: editor.activeVersion.rowHash }) }) ] }), isBlocking && isNavigationChange && /* @__PURE__ */ jsx(Modal, { open: true, onClose: () => cancel(), children: /* @__PURE__ */ jsxs(VStack, { gap: 30, children: [ /* @__PURE__ */ jsxs("p", { children: [ "This document was changed, would you like to save your changes", isNavigationChange ? " before navigating" : "", "?" ] }), /* @__PURE__ */ jsx(HStack, { as: "footer", children: /* @__PURE__ */ jsx(Stack.Right, { children: /* @__PURE__ */ jsxs(HStack, { gap: 16, children: [ /* @__PURE__ */ jsx( Button, { outline: true, type: "button", onClick: () => { discardEdits(); confirm(); }, children: "Discard my changes" } ), enableDrafts ? /* @__PURE__ */ jsx( Button, { onClick: () => { saveDraft(); confirm(); }, children: "Save as draft" } ) : /* @__PURE__ */ jsx( Button, { onClick: () => { publishEdits(); confirm(); }, children: "Publish changes" } ) ] }) }) }) ] }) }), /* @__PURE__ */ jsx(Main, { scrollRef: ref, className: styles.root(), children: /* @__PURE__ */ jsxs(FieldToolbar.Provider, { children: [ /* @__PURE__ */ jsx(EntryHeader, { editor }), showHistory && /* @__PURE__ */ jsx(EntryHistory, { editor }), /* @__PURE__ */ jsxs(Tabs.Root, { children: [ /* @__PURE__ */ jsx( EntryTitle, { editor, backLink: editor.activeVersion.parent ? nav.entry({ entryId: editor.activeVersion.parent, workspace: editor.activeVersion.workspace }) : nav.entry({ entryId: void 0 }), children: hasRootTabs && /* @__PURE__ */ jsx("div", { className: styles.root.tabs(), children: /* @__PURE__ */ jsx(TabsHeader, { backdrop: false, section: sections[0] }) }) } ), /* @__PURE__ */ jsxs(Main.Container, { children: [ untranslated && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs( EntryNotice, { icon: IcRoundTranslate, title: "Untranslated", variant: "untranslated", children: [ "This page has not yet been translated to this language,", /* @__PURE__ */ jsx("br", {}), editor.parentNeedsTranslation ? "please translate the parent page first." : "please enter the details below and save to start translating." ] } ) }), /* @__PURE__ */ jsx(EntryEditorProvider, { editor, children: /* @__PURE__ */ jsx(SuspenseBoundary, { name: "input form", children: mode === EditMode.Diff ? /* @__PURE__ */ jsx(ShowChanges, { editor }) : hasRootTabs && visibleTypes ? /* @__PURE__ */ jsx(Tabs.Panels, { children: visibleTypes.map((type, i) => { return /* @__PURE__ */ jsx(FormProvider, { form, children: /* @__PURE__ */ jsx(Tabs.Panel, { tabIndex: i, children: /* @__PURE__ */ jsx(InputForm, { type }) }) }, i); }) }) : /* @__PURE__ */ jsx(VStack, { gap: 18, children: /* @__PURE__ */ jsx(InputForm, { form }) }) }) }) ] }) ] }), /* @__PURE__ */ jsx(FieldToolbar.Root, {}) ] }) }), preview && isPreviewOpen && !untranslated && /* @__PURE__ */ jsx(EntryPreview, { preview, editor }) ] }); } export { EntryEdit };