mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 15:19:01 +02:00
chore(react/ribbon): port convert to attachment
This commit is contained in:
parent
f91c1f4180
commit
a3e8fd374f
@ -10,11 +10,6 @@ import { t } from "../../services/i18n.js";
|
|||||||
import type FNote from "../../entities/fnote.js";
|
import type FNote from "../../entities/fnote.js";
|
||||||
import type { FAttachmentRow } from "../../entities/fattachment.js";
|
import type { FAttachmentRow } from "../../entities/fattachment.js";
|
||||||
|
|
||||||
// TODO: Deduplicate with server
|
|
||||||
interface ConvertToAttachmentResponse {
|
|
||||||
attachment: FAttachmentRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TPL = /*html*/`
|
const TPL = /*html*/`
|
||||||
<div class="dropdown note-actions">
|
<div class="dropdown note-actions">
|
||||||
<style>
|
<style>
|
||||||
@ -42,14 +37,7 @@ const TPL = /*html*/`
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<button type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
|
||||||
class="icon-action bx bx-dots-vertical-rounded"></button>
|
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right">
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
<li data-trigger-command="convertNoteIntoAttachment" class="dropdown-item">
|
|
||||||
<span class="bx bx-paperclip"></span> ${t("note_actions.convert_into_attachment")}
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li data-trigger-command="renderActiveNote" class="dropdown-item render-note-button">
|
<li data-trigger-command="renderActiveNote" class="dropdown-item render-note-button">
|
||||||
<span class="bx bx-extension"></span> ${t("note_actions.re_render_note")}<kbd data-command="renderActiveNote"></kbd>
|
<span class="bx bx-extension"></span> ${t("note_actions.re_render_note")}<kbd data-command="renderActiveNote"></kbd>
|
||||||
</li>
|
</li>
|
||||||
@ -214,28 +202,6 @@ export default class NoteActionsWidget extends NoteContextAwareWidget {
|
|||||||
this.toggleDisabled(this.$saveRevisionButton, !isInOptions);
|
this.toggleDisabled(this.$saveRevisionButton, !isInOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async convertNoteIntoAttachmentCommand() {
|
|
||||||
if (!this.note || !(await dialogService.confirm(t("note_actions.convert_into_attachment_prompt", { title: this.note.title })))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { attachment: newAttachment } = await server.post<ConvertToAttachmentResponse>(`notes/${this.noteId}/convert-to-attachment`);
|
|
||||||
|
|
||||||
if (!newAttachment) {
|
|
||||||
toastService.showMessage(t("note_actions.convert_into_attachment_failed", { title: this.note.title }));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toastService.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
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDisabled($el: JQuery<HTMLElement>, enable: boolean) {
|
toggleDisabled($el: JQuery<HTMLElement>, enable: boolean) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
$el.removeAttr("disabled");
|
$el.removeAttr("disabled");
|
||||||
|
@ -3,6 +3,7 @@ import { ComponentChildren } from "preact";
|
|||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
import { useEffect, useMemo, useRef, type CSSProperties } from "preact/compat";
|
import { useEffect, useMemo, useRef, type CSSProperties } from "preact/compat";
|
||||||
import "./FormList.css";
|
import "./FormList.css";
|
||||||
|
import { CommandNames } from "../../components/app_context";
|
||||||
|
|
||||||
interface FormListOpts {
|
interface FormListOpts {
|
||||||
children: ComponentChildren;
|
children: ComponentChildren;
|
||||||
@ -80,12 +81,13 @@ interface FormListItemOpts {
|
|||||||
checked?: boolean | null;
|
checked?: boolean | null;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
triggerCommand?: CommandNames;
|
||||||
description?: string;
|
description?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
rtl?: boolean;
|
rtl?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FormListItem({ children, icon, value, title, active, badges, disabled, checked, onClick, description, selected, rtl }: FormListItemOpts) {
|
export function FormListItem({ children, icon, value, title, active, badges, disabled, checked, onClick, description, selected, rtl, triggerCommand }: FormListItemOpts) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
icon = "bx bx-check";
|
icon = "bx bx-check";
|
||||||
}
|
}
|
||||||
@ -96,6 +98,7 @@ export function FormListItem({ children, icon, value, title, active, badges, dis
|
|||||||
data-value={value} title={title}
|
data-value={value} title={title}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
data-trigger-command={triggerCommand}
|
||||||
dir={rtl ? "rtl" : undefined}
|
dir={rtl ? "rtl" : undefined}
|
||||||
>
|
>
|
||||||
<Icon icon={icon} />
|
<Icon icon={icon} />
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
|
import { ConvertToAttachmentResponse } from "@triliumnext/commons";
|
||||||
|
import appContext from "../../components/app_context";
|
||||||
import FNote from "../../entities/fnote"
|
import FNote from "../../entities/fnote"
|
||||||
|
import dialog from "../../services/dialog";
|
||||||
import { t } from "../../services/i18n"
|
import { t } from "../../services/i18n"
|
||||||
|
import server from "../../services/server";
|
||||||
|
import toast from "../../services/toast";
|
||||||
|
import ws from "../../services/ws";
|
||||||
import ActionButton from "../react/ActionButton"
|
import ActionButton from "../react/ActionButton"
|
||||||
|
import Dropdown from "../react/Dropdown";
|
||||||
|
import { FormListItem } from "../react/FormList";
|
||||||
|
|
||||||
interface NoteActionsProps {
|
interface NoteActionsProps {
|
||||||
note?: FNote;
|
note?: FNote;
|
||||||
@ -10,8 +18,9 @@ export default function NoteActions(props: NoteActionsProps) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<RevisionsButton {...props} />
|
<RevisionsButton {...props} />
|
||||||
|
<NoteContextMenu {...props} />
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function RevisionsButton({ note }: NoteActionsProps) {
|
function RevisionsButton({ note }: NoteActionsProps) {
|
||||||
@ -24,5 +33,46 @@ function RevisionsButton({ note }: NoteActionsProps) {
|
|||||||
triggerCommand="showRevisions"
|
triggerCommand="showRevisions"
|
||||||
titlePosition="bottom"
|
titlePosition="bottom"
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function NoteContextMenu(props: NoteActionsProps) {
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
buttonClassName="bx bx-dots-vertical-rounded"
|
||||||
|
hideToggleArrow
|
||||||
|
noSelectButtonStyle
|
||||||
|
>
|
||||||
|
<ConvertToAttachment {...props} />
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ConvertToAttachment({ note }: NoteActionsProps) {
|
||||||
|
return (note?.isEligibleForConversionToAttachment() &&
|
||||||
|
<FormListItem
|
||||||
|
icon="bx bx-paperclip"
|
||||||
|
onClick={async () => {
|
||||||
|
if (!note || !(await dialog.confirm(t("note_actions.convert_into_attachment_prompt", { title: note.title })))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { attachment: newAttachment } = await server.post<ConvertToAttachmentResponse>(`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")}</FormListItem>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { AttributeRow, NoteType } from "./rows.js";
|
import { AttachmentRow, AttributeRow, NoteType } from "./rows.js";
|
||||||
|
|
||||||
type Response = {
|
type Response = {
|
||||||
success: true,
|
success: true,
|
||||||
@ -202,3 +202,7 @@ export interface CloneResponse {
|
|||||||
branchId?: string;
|
branchId?: string;
|
||||||
notePath?: string;
|
notePath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ConvertToAttachmentResponse {
|
||||||
|
attachment: AttachmentRow;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user