mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
864079e30b
Allow users to comment on mermaid diagrams via the selection toolbar, matching the existing comment-on-image pattern. https://claude.ai/code/session_01E7BvJCgSpXJZdQEqj9mHgs
126 lines
3.1 KiB
TypeScript
126 lines
3.1 KiB
TypeScript
import {
|
|
CommentIcon,
|
|
CopyIcon,
|
|
EditIcon,
|
|
ExpandedIcon,
|
|
TextWrapIcon,
|
|
} from "outline-icons";
|
|
import type { Node as ProseMirrorNode } from "prosemirror-model";
|
|
import { NodeSelection } from "prosemirror-state";
|
|
import type { EditorState } from "prosemirror-state";
|
|
import {
|
|
pluginKey as mermaidPluginKey,
|
|
type MermaidState,
|
|
} from "@shared/editor/extensions/Mermaid";
|
|
import {
|
|
getFrequentCodeLanguages,
|
|
codeLanguages,
|
|
getLabelForLanguage,
|
|
} from "@shared/editor/lib/code";
|
|
import { isMermaid } from "@shared/editor/lib/isCode";
|
|
import type { TFunction } from "i18next";
|
|
import type { MenuItem } from "@shared/editor/types";
|
|
import { metaDisplay } from "@shared/utils/keyboard";
|
|
|
|
export default function codeMenuItems(
|
|
state: EditorState,
|
|
readOnly: boolean | undefined,
|
|
t: TFunction
|
|
): MenuItem[] {
|
|
const node =
|
|
state.selection instanceof NodeSelection
|
|
? state.selection.node
|
|
: state.selection.$from.node();
|
|
|
|
const frequentLanguages = getFrequentCodeLanguages();
|
|
|
|
const frequentLangMenuItems = frequentLanguages.map((value) => {
|
|
const label = codeLanguages[value]?.label;
|
|
return langToMenuItem({ node, value, label });
|
|
});
|
|
|
|
const remainingLangMenuItems = Object.entries(codeLanguages)
|
|
.filter(
|
|
([value]) =>
|
|
!frequentLanguages.includes(value as keyof typeof codeLanguages)
|
|
)
|
|
.map(([value, item]) => langToMenuItem({ node, value, label: item.label }));
|
|
|
|
const getLanguageMenuItems = () =>
|
|
frequentLangMenuItems.length
|
|
? [
|
|
...frequentLangMenuItems,
|
|
{ name: "separator" },
|
|
...remainingLangMenuItems,
|
|
]
|
|
: remainingLangMenuItems;
|
|
|
|
const isEditingMermaid = !!(mermaidPluginKey.getState(state) as MermaidState)
|
|
?.editingId;
|
|
|
|
return [
|
|
{
|
|
name: "copyToClipboard",
|
|
icon: <CopyIcon />,
|
|
label: readOnly
|
|
? getLabelForLanguage(node.attrs.language ?? "none")
|
|
: undefined,
|
|
tooltip: t("Copy"),
|
|
},
|
|
{
|
|
name: "separator",
|
|
},
|
|
{
|
|
name: "edit_mermaid",
|
|
icon: <EditIcon />,
|
|
tooltip: t("Edit diagram"),
|
|
shortcut: `${metaDisplay} Enter`,
|
|
visible: isMermaid(node) && !isEditingMermaid && !readOnly,
|
|
},
|
|
{
|
|
name: "commentOnMermaid",
|
|
icon: <CommentIcon />,
|
|
tooltip: t("Comment"),
|
|
shortcut: `${metaDisplay}+⌥+M`,
|
|
visible: isMermaid(node) && !isEditingMermaid && !readOnly,
|
|
},
|
|
{
|
|
name: "separator",
|
|
},
|
|
{
|
|
name: "toggleCodeBlockWrap",
|
|
icon: <TextWrapIcon />,
|
|
tooltip: t("Wrap text"),
|
|
active: () => node.attrs.wrap,
|
|
visible: !readOnly && (!isMermaid(node) || isEditingMermaid),
|
|
},
|
|
{
|
|
name: "separator",
|
|
},
|
|
{
|
|
name: "code_block",
|
|
label: getLabelForLanguage(node.attrs.language ?? "none"),
|
|
icon: <ExpandedIcon />,
|
|
children: getLanguageMenuItems(),
|
|
visible: !readOnly,
|
|
},
|
|
];
|
|
}
|
|
|
|
const langToMenuItem = ({
|
|
node,
|
|
value,
|
|
label,
|
|
}: {
|
|
node: ProseMirrorNode;
|
|
value: string;
|
|
label: string;
|
|
}): MenuItem => ({
|
|
name: "code_block",
|
|
label,
|
|
active: () => node.attrs.language === value,
|
|
attrs: {
|
|
language: value,
|
|
},
|
|
});
|