import { ConvertToAttachmentResponse } from "@triliumnext/commons"; import { useContext } from "preact/hooks"; import appContext, { CommandNames } from "../../components/app_context"; import NoteContext from "../../components/note_context"; import FNote from "../../entities/fnote"; import branches from "../../services/branches"; import dialog from "../../services/dialog"; import { t } from "../../services/i18n"; import server from "../../services/server"; import toast from "../../services/toast"; import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/utils"; import ws from "../../services/ws"; import ActionButton from "../react/ActionButton"; import Dropdown from "../react/Dropdown"; import { FormDropdownDivider, FormDropdownSubmenu, FormListItem, FormListToggleableItem } from "../react/FormList"; import { useIsNoteReadOnly, useNoteContext, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumOption } from "../react/hooks"; import { ParentComponent } from "../react/react_utils"; import { isExperimentalFeatureEnabled } from "../../services/experimental_features"; import { useNoteBookmarkState, useShareState } from "./BasicPropertiesTab"; const isNewLayout = isExperimentalFeatureEnabled("new-layout"); export default function NoteActions() { const { note, noteContext } = useNoteContext(); return (
{note && !isNewLayout && } {note && note.type !== "launcher" && }
); } function RevisionsButton({ note }: { note: FNote }) { const isEnabled = !["launcher", "doc"].includes(note?.type ?? ""); return (isEnabled && ); } function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: NoteContext }) { const parentComponent = useContext(ParentComponent); const noteType = useNoteProperty(note, "type") ?? ""; const [viewType] = useNoteLabel(note, "viewType"); const canBeConvertedToAttachment = note?.isEligibleForConversionToAttachment(); const isSearchable = ["text", "code", "book", "mindMap", "doc"].includes(noteType); const isInOptionsOrHelp = note?.noteId.startsWith("_options") || note?.noteId.startsWith("_help"); const isPrintable = ["text", "code"].includes(noteType) || (noteType === "book" && ["presentation", "list", "table"].includes(viewType ?? "")); const isElectron = getIsElectron(); const isMac = getIsMac(); const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "aiChat"].includes(noteType); const isSearchOrBook = ["search", "book"].includes(noteType); const [syncServerHost] = useTriliumOption("syncServerHost"); const { isReadOnly, enableEditing } = useIsNoteReadOnly(note, noteContext); return ( {isReadOnly && <> enableEditing()} /> } {canBeConvertedToAttachment && } {note.type === "render" && } {isElectron && } {isNewLayout && } parentComponent?.triggerCommand("showImportDialog", { noteId: note.noteId })} /> noteContext?.notePath && parentComponent?.triggerCommand("showExportDialog", { notePath: noteContext.notePath, defaultType: "single" })} /> {(syncServerHost && isElectron) && } branches.deleteNotes([note.getParentBranches()[0].branchId])} /> {glob.isDev && } ); } function NoteBasicProperties({ note }: { note: FNote }) { const [ isBookmarked, setIsBookmarked ] = useNoteBookmarkState(note); const [ isShared, switchShareState ] = useShareState(note); const [ isTemplate, setIsTemplate ] = useNoteLabelBoolean(note, "template"); return <> ; } function EditabilityDropdown({ note }: { note: FNote }) { const [ readOnly, setReadOnly ] = useNoteLabelBoolean(note, "readOnly"); const [ autoReadOnlyDisabled, setAutoReadOnlyDisabled ] = useNoteLabelBoolean(note, "autoReadOnlyDisabled"); function setState(readOnly: boolean, autoReadOnlyDisabled: boolean) { setReadOnly(readOnly); setAutoReadOnlyDisabled(autoReadOnlyDisabled); } return ( setState(false, false)} description={t("editability_select.note_is_editable")}>{t("editability_select.auto")} setState(true, false)} description={t("editability_select.note_is_read_only")}>{t("editability_select.read_only")} setState(false, true)} description={t("editability_select.note_is_always_editable")}>{t("editability_select.always_editable")} ); } function DevelopmentActions({ note, noteContext }: { note: FNote, noteContext?: NoteContext }) { return ( window.open(`/?print=#root/${note.noteId}`, "_blank")} >Open print page { noteContext?.getTextEditor(editor => { editor.editing.view.change(() => { throw new Error("Editor crashed."); }); }); }}>Crash editor ); } function CommandItem({ icon, text, title, command, disabled }: { icon: string, text: string, title?: string, command: CommandNames | (() => void), disabled?: boolean, destructive?: boolean }) { return {text}; } function ConvertToAttachment({ note }: { note: FNote }) { return ( { if (!note || !(await dialog.confirm(t("note_actions.convert_into_attachment_prompt", { title: note.title })))) { return; } const { attachment: newAttachment } = await server.post(`notes/${note.noteId}/convert-to-attachment`); if (!newAttachment) { toast.showMessage(t("note_actions.convert_into_attachment_failed", { title: note.title })); return; } toast.showMessage(t("note_actions.convert_into_attachment_successful", { title: newAttachment.title })); await ws.waitForMaxKnownEntityChangeId(); await appContext.tabManager.getActiveContext()?.setNote(newAttachment.ownerId, { viewScope: { viewMode: "attachments", attachmentId: newAttachment.attachmentId } }); }} >{t("note_actions.convert_into_attachment")} ); }