Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
dc8c2dc
chore: refactor editor
iam-vipin Jun 2, 2025
85659a5
Merge branch 'preview' into chore-refactor_editor
iam-vipin Jun 19, 2025
d9bcc1e
sync changes
iam-vipin Jun 20, 2025
0d7b5cb
feat: api service update
iam-vipin Jun 20, 2025
13a2943
Merge branch 'preview' into chore-refactor_editor
iam-vipin Jun 20, 2025
98386a0
refactor : update sync
iam-vipin Jun 20, 2025
a435baa
fix : package sync
iam-vipin Jun 20, 2025
a92b482
fix: requested changes
iam-vipin Jun 20, 2025
13f08bb
fix : embedhandler type
iam-vipin Jun 20, 2025
4e87603
fix : remove commands
iam-vipin Jun 20, 2025
c2df565
refactor : space
iam-vipin Jun 25, 2025
96071bf
refactor : rich lite editors
iam-vipin Jun 25, 2025
0f82085
refactor : minor ce changes
iam-vipin Jul 24, 2025
84d0da9
Merge branch 'preview' into chore-refactor_editor
iam-vipin Jul 24, 2025
fc3d923
chore : minor ui fix
iam-vipin Jul 24, 2025
735fe53
package: tldjs
iam-vipin Jul 24, 2025
a584867
Merge branch 'preview' into chore-refactor_editor
iam-vipin Aug 1, 2025
44443d4
refactor : remove tldjs
iam-vipin Aug 8, 2025
5d084ce
refactor: flagged
iam-vipin Aug 8, 2025
d0e570c
Merge branch 'preview' into chore-refactor_editor
iam-vipin Aug 8, 2025
7803d56
refactor: flagged
iam-vipin Aug 8, 2025
16c602a
chore : remove disbaled check in menu
iam-vipin Aug 8, 2025
471878a
refactor: fix space
iam-vipin Aug 8, 2025
067f020
refactor: NodeViewProps
iam-vipin Aug 8, 2025
5bbd8ad
refactor: type
iam-vipin Aug 8, 2025
6e3940a
refactor : update community types
iam-vipin Aug 19, 2025
273fb62
Merge branch 'preview' into chore-refactor_editor
iam-vipin Aug 19, 2025
3eb0e04
refactor : remove external embed CE
iam-vipin Aug 20, 2025
f19456b
remove : external embed config from ce
iam-vipin Aug 21, 2025
b378d16
refactor : update disabled
iam-vipin Aug 22, 2025
294318b
chore: pass disabled
iam-vipin Aug 22, 2025
696a4b5
chore : update utils
iam-vipin Aug 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/live/src/core/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export abstract class APIService {
this.axiosInstance = axios.create({
baseURL,
withCredentials: true,
timeout: 20000,
});
}

Expand Down
2 changes: 1 addition & 1 deletion apps/space/helpers/string.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const isCommentEmpty = (comment: string | undefined): boolean => {
return (
comment?.trim() === "" ||
comment === "<p></p>" ||
isEmptyHtmlString(comment ?? "", ["img", "mention-component", "image-component"])
isEmptyHtmlString(comment ?? "", ["img", "mention-component", "image-component", "embed-component"])
);
};

Expand Down
4 changes: 2 additions & 2 deletions apps/web/core/components/editor/lite-text/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from "react";
// plane imports
// plane constants
import { EIssueCommentAccessSpecifier } from "@plane/constants";
// plane imports
import { type EditorRefApi, type ILiteTextEditorProps, LiteTextEditorWithRef, type TFileHandler } from "@plane/editor";
import { useTranslation } from "@plane/i18n";
import type { MakeOptional } from "@plane/types";
Expand Down Expand Up @@ -87,7 +88,6 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
// derived values
const isEmpty = isCommentEmpty(props.initialValue);
const editorRef = isMutableRefObject<EditorRefApi>(ref) ? ref.current : null;

