From 5fafdddb1ecc65d94d86f68f0b78b5c7ca8bd874 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Tue, 11 Feb 2025 15:00:42 +0530 Subject: [PATCH 1/5] fix: markdown for mentions fixed --- .../editor/src/core/extensions/extensions.tsx | 2 +- .../extensions/mentions/extension-config.ts | 22 +++++++++++++++++-- .../core/extensions/mentions/extension.tsx | 3 ++- packages/editor/src/core/types/mention.ts | 3 ++- .../components/pages/editor/editor-body.tsx | 5 ++++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/editor/src/core/extensions/extensions.tsx b/packages/editor/src/core/extensions/extensions.tsx index 0b772baf9db..bcf4b5b4a97 100644 --- a/packages/editor/src/core/extensions/extensions.tsx +++ b/packages/editor/src/core/extensions/extensions.tsx @@ -137,7 +137,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => { CustomCodeInlineExtension, Markdown.configure({ html: true, - transformCopiedText: true, + transformCopiedText: false, transformPastedText: true, breaks: true, }), diff --git a/packages/editor/src/core/extensions/mentions/extension-config.ts b/packages/editor/src/core/extensions/mentions/extension-config.ts index 827137a1df1..d03718d8f0d 100644 --- a/packages/editor/src/core/extensions/mentions/extension-config.ts +++ b/packages/editor/src/core/extensions/mentions/extension-config.ts @@ -1,12 +1,15 @@ import { mergeAttributes } from "@tiptap/core"; import Mention, { MentionOptions } from "@tiptap/extension-mention"; +import { MarkdownSerializerState } from "@tiptap/pm/markdown"; +import { Node as NodeType } from "@tiptap/pm/model"; // types import { TMentionHandler } from "@/types"; // local types -import { EMentionComponentAttributeNames } from "./types"; +import { EMentionComponentAttributeNames, TMentionComponentAttributes } from "./types"; export type TMentionExtensionOptions = MentionOptions & { renderComponent: TMentionHandler["renderComponent"]; + getMentionComponentAttributes: TMentionHandler["getMentionComponentAttributes"]; }; export const CustomMentionExtensionConfig = Mention.extend({ @@ -40,9 +43,24 @@ export const CustomMentionExtensionConfig = Mention.extend { - const { searchCallback, renderComponent } = props; + const { searchCallback, renderComponent, getMentionComponentAttributes } = props; return CustomMentionExtensionConfig.extend({ addOptions(this) { return { ...this.parent?.(), renderComponent, + getMentionComponentAttributes, }; }, diff --git a/packages/editor/src/core/types/mention.ts b/packages/editor/src/core/types/mention.ts index 20f1ec0dcc6..7ce681d0707 100644 --- a/packages/editor/src/core/types/mention.ts +++ b/packages/editor/src/core/types/mention.ts @@ -1,5 +1,5 @@ // plane types -import { TSearchEntities } from "@plane/types"; +import { IUserLite, TSearchEntities } from "@plane/types"; export type TMentionSuggestion = { entity_identifier: string; @@ -20,6 +20,7 @@ export type TMentionComponentProps = Pick React.ReactNode; + getMentionComponentAttributes?: (entity_identifier: string) => IUserLite | undefined; }; export type TMentionHandler = TReadOnlyMentionHandler & { diff --git a/web/core/components/pages/editor/editor-body.tsx b/web/core/components/pages/editor/editor-body.tsx index 161d63c47cc..7ad6c38ef8d 100644 --- a/web/core/components/pages/editor/editor-body.tsx +++ b/web/core/components/pages/editor/editor-body.tsx @@ -21,7 +21,7 @@ import { PageContentBrowser, PageContentLoader, PageEditorTitle } from "@/compon import { cn, LIVE_BASE_PATH, LIVE_BASE_URL } from "@/helpers/common.helper"; import { generateRandomColor } from "@/helpers/string.helper"; // hooks -import { useUser } from "@/hooks/store"; +import { useMember, useUser } from "@/hooks/store"; import { useEditorMention } from "@/hooks/use-editor-mention"; import { usePageFilters } from "@/hooks/use-page-filters"; // plane web components @@ -66,6 +66,8 @@ export const PageEditorBody: React.FC = observer((props) => { } = props; // store hooks const { data: currentUser } = useUser(); + const { getUserDetails } = useMember(); + // derived values const { id: pageId, name: pageTitle, isContentEditable, updateTitle } = page; // issue-embed @@ -188,6 +190,7 @@ export const PageEditorBody: React.FC = observer((props) => { return res; }, renderComponent: (props) => , + getMentionComponentAttributes: (id: string) => getUserDetails(id), }} embedHandler={{ issue: issueEmbedProps, From a1b91a58a18a72a4fc6a419d706a3a9f7b271556 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Tue, 11 Feb 2025 15:47:43 +0530 Subject: [PATCH 2/5] fix: copying text in mentions --- .../src/core/extensions/mentions/extension-config.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/editor/src/core/extensions/mentions/extension-config.ts b/packages/editor/src/core/extensions/mentions/extension-config.ts index d03718d8f0d..7c53a6c4ae0 100644 --- a/packages/editor/src/core/extensions/mentions/extension-config.ts +++ b/packages/editor/src/core/extensions/mentions/extension-config.ts @@ -35,7 +35,7 @@ export const CustomMentionExtensionConfig = Mention.extend Date: Tue, 11 Feb 2025 15:57:12 +0530 Subject: [PATCH 3/5] fix: refactored the component to use the same function --- .../extensions/mentions/extension-config.ts | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/packages/editor/src/core/extensions/mentions/extension-config.ts b/packages/editor/src/core/extensions/mentions/extension-config.ts index 7c53a6c4ae0..77401f6d865 100644 --- a/packages/editor/src/core/extensions/mentions/extension-config.ts +++ b/packages/editor/src/core/extensions/mentions/extension-config.ts @@ -35,7 +35,7 @@ export const CustomMentionExtensionConfig = Mention.extend Date: Tue, 11 Feb 2025 16:02:14 +0530 Subject: [PATCH 4/5] chore: renamed funcion name --- .../editor/src/core/extensions/mentions/extension-config.ts | 6 +++--- packages/editor/src/core/extensions/mentions/extension.tsx | 4 ++-- packages/editor/src/core/types/mention.ts | 2 +- web/core/components/pages/editor/editor-body.tsx | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/editor/src/core/extensions/mentions/extension-config.ts b/packages/editor/src/core/extensions/mentions/extension-config.ts index 77401f6d865..a8921648a0d 100644 --- a/packages/editor/src/core/extensions/mentions/extension-config.ts +++ b/packages/editor/src/core/extensions/mentions/extension-config.ts @@ -9,7 +9,7 @@ import { EMentionComponentAttributeNames, TMentionComponentAttributes } from "./ export type TMentionExtensionOptions = MentionOptions & { renderComponent: TMentionHandler["renderComponent"]; - getMentionComponentAttributes: TMentionHandler["getMentionComponentAttributes"]; + getMentionedEntityDetails: TMentionHandler["getMentionedEntityDetails"]; }; export const CustomMentionExtensionConfig = Mention.extend({ @@ -63,6 +63,6 @@ export const CustomMentionExtensionConfig = Mention.extend { - const { searchCallback, renderComponent, getMentionComponentAttributes } = props; + const { searchCallback, renderComponent, getMentionedEntityDetails } = props; return CustomMentionExtensionConfig.extend({ addOptions(this) { return { ...this.parent?.(), renderComponent, - getMentionComponentAttributes, + getMentionedEntityDetails, }; }, diff --git a/packages/editor/src/core/types/mention.ts b/packages/editor/src/core/types/mention.ts index 7ce681d0707..5d75cca9066 100644 --- a/packages/editor/src/core/types/mention.ts +++ b/packages/editor/src/core/types/mention.ts @@ -20,7 +20,7 @@ export type TMentionComponentProps = Pick React.ReactNode; - getMentionComponentAttributes?: (entity_identifier: string) => IUserLite | undefined; + getMentionedEntityDetails?: (entity_identifier: string) => IUserLite | undefined; }; export type TMentionHandler = TReadOnlyMentionHandler & { diff --git a/web/core/components/pages/editor/editor-body.tsx b/web/core/components/pages/editor/editor-body.tsx index 7ad6c38ef8d..aaac4389fcf 100644 --- a/web/core/components/pages/editor/editor-body.tsx +++ b/web/core/components/pages/editor/editor-body.tsx @@ -190,7 +190,7 @@ export const PageEditorBody: React.FC = observer((props) => { return res; }, renderComponent: (props) => , - getMentionComponentAttributes: (id: string) => getUserDetails(id), + getMentionedEntityDetails: (id: string) => getUserDetails(id), }} embedHandler={{ issue: issueEmbedProps, From cd146aa60820ca69b95a03d5dd2134dca9e0d1f1 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Wed, 19 Mar 2025 17:26:00 +0530 Subject: [PATCH 5/5] fix: store hooks fixed --- packages/editor/src/core/types/mention.ts | 2 +- .../editor/lite-text-read-only-editor.tsx | 38 +++++++++++-------- .../components/editor/rich-text-editor.tsx | 7 ++++ .../editor/rich-text-read-only-editor.tsx | 38 +++++++++++-------- .../lite-text-editor/lite-text-editor.tsx | 5 +++ .../lite-text-read-only-editor.tsx | 6 +++ .../rich-text-editor/rich-text-editor.tsx | 5 +++ .../rich-text-read-only-editor.tsx | 6 +++ .../components/pages/editor/editor-body.tsx | 2 +- web/core/components/pages/version/editor.tsx | 5 +++ 10 files changed, 82 insertions(+), 32 deletions(-) diff --git a/packages/editor/src/core/types/mention.ts b/packages/editor/src/core/types/mention.ts index 5d75cca9066..b7a65f8b4c9 100644 --- a/packages/editor/src/core/types/mention.ts +++ b/packages/editor/src/core/types/mention.ts @@ -20,7 +20,7 @@ export type TMentionComponentProps = Pick React.ReactNode; - getMentionedEntityDetails?: (entity_identifier: string) => IUserLite | undefined; + getMentionedEntityDetails?: (entity_identifier: string) => { display_name: string } | undefined; }; export type TMentionHandler = TReadOnlyMentionHandler & { diff --git a/space/core/components/editor/lite-text-read-only-editor.tsx b/space/core/components/editor/lite-text-read-only-editor.tsx index 5f936baec5a..e4be5693518 100644 --- a/space/core/components/editor/lite-text-read-only-editor.tsx +++ b/space/core/components/editor/lite-text-read-only-editor.tsx @@ -6,6 +6,8 @@ import { EditorMentionsRoot } from "@/components/editor"; // helpers import { cn } from "@/helpers/common.helper"; import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper"; +// store hooks +import { useMember } from "@/hooks/store"; type LiteTextReadOnlyEditorWrapperProps = Omit< ILiteTextReadOnlyEditor, @@ -15,21 +17,27 @@ type LiteTextReadOnlyEditorWrapperProps = Omit< }; export const LiteTextReadOnlyEditor = React.forwardRef( - ({ anchor, ...props }, ref) => ( - , - }} - {...props} - // overriding the customClassName to add relative class passed - containerClassName={cn(props.containerClassName, "relative p-2")} - /> - ) + ({ anchor, ...props }, ref) => { + const { getMemberById } = useMember(); + return ( + , + getMentionedEntityDetails: (id: string) => ({ + display_name: getMemberById(id)?.member__display_name ?? "", + }), + }} + {...props} + // overriding the customClassName to add relative class passed + containerClassName={cn(props.containerClassName, "relative p-2")} + /> + ); + } ); LiteTextReadOnlyEditor.displayName = "LiteTextReadOnlyEditor"; diff --git a/space/core/components/editor/rich-text-editor.tsx b/space/core/components/editor/rich-text-editor.tsx index 96f4900548c..f7f4358770c 100644 --- a/space/core/components/editor/rich-text-editor.tsx +++ b/space/core/components/editor/rich-text-editor.tsx @@ -5,6 +5,8 @@ import { EditorRefApi, IRichTextEditor, RichTextEditorWithRef } from "@plane/edi import { EditorMentionsRoot } from "@/components/editor"; // helpers import { getEditorFileHandlers } from "@/helpers/editor.helper"; +// store hooks +import { useMember } from "@/hooks/store"; interface RichTextEditorWrapperProps extends Omit { @@ -12,12 +14,17 @@ interface RichTextEditorWrapperProps } export const RichTextEditor = forwardRef((props, ref) => { + const { getMemberById } = useMember(); + const { containerClassName, uploadFile, ...rest } = props; return ( , + getMentionedEntityDetails: (id: string) => ({ + display_name: getMemberById(id)?.member__display_name ?? "", + }), }} ref={ref} disabledExtensions={[]} diff --git a/space/core/components/editor/rich-text-read-only-editor.tsx b/space/core/components/editor/rich-text-read-only-editor.tsx index 76075f29656..5bc6ccfdcc0 100644 --- a/space/core/components/editor/rich-text-read-only-editor.tsx +++ b/space/core/components/editor/rich-text-read-only-editor.tsx @@ -6,6 +6,8 @@ import { EditorMentionsRoot } from "@/components/editor"; // helpers import { cn } from "@/helpers/common.helper"; import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper"; +// store hooks +import { useMember } from "@/hooks/store"; type RichTextReadOnlyEditorWrapperProps = Omit< IRichTextReadOnlyEditor, @@ -15,21 +17,27 @@ type RichTextReadOnlyEditorWrapperProps = Omit< }; export const RichTextReadOnlyEditor = React.forwardRef( - ({ anchor, ...props }, ref) => ( - , - }} - {...props} - // overriding the customClassName to add relative class passed - containerClassName={cn("relative p-0 border-none", props.containerClassName)} - /> - ) + ({ anchor, ...props }, ref) => { + const { getMemberById } = useMember(); + return ( + , + getMentionedEntityDetails: (id: string) => ({ + display_name: getMemberById(id)?.member__display_name ?? "", + }), + }} + {...props} + // overriding the customClassName to add relative class passed + containerClassName={cn("relative p-0 border-none", props.containerClassName)} + /> + ); + } ); RichTextReadOnlyEditor.displayName = "RichTextReadOnlyEditor"; diff --git a/web/core/components/editor/lite-text-editor/lite-text-editor.tsx b/web/core/components/editor/lite-text-editor/lite-text-editor.tsx index 82cbd12257b..4456fcde80c 100644 --- a/web/core/components/editor/lite-text-editor/lite-text-editor.tsx +++ b/web/core/components/editor/lite-text-editor/lite-text-editor.tsx @@ -13,6 +13,8 @@ import { getEditorFileHandlers } from "@/helpers/editor.helper"; import { isCommentEmpty } from "@/helpers/string.helper"; // hooks import { useEditorMention } from "@/hooks/use-editor-mention"; +// store hooks +import { useMember } from "@/hooks/store"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; import { useFileSize } from "@/plane-web/hooks/use-file-size"; @@ -57,6 +59,8 @@ export const LiteTextEditor = React.forwardRef @@ -98,6 +102,7 @@ export const LiteTextEditor = React.forwardRef , + getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }), }} placeholder={placeholder} containerClassName={cn(containerClassName, "relative")} diff --git a/web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx b/web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx index 1272604e2d6..0dbe1984022 100644 --- a/web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx +++ b/web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx @@ -8,6 +8,8 @@ import { cn } from "@/helpers/common.helper"; import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; +// store hooks +import { useMember } from "@/hooks/store"; type LiteTextReadOnlyEditorWrapperProps = Omit< ILiteTextReadOnlyEditor, @@ -19,6 +21,9 @@ type LiteTextReadOnlyEditorWrapperProps = Omit< export const LiteTextReadOnlyEditor = React.forwardRef( ({ workspaceSlug, projectId, ...props }, ref) => { + // store hooks + const { getUserDetails } = useMember(); + // editor flaggings const { liteTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString()); @@ -32,6 +37,7 @@ export const LiteTextReadOnlyEditor = React.forwardRef , + getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }), }} {...props} // overriding the containerClassName to add relative class passed diff --git a/web/core/components/editor/rich-text-editor/rich-text-editor.tsx b/web/core/components/editor/rich-text-editor/rich-text-editor.tsx index e3b5aa7a313..c393b611724 100644 --- a/web/core/components/editor/rich-text-editor/rich-text-editor.tsx +++ b/web/core/components/editor/rich-text-editor/rich-text-editor.tsx @@ -13,6 +13,8 @@ import { useEditorMention } from "@/hooks/use-editor-mention"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; import { useFileSize } from "@/plane-web/hooks/use-file-size"; +// store hooks +import { useMember } from "@/hooks/store"; interface RichTextEditorWrapperProps extends Omit { @@ -26,6 +28,8 @@ interface RichTextEditorWrapperProps export const RichTextEditor = forwardRef((props, ref) => { const { containerClassName, workspaceSlug, workspaceId, projectId, searchMentionCallback, uploadFile, ...rest } = props; + // store hooks + const { getUserDetails } = useMember(); // editor flaggings const { richTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString()); // use editor mention @@ -53,6 +57,7 @@ export const RichTextEditor = forwardRef , + getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }), }} {...rest} containerClassName={cn("relative pl-3", containerClassName)} diff --git a/web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx b/web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx index a21e8b668b2..97c792775c5 100644 --- a/web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx +++ b/web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx @@ -6,6 +6,8 @@ import { EditorMentionsRoot } from "@/components/editor"; // helpers import { cn } from "@/helpers/common.helper"; import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper"; +// store hooks +import { useMember } from "@/hooks/store"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; @@ -19,6 +21,9 @@ type RichTextReadOnlyEditorWrapperProps = Omit< export const RichTextReadOnlyEditor = React.forwardRef( ({ workspaceSlug, projectId, ...props }, ref) => { + // store hooks + const { getUserDetails } = useMember(); + // editor flaggings const { richTextEditor: disabledExtensions } = useEditorFlagging(workspaceSlug?.toString()); @@ -32,6 +37,7 @@ export const RichTextReadOnlyEditor = React.forwardRef , + getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }), }} {...props} // overriding the containerClassName to add relative class passed diff --git a/web/core/components/pages/editor/editor-body.tsx b/web/core/components/pages/editor/editor-body.tsx index aaac4389fcf..2d3b4b36ca7 100644 --- a/web/core/components/pages/editor/editor-body.tsx +++ b/web/core/components/pages/editor/editor-body.tsx @@ -190,7 +190,7 @@ export const PageEditorBody: React.FC = observer((props) => { return res; }, renderComponent: (props) => , - getMentionedEntityDetails: (id: string) => getUserDetails(id), + getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }), }} embedHandler={{ issue: issueEmbedProps, diff --git a/web/core/components/pages/version/editor.tsx b/web/core/components/pages/version/editor.tsx index 0beffa6f358..397b2ff029a 100644 --- a/web/core/components/pages/version/editor.tsx +++ b/web/core/components/pages/version/editor.tsx @@ -12,6 +12,8 @@ import { EditorMentionsRoot } from "@/components/editor"; import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper"; // hooks import { usePageFilters } from "@/hooks/use-page-filters"; +// store hooks +import { useMember } from "@/hooks/store"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; import { useIssueEmbed } from "@/plane-web/hooks/use-issue-embed"; @@ -25,6 +27,8 @@ export type TVersionEditorProps = { export const PagesVersionEditor: React.FC = observer((props) => { const { activeVersion, currentVersionDescription, isCurrentVersionActive, versionDetails } = props; + // store hooks + const { getUserDetails } = useMember(); // params const { workspaceSlug, projectId } = useParams(); // editor flaggings @@ -101,6 +105,7 @@ export const PagesVersionEditor: React.FC = observer((props })} mentionHandler={{ renderComponent: (props) => , + getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }), }} embedHandler={{ issue: {