🚜 refactor: added a common place for rich text and lite text read only editors

This commit is contained in:
Palanikannan1437 2024-01-11 18:47:51 +05:30
parent ce987833b7
commit 4c38117316
9 changed files with 36 additions and 55 deletions

View File

@ -1,4 +1,4 @@
export { LiteTextEditor, LiteTextEditorWithRef } from "src/ui"; export { LiteTextEditor, LiteTextEditorWithRef } from "src/ui";
export { LiteReadOnlyEditor, LiteReadOnlyEditorWithRef } from "src/ui/read-only"; export { LiteTextReadOnlyEditor, LiteTextReadOnlyEditorWithRef } from "src/ui/read-only";
export type { LiteTextEditorProps, ILiteTextEditor } from "src/ui"; export type { LiteTextEditorProps, ILiteTextEditor } from "src/ui";
export type { LiteTextEditorReadOnlyProps, ILiteReadOnlyEditor } from "src/ui/read-only"; export type { LiteTextReadOnlyEditorProps, ILiteTextReadOnlyEditor } from "src/ui/read-only";

View File

@ -1,7 +1,7 @@
import * as React from "react"; import * as React from "react";
import { EditorContainer, EditorContentWrapper, getEditorClassNames, useReadOnlyEditor } from "@plane/editor-core"; import { EditorContainer, EditorContentWrapper, getEditorClassNames, useReadOnlyEditor } from "@plane/editor-core";
export type ILiteReadOnlyEditor = { export type ILiteTextReadOnlyEditor = {
value: string; value: string;
editorContentCustomClassNames?: string; editorContentCustomClassNames?: string;
noBorder?: boolean; noBorder?: boolean;
@ -10,7 +10,7 @@ export type ILiteReadOnlyEditor = {
mentionHighlights: string[]; mentionHighlights: string[];
}; };
export interface LiteTextEditorReadOnlyProps extends ILiteReadOnlyEditor { export interface LiteTextReadOnlyEditorProps extends ILiteTextReadOnlyEditor {
forwardedRef?: React.Ref<EditorHandle>; forwardedRef?: React.Ref<EditorHandle>;
} }
@ -19,7 +19,7 @@ interface EditorHandle {
setEditorValue: (content: string) => void; setEditorValue: (content: string) => void;
} }
const LiteReadOnlyEditor = ({ const LiteTextReadOnlyEditor = ({
editorContentCustomClassNames, editorContentCustomClassNames,
noBorder, noBorder,
borderOnFocus, borderOnFocus,
@ -27,7 +27,7 @@ const LiteReadOnlyEditor = ({
value, value,
forwardedRef, forwardedRef,
mentionHighlights, mentionHighlights,
}: LiteTextEditorReadOnlyProps) => { }: LiteTextReadOnlyEditorProps) => {
const editor = useReadOnlyEditor({ const editor = useReadOnlyEditor({
value, value,
forwardedRef, forwardedRef,
@ -51,10 +51,10 @@ const LiteReadOnlyEditor = ({
); );
}; };
const LiteReadOnlyEditorWithRef = React.forwardRef<EditorHandle, ILiteReadOnlyEditor>((props, ref) => ( const LiteTextReadOnlyEditorWithRef = React.forwardRef<EditorHandle, ILiteTextReadOnlyEditor>((props, ref) => (
<LiteReadOnlyEditor {...props} forwardedRef={ref} /> <LiteTextReadOnlyEditor {...props} forwardedRef={ref} />
)); ));
LiteReadOnlyEditorWithRef.displayName = "LiteReadOnlyEditorWithRef"; LiteTextReadOnlyEditorWithRef.displayName = "LiteTextReadOnlyEditorWithRef";
export { LiteReadOnlyEditor, LiteReadOnlyEditorWithRef }; export { LiteTextReadOnlyEditor, LiteTextReadOnlyEditorWithRef };

View File

@ -1,3 +1,4 @@
export { RichTextEditor, RichTextEditorWithRef } from "src/ui"; export { RichTextEditor, RichTextEditorWithRef } from "src/ui";
export { RichReadOnlyEditor, RichReadOnlyEditorWithRef } from "src/ui/read-only"; export { RichTextReadOnlyEditor, RichTextReadOnlyEditorWithRef } from "src/ui/read-only";
export type { RichTextEditorProps, IRichTextEditor } from "src/ui"; export type { RichTextEditorProps, IRichTextEditor } from "src/ui";
export type { IRichTextReadOnlyEditor } from "src/ui/read-only";

View File

@ -2,7 +2,7 @@
import { EditorContainer, EditorContentWrapper, getEditorClassNames, useReadOnlyEditor } from "@plane/editor-core"; import { EditorContainer, EditorContentWrapper, getEditorClassNames, useReadOnlyEditor } from "@plane/editor-core";
import * as React from "react"; import * as React from "react";
interface IRichTextReadOnlyEditor { export interface IRichTextReadOnlyEditor {
value: string; value: string;
editorContentCustomClassNames?: string; editorContentCustomClassNames?: string;
noBorder?: boolean; noBorder?: boolean;
@ -20,7 +20,7 @@ interface EditorHandle {
setEditorValue: (content: string) => void; setEditorValue: (content: string) => void;
} }
const RichReadOnlyEditor = ({ const RichTextReadOnlyEditor = ({
editorContentCustomClassNames, editorContentCustomClassNames,
noBorder, noBorder,
borderOnFocus, borderOnFocus,
@ -52,10 +52,10 @@ const RichReadOnlyEditor = ({
); );
}; };
const RichReadOnlyEditorWithRef = React.forwardRef<EditorHandle, IRichTextReadOnlyEditor>((props, ref) => ( const RichTextReadOnlyEditorWithRef = React.forwardRef<EditorHandle, IRichTextReadOnlyEditor>((props, ref) => (
<RichReadOnlyEditor {...props} forwardedRef={ref} /> <RichTextReadOnlyEditor {...props} forwardedRef={ref} />
)); ));
RichReadOnlyEditorWithRef.displayName = "RichReadOnlyEditorWithRef"; RichTextReadOnlyEditorWithRef.displayName = "RichTextReadOnlyEditorWithRef";
export { RichReadOnlyEditor, RichReadOnlyEditorWithRef }; export { RichTextReadOnlyEditor, RichTextReadOnlyEditorWithRef };

View File

@ -1,16 +1,13 @@
import { IssueReactions } from "components/issues/peek-overview"; import { IssueReactions } from "components/issues/peek-overview";
import { RichReadOnlyEditor } from "@plane/rich-text-editor"; import { RichTextReadOnlyEditor } from "@plane/rich-text-editor";
// types // types
import { IIssue } from "types/issue"; import { IIssue } from "types/issue";
import useEditorSuggestions from "hooks/use-editor-suggestions";
type Props = { type Props = {
issueDetails: IIssue; issueDetails: IIssue;
}; };
export const PeekOverviewIssueDetails: React.FC<Props> = ({ issueDetails }) => { export const PeekOverviewIssueDetails: React.FC<Props> = ({ issueDetails }) => {
const mentionConfig = useEditorSuggestions();
return ( return (
<div className="space-y-2"> <div className="space-y-2">
<h6 className="font-medium text-custom-text-200"> <h6 className="font-medium text-custom-text-200">
@ -18,7 +15,7 @@ export const PeekOverviewIssueDetails: React.FC<Props> = ({ issueDetails }) => {
</h6> </h6>
<h4 className="break-words text-2xl font-semibold">{issueDetails.name}</h4> <h4 className="break-words text-2xl font-semibold">{issueDetails.name}</h4>
{issueDetails.description_html !== "" && issueDetails.description_html !== "<p></p>" && ( {issueDetails.description_html !== "" && issueDetails.description_html !== "<p></p>" && (
<RichReadOnlyEditor <RichTextReadOnlyEditor
value={ value={
!issueDetails.description_html || !issueDetails.description_html ||
issueDetails.description_html === "" || issueDetails.description_html === "" ||
@ -28,7 +25,6 @@ export const PeekOverviewIssueDetails: React.FC<Props> = ({ issueDetails }) => {
: issueDetails.description_html : issueDetails.description_html
} }
customClassName="p-3 min-h-[50px] shadow-sm" customClassName="p-3 min-h-[50px] shadow-sm"
mentionHighlights={mentionConfig.mentionHighlights}
/> />
)} )}
<IssueReactions /> <IssueReactions />

View File

@ -8,10 +8,10 @@ import { usePopper } from "react-popper";
// ui // ui
import { Button, Input } from "@plane/ui"; import { Button, Input } from "@plane/ui";
// components // components
import { RichReadOnlyEditorWithRef } from "@plane/rich-text-editor";
import { Popover, Transition } from "@headlessui/react"; import { Popover, Transition } from "@headlessui/react";
// types // types
import { Placement } from "@popperjs/core"; import { Placement } from "@popperjs/core";
import { RichTextReadOnlyEditor } from "components/editor/rich-text-read-only-editor";
type Props = { type Props = {
isOpen: boolean; isOpen: boolean;
@ -203,7 +203,7 @@ export const GptAssistantPopover: React.FC<Props> = (props) => {
{prompt && ( {prompt && (
<div className="text-sm"> <div className="text-sm">
Content: Content:
<RichReadOnlyEditorWithRef <RichTextReadOnlyEditor
value={prompt} value={prompt}
customClassName="-m-3" customClassName="-m-3"
noBorder noBorder
@ -215,7 +215,7 @@ export const GptAssistantPopover: React.FC<Props> = (props) => {
{response !== "" && ( {response !== "" && (
<div className="page-block-section text-sm max-h-[8rem]"> <div className="page-block-section text-sm max-h-[8rem]">
Response: Response:
<RichReadOnlyEditorWithRef <RichTextReadOnlyEditor
value={`<p>${response}</p>`} value={`<p>${response}</p>`}
customClassName={response ? "-mx-3 -my-3" : ""} customClassName={response ? "-mx-3 -my-3" : ""}
noBorder noBorder

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { ILiteReadOnlyEditor, LiteReadOnlyEditorWithRef } from "@plane/lite-text-editor"; import { ILiteReadOnlyEditor, LiteTextReadOnlyEditorWithRef } from "@plane/lite-text-editor";
import { useMention } from "hooks/store"; import { useMention } from "hooks/store";
@ -14,7 +14,9 @@ export const LiteTextReadOnlyEditor = React.forwardRef<EditorHandle, LiteTextRea
({ ...props }, ref) => { ({ ...props }, ref) => {
const editorSuggestions = useMention(); const editorSuggestions = useMention();
return <LiteReadOnlyEditorWithRef ref={ref} mentionHighlights={editorSuggestions.mentionHighlights} {...props} />; return (
<LiteTextReadOnlyEditorWithRef ref={ref} mentionHighlights={editorSuggestions.mentionHighlights} {...props} />
);
} }
); );

View File

@ -1,41 +1,23 @@
import React from "react"; import React from "react";
import { RichTextEditorWithRef, IRichTextEditor } from "@plane/rich-text-editor"; import { IRichTextReadOnlyEditor, RichTextReadOnlyEditorWithRef } from "@plane/rich-text-editor";
import { useMention } from "hooks/store"; import { useMention } from "hooks/store";
import { FileService } from "services/file.service";
interface EditorHandle { interface EditorHandle {
clearEditor: () => void; clearEditor: () => void;
setEditorValue: (content: string) => void; setEditorValue: (content: string) => void;
} }
interface RichTextEditorWrapperProps interface RichTextReadOnlyEditorWrapperProps extends Omit<IRichTextReadOnlyEditor, "mentionHighlights"> {}
extends Omit<
IRichTextEditor,
"uploadFile" | "deleteFile" | "restoreFile" | "mentionSuggestions" | "mentionHighlights"
> {
workspaceSlug: string;
}
const fileService = new FileService(); export const RichTextReadOnlyEditor = React.forwardRef<EditorHandle, RichTextReadOnlyEditorWrapperProps>(
({ ...props }, ref) => {
export const RichTextEditor = React.forwardRef<EditorHandle, RichTextEditorWrapperProps>(
({ workspaceSlug, ...props }, ref) => {
const editorSuggestions = useMention(); const editorSuggestions = useMention();
return ( return (
<RichTextEditorWithRef <RichTextReadOnlyEditorWithRef ref={ref} mentionHighlights={editorSuggestions.mentionHighlights} {...props} />
ref={ref}
uploadFile={fileService.getUploadFileFunction(workspaceSlug)}
deleteFile={fileService.deleteImage}
restoreFile={fileService.restoreImage}
mentionSuggestions={editorSuggestions.mentionSuggestions}
mentionHighlights={editorSuggestions.mentionHighlights}
{...props}
/>
); );
} }
); );
RichTextEditor.displayName = "RichTextEditor"; RichTextReadOnlyEditor.displayName = "RichTextReadOnlyEditor";

View File

@ -7,7 +7,7 @@ import { UserService } from "services/user.service";
import { ProfileSettingsLayout } from "layouts/settings-layout"; import { ProfileSettingsLayout } from "layouts/settings-layout";
// components // components
import { ActivityIcon, ActivityMessage } from "components/core"; import { ActivityIcon, ActivityMessage } from "components/core";
import { RichReadOnlyEditor } from "@plane/rich-text-editor"; import { RichTextReadOnlyEditor } from "components/editor/rich-text-read-only-editor";
// icons // icons
import { History, MessageSquare } from "lucide-react"; import { History, MessageSquare } from "lucide-react";
// ui // ui
@ -74,11 +74,11 @@ const ProfileActivityPage: NextPageWithLayout = () => {
</p> </p>
</div> </div>
<div className="issue-comments-section p-0"> <div className="issue-comments-section p-0">
<RichReadOnlyEditor <RichTextReadOnlyEditor
value={activityItem?.new_value !== "" ? activityItem.new_value : activityItem.old_value}
customClassName="text-xs border border-custom-border-200 bg-custom-background-100" customClassName="text-xs border border-custom-border-200 bg-custom-background-100"
noBorder noBorder
borderOnFocus={false} borderOnFocus={false}
value={activityItem?.new_value !== "" ? activityItem.new_value : activityItem.old_value}
/> />
</div> </div>
</div> </div>