return (
<div
className={cn(
Expand Down
1 change: 0 additions & 1 deletion apps/web/core/components/editor/sticky-editor/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export const StickyEditor = React.forwardRef<EditorRefApi, StickyEditorWrapperPr
}
// derived values
const editorRef = isMutableRefObject<EditorRefApi>(ref) ? ref.current : null;

return (
<div
className={cn("relative border border-custom-border-200 rounded", parentClassName)}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const nextConfig = {
return [
{
source: "/(.*)?",
headers: [{ key: "X-Frame-Options", value: "SAMEORIGIN" }],
headers: [{ key: "X-Frame-Options", value: "DENY" }],
},
];
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ const CollaborativeDocumentEditor: React.FC<ICollaborativeDocumentEditorProps> =
isTouchDevice={!!isTouchDevice}
isLoading={!hasServerSynced && !hasServerConnectionFailed}
tabIndex={tabIndex}
flaggedExtensions={flaggedExtensions}
disabledExtensions={disabledExtensions}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ const DocumentEditor = (props: IDocumentEditorProps) => {
initialValue: value,
mentionHandler,
onChange,
embedHandler,
});

const editorContainerClassName = getEditorClassNames({
Expand All @@ -98,6 +99,8 @@ const DocumentEditor = (props: IDocumentEditorProps) => {
editorContainerClassName={cn(editorContainerClassName, "document-editor")}
id={id}
isTouchDevice={!!isTouchDevice}
flaggedExtensions={flaggedExtensions}
disabledExtensions={disabledExtensions}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { cn } from "@plane/utils";
import { DocumentContentLoader, EditorContainer, EditorContentWrapper } from "@/components/editors";
import { AIFeaturesMenu, BlockMenu, EditorBubbleMenu } from "@/components/menus";
// types
import { TAIHandler, TDisplayConfig } from "@/types";
import { IEditorProps, TAIHandler, TDisplayConfig } from "@/types";

type Props = {
aiHandler?: TAIHandler;
Expand All @@ -18,6 +18,8 @@ type Props = {
isLoading?: boolean;
isTouchDevice: boolean;
tabIndex?: number;
flaggedExtensions?: IEditorProps["flaggedExtensions"];
disabledExtensions?: IEditorProps["disabledExtensions"];
};

export const PageRenderer = (props: Props) => {
Expand All @@ -32,6 +34,8 @@ export const PageRenderer = (props: Props) => {
isLoading,
isTouchDevice,
tabIndex,
flaggedExtensions,
disabledExtensions,
} = props;

return (
Expand All @@ -54,7 +58,11 @@ export const PageRenderer = (props: Props) => {
{editor.isEditable && !isTouchDevice && (
<div>
{bubbleMenuEnabled && <EditorBubbleMenu editor={editor} />}
<BlockMenu editor={editor} />
<BlockMenu
editor={editor}
flaggedExtensions={flaggedExtensions}
disabledExtensions={disabledExtensions}
/>
<AIFeaturesMenu menu={aiHandler?.menu} />
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const EditorWrapper: React.FC<Props> = (props) => {
placeholder,
tabIndex,
value,
embedHandler,
} = props;

const editor = useEditor({
Expand All @@ -65,6 +66,7 @@ export const EditorWrapper: React.FC<Props> = (props) => {
placeholder,
tabIndex,
value,
embedHandler,
});

const editorContainerClassName = getEditorClassNames({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { autoUpdate, flip, hide, shift, useDismiss, useFloating, useInteractions } from "@floating-ui/react";
import { Editor, useEditorState } from "@tiptap/react";
import { FC, useCallback, useEffect, useRef, useState } from "react";

// components
import { LinkView, LinkViewProps } from "@/components/links";
import { CORE_EXTENSIONS } from "@/constants/extension";
// components
import { getExtensionStorage } from "@/helpers/get-extension-storage";

type Props = {
editor: Editor;
Expand All @@ -18,7 +22,7 @@ export const LinkViewContainer: FC<Props> = ({ editor, containerRef }) => {
const editorState = useEditorState({
editor,
selector: ({ editor }: { editor: Editor }) => ({
linkExtensionStorage: editor.storage.link,
linkExtensionStorage: getExtensionStorage(editor, CORE_EXTENSIONS.CUSTOM_LINK),
}),
});

Expand Down
3 changes: 3 additions & 0 deletions packages/editor/src/core/components/menus/block-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import { useCallback, useEffect, useRef } from "react";
import tippy, { Instance } from "tippy.js";
// constants
import { CORE_EXTENSIONS } from "@/constants/extension";
import { IEditorProps } from "@/types";

type Props = {
editor: Editor;
flaggedExtensions?: IEditorProps["flaggedExtensions"];
disabledExtensions?: IEditorProps["disabledExtensions"];
};

export const BlockMenu = (props: Props) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ declare module "@tiptap/core" {
export type CustomLinkStorage = {
isPreviewOpen: boolean;
posToInsert: { from: number; to: number };
isBubbleMenuOpen: boolean;
};

export const CustomLinkExtension = Mark.create<LinkOptions, CustomLinkStorage>({
Expand Down
6 changes: 5 additions & 1 deletion packages/editor/src/core/extensions/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
// plane editor extensions
import { CoreEditorAdditionalExtensions } from "@/plane-editor/extensions";
// types
import type { IEditorProps } from "@/types";
import type { IEditorProps, TEmbedConfig } from "@/types";
// local imports
import { CustomImageExtension } from "./custom-image/extension";
import { EmojiExtension } from "./emoji/extension";
Expand All @@ -45,9 +45,11 @@ type TArguments = Pick<
| "mentionHandler"
| "placeholder"
| "tabIndex"
| "embedHandler"
> & {
enableHistory: boolean;
editable: boolean;
embedHandler?: TEmbedConfig;
};

export const CoreEditorExtensions = (args: TArguments): Extensions => {
Expand All @@ -60,6 +62,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {
mentionHandler,
placeholder,
tabIndex,
embedHandler,
editable,
} = args;

Expand Down Expand Up @@ -115,6 +118,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {
disabledExtensions,
flaggedExtensions,
fileHandler,
embedHandler,
}),
];

Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/core/hooks/use-collaborative-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorHookProps) =>
);

const editor = useEditor({
embedHandler,
disabledExtensions,
id,
editable,
Expand Down
2 changes: 2 additions & 0 deletions packages/editor/src/core/hooks/use-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const useEditor = (props: TEditorHookProps) => {
onAssetChange,
onChange,
onEditorFocus,
embedHandler,
onTransaction,
placeholder,
provider,
Expand Down Expand Up @@ -63,6 +64,7 @@ export const useEditor = (props: TEditorHookProps) => {
mentionHandler,
placeholder,
tabIndex,
embedHandler,
}),
...extensions,
],
Expand Down
6 changes: 6 additions & 0 deletions packages/editor/src/core/plugins/drag-handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const generalSelectors = [
".image-component",
".image-upload-component",
".editor-callout-component",
".editor-embed-component",
].join(", ");

const maxScrollSpeed = 20;
Expand Down Expand Up @@ -105,6 +106,11 @@ export const nodeDOMAtCoords = (coords: { x: number; y: number }) => {
continue;
}

// Skip elements inside .editor-embed-component
if (elem.closest(".editor-embed-component") && !elem.matches(".editor-embed-component")) {
continue;
}

// apply general selector
if (elem.matches(generalSelectors)) {
return elem;
Expand Down
7 changes: 6 additions & 1 deletion packages/editor/src/core/types/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Content, Extensions, JSONContent, RawCommands } from "@tiptap/core
import type { MarkType, NodeType } from "@tiptap/pm/model";
import type { Selection } from "@tiptap/pm/state";
import type { EditorProps, EditorView } from "@tiptap/pm/view";
import type { NodeViewProps as TNodeViewProps } from "@tiptap/react";
// extension types
import type { TTextAlign } from "@/extensions";
// types
Expand Down Expand Up @@ -48,7 +49,8 @@ export type TEditorCommands =
| "text-align"
| "callout"
| "attachment"
| "emoji";
| "emoji"
| "external-embed";

export type TCommandExtraProps = {
image: {
Expand Down Expand Up @@ -138,6 +140,7 @@ export type IEditorProps = {
editorClassName?: string;
editorProps?: EditorProps;
extensions?: Extensions;
embedHandler?: TEmbedConfig;
flaggedExtensions: TExtensions[];
fileHandler: TFileHandler;
forwardedRef?: React.MutableRefObject<EditorRefApi | null>;
Expand Down Expand Up @@ -191,3 +194,5 @@ export type EditorEvents = {
destroy: never;
ready: { height: number };
};

export type NodeViewProps = TNodeViewProps;
1 change: 1 addition & 0 deletions packages/editor/src/core/types/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type TCoreHookProps = Pick<
| "handleEditorReady"
| "isTouchDevice"
| "onEditorFocus"
| "embedHandler"
>;

export type TEditorHookProps = TCoreHookProps &
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export const isCommentEmpty = (comment: string | undefined): boolean => {
return (
comment?.trim() === "" ||
comment === "<p></p>" ||
isEmptyHtmlString(comment ?? "", ["img", "mention-component", "image-component"])
isEmptyHtmlString(comment ?? "", ["img", "mention-component", "image-component", "embed-component"])
);
};

Expand Down
Loading