mirror of
https://github.com/zadam/trilium.git
synced 2025-12-11 18:04:24 +01:00
feat(ckeditor/watchdog): functional copy to clipboard button
This commit is contained in:
parent
75a1fcc933
commit
397fb785d6
@ -205,7 +205,8 @@
|
||||
"info": {
|
||||
"modalTitle": "Info message",
|
||||
"closeButton": "Close",
|
||||
"okButton": "OK"
|
||||
"okButton": "OK",
|
||||
"copy_to_clipboard": "Copy to clipboard"
|
||||
},
|
||||
"jump_to_note": {
|
||||
"search_placeholder": "Search for note by its name or type > for commands...",
|
||||
|
||||
@ -8,11 +8,19 @@ import { useTriliumEvent } from "../react/hooks";
|
||||
import { isValidElement } from "preact";
|
||||
import { ConfirmWithMessageOptions } from "./confirm";
|
||||
import "./info.css";
|
||||
import server from "../../services/server";
|
||||
import { ToMarkdownResponse } from "@triliumnext/commons";
|
||||
import { copyTextWithToast } from "../../services/clipboard_ext";
|
||||
|
||||
export interface InfoExtraProps extends Partial<Pick<ModalProps, "size" | "title">> {
|
||||
/** Adds a button in the footer that allows easily copying the content of the infobox to clipboard. */
|
||||
copyToClipboardButton?: boolean;
|
||||
}
|
||||
|
||||
export type InfoExtraProps = Partial<Pick<ModalProps, "size" | "title">>;
|
||||
export type InfoProps = ConfirmWithMessageOptions & InfoExtraProps;
|
||||
|
||||
export default function InfoDialog() {
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
const [ opts, setOpts ] = useState<EventData<"showInfoDialog">>();
|
||||
const [ shown, setShown ] = useState(false);
|
||||
const okButtonRef = useRef<HTMLButtonElement>(null);
|
||||
@ -31,11 +39,28 @@ export default function InfoDialog() {
|
||||
setShown(false);
|
||||
}}
|
||||
onShown={() => okButtonRef.current?.focus?.()}
|
||||
footer={<Button
|
||||
modalRef={modalRef}
|
||||
footer={<>
|
||||
{opts?.copyToClipboardButton && (
|
||||
<Button
|
||||
text={t("info.copy_to_clipboard")}
|
||||
icon="bx bx-copy"
|
||||
onClick={async () => {
|
||||
const htmlContent = modalRef.current?.querySelector<HTMLDivElement>(".modal-body")?.innerHTML;
|
||||
if (!htmlContent) return;
|
||||
|
||||
const { markdownContent } = await server.post<ToMarkdownResponse>("other/to-markdown", { htmlContent });
|
||||
copyTextWithToast(markdownContent);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Button
|
||||
buttonRef={okButtonRef}
|
||||
text={t("info.okButton")}
|
||||
onClick={() => setShown(false)}
|
||||
/>}
|
||||
/>
|
||||
</>}
|
||||
show={shown}
|
||||
stackable
|
||||
scrollable
|
||||
|
||||
@ -7,15 +7,12 @@ import Modal from "../react/Modal";
|
||||
import Button from "../react/Button";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
import { CKEditorApi } from "../type_widgets/text/CKEditorWithWatchdog";
|
||||
import { RenderMarkdownResponse } from "@triliumnext/commons";
|
||||
|
||||
export interface MarkdownImportOpts {
|
||||
editorApi: CKEditorApi;
|
||||
}
|
||||
|
||||
interface RenderMarkdownResponse {
|
||||
htmlContent: string;
|
||||
}
|
||||
|
||||
export default function MarkdownImportDialog() {
|
||||
const markdownImportTextArea = useRef<HTMLTextAreaElement>(null);
|
||||
const editorApiRef = useRef<CKEditorApi>(null);
|
||||
|
||||
@ -310,10 +310,11 @@ function useWatchdogCrashHandling() {
|
||||
dialog.info(<>
|
||||
<p>{t("editable_text.editor_crashed_details_intro")}</p>
|
||||
<h3>{t("editable_text.editor_crashed_details_title")}</h3>
|
||||
<pre>{formattedCrash}</pre>
|
||||
<pre><code class="language-application-json">{formattedCrash}</code></pre>
|
||||
</>, {
|
||||
title: t("editable_text.editor_crashed_title"),
|
||||
size: "lg"
|
||||
size: "lg",
|
||||
copyToClipboardButton: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ import type { Request } from "express";
|
||||
|
||||
import becca from "../../becca/becca.js";
|
||||
import markdownService from "../../services/import/markdown.js";
|
||||
import markdown from "../../services/export/markdown.js";
|
||||
import { RenderMarkdownResponse, ToMarkdownResponse } from "@triliumnext/commons";
|
||||
|
||||
function getIconUsage() {
|
||||
const iconClassToCountMap: Record<string, number> = {};
|
||||
@ -29,13 +31,20 @@ function getIconUsage() {
|
||||
|
||||
function renderMarkdown(req: Request) {
|
||||
const { markdownContent } = req.body;
|
||||
|
||||
return {
|
||||
htmlContent: markdownService.renderToHtml(markdownContent, "")
|
||||
};
|
||||
} satisfies RenderMarkdownResponse;
|
||||
}
|
||||
|
||||
function toMarkdown(req: Request) {
|
||||
const { htmlContent } = req.body;
|
||||
return {
|
||||
markdownContent: markdown.toMarkdown(htmlContent)
|
||||
} satisfies ToMarkdownResponse;
|
||||
}
|
||||
|
||||
export default {
|
||||
getIconUsage,
|
||||
renderMarkdown
|
||||
renderMarkdown,
|
||||
toMarkdown
|
||||
};
|
||||
|
||||
@ -348,6 +348,7 @@ function register(app: express.Application) {
|
||||
route(GET, "/api/fonts", [auth.checkApiAuthOrElectron], fontsRoute.getFontCss);
|
||||
apiRoute(GET, "/api/other/icon-usage", otherRoute.getIconUsage);
|
||||
apiRoute(PST, "/api/other/render-markdown", otherRoute.renderMarkdown);
|
||||
apiRoute(PST, "/api/other/to-markdown", otherRoute.toMarkdown);
|
||||
apiRoute(GET, "/api/recent-changes/:ancestorNoteId", recentChangesApiRoute.getRecentChanges);
|
||||
apiRoute(GET, "/api/edited-notes/:date", revisionsApiRoute.getEditedNotesOnDate);
|
||||
|
||||
|
||||
@ -277,3 +277,11 @@ export interface NoteMapPostResponse {
|
||||
export interface UpdateAttributeResponse {
|
||||
attributeId: string;
|
||||
}
|
||||
|
||||
export interface RenderMarkdownResponse {
|
||||
htmlContent: string;
|
||||
}
|
||||
|
||||
export interface ToMarkdownResponse {
|
||||
markdownContent: string;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user