From 3ec123dc5ac884bd3eb8aff6f39e67a9c0a043a8 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Thu, 25 Jul 2024 18:15:21 +0530
Subject: [PATCH 1/3] fix: image resizer error
---
.../components/editors/document/editor.tsx | 3 +-
.../editors/document/page-renderer.tsx | 8 +-
.../editors/document/read-only-editor.tsx | 6 +-
.../components/editors/editor-container.tsx | 7 +-
.../components/editors/editor-content.tsx | 7 +-
.../components/editors/editor-wrapper.tsx | 7 +-
.../editors/read-only-editor-wrapper.tsx | 6 +-
.../core/extensions/image/image-resize.tsx | 136 ++++++++++--------
.../core/extensions/mentions/extension.tsx | 3 +-
.../src/core/extensions/slash-commands.tsx | 3 +-
packages/editor/src/core/types/editor.ts | 3 +-
.../peek-overview/comment/add-comment.tsx | 1 +
.../comment/comment-detail-card.tsx | 3 +-
.../issues/peek-overview/issue-details.tsx | 1 +
.../core/modals/gpt-assistant-popover.tsx | 13 +-
.../create-edit-modal/issue-description.tsx | 1 +
.../components/issues/description-input.tsx | 1 +
.../issue-activity/comments/comment-card.tsx | 3 +-
.../components/issues/issue-modal/form.tsx | 1 +
.../profile/activity/activity-list.tsx | 1 +
.../activity/profile-activity-list.tsx | 1 +
21 files changed, 128 insertions(+), 87 deletions(-)
diff --git a/packages/editor/src/core/components/editors/document/editor.tsx b/packages/editor/src/core/components/editors/document/editor.tsx
index d39f1b99fc3..6576dacba7e 100644
--- a/packages/editor/src/core/components/editors/document/editor.tsx
+++ b/packages/editor/src/core/components/editors/document/editor.tsx
@@ -78,10 +78,11 @@ const DocumentEditor = (props: IDocumentEditor) => {
return (
);
};
diff --git a/packages/editor/src/core/components/editors/document/page-renderer.tsx b/packages/editor/src/core/components/editors/document/page-renderer.tsx
index 5e1d1ef8a20..9254d52c654 100644
--- a/packages/editor/src/core/components/editors/document/page-renderer.tsx
+++ b/packages/editor/src/core/components/editors/document/page-renderer.tsx
@@ -21,11 +21,12 @@ type IPageRenderer = {
editor: Editor;
editorContainerClassName: string;
hideDragHandle?: () => void;
+ id: string;
tabIndex?: number;
};
export const PageRenderer = (props: IPageRenderer) => {
- const { tabIndex, editor, hideDragHandle, editorContainerClassName } = props;
+ const { editor, editorContainerClassName, hideDragHandle, id, tabIndex } = props;
// states
const [linkViewProps, setLinkViewProps] = useState();
const [isOpen, setIsOpen] = useState(false);
@@ -130,10 +131,11 @@ export const PageRenderer = (props: IPageRenderer) => {
-
+
{editor && editor.isEditable && }
diff --git a/packages/editor/src/core/components/editors/document/read-only-editor.tsx b/packages/editor/src/core/components/editors/document/read-only-editor.tsx
index 9b91d9782e0..b259574e437 100644
--- a/packages/editor/src/core/components/editors/document/read-only-editor.tsx
+++ b/packages/editor/src/core/components/editors/document/read-only-editor.tsx
@@ -13,6 +13,7 @@ import { TEmbedConfig } from "@/plane-editor/types";
import { EditorReadOnlyRefApi, IMentionHighlight } from "@/types";
interface IDocumentReadOnlyEditor {
+ id: string;
initialValue: string;
containerClassName: string;
editorClassName?: string;
@@ -30,6 +31,7 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
containerClassName,
editorClassName = "",
embedHandler,
+ id,
initialValue,
forwardedRef,
tabIndex,
@@ -58,7 +60,9 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
containerClassName,
});
- return ;
+ return (
+
+ );
};
const DocumentReadOnlyEditorWithRef = forwardRef((props, ref) => (
diff --git a/packages/editor/src/core/components/editors/editor-container.tsx b/packages/editor/src/core/components/editors/editor-container.tsx
index 7e515766b97..5c09f42e56f 100644
--- a/packages/editor/src/core/components/editors/editor-container.tsx
+++ b/packages/editor/src/core/components/editors/editor-container.tsx
@@ -4,14 +4,15 @@ import { Editor } from "@tiptap/react";
import { cn } from "@/helpers/common";
interface EditorContainerProps {
+ children: ReactNode;
editor: Editor | null;
editorContainerClassName: string;
- children: ReactNode;
hideDragHandle?: () => void;
+ id: string;
}
export const EditorContainer: FC = (props) => {
- const { editor, editorContainerClassName, hideDragHandle, children } = props;
+ const { children, editor, editorContainerClassName, hideDragHandle, id } = props;
const handleContainerClick = () => {
if (!editor) return;
@@ -54,7 +55,7 @@ export const EditorContainer: FC = (props) => {
return (
= (props) => {
- const { editor, tabIndex, children } = props;
+ const { editor, children, id, tabIndex } = props;
return (
editor?.chain().focus(undefined, { scrollIntoView: false }).run()}>
- {editor?.isActive("image") && editor?.isEditable && }
+ {editor?.isActive("image") && editor?.isEditable && }
{children}
);
diff --git a/packages/editor/src/core/components/editors/editor-wrapper.tsx b/packages/editor/src/core/components/editors/editor-wrapper.tsx
index e5142eeba4c..e9d38432ccd 100644
--- a/packages/editor/src/core/components/editors/editor-wrapper.tsx
+++ b/packages/editor/src/core/components/editors/editor-wrapper.tsx
@@ -21,7 +21,7 @@ export const EditorWrapper: React.FC
= (props) => {
editorClassName = "",
extensions,
hideDragHandleOnMouseLeave,
- id = "",
+ id,
initialValue,
fileHandler,
forwardedRef,
@@ -57,13 +57,14 @@ export const EditorWrapper: React.FC = (props) => {
return (
{children?.(editor)}
-
+
);
diff --git a/packages/editor/src/core/components/editors/read-only-editor-wrapper.tsx b/packages/editor/src/core/components/editors/read-only-editor-wrapper.tsx
index 25da4d9afb8..d75a5d53045 100644
--- a/packages/editor/src/core/components/editors/read-only-editor-wrapper.tsx
+++ b/packages/editor/src/core/components/editors/read-only-editor-wrapper.tsx
@@ -8,7 +8,7 @@ import { useReadOnlyEditor } from "@/hooks/use-read-only-editor";
import { IReadOnlyEditorProps } from "@/types";
export const ReadOnlyEditorWrapper = (props: IReadOnlyEditorProps) => {
- const { containerClassName, editorClassName = "", initialValue, forwardedRef, mentionHandler } = props;
+ const { containerClassName, editorClassName = "", id, initialValue, forwardedRef, mentionHandler } = props;
const editor = useReadOnlyEditor({
initialValue,
@@ -24,9 +24,9 @@ export const ReadOnlyEditorWrapper = (props: IReadOnlyEditorProps) => {
if (!editor) return null;
return (
-
+
-
+
);
diff --git a/packages/editor/src/core/extensions/image/image-resize.tsx b/packages/editor/src/core/extensions/image/image-resize.tsx
index 6be8214d72e..25d5f70a4c7 100644
--- a/packages/editor/src/core/extensions/image/image-resize.tsx
+++ b/packages/editor/src/core/extensions/image/image-resize.tsx
@@ -2,75 +2,85 @@ import { useState } from "react";
import { Editor } from "@tiptap/react";
import Moveable from "react-moveable";
-export const ImageResizer = ({ editor }: { editor: Editor }) => {
+type Props = {
+ editor: Editor;
+ id: string;
+};
+
+export const ImageResizer = (props: Props) => {
+ const { editor, id } = props;
+ // states
+ const [aspectRatio, setAspectRatio] = useState(1);
+
const updateMediaSize = () => {
- const imageInfo = document.querySelector(".ProseMirror-selectednode") as HTMLImageElement;
- if (imageInfo) {
- const selection = editor.state.selection;
+ const imageElement = document.querySelector(
+ `#editor-container-${id}.active-editor .ProseMirror-seclectednode`
+ ) as HTMLImageElement;
- // Use the style width/height if available, otherwise fall back to the element's natural width/height
- const width = imageInfo.style.width
- ? Number(imageInfo.style.width.replace("px", ""))
- : imageInfo.getAttribute("width");
- const height = imageInfo.style.height
- ? Number(imageInfo.style.height.replace("px", ""))
- : imageInfo.getAttribute("height");
+ if (!imageElement) return;
- editor.commands.setImage({
- src: imageInfo.src,
- width: width,
- height: height,
- } as any);
- editor.commands.setNodeSelection(selection.from);
- }
- };
+ const selection = editor.state.selection;
- const [aspectRatio, setAspectRatio] = useState(1);
+ // Use the style width/height if available, otherwise fall back to the element's natural width/height
+ const width = imageElement.style.width
+ ? Number(imageElement.style.width.replace("px", ""))
+ : imageElement.getAttribute("width");
+ const height = imageElement.style.height
+ ? Number(imageElement.style.height.replace("px", ""))
+ : imageElement.getAttribute("height");
+
+ editor.commands.setImage({
+ src: imageElement.src,
+ width: width,
+ height: height,
+ } as any);
+ editor.commands.setNodeSelection(selection.from);
+ };
return (
- <>
- {
- const imageInfo = document.querySelector(".ProseMirror-selectednode") as HTMLImageElement;
- if (imageInfo) {
- const originalWidth = Number(imageInfo.width);
- const originalHeight = Number(imageInfo.height);
- setAspectRatio(originalWidth / originalHeight);
- }
- }}
- onResize={({ target, width, height, delta }) => {
- if (delta[0] || delta[1]) {
- let newWidth, newHeight;
- if (delta[0]) {
- // Width change detected
- newWidth = Math.max(width, 100);
- newHeight = newWidth / aspectRatio;
- } else if (delta[1]) {
- // Height change detected
- newHeight = Math.max(height, 100);
- newWidth = newHeight * aspectRatio;
- }
- target.style.width = `${newWidth}px`;
- target.style.height = `${newHeight}px`;
+ {
+ const imageElement = document.querySelector(
+ `#editor-container-${id}.active-editor .ProseMirror-selectednode`
+ ) as HTMLImageElement;
+ if (imageElement) {
+ const originalWidth = Number(imageElement.width);
+ const originalHeight = Number(imageElement.height);
+ setAspectRatio(originalWidth / originalHeight);
+ }
+ }}
+ onResize={({ target, width, height, delta }) => {
+ if (delta[0] || delta[1]) {
+ let newWidth, newHeight;
+ if (delta[0]) {
+ // Width change detected
+ newWidth = Math.max(width, 100);
+ newHeight = newWidth / aspectRatio;
+ } else if (delta[1]) {
+ // Height change detected
+ newHeight = Math.max(height, 100);
+ newWidth = newHeight * aspectRatio;
}
- }}
- onResizeEnd={() => {
- updateMediaSize();
- }}
- scalable
- renderDirections={["se"]}
- onScale={({ target, transform }) => {
- target.style.transform = transform;
- }}
- />
- >
+ target.style.width = `${newWidth}px`;
+ target.style.height = `${newHeight}px`;
+ }
+ }}
+ onResizeEnd={() => {
+ updateMediaSize();
+ }}
+ scalable
+ renderDirections={["se"]}
+ onScale={({ target, transform }) => {
+ target.style.transform = transform;
+ }}
+ />
);
};
diff --git a/packages/editor/src/core/extensions/mentions/extension.tsx b/packages/editor/src/core/extensions/mentions/extension.tsx
index e5a447c7fe3..93453f625e6 100644
--- a/packages/editor/src/core/extensions/mentions/extension.tsx
+++ b/packages/editor/src/core/extensions/mentions/extension.tsx
@@ -91,7 +91,8 @@ export const CustomMention = ({
// @ts-expect-error - Tippy types are incorrect
popup = tippy("body", {
getReferenceClientRect: props.clientRect,
- appendTo: () => document.querySelector(".active-editor") ?? document.querySelector("#editor-container"),
+ appendTo: () =>
+ document.querySelector(".active-editor") ?? document.querySelector('[id^="editor-container"]'),
content: component.element,
showOnCreate: true,
interactive: true,
diff --git a/packages/editor/src/core/extensions/slash-commands.tsx b/packages/editor/src/core/extensions/slash-commands.tsx
index a84ff5d1627..a61198db2bd 100644
--- a/packages/editor/src/core/extensions/slash-commands.tsx
+++ b/packages/editor/src/core/extensions/slash-commands.tsx
@@ -374,7 +374,8 @@ const renderItems = () => {
editor: props.editor,
});
- const tippyContainer = document.querySelector(".active-editor") ?? document.querySelector("#editor-container");
+ const tippyContainer =
+ document.querySelector(".active-editor") ?? document.querySelector('[id^="editor-container"]');
// @ts-expect-error Tippy overloads are messed up
popup = tippy("body", {
diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts
index 6fa243f8ab7..695082c11fc 100644
--- a/packages/editor/src/core/types/editor.ts
+++ b/packages/editor/src/core/types/editor.ts
@@ -29,7 +29,7 @@ export interface IEditorProps {
editorClassName?: string;
fileHandler: TFileHandler;
forwardedRef?: React.MutableRefObject;
- id?: string;
+ id: string;
initialValue: string;
mentionHandler: {
highlights: () => Promise;
@@ -52,6 +52,7 @@ export interface IReadOnlyEditorProps {
containerClassName?: string;
editorClassName?: string;
forwardedRef?: React.MutableRefObject;
+ id: string;
initialValue: string;
mentionHandler: {
highlights: () => Promise;
diff --git a/space/core/components/issues/peek-overview/comment/add-comment.tsx b/space/core/components/issues/peek-overview/comment/add-comment.tsx
index 60db5631487..a602538e00e 100644
--- a/space/core/components/issues/peek-overview/comment/add-comment.tsx
+++ b/space/core/components/issues/peek-overview/comment/add-comment.tsx
@@ -72,6 +72,7 @@ export const AddComment: React.FC = observer((props) => {
workspaceId={workspaceID?.toString() ?? ""}
workspaceSlug={workspaceSlug?.toString() ?? ""}
ref={editorRef}
+ id="peek-overview-add-comment"
initialValue={
!value || value === "" || (typeof value === "object" && Object.keys(value).length === 0)
? watch("comment_html")
diff --git a/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx b/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx
index 4f36cb55fbc..67738b524da 100644
--- a/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx
+++ b/space/core/components/issues/peek-overview/comment/comment-detail-card.tsx
@@ -105,6 +105,7 @@ export const CommentCard: React.FC = observer((props) => {
workspaceSlug={workspaceSlug?.toString() ?? ""}
onEnterKeyPress={() => handleSubmit(handleCommentUpdate)()}
ref={editorRef}
+ id={comment.id}
initialValue={value}
value={null}
onChange={(comment_json, comment_html) => onChange(comment_html)}
@@ -132,7 +133,7 @@ export const CommentCard: React.FC = observer((props) => {
-
+
diff --git a/space/core/components/issues/peek-overview/issue-details.tsx b/space/core/components/issues/peek-overview/issue-details.tsx
index 8c24ad6441a..b47bfad68cb 100644
--- a/space/core/components/issues/peek-overview/issue-details.tsx
+++ b/space/core/components/issues/peek-overview/issue-details.tsx
@@ -26,6 +26,7 @@ export const PeekOverviewIssueDetails: React.FC = observer((props) => {
{issueDetails.name}
{description !== "" && description !== "" && (
= (props) => {
{prompt && (
Content:
-
+
)}
{response !== "" && (
Response:
- ${response}`} ref={responseRef} />
+ ${response}`}
+ ref={responseRef}
+ />
)}
{invalidResponse && (
diff --git a/web/core/components/inbox/modals/create-edit-modal/issue-description.tsx b/web/core/components/inbox/modals/create-edit-modal/issue-description.tsx
index 7b9ef674972..18cd40944b1 100644
--- a/web/core/components/inbox/modals/create-edit-modal/issue-description.tsx
+++ b/web/core/components/inbox/modals/create-edit-modal/issue-description.tsx
@@ -42,6 +42,7 @@ export const InboxIssueDescription: FC = observer((props
return (
" : data?.description_html}
ref={editorRef}
workspaceSlug={workspaceSlug}
diff --git a/web/core/components/issues/description-input.tsx b/web/core/components/issues/description-input.tsx
index f78bce8536d..b78f0b91f61 100644
--- a/web/core/components/issues/description-input.tsx
+++ b/web/core/components/issues/description-input.tsx
@@ -118,6 +118,7 @@ export const IssueDescriptionInput: FC = observer((p
/>
) : (
diff --git a/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx b/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx
index 8779e2cc95c..0ea9e8f15b2 100644
--- a/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx
+++ b/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx
@@ -143,6 +143,7 @@ export const IssueCommentCard: FC = observer((props) => {
projectId={projectId}
workspaceSlug={workspaceSlug}
ref={editorRef}
+ id={comment.id}
initialValue={watch("comment_html") ?? ""}
value={null}
onChange={(comment_json, comment_html) => setValue("comment_html", comment_html)}
@@ -190,7 +191,7 @@ export const IssueCommentCard: FC = observer((props) => {
)}
)}
-
+
= observer((props) => {
control={control}
render={({ field: { value, onChange } }) => (
= observer((props) => {
= observer((props) => {
Date: Thu, 25 Jul 2024 18:20:59 +0530
Subject: [PATCH 2/3] refactor: created common function to get the active image
element
---
.../src/core/extensions/image/image-resize.tsx | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/packages/editor/src/core/extensions/image/image-resize.tsx b/packages/editor/src/core/extensions/image/image-resize.tsx
index 25d5f70a4c7..c50e3189660 100644
--- a/packages/editor/src/core/extensions/image/image-resize.tsx
+++ b/packages/editor/src/core/extensions/image/image-resize.tsx
@@ -7,15 +7,16 @@ type Props = {
id: string;
};
+const getImageElement = (editorId: string): HTMLImageElement | null =>
+ document.querySelector(`#editor-container-${editorId}.active-editor .ProseMirror-selectednode`);
+
export const ImageResizer = (props: Props) => {
const { editor, id } = props;
// states
const [aspectRatio, setAspectRatio] = useState(1);
const updateMediaSize = () => {
- const imageElement = document.querySelector(
- `#editor-container-${id}.active-editor .ProseMirror-seclectednode`
- ) as HTMLImageElement;
+ const imageElement = getImageElement(id);
if (!imageElement) return;
@@ -39,7 +40,7 @@ export const ImageResizer = (props: Props) => {
return (
{
resizable
throttleResize={0}
onResizeStart={() => {
- const imageElement = document.querySelector(
- `#editor-container-${id}.active-editor .ProseMirror-selectednode`
- ) as HTMLImageElement;
+ const imageElement = getImageElement(id);
if (imageElement) {
const originalWidth = Number(imageElement.width);
const originalHeight = Number(imageElement.height);
From 3a47173265a8d2007ef8b34f5859cd15ab055f0d Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Tue, 30 Jul 2024 14:16:32 +0530
Subject: [PATCH 3/3] fix: build errors
---
web/core/components/pages/editor/editor-body.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/web/core/components/pages/editor/editor-body.tsx b/web/core/components/pages/editor/editor-body.tsx
index 6bc1b2e7bcd..d142800ff88 100644
--- a/web/core/components/pages/editor/editor-body.tsx
+++ b/web/core/components/pages/editor/editor-body.tsx
@@ -153,6 +153,7 @@ export const PageEditorBody: React.FC = observer((props) => {
) : (
"}
handleEditorReady={handleReadOnlyEditorReady}
containerClassName="p-0 pb-64 border-none"