mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
🚜 refactor: added a common place for rich text and lite text read only editors
This commit is contained in:
parent
ce987833b7
commit
4c38117316
@ -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";
|
||||||
|
@ -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 };
|
||||||
|
@ -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";
|
||||||
|
@ -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 };
|
||||||
|
@ -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 />
|
||||||
|
@ -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
|
||||||
|
@ -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} />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user