[WIKI-539] refactor: remove lite text read only editor (#7481)
* refactor: remove lite text read only editor * chore: update types
This commit is contained in:
parent
55f06cf546
commit
e0fa6553ae
45 changed files with 280 additions and 758 deletions
|
|
@ -3,12 +3,12 @@ import { observer } from "mobx-react";
|
|||
import { usePathname } from "next/navigation";
|
||||
import { Globe2, Lock } from "lucide-react";
|
||||
// plane imports
|
||||
import type { EditorReadOnlyRefApi } from "@plane/editor";
|
||||
import type { EditorRefApi } from "@plane/editor";
|
||||
import { useHashScroll } from "@plane/hooks";
|
||||
import { EIssueCommentAccessSpecifier, type TCommentsOperations, type TIssueComment } from "@plane/types";
|
||||
import { cn } from "@plane/utils";
|
||||
// components
|
||||
import { LiteTextReadOnlyEditor } from "@/components/editor";
|
||||
import { LiteTextEditor } from "@/components/editor/lite-text";
|
||||
// local imports
|
||||
import { CommentReactions } from "../comment-reaction";
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ type Props = {
|
|||
comment: TIssueComment;
|
||||
disabled: boolean;
|
||||
projectId?: string;
|
||||
readOnlyEditorRef: React.RefObject<EditorReadOnlyRefApi>;
|
||||
readOnlyEditorRef: React.RefObject<EditorRefApi>;
|
||||
showAccessSpecifier: boolean;
|
||||
workspaceId: string;
|
||||
workspaceSlug: string;
|
||||
|
|
@ -67,7 +67,8 @@ export const CommentCardDisplay: React.FC<Props> = observer((props) => {
|
|||
)}
|
||||
</div>
|
||||
)}
|
||||
<LiteTextReadOnlyEditor
|
||||
<LiteTextEditor
|
||||
editable={false}
|
||||
ref={readOnlyEditorRef}
|
||||
id={comment.id}
|
||||
initialValue={comment.comment_html ?? ""}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { observer } from "mobx-react";
|
|||
import { useForm } from "react-hook-form";
|
||||
import { Check, X } from "lucide-react";
|
||||
// plane imports
|
||||
import type { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor";
|
||||
import type { EditorRefApi } from "@plane/editor";
|
||||
import type { TCommentsOperations, TIssueComment } from "@plane/types";
|
||||
import { isCommentEmpty } from "@plane/utils";
|
||||
// components
|
||||
|
|
@ -14,7 +14,7 @@ type Props = {
|
|||
comment: TIssueComment;
|
||||
isEditing: boolean;
|
||||
projectId?: string;
|
||||
readOnlyEditorRef: EditorReadOnlyRefApi | null;
|
||||
readOnlyEditorRef: EditorRefApi | null;
|
||||
setIsEditing: (isEditing: boolean) => void;
|
||||
workspaceId: string;
|
||||
workspaceSlug: string;
|
||||
|
|
@ -75,6 +75,7 @@ export const CommentCardEditForm: React.FC<Props> = observer((props) => {
|
|||
}}
|
||||
>
|
||||
<LiteTextEditor
|
||||
editable
|
||||
workspaceId={workspaceId}
|
||||
workspaceSlug={workspaceSlug}
|
||||
ref={editorRef}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { FC, useRef, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// plane imports
|
||||
import type { EditorReadOnlyRefApi } from "@plane/editor";
|
||||
import type { EditorRefApi } from "@plane/editor";
|
||||
import type { TIssueComment, TCommentsOperations } from "@plane/types";
|
||||
// plane web imports
|
||||
import { CommentBlock } from "@/plane-web/components/comments";
|
||||
|
|
@ -34,9 +34,10 @@ export const CommentCard: FC<TCommentCard> = observer((props) => {
|
|||
disabled = false,
|
||||
projectId,
|
||||
} = props;
|
||||
const readOnlyEditorRef = useRef<EditorReadOnlyRefApi>(null);
|
||||
// states
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
// refs
|
||||
const readOnlyEditorRef = useRef<EditorRefApi>(null);
|
||||
// derived values
|
||||
const workspaceId = comment?.workspace;
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ export const CommentCreate: FC<TCommentCreate> = observer((props) => {
|
|||
control={control}
|
||||
render={({ field: { value, onChange } }) => (
|
||||
<LiteTextEditor
|
||||
editable
|
||||
workspaceId={workspaceId}
|
||||
id={"add_comment_" + entityId}
|
||||
value={"<p></p>"}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
import React, { useState } from "react";
|
||||
// plane constants
|
||||
// plane imports
|
||||
import { EIssueCommentAccessSpecifier } from "@plane/constants";
|
||||
// plane editor
|
||||
import { EditorRefApi, ILiteTextEditorProps, LiteTextEditorWithRef, TFileHandler } from "@plane/editor";
|
||||
// i18n
|
||||
import { type EditorRefApi, type ILiteTextEditorProps, LiteTextEditorWithRef, type TFileHandler } from "@plane/editor";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// components
|
||||
import { MakeOptional } from "@plane/types";
|
||||
import type { MakeOptional } from "@plane/types";
|
||||
import { cn, isCommentEmpty } from "@plane/utils";
|
||||
// components
|
||||
import { EditorMentionsRoot, IssueCommentToolbar } from "@/components/editor";
|
||||
// helpers
|
||||
// hooks
|
||||
import { useEditorConfig, useEditorMention } from "@/hooks/editor";
|
||||
// store hooks
|
||||
import { useMember } from "@/hooks/store";
|
||||
// plane web hooks
|
||||
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||
|
|
@ -20,11 +16,10 @@ import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
|||
import { WorkspaceService } from "@/plane-web/services";
|
||||
const workspaceService = new WorkspaceService();
|
||||
|
||||
interface LiteTextEditorWrapperProps
|
||||
extends MakeOptional<
|
||||
Omit<ILiteTextEditorProps, "fileHandler" | "mentionHandler">,
|
||||
"disabledExtensions" | "flaggedExtensions"
|
||||
> {
|
||||
type LiteTextEditorWrapperProps = MakeOptional<
|
||||
Omit<ILiteTextEditorProps, "fileHandler" | "mentionHandler">,
|
||||
"disabledExtensions" | "flaggedExtensions"
|
||||
> & {
|
||||
workspaceSlug: string;
|
||||
workspaceId: string;
|
||||
projectId?: string;
|
||||
|
|
@ -35,15 +30,23 @@ interface LiteTextEditorWrapperProps
|
|||
isSubmitting?: boolean;
|
||||
showToolbarInitially?: boolean;
|
||||
showToolbar?: boolean;
|
||||
uploadFile: TFileHandler["upload"];
|
||||
issue_id?: string;
|
||||
parentClassName?: string;
|
||||
}
|
||||
} & (
|
||||
| {
|
||||
editable: false;
|
||||
}
|
||||
| {
|
||||
editable: true;
|
||||
uploadFile: TFileHandler["upload"];
|
||||
}
|
||||
);
|
||||
|
||||
export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapperProps>((props, ref) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
containerClassName,
|
||||
editable,
|
||||
workspaceSlug,
|
||||
workspaceId,
|
||||
projectId,
|
||||
|
|
@ -57,7 +60,6 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
|||
showToolbar = true,
|
||||
parentClassName = "",
|
||||
placeholder = t("issue.comments.placeholder"),
|
||||
uploadFile,
|
||||
disabledExtensions: additionalDisabledExtensions = [],
|
||||
...rest
|
||||
} = props;
|
||||
|
|
@ -70,10 +72,10 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
|||
// use editor mention
|
||||
const { fetchMentions } = useEditorMention({
|
||||
searchEntity: async (payload) =>
|
||||
await workspaceService.searchEntity(workspaceSlug?.toString() ?? "", {
|
||||
await workspaceService.searchEntity(workspaceSlug, {
|
||||
...payload,
|
||||
project_id: projectId?.toString() ?? "",
|
||||
issue_id: issue_id,
|
||||
project_id: projectId,
|
||||
issue_id,
|
||||
}),
|
||||
});
|
||||
// editor config
|
||||
|
|
@ -94,10 +96,11 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
|||
<LiteTextEditorWithRef
|
||||
ref={ref}
|
||||
disabledExtensions={[...liteTextEditorExtensions.disabled, ...additionalDisabledExtensions]}
|
||||
editable={editable}
|
||||
flaggedExtensions={liteTextEditorExtensions.flagged}
|
||||
fileHandler={getEditorFileHandlers({
|
||||
projectId,
|
||||
uploadFile,
|
||||
uploadFile: editable ? props.uploadFile : async () => "",
|
||||
workspaceId,
|
||||
workspaceSlug,
|
||||
})}
|
||||
|
|
@ -107,8 +110,10 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
|
|||
if (!res) throw new Error("Failed in fetching mentions");
|
||||
return res;
|
||||
},
|
||||
renderComponent: (props) => <EditorMentionsRoot {...props} />,
|
||||
getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }),
|
||||
renderComponent: EditorMentionsRoot,
|
||||
getMentionedEntityDetails: (id) => ({
|
||||
display_name: getUserDetails(id)?.display_name ?? "",
|
||||
}),
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
containerClassName={cn(containerClassName, "relative")}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,2 @@
|
|||
export * from "./editor";
|
||||
export * from "./read-only-editor";
|
||||
export * from "./toolbar";
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
import React from "react";
|
||||
// plane imports
|
||||
import { EditorReadOnlyRefApi, ILiteTextReadOnlyEditorProps, LiteTextReadOnlyEditorWithRef } from "@plane/editor";
|
||||
import { MakeOptional } from "@plane/types";
|
||||
// components
|
||||
import { cn } from "@plane/utils";
|
||||
import { EditorMentionsRoot } from "@/components/editor";
|
||||
// helpers
|
||||
// hooks
|
||||
import { useEditorConfig } from "@/hooks/editor";
|
||||
// store hooks
|
||||
import { useMember } from "@/hooks/store";
|
||||
// plane web hooks
|
||||
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||
|
||||
type LiteTextReadOnlyEditorWrapperProps = MakeOptional<
|
||||
Omit<ILiteTextReadOnlyEditorProps, "fileHandler" | "mentionHandler">,
|
||||
"disabledExtensions" | "flaggedExtensions"
|
||||
> & {
|
||||
workspaceId: string;
|
||||
workspaceSlug: string;
|
||||
projectId?: string;
|
||||
};
|
||||
|
||||
export const LiteTextReadOnlyEditor = React.forwardRef<EditorReadOnlyRefApi, LiteTextReadOnlyEditorWrapperProps>(
|
||||
({ workspaceId, workspaceSlug, projectId, disabledExtensions: additionalDisabledExtensions, ...props }, ref) => {
|
||||
// store hooks
|
||||
const { getUserDetails } = useMember();
|
||||
|
||||
// editor flaggings
|
||||
const { liteText: liteTextEditorExtensions } = useEditorFlagging(workspaceSlug?.toString());
|
||||
// editor config
|
||||
const { getReadOnlyEditorFileHandlers } = useEditorConfig();
|
||||
|
||||
return (
|
||||
<LiteTextReadOnlyEditorWithRef
|
||||
ref={ref}
|
||||
disabledExtensions={[...liteTextEditorExtensions.disabled, ...(additionalDisabledExtensions ?? [])]}
|
||||
flaggedExtensions={liteTextEditorExtensions.flagged}
|
||||
fileHandler={getReadOnlyEditorFileHandlers({
|
||||
projectId,
|
||||
workspaceId,
|
||||
workspaceSlug,
|
||||
})}
|
||||
mentionHandler={{
|
||||
renderComponent: (props) => <EditorMentionsRoot {...props} />,
|
||||
getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }),
|
||||
}}
|
||||
{...props}
|
||||
// overriding the containerClassName to add relative class passed
|
||||
containerClassName={cn(props.containerClassName, "relative p-2")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
LiteTextReadOnlyEditor.displayName = "LiteTextReadOnlyEditor";
|
||||
|
|
@ -1,14 +1,12 @@
|
|||
import React, { forwardRef } from "react";
|
||||
// plane imports
|
||||
import { EditorRefApi, IRichTextEditorProps, RichTextEditorWithRef, TFileHandler } from "@plane/editor";
|
||||
import { MakeOptional, TSearchEntityRequestPayload, TSearchResponse } from "@plane/types";
|
||||
// components
|
||||
import { type EditorRefApi, type IRichTextEditorProps, RichTextEditorWithRef, type TFileHandler } from "@plane/editor";
|
||||
import type { MakeOptional, TSearchEntityRequestPayload, TSearchResponse } from "@plane/types";
|
||||
import { cn } from "@plane/utils";
|
||||
// components
|
||||
import { EditorMentionsRoot } from "@/components/editor";
|
||||
// helpers
|
||||
// hooks
|
||||
import { useEditorConfig, useEditorMention } from "@/hooks/editor";
|
||||
// store hooks
|
||||
import { useMember } from "@/hooks/store";
|
||||
// plane web hooks
|
||||
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||
|
|
@ -38,7 +36,7 @@ export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProp
|
|||
workspaceSlug,
|
||||
workspaceId,
|
||||
projectId,
|
||||
disabledExtensions: additionalDisabledExtensions,
|
||||
disabledExtensions: additionalDisabledExtensions = [],
|
||||
...rest
|
||||
} = props;
|
||||
// store hooks
|
||||
|
|
@ -70,8 +68,10 @@ export const RichTextEditor = forwardRef<EditorRefApi, RichTextEditorWrapperProp
|
|||
if (!res) throw new Error("Failed in fetching mentions");
|
||||
return res;
|
||||
},
|
||||
renderComponent: (props) => <EditorMentionsRoot {...props} />,
|
||||
getMentionedEntityDetails: (id: string) => ({ display_name: getUserDetails(id)?.display_name ?? "" }),
|
||||
renderComponent: EditorMentionsRoot,
|
||||
getMentionedEntityDetails: (id) => ({
|
||||
display_name: getUserDetails(id)?.display_name ?? "",
|
||||
}),
|
||||
}}
|
||||
{...rest}
|
||||
containerClassName={cn("relative pl-3 pb-3", containerClassName)}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
|||
import { StickyEditorToolbar } from "./toolbar";
|
||||
|
||||
interface StickyEditorWrapperProps
|
||||
extends Omit<ILiteTextEditorProps, "disabledExtensions" | "flaggedExtensions" | "fileHandler" | "mentionHandler"> {
|
||||
extends Omit<
|
||||
ILiteTextEditorProps,
|
||||
"disabledExtensions" | "editable" | "flaggedExtensions" | "fileHandler" | "mentionHandler"
|
||||
> {
|
||||
workspaceSlug: string;
|
||||
workspaceId: string;
|
||||
projectId?: string;
|
||||
|
|
@ -67,6 +70,7 @@ export const StickyEditor = React.forwardRef<EditorRefApi, StickyEditorWrapperPr
|
|||
ref={ref}
|
||||
disabledExtensions={[...liteTextEditorExtensions.disabled, "enter-key"]}
|
||||
flaggedExtensions={liteTextEditorExtensions.flagged}
|
||||
editable
|
||||
fileHandler={getEditorFileHandlers({
|
||||
projectId,
|
||||
uploadFile,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { useCallback } from "react";
|
||||
// plane editor
|
||||
import { TFileHandler, TReadOnlyFileHandler } from "@plane/editor";
|
||||
// helpers
|
||||
// plane imports
|
||||
import type { TFileHandler } from "@plane/editor";
|
||||
import { getEditorAssetDownloadSrc, getEditorAssetSrc } from "@plane/utils";
|
||||
// hooks
|
||||
import { useEditorAsset } from "@/hooks/store";
|
||||
|
|
@ -24,15 +23,30 @@ export const useEditorConfig = () => {
|
|||
// file size
|
||||
const { maxFileSize } = useFileSize();
|
||||
|
||||
const getReadOnlyEditorFileHandlers = useCallback(
|
||||
(args: Pick<TArgs, "projectId" | "workspaceId" | "workspaceSlug">): TReadOnlyFileHandler => {
|
||||
const { projectId, workspaceId, workspaceSlug } = args;
|
||||
const getEditorFileHandlers = useCallback(
|
||||
(args: TArgs): TFileHandler => {
|
||||
const { projectId, uploadFile, workspaceId, workspaceSlug } = args;
|
||||
|
||||
return {
|
||||
assetsUploadStatus: assetsUploadPercentage,
|
||||
cancel: fileService.cancelUpload,
|
||||
checkIfAssetExists: async (assetId: string) => {
|
||||
const res = await fileService.checkIfAssetExists(workspaceSlug, assetId);
|
||||
return res?.exists ?? false;
|
||||
},
|
||||
delete: async (src: string) => {
|
||||
if (src?.startsWith("http")) {
|
||||
await fileService.deleteOldWorkspaceAsset(workspaceId, src);
|
||||
} else {
|
||||
await fileService.deleteNewAsset(
|
||||
getEditorAssetSrc({
|
||||
assetId: src,
|
||||
projectId,
|
||||
workspaceSlug,
|
||||
}) ?? ""
|
||||
);
|
||||
}
|
||||
},
|
||||
getAssetDownloadSrc: async (path) => {
|
||||
if (!path) return "";
|
||||
if (path?.startsWith("http")) {
|
||||
|
|
@ -68,47 +82,16 @@ export const useEditorConfig = () => {
|
|||
await fileService.restoreNewAsset(workspaceSlug, src);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const getEditorFileHandlers = useCallback(
|
||||
(args: TArgs): TFileHandler => {
|
||||
const { projectId, uploadFile, workspaceId, workspaceSlug } = args;
|
||||
|
||||
return {
|
||||
...getReadOnlyEditorFileHandlers({
|
||||
projectId,
|
||||
workspaceId,
|
||||
workspaceSlug,
|
||||
}),
|
||||
assetsUploadStatus: assetsUploadPercentage,
|
||||
upload: uploadFile,
|
||||
delete: async (src: string) => {
|
||||
if (src?.startsWith("http")) {
|
||||
await fileService.deleteOldWorkspaceAsset(workspaceId, src);
|
||||
} else {
|
||||
await fileService.deleteNewAsset(
|
||||
getEditorAssetSrc({
|
||||
assetId: src,
|
||||
projectId,
|
||||
workspaceSlug,
|
||||
}) ?? ""
|
||||
);
|
||||
}
|
||||
},
|
||||
cancel: fileService.cancelUpload,
|
||||
validation: {
|
||||
maxFileSize,
|
||||
},
|
||||
};
|
||||
},
|
||||
[assetsUploadPercentage, getReadOnlyEditorFileHandlers, maxFileSize]
|
||||
[assetsUploadPercentage, maxFileSize]
|
||||
);
|
||||
|
||||
return {
|
||||
getEditorFileHandlers,
|
||||
getReadOnlyEditorFileHandlers,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue