diff --git a/packages/editor/core/src/ui/hooks/use-editor.tsx b/packages/editor/core/src/ui/hooks/use-editor.tsx
index bd349f3ef..d30e8ca89 100644
--- a/packages/editor/core/src/ui/hooks/use-editor.tsx
+++ b/packages/editor/core/src/ui/hooks/use-editor.tsx
@@ -14,7 +14,10 @@ import {
interface CustomEditorProps {
uploadFile: UploadImage;
restoreFile: RestoreImage;
- text_html?: string;
+ rerenderOnPropsChange?: {
+ id: string;
+ description_html: string;
+ };
deleteFile: DeleteImage;
cancelUploadImage?: () => any;
setIsSubmitting?: (
@@ -38,7 +41,7 @@ export const useEditor = ({
cancelUploadImage,
editorProps = {},
value,
- text_html,
+ rerenderOnPropsChange,
extensions = [],
onStart,
onChange,
@@ -79,7 +82,7 @@ export const useEditor = ({
onChange?.(editor.getJSON(), getTrimmedHTML(editor.getHTML()));
},
},
- [text_html],
+ [rerenderOnPropsChange],
);
const editorRef: MutableRefObject = useRef(null);
diff --git a/packages/editor/core/src/ui/hooks/use-read-only-editor.tsx b/packages/editor/core/src/ui/hooks/use-read-only-editor.tsx
index 3207e5e56..3339e095f 100644
--- a/packages/editor/core/src/ui/hooks/use-read-only-editor.tsx
+++ b/packages/editor/core/src/ui/hooks/use-read-only-editor.tsx
@@ -1,10 +1,5 @@
import { useEditor as useCustomEditor, Editor } from "@tiptap/react";
-import {
- useImperativeHandle,
- useRef,
- MutableRefObject,
- useEffect,
-} from "react";
+import { useImperativeHandle, useRef, MutableRefObject } from "react";
import { CoreReadOnlyEditorExtensions } from "../read-only/extensions";
import { CoreReadOnlyEditorProps } from "../read-only/props";
import { EditorProps } from "@tiptap/pm/view";
@@ -15,6 +10,10 @@ interface CustomReadOnlyEditorProps {
forwardedRef?: any;
extensions?: any;
editorProps?: EditorProps;
+ rerenderOnPropsChange?: {
+ id: string;
+ description_html: string;
+ };
mentionHighlights?: string[];
mentionSuggestions?: IMentionSuggestion[];
}
@@ -24,33 +23,29 @@ export const useReadOnlyEditor = ({
forwardedRef,
extensions = [],
editorProps = {},
+ rerenderOnPropsChange,
mentionHighlights,
mentionSuggestions,
}: CustomReadOnlyEditorProps) => {
- const editor = useCustomEditor({
- editable: false,
- content:
- typeof value === "string" && value.trim() !== "" ? value : "",
- editorProps: {
- ...CoreReadOnlyEditorProps,
- ...editorProps,
+ const editor = useCustomEditor(
+ {
+ editable: false,
+ content:
+ typeof value === "string" && value.trim() !== "" ? value : "",
+ editorProps: {
+ ...CoreReadOnlyEditorProps,
+ ...editorProps,
+ },
+ extensions: [
+ ...CoreReadOnlyEditorExtensions({
+ mentionSuggestions: mentionSuggestions ?? [],
+ mentionHighlights: mentionHighlights ?? [],
+ }),
+ ...extensions,
+ ],
},
- extensions: [
- ...CoreReadOnlyEditorExtensions({
- mentionSuggestions: mentionSuggestions ?? [],
- mentionHighlights: mentionHighlights ?? [],
- }),
- ...extensions,
- ],
- });
-
- const hasIntiliazedContent = useRef(false);
- useEffect(() => {
- if (editor && !value && !hasIntiliazedContent.current) {
- editor.commands.setContent(value);
- hasIntiliazedContent.current = true;
- }
- }, [value]);
+ [rerenderOnPropsChange],
+ );
const editorRef: MutableRefObject = useRef(null);
editorRef.current = editor;
diff --git a/packages/editor/document-editor/package.json b/packages/editor/document-editor/package.json
index 8789f37ee..4e0eeffb2 100644
--- a/packages/editor/document-editor/package.json
+++ b/packages/editor/document-editor/package.json
@@ -28,15 +28,22 @@
"react-dom": "18.2.0"
},
"dependencies": {
- "@plane/ui": "*",
"@plane/editor-core": "*",
"@plane/editor-extensions": "*",
"@plane/editor-types": "*",
+ "@plane/ui": "*",
"@tiptap/core": "^2.1.7",
"@tiptap/extension-placeholder": "^2.1.11",
+ "@tiptap/pm": "^2.1.12",
+ "@tiptap/suggestion": "^2.1.12",
+ "@types/node": "18.15.3",
+ "@types/react": "^18.2.39",
+ "@types/react-dom": "18.0.11",
"eslint": "8.36.0",
"eslint-config-next": "13.2.4",
- "react-popper": "^2.3.0"
+ "react-popper": "^2.3.0",
+ "tippy.js": "^6.3.7",
+ "uuid": "^9.0.1"
},
"devDependencies": {
"@types/node": "18.15.3",
diff --git a/packages/editor/document-editor/src/ui/components/content-browser.tsx b/packages/editor/document-editor/src/ui/components/content-browser.tsx
index bb0e3fb8b..68f6469b8 100644
--- a/packages/editor/document-editor/src/ui/components/content-browser.tsx
+++ b/packages/editor/document-editor/src/ui/components/content-browser.tsx
@@ -1,4 +1,8 @@
-import { HeadingComp, SubheadingComp } from "./heading-component";
+import {
+ HeadingComp,
+ HeadingThreeComp,
+ SubheadingComp,
+} from "./heading-component";
import { IMarking } from "..";
import { Editor } from "@tiptap/react";
import { scrollSummary } from "../utils/editor-summary-utils";
@@ -22,11 +26,16 @@ export const ContentBrowser = (props: ContentBrowserProps) => {
onClick={() => scrollSummary(editor, marking)}
heading={marking.text}
/>
- ) : (
+ ) : marking.level === 2 ? (
scrollSummary(editor, marking)}
subHeading={marking.text}
/>
+ ) : (
+ scrollSummary(editor, marking)}
+ />
),
)
) : (
diff --git a/packages/editor/document-editor/src/ui/components/editor-header.tsx b/packages/editor/document-editor/src/ui/components/editor-header.tsx
index 74372ae16..6d548669e 100644
--- a/packages/editor/document-editor/src/ui/components/editor-header.tsx
+++ b/packages/editor/document-editor/src/ui/components/editor-header.tsx
@@ -1,7 +1,8 @@
import { Editor } from "@tiptap/react";
-import { Archive, Info, Lock } from "lucide-react";
-import { IMarking, UploadImage } from "..";
+import { Archive, RefreshCw, Lock } from "lucide-react";
+import { IMarking } from "..";
import { FixedMenu } from "../menu";
+import { UploadImage } from "@plane/editor-types";
import { DocumentDetails } from "../types/editor-types";
import { AlertLabel } from "./alert-label";
import {
@@ -26,6 +27,7 @@ interface IEditorHeader {
isSubmitting: "submitting" | "submitted" | "saved",
) => void;
documentDetails: DocumentDetails;
+ isSubmitting?: "submitting" | "submitted" | "saved";
}
export const EditorHeader = (props: IEditorHeader) => {
@@ -42,6 +44,7 @@ export const EditorHeader = (props: IEditorHeader) => {
KanbanMenuOptions,
isArchived,
isLocked,
+ isSubmitting,
} = props;
return (
@@ -82,6 +85,21 @@ export const EditorHeader = (props: IEditorHeader) => {
label={`Archived at ${new Date(archivedAt).toLocaleString()}`}
/>
)}
+
+ {!isLocked && !isArchived ? (
+
+ {isSubmitting !== "submitted" && isSubmitting !== "saved" && (
+
+ )}
+
+ {isSubmitting === "submitting" ? "Saving..." : "Saved"}
+
+
+ ) : null}
{!isArchived && }
diff --git a/packages/editor/document-editor/src/ui/components/heading-component.tsx b/packages/editor/document-editor/src/ui/components/heading-component.tsx
index ea31b67c1..d8ceea8f9 100644
--- a/packages/editor/document-editor/src/ui/components/heading-component.tsx
+++ b/packages/editor/document-editor/src/ui/components/heading-component.tsx
@@ -29,3 +29,19 @@ export const SubheadingComp = ({
{subHeading}
);
+
+export const HeadingThreeComp = ({
+ heading,
+ onClick,
+}: {
+ heading: string;
+ onClick: (event: React.MouseEvent) => void;
+}) => (
+
+ {heading}
+
+);
diff --git a/packages/editor/document-editor/src/ui/components/info-popover.tsx b/packages/editor/document-editor/src/ui/components/info-popover.tsx
index d42e32a8d..41d131afb 100644
--- a/packages/editor/document-editor/src/ui/components/info-popover.tsx
+++ b/packages/editor/document-editor/src/ui/components/info-popover.tsx
@@ -48,7 +48,7 @@ export const InfoPopover: React.FC = (props) => {
onMouseEnter={() => setIsPopoverOpen(true)}
onMouseLeave={() => setIsPopoverOpen(false)}
>
-