refactor: change all RichTextEditor and RichTextEditorWithRef instances in web

This commit is contained in:
Palanikannan1437 2024-01-11 13:06:32 +05:30
parent 7c0711dc90
commit 07c4699b02
5 changed files with 47 additions and 94 deletions

View File

@ -1,19 +1,18 @@
import { Fragment, useRef, useState } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { Dialog, Transition } from "@headlessui/react"; import { Dialog, Transition } from "@headlessui/react";
import { Controller, useForm } from "react-hook-form";
import { RichTextEditorWithRef } from "@plane/rich-text-editor";
import { Sparkle } from "lucide-react"; import { Sparkle } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
import { Fragment, useRef, useState } from "react";
import { Controller, useForm } from "react-hook-form";
// hooks // hooks
import { useApplication, useWorkspace, useInboxIssues, useMention } from "hooks/store"; import { useApplication, useInboxIssues, useWorkspace } from "hooks/store";
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// services // services
import { FileService } from "services/file.service";
import { AIService } from "services/ai.service"; import { AIService } from "services/ai.service";
// components // components
import { PriorityDropdown } from "components/dropdowns";
import { GptAssistantPopover } from "components/core"; import { GptAssistantPopover } from "components/core";
import { PriorityDropdown } from "components/dropdowns";
import { RichTextEditorWrapper } from "components/editor/rich-text-wrapper";
// ui // ui
import { Button, Input, ToggleSwitch } from "@plane/ui"; import { Button, Input, ToggleSwitch } from "@plane/ui";
// types // types
@ -34,7 +33,6 @@ const defaultValues: Partial<TIssue> = {
// services // services
const aiService = new AIService(); const aiService = new AIService();
const fileService = new FileService();
export const CreateInboxIssueModal: React.FC<Props> = observer((props) => { export const CreateInboxIssueModal: React.FC<Props> = observer((props) => {
const { isOpen, onClose } = props; const { isOpen, onClose } = props;
@ -46,7 +44,6 @@ export const CreateInboxIssueModal: React.FC<Props> = observer((props) => {
const editorRef = useRef<any>(null); const editorRef = useRef<any>(null);
// toast alert // toast alert
const { setToastAlert } = useToast(); const { setToastAlert } = useToast();
const { mentionHighlights, mentionSuggestions } = useMention();
// router // router
const router = useRouter(); const router = useRouter();
const { workspaceSlug, projectId, inboxId } = router.query as { const { workspaceSlug, projectId, inboxId } = router.query as {
@ -274,11 +271,8 @@ export const CreateInboxIssueModal: React.FC<Props> = observer((props) => {
name="description_html" name="description_html"
control={control} control={control}
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<RichTextEditorWithRef <RichTextEditorWrapper
cancelUploadImage={fileService.cancelUpload} workspaceSlug={workspaceSlug}
uploadFile={fileService.getUploadFileFunction(workspaceSlug as string)}
deleteFile={fileService.deleteImage}
restoreFile={fileService.restoreImage}
ref={editorRef} ref={editorRef}
debouncedUpdatesEnabled={false} debouncedUpdatesEnabled={false}
value={!value || value === "" ? "<p></p>" : value} value={!value || value === "" ? "<p></p>" : value}
@ -286,8 +280,6 @@ export const CreateInboxIssueModal: React.FC<Props> = observer((props) => {
onChange={(description, description_html: string) => { onChange={(description, description_html: string) => {
onChange(description_html); onChange(description_html);
}} }}
mentionSuggestions={mentionSuggestions}
mentionHighlights={mentionHighlights}
/> />
)} )}
/> />

View File

@ -5,13 +5,10 @@ import useReloadConfirmations from "hooks/use-reload-confirmation";
import debounce from "lodash/debounce"; import debounce from "lodash/debounce";
// components // components
import { TextArea } from "@plane/ui"; import { TextArea } from "@plane/ui";
import { RichTextEditor } from "@plane/rich-text-editor"; import { RichTextEditorWrapper } from "components/editor/rich-text-wrapper";
// types // types
import { TIssue } from "@plane/types"; import { TIssue } from "@plane/types";
import { TIssueOperations } from "./issue-detail"; import { TIssueOperations } from "./issue-detail";
// services
import { FileService } from "services/file.service";
import { useMention } from "hooks/store";
export interface IssueDescriptionFormValues { export interface IssueDescriptionFormValues {
name: string; name: string;
@ -34,16 +31,12 @@ export interface IssueDetailsProps {
setIsSubmitting: (value: "submitting" | "submitted" | "saved") => void; setIsSubmitting: (value: "submitting" | "submitted" | "saved") => void;
} }
const fileService = new FileService();
export const IssueDescriptionForm: FC<IssueDetailsProps> = (props) => { export const IssueDescriptionForm: FC<IssueDetailsProps> = (props) => {
const { workspaceSlug, projectId, issueId, issue, issueOperations, isAllowed, isSubmitting, setIsSubmitting } = props; const { workspaceSlug, projectId, issueId, issue, issueOperations, isAllowed, isSubmitting, setIsSubmitting } = props;
// states // states
const [characterLimit, setCharacterLimit] = useState(false); const [characterLimit, setCharacterLimit] = useState(false);
const { setShowAlert } = useReloadConfirmations(); const { setShowAlert } = useReloadConfirmations();
// store hooks
const { mentionHighlights, mentionSuggestions } = useMention();
// form info // form info
const { const {
handleSubmit, handleSubmit,
@ -157,17 +150,16 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = (props) => {
</div> </div>
)} )}
</div> </div>
<span>{errors.name ? errors.name.message : null}</span> <span>
<>{errors.name ? errors.name.message : null}</>
</span>
<div className="relative"> <div className="relative">
<Controller <Controller
name="description_html" name="description_html"
control={control} control={control}
render={({ field: { onChange } }) => ( render={({ field: { onChange } }) => (
<RichTextEditor <RichTextEditorWrapper
cancelUploadImage={fileService.cancelUpload} workspaceSlug={workspaceSlug}
uploadFile={fileService.getUploadFileFunction(workspaceSlug)}
deleteFile={fileService.deleteImage}
restoreFile={fileService.restoreImage}
value={localIssueDescription.description_html} value={localIssueDescription.description_html}
rerenderOnPropsChange={localIssueDescription} rerenderOnPropsChange={localIssueDescription}
setShouldShowAlert={setShowAlert} setShouldShowAlert={setShowAlert}
@ -181,8 +173,6 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = (props) => {
onChange(description_html); onChange(description_html);
debouncedFormSave(); debouncedFormSave();
}} }}
mentionSuggestions={mentionSuggestions}
mentionHighlights={mentionHighlights}
/> />
)} )}
/> />

View File

@ -1,22 +1,16 @@
import React, { FC, useState, useEffect, useRef } from "react";
import { useRouter } from "next/router";
import { Controller, useForm } from "react-hook-form";
import { observer } from "mobx-react-lite";
import { Sparkle, X } from "lucide-react"; import { Sparkle, X } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
import React, { FC, useEffect, useRef, useState } from "react";
import { Controller, useForm } from "react-hook-form";
// hooks // hooks
import { useApplication, useEstimate, useMention, useProject } from "hooks/store"; import { useApplication, useEstimate, useProject } from "hooks/store";
import useToast from "hooks/use-toast";
import useLocalStorage from "hooks/use-local-storage"; import useLocalStorage from "hooks/use-local-storage";
import useToast from "hooks/use-toast";
// services // services
import { AIService } from "services/ai.service"; import { AIService } from "services/ai.service";
import { FileService } from "services/file.service";
// components // components
import { GptAssistantPopover } from "components/core"; import { GptAssistantPopover } from "components/core";
import { ParentIssuesListModal } from "components/issues";
import { IssueLabelSelect } from "components/issues/select";
import { CreateStateModal } from "components/states";
import { CreateLabelModal } from "components/labels";
import { RichTextEditorWithRef } from "@plane/rich-text-editor";
import { import {
CycleDropdown, CycleDropdown,
DateDropdown, DateDropdown,
@ -27,15 +21,19 @@ import {
ProjectMemberDropdown, ProjectMemberDropdown,
StateDropdown, StateDropdown,
} from "components/dropdowns"; } from "components/dropdowns";
import { ParentIssuesListModal } from "components/issues";
import { IssueLabelSelect } from "components/issues/select";
import { CreateLabelModal } from "components/labels";
import { CreateStateModal } from "components/states";
import { RichTextEditorWrapper } from "components/editor/rich-text-wrapper";
// ui // ui
import { Button, CustomMenu, Input, ToggleSwitch } from "@plane/ui"; import { Button, CustomMenu, Input, ToggleSwitch } from "@plane/ui";
// helpers // helpers
import { renderFormattedPayloadDate } from "helpers/date-time.helper"; import { renderFormattedPayloadDate } from "helpers/date-time.helper";
// types // types
import type { IUser, TIssue, ISearchIssueResponse } from "@plane/types"; import type { ISearchIssueResponse, IUser, TIssue } from "@plane/types";
const aiService = new AIService(); const aiService = new AIService();
const fileService = new FileService();
const defaultValues: Partial<TIssue> = { const defaultValues: Partial<TIssue> = {
project_id: "", project_id: "",
@ -106,7 +104,6 @@ export const DraftIssueForm: FC<IssueFormProps> = observer((props) => {
const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false); const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false);
// store hooks // store hooks
const { areEstimatesEnabledForProject } = useEstimate(); const { areEstimatesEnabledForProject } = useEstimate();
const { mentionHighlights, mentionSuggestions } = useMention();
// hooks // hooks
const { setValue: setLocalStorageValue } = useLocalStorage("draftedIssue", {}); const { setValue: setLocalStorageValue } = useLocalStorage("draftedIssue", {});
const { setToastAlert } = useToast(); const { setToastAlert } = useToast();
@ -431,11 +428,8 @@ export const DraftIssueForm: FC<IssueFormProps> = observer((props) => {
name="description_html" name="description_html"
control={control} control={control}
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<RichTextEditorWithRef <RichTextEditorWrapper
cancelUploadImage={fileService.cancelUpload} workspaceSlug={workspaceSlug as string}
uploadFile={fileService.getUploadFileFunction(workspaceSlug as string)}
deleteFile={fileService.deleteImage}
restoreFile={fileService.restoreImage}
ref={editorRef} ref={editorRef}
debouncedUpdatesEnabled={false} debouncedUpdatesEnabled={false}
value={ value={
@ -447,8 +441,6 @@ export const DraftIssueForm: FC<IssueFormProps> = observer((props) => {
onChange={(description: Object, description_html: string) => { onChange={(description: Object, description_html: string) => {
onChange(description_html); onChange(description_html);
}} }}
mentionHighlights={mentionHighlights}
mentionSuggestions={mentionSuggestions}
/> />
)} )}
/> />

View File

@ -1,21 +1,16 @@
import React, { FC, useState, useRef } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { Controller, useForm } from "react-hook-form";
import { LayoutPanelTop, Sparkle, X } from "lucide-react"; import { LayoutPanelTop, Sparkle, X } from "lucide-react";
// editor import { observer } from "mobx-react-lite";
import { RichTextEditorWithRef } from "@plane/rich-text-editor"; import { useRouter } from "next/router";
import { FC, useRef, useState } from "react";
import { Controller, useForm } from "react-hook-form";
// hooks // hooks
import { useApplication, useEstimate, useMention, useProject } from "hooks/store"; import { useApplication, useEstimate, useProject } from "hooks/store";
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// services // services
import { AIService } from "services/ai.service"; import { AIService } from "services/ai.service";
import { FileService } from "services/file.service";
// components // components
import { RichTextEditorWrapper } from "components/editor/rich-text-wrapper";
import { GptAssistantPopover } from "components/core"; import { GptAssistantPopover } from "components/core";
import { ParentIssuesListModal } from "components/issues";
import { IssueLabelSelect } from "components/issues/select";
import { CreateLabelModal } from "components/labels";
import { import {
CycleDropdown, CycleDropdown,
DateDropdown, DateDropdown,
@ -26,12 +21,15 @@ import {
ProjectMemberDropdown, ProjectMemberDropdown,
StateDropdown, StateDropdown,
} from "components/dropdowns"; } from "components/dropdowns";
import { ParentIssuesListModal } from "components/issues";
import { IssueLabelSelect } from "components/issues/select";
import { CreateLabelModal } from "components/labels";
// ui // ui
import { Button, CustomMenu, Input, ToggleSwitch } from "@plane/ui"; import { Button, CustomMenu, Input, ToggleSwitch } from "@plane/ui";
// helpers // helpers
import { renderFormattedPayloadDate } from "helpers/date-time.helper"; import { renderFormattedPayloadDate } from "helpers/date-time.helper";
// types // types
import type { TIssue, ISearchIssueResponse } from "@plane/types"; import type { ISearchIssueResponse, TIssue } from "@plane/types";
const defaultValues: Partial<TIssue> = { const defaultValues: Partial<TIssue> = {
project_id: "", project_id: "",
@ -59,7 +57,6 @@ export interface IssueFormProps {
// services // services
const aiService = new AIService(); const aiService = new AIService();
const fileService = new FileService();
export const IssueFormRoot: FC<IssueFormProps> = observer((props) => { export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
const { data, onChange, onClose, onSubmit, projectId } = props; const { data, onChange, onClose, onSubmit, projectId } = props;
@ -81,7 +78,6 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
} = useApplication(); } = useApplication();
const { getProjectById } = useProject(); const { getProjectById } = useProject();
const { areEstimatesEnabledForProject } = useEstimate(); const { areEstimatesEnabledForProject } = useEstimate();
const { mentionHighlights, mentionSuggestions } = useMention();
// toast alert // toast alert
const { setToastAlert } = useToast(); const { setToastAlert } = useToast();
// form info // form info
@ -326,11 +322,8 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
name="description_html" name="description_html"
control={control} control={control}
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<RichTextEditorWithRef <RichTextEditorWrapper
cancelUploadImage={fileService.cancelUpload} workspaceSlug={workspaceSlug as string}
uploadFile={fileService.getUploadFileFunction(workspaceSlug as string)}
deleteFile={fileService.deleteImage}
restoreFile={fileService.restoreImage}
ref={editorRef} ref={editorRef}
debouncedUpdatesEnabled={false} debouncedUpdatesEnabled={false}
value={ value={
@ -343,9 +336,6 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
onChange(description_html); onChange(description_html);
handleFormChange(); handleFormChange();
}} }}
mentionHighlights={mentionHighlights}
mentionSuggestions={mentionSuggestions}
// tabIndex={2}
/> />
)} )}
/> />

View File

@ -1,24 +1,19 @@
import debounce from "lodash/debounce";
import { ChangeEvent, FC, useCallback, useEffect, useState } from "react"; import { ChangeEvent, FC, useCallback, useEffect, useState } from "react";
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import debounce from "lodash/debounce";
// packages
import { RichTextEditor } from "@plane/rich-text-editor";
// hooks // hooks
import { useMention, useProject, useUser } from "hooks/store"; import { useProject, useUser } from "hooks/store";
import useReloadConfirmations from "hooks/use-reload-confirmation"; import useReloadConfirmations from "hooks/use-reload-confirmation";
// components // components
import { RichTextEditorWrapper } from "components/editor/rich-text-wrapper";
import { IssuePeekOverviewReactions } from "components/issues"; import { IssuePeekOverviewReactions } from "components/issues";
// ui // ui
import { TextArea } from "@plane/ui"; import { TextArea } from "@plane/ui";
// types // types
import { TIssue, IUser } from "@plane/types"; import { IUser, TIssue } from "@plane/types";
// services
import { FileService } from "services/file.service";
// constants // constants
import { EUserProjectRoles } from "constants/project"; import { EUserProjectRoles } from "constants/project";
const fileService = new FileService();
interface IPeekOverviewIssueDetails { interface IPeekOverviewIssueDetails {
workspaceSlug: string; workspaceSlug: string;
issue: TIssue; issue: TIssue;
@ -49,7 +44,6 @@ export const PeekOverviewIssueDetails: FC<IPeekOverviewIssueDetails> = (props) =
const { const {
membership: { currentProjectRole }, membership: { currentProjectRole },
} = useUser(); } = useUser();
const { mentionHighlights, mentionSuggestions } = useMention();
const { getProjectById } = useProject(); const { getProjectById } = useProject();
// derived values // derived values
const isAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER; const isAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
@ -181,11 +175,8 @@ export const PeekOverviewIssueDetails: FC<IPeekOverviewIssueDetails> = (props) =
name="description_html" name="description_html"
control={control} control={control}
render={({ field: { onChange } }) => ( render={({ field: { onChange } }) => (
<RichTextEditor <RichTextEditorWrapper
cancelUploadImage={fileService.cancelUpload} workspaceSlug={workspaceSlug}
uploadFile={fileService.getUploadFileFunction(workspaceSlug)}
deleteFile={fileService.deleteImage}
restoreFile={fileService.restoreImage}
value={localIssueDescription.description_html} value={localIssueDescription.description_html}
rerenderOnPropsChange={localIssueDescription} rerenderOnPropsChange={localIssueDescription}
setShouldShowAlert={setShowAlert} setShouldShowAlert={setShowAlert}
@ -199,8 +190,6 @@ export const PeekOverviewIssueDetails: FC<IPeekOverviewIssueDetails> = (props) =
onChange(description_html); onChange(description_html);
debouncedFormSave(); debouncedFormSave();
}} }}
mentionSuggestions={mentionSuggestions}
mentionHighlights={mentionHighlights}
/> />
)} )}
/> />