Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: rich text editor #1008

Merged
merged 7 commits into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions apps/app/components/core/gpt-assistant-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useEffect, useState, forwardRef, useRef } from "react";

import { useRouter } from "next/router";
import dynamic from "next/dynamic";
Expand Down Expand Up @@ -35,6 +35,14 @@ const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor
ssr: false,
});

import { IRemirrorRichTextEditor } from "components/rich-text-editor";

const WrappedRemirrorRichTextEditor = forwardRef<IRemirrorRichTextEditor, IRemirrorRichTextEditor>(
(props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />
);

WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor";

export const GptAssistantModal: React.FC<Props> = ({
isOpen,
handleClose,
Expand Down Expand Up @@ -125,7 +133,7 @@ export const GptAssistantModal: React.FC<Props> = ({
isOpen ? "block" : "hidden"
}`}
>
{((content && content !== "") || htmlContent !== "<p></p>") && (
{((content && content !== "") || (htmlContent && htmlContent !== "<p></p>")) && (
<div className="remirror-section text-sm">
Content:
<RemirrorRichTextEditor
Expand Down
4 changes: 2 additions & 2 deletions apps/app/components/integration/jira/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { FormProvider, useForm } from "react-hook-form";

// icons
import { ArrowLeftIcon, ListBulletIcon } from "@heroicons/react/24/outline";
import { CogIcon, CloudUploadIcon, UsersIcon, CheckIcon } from "components/icons";
import { CogIcon, UsersIcon, CheckIcon } from "components/icons";

// services
import jiraImporterService from "services/integration/jira.service";
Expand All @@ -40,7 +40,7 @@ import { IJiraImporterForm } from "types";
const integrationWorkflowData: Array<{
title: string;
key: TJiraIntegrationSteps;
icon: React.FC<React.SVGProps<SVGSVGElement>>;
icon: React.FC<React.SVGProps<SVGSVGElement> & React.RefAttributes<SVGSVGElement>>;
}> = [
{
title: "Configure",
Expand Down
14 changes: 13 additions & 1 deletion apps/app/components/issues/comment/add-comment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor
</Loader>
),
});
import { IRemirrorRichTextEditor } from "components/rich-text-editor";

const WrappedRemirrorRichTextEditor = React.forwardRef<
IRemirrorRichTextEditor,
IRemirrorRichTextEditor
>((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />);

WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor";

const defaultValues: Partial<IIssueComment> = {
comment_json: "",
Expand All @@ -41,6 +49,8 @@ export const AddComment: React.FC = () => {
reset,
} = useForm<IIssueComment>({ defaultValues });

const editorRef = React.useRef<any>(null);

const router = useRouter();
const { workspaceSlug, projectId, issueId } = router.query;

Expand All @@ -61,6 +71,7 @@ export const AddComment: React.FC = () => {
.then(() => {
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
reset(defaultValues);
editorRef.current?.clearEditor();
})
.catch(() =>
setToastAlert({
Expand All @@ -79,11 +90,12 @@ export const AddComment: React.FC = () => {
name="comment_json"
control={control}
render={({ field: { value } }) => (
<RemirrorRichTextEditor
<WrappedRemirrorRichTextEditor
value={value}
onJSONChange={(jsonValue) => setValue("comment_json", jsonValue)}
onHTMLChange={(htmlValue) => setValue("comment_html", htmlValue)}
placeholder="Enter your comment..."
ref={editorRef}
/>
)}
/>
Expand Down
80 changes: 50 additions & 30 deletions apps/app/components/issues/comment/comment-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ import type { IIssueComment } from "types";

const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), { ssr: false });

import { IRemirrorRichTextEditor } from "components/rich-text-editor";

const WrappedRemirrorRichTextEditor = React.forwardRef<
IRemirrorRichTextEditor,
IRemirrorRichTextEditor
>((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />);

WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor";

type Props = {
comment: IIssueComment;
onSubmit: (comment: IIssueComment) => void;
Expand All @@ -27,6 +36,9 @@ type Props = {
export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentDeletion }) => {
const { user } = useUser();

const editorRef = React.useRef<any>(null);
const showEditorRef = React.useRef<any>(null);

const [isEditing, setIsEditing] = useState(false);

const {
Expand All @@ -42,6 +54,10 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
if (isSubmitting) return;
setIsEditing(false);
onSubmit(formData);
console.log(formData);

editorRef.current?.setEditorValue(formData.comment_json);
showEditorRef.current?.setEditorValue(formData.comment_json);
};

useEffect(() => {
Expand Down Expand Up @@ -85,41 +101,45 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
</p>
</div>
<div className="issue-comments-section p-0">
{isEditing ? (
<form className="flex flex-col gap-2" onSubmit={handleSubmit(onEnter)}>
<RemirrorRichTextEditor
value={comment.comment_html}
onBlur={(jsonValue, htmlValue) => {
setValue("comment_json", jsonValue);
setValue("comment_html", htmlValue);
}}
placeholder="Enter Your comment..."
/>
<div className="flex gap-1 self-end">
<button
type="submit"
disabled={isSubmitting}
className="group rounded border border-green-500 bg-green-500/20 p-2 shadow-md duration-300 hover:bg-green-500"
>
<CheckIcon className="h-3 w-3 text-green-500 duration-300 group-hover:text-white" />
</button>
<button
type="button"
className="group rounded border border-red-500 bg-red-500/20 p-2 shadow-md duration-300 hover:bg-red-500"
onClick={() => setIsEditing(false)}
>
<XMarkIcon className="h-3 w-3 text-red-500 duration-300 group-hover:text-white" />
</button>
</div>
</form>
) : (
<RemirrorRichTextEditor
<form
className={`flex-col gap-2 ${isEditing ? "flex" : "hidden"}`}
onSubmit={handleSubmit(onEnter)}
>
<WrappedRemirrorRichTextEditor
value={comment.comment_html}
onBlur={(jsonValue, htmlValue) => {
setValue("comment_json", jsonValue);
setValue("comment_html", htmlValue);
}}
placeholder="Enter Your comment..."
ref={editorRef}
/>
<div className="flex gap-1 self-end">
<button
type="submit"
disabled={isSubmitting}
className="group rounded border border-green-500 bg-green-500/20 p-2 shadow-md duration-300 hover:bg-green-500"
>
<CheckIcon className="h-3 w-3 text-green-500 duration-300 group-hover:text-white" />
</button>
<button
type="button"
className="group rounded border border-red-500 bg-red-500/20 p-2 shadow-md duration-300 hover:bg-red-500"
onClick={() => setIsEditing(false)}
>
<XMarkIcon className="h-3 w-3 text-red-500 duration-300 group-hover:text-white" />
</button>
</div>
</form>
<div className={`${isEditing ? "hidden" : ""}`}>
<WrappedRemirrorRichTextEditor
value={comment.comment_html}
editable={false}
noBorder
customClassName="text-xs border border-brand-base bg-brand-base"
ref={showEditorRef}
/>
)}
</div>
</div>
</div>
{user?.id === comment.actor && (
Expand Down
70 changes: 44 additions & 26 deletions apps/app/components/issues/description-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import dynamic from "next/dynamic";
import { Controller, useForm } from "react-hook-form";
// contexts
import { useProjectMyMembership } from "contexts/project-member.context";
// hooks
import useReloadConfirmations from "hooks/use-reload-confirmation";
// components
import { Loader, TextArea } from "components/ui";
const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
Expand Down Expand Up @@ -36,6 +38,8 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({ issue, handleFormS

const { memberRole } = useProjectMyMembership();

const { setShowAlert } = useReloadConfirmations();

const {
handleSubmit,
watch,
Expand Down Expand Up @@ -82,7 +86,10 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({ issue, handleFormS
useEffect(() => {
if (!issue) return;

reset(issue);
reset({
...issue,
description: issue.description,
});
}, [issue, reset]);

const isNotAllowed = memberRole.isGuest || memberRole.isViewer;
Expand Down Expand Up @@ -131,31 +138,42 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({ issue, handleFormS
<Controller
name="description"
control={control}
render={({ field: { value } }) => (
<RemirrorRichTextEditor
value={
!value ||
value === "" ||
(typeof value === "object" && Object.keys(value).length === 0)
? watch("description_html")
: value
}
onJSONChange={(jsonValue) => setValue("description", jsonValue)}
onHTMLChange={(htmlValue) => setValue("description_html", htmlValue)}
onBlur={() => {
setIsSubmitting(true);
handleSubmit(handleDescriptionFormSubmit)()
.then(() => {
setIsSubmitting(false);
})
.catch(() => {
setIsSubmitting(false);
});
}}
placeholder="Describe the issue..."
editable={!isNotAllowed}
/>
)}
render={({ field: { value } }) => {
if (!value || !watch("description_html")) return <></>;

return (
<RemirrorRichTextEditor
value={
!value ||
value === "" ||
(typeof value === "object" && Object.keys(value).length === 0)
? watch("description_html")
: value
}
onJSONChange={(jsonValue) => {
setShowAlert(true);
setValue("description", jsonValue);
}}
onHTMLChange={(htmlValue) => {
setShowAlert(true);
setValue("description_html", htmlValue);
}}
onBlur={() => {
setIsSubmitting(true);
handleSubmit(handleDescriptionFormSubmit)()
.then(() => {
setIsSubmitting(false);
setShowAlert(false);
})
.catch(() => {
setIsSubmitting(false);
});
}}
placeholder="Describe the issue..."
editable={!isNotAllowed}
/>
);
}}
/>
<div
className={`absolute -bottom-8 right-0 text-sm text-brand-secondary ${
Expand Down
18 changes: 16 additions & 2 deletions apps/app/components/issues/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@ const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor
const defaultValues: Partial<IIssue> = {
project: "",
name: "",
description: { type: "doc", content: [] },
description: {
type: "doc",
content: [
{
type: "paragraph",
},
],
},
description_html: "<p></p>",
estimate_point: null,
state: "",
Expand Down Expand Up @@ -132,7 +139,14 @@ export const IssueForm: FC<IssueFormProps> = ({
reset({
...defaultValues,
project: projectId,
description: "",
description: {
type: "doc",
content: [
{
type: "paragraph",
},
],
},
description_html: "<p></p>",
});
};
Expand Down
Loading