added additional props and Tiptap Integration with Comments

This commit is contained in:
Palanikannan1437 2023-08-10 01:20:15 +05:30
parent 5c290e1302
commit 0b6d510cc7
5 changed files with 96 additions and 51 deletions

View File

@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import dynamic from "next/dynamic";
import { mutate } from "swr"; import { mutate } from "swr";
@ -12,11 +11,12 @@ import issuesServices from "services/issues.service";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// ui // ui
import { Loader, SecondaryButton } from "components/ui"; import { SecondaryButton } from "components/ui";
// types // types
import type { ICurrentUserResponse, IIssueComment } from "types"; import type { ICurrentUserResponse, IIssueComment } from "types";
// fetch-keys // fetch-keys
import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
import Tiptap, { ITiptapRichTextEditor } from "components/tiptap";
// const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), { // const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
// ssr: false, // ssr: false,
@ -34,7 +34,14 @@ import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
// >((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />); // >((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />);
// //
// WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor"; // WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor";
//
const TiptapEditor = React.forwardRef<
ITiptapRichTextEditor,
ITiptapRichTextEditor
>((props, ref) => <Tiptap {...props} forwardedRef={ref} />);
TiptapEditor.displayName = "TiptapEditor";
const defaultValues: Partial<IIssueComment> = { const defaultValues: Partial<IIssueComment> = {
comment_json: "", comment_json: "",
comment_html: "", comment_html: "",
@ -51,6 +58,7 @@ export const AddComment: React.FC<Props> = ({ issueId, user, disabled = false })
handleSubmit, handleSubmit,
control, control,
setValue, setValue,
watch,
formState: { isSubmitting }, formState: { isSubmitting },
reset, reset,
} = useForm<IIssueComment>({ defaultValues }); } = useForm<IIssueComment>({ defaultValues });
@ -98,19 +106,26 @@ export const AddComment: React.FC<Props> = ({ issueId, user, disabled = false })
<div> <div>
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<div className="issue-comments-section"> <div className="issue-comments-section">
{/* <Controller */} <Controller
{/* name="comment_json" */} name="comment_html"
{/* control={control} */} control={control}
{/* render={({ field: { value } }) => ( */} render={({ field: { value, onChange } }) =>
{/* <WrappedRemirrorRichTextEditor */} <TiptapEditor
{/* value={value} */} ref={editorRef}
{/* onJSONChange={(jsonValue) => setValue("comment_json", jsonValue)} */} value={
{/* onHTMLChange={(htmlValue) => setValue("comment_html", htmlValue)} */} !value || value === "" || (typeof value === "object" && Object.keys(value).length === 0)
{/* placeholder="Enter your comment..." */} ? watch("comment_html")
{/* ref={editorRef} */} : value
{/* /> */} }
{/* )} */} customClassName="p-3 min-h-[50px]"
{/* /> */} debouncedUpdatesEnabled={false}
onChange={(comment_json: Object, comment_html: string) => {
onChange(comment_html);
setValue("comment_json", comment_json);
}}
/>
}
/>
<SecondaryButton type="submit" disabled={isSubmitting || disabled} className="mt-2"> <SecondaryButton type="submit" disabled={isSubmitting || disabled} className="mt-2">
{isSubmitting ? "Adding..." : "Comment"} {isSubmitting ? "Adding..." : "Comment"}

View File

@ -15,6 +15,7 @@ import { CommentReaction } from "components/issues";
import { timeAgo } from "helpers/date-time.helper"; import { timeAgo } from "helpers/date-time.helper";
// types // types
import type { IIssueComment } from "types"; import type { IIssueComment } from "types";
import Tiptap, { ITiptapRichTextEditor } from "components/tiptap";
// const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), { ssr: false }); // const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), { ssr: false });
// //
@ -26,7 +27,14 @@ import type { IIssueComment } from "types";
// >((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />); // >((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />);
// //
// WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor"; // WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor";
//
const TiptapEditor = React.forwardRef<
ITiptapRichTextEditor,
ITiptapRichTextEditor
>((props, ref) => <Tiptap {...props} forwardedRef={ref} />);
TiptapEditor.displayName = "TiptapEditor";
type Props = { type Props = {
comment: IIssueComment; comment: IIssueComment;
onSubmit: (comment: IIssueComment) => void; onSubmit: (comment: IIssueComment) => void;
@ -45,6 +53,7 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
formState: { isSubmitting }, formState: { isSubmitting },
handleSubmit, handleSubmit,
setFocus, setFocus,
watch,
setValue, setValue,
} = useForm<IIssueComment>({ } = useForm<IIssueComment>({
defaultValues: comment, defaultValues: comment,
@ -55,9 +64,10 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
setIsEditing(false); setIsEditing(false);
onSubmit(formData); onSubmit(formData);
console.log("watching", formData.comment_html)
editorRef.current?.setEditorValue(formData.comment_json); editorRef.current?.setEditorValue(formData.comment_html);
showEditorRef.current?.setEditorValue(formData.comment_json); showEditorRef.current?.setEditorValue(formData.comment_html);
}; };
useEffect(() => { useEffect(() => {
@ -105,14 +115,24 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
className={`flex-col gap-2 ${isEditing ? "flex" : "hidden"}`} className={`flex-col gap-2 ${isEditing ? "flex" : "hidden"}`}
onSubmit={handleSubmit(onEnter)} onSubmit={handleSubmit(onEnter)}
> >
<WrappedRemirrorRichTextEditor {/* <WrappedRemirrorRichTextEditor */}
value={comment.comment_html} {/* value={comment.comment_html} */}
onBlur={(jsonValue, htmlValue) => { {/* onBlur={(jsonValue, htmlValue) => { */}
setValue("comment_json", jsonValue); {/* setValue("comment_json", jsonValue); */}
setValue("comment_html", htmlValue); {/* setValue("comment_html", htmlValue); */}
}} {/* }} */}
placeholder="Enter Your comment..." {/* placeholder="Enter Your comment..." */}
{/* ref={editorRef} */}
{/* /> */}
<TiptapEditor
ref={editorRef} ref={editorRef}
value={watch("comment_html")}
debouncedUpdatesEnabled={false}
customClassName="min-h-[50px] p-3"
onChange={(comment_json: Object, comment_html: string) => {
setValue("comment_json", comment_json);
setValue("comment_html", comment_html);
}}
/> />
<div className="flex gap-1 self-end"> <div className="flex gap-1 self-end">
<button <button
@ -132,6 +152,12 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
</div> </div>
</form> </form>
<div className={`${isEditing ? "hidden" : ""}`}> <div className={`${isEditing ? "hidden" : ""}`}>
<TiptapEditor
ref={showEditorRef}
value={comment.comment_html}
editable={false}
customClassName="text-xs border border-custom-border-200 bg-custom-background-100"
/>
{/* <WrappedRemirrorRichTextEditor */} {/* <WrappedRemirrorRichTextEditor */}
{/* value={comment.comment_html} */} {/* value={comment.comment_html} */}
{/* editable={false} */} {/* editable={false} */}
@ -139,7 +165,6 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
{/* customClassName="text-xs border border-custom-border-200 bg-custom-background-100" */} {/* customClassName="text-xs border border-custom-border-200 bg-custom-background-100" */}
{/* ref={showEditorRef} */} {/* ref={showEditorRef} */}
{/* /> */} {/* /> */}
<CommentReaction projectId={comment.project} commentId={comment.id} /> <CommentReaction projectId={comment.project} commentId={comment.id} />
</div> </div>
</div> </div>

View File

@ -123,8 +123,12 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({
? watch("description_html") ? watch("description_html")
: value : value
} }
debouncedUpdatesEnabled={true}
setIsSubmitting={setIsSubmitting} setIsSubmitting={setIsSubmitting}
customClassName="min-h-[150px]"
editorContentCustomClassNames="pt-9"
onChange={(description: Object, description_html: string) => { onChange={(description: Object, description_html: string) => {
setIsSubmitting(true);
onChange(description_html); onChange(description_html);
setValue("description", description); setValue("description", description);
handleSubmit(handleDescriptionFormSubmit)().finally(() => setIsSubmitting(false)); handleSubmit(handleDescriptionFormSubmit)().finally(() => setIsSubmitting(false));

View File

@ -372,6 +372,7 @@ export const IssueForm: FC<IssueFormProps> = ({
return ( return (
<Tiptap <Tiptap
debouncedUpdatesEnabled={false}
value={ value={
!value || value === "" || (typeof value === "object" && Object.keys(value).length === 0) !value || value === "" || (typeof value === "object" && Object.keys(value).length === 0)
? watch("description_html") ? watch("description_html")

View File

@ -129,30 +129,30 @@ export const IssueMainContent: React.FC<Props> = ({
isAllowed={memberRole.isMember || memberRole.isOwner || !uneditable} isAllowed={memberRole.isMember || memberRole.isOwner || !uneditable}
/> />
{/* <IssueReaction workspaceSlug={workspaceSlug} issueId={issueId} projectId={projectId} /> */} <IssueReaction workspaceSlug={workspaceSlug} issueId={issueId} projectId={projectId} />
{/**/}
{/* <div className="mt-2 space-y-2"> */} <div className="mt-2 space-y-2">
{/* <SubIssuesList parentIssue={issueDetails} user={user} disabled={uneditable} /> */} <SubIssuesList parentIssue={issueDetails} user={user} disabled={uneditable} />
{/* </div> */} </div>
{/* </div> */} </div>
{/* <div className="flex flex-col gap-3 py-3"> */} <div className="flex flex-col gap-3 py-3">
{/* <h3 className="text-lg">Attachments</h3> */} <h3 className="text-lg">Attachments</h3>
{/* <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4"> */} <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
{/* <IssueAttachmentUpload disabled={uneditable} /> */} <IssueAttachmentUpload disabled={uneditable} />
{/* <IssueAttachments /> */} <IssueAttachments />
{/* </div> */} </div>
{/* </div> */} </div>
{/* <div className="space-y-5 pt-3"> */} <div className="space-y-5 pt-3">
{/* <h3 className="text-lg text-custom-text-100">Comments/Activity</h3> */} <h3 className="text-lg text-custom-text-100">Comments/Activity</h3>
{/* <IssueActivitySection */} <IssueActivitySection
{/* issueId={(archivedIssueId as string) ?? (issueId as string)} */} issueId={(archivedIssueId as string) ?? (issueId as string)}
{/* user={user} */} user={user}
{/* /> */} />
{/* <AddComment */} <AddComment
{/* issueId={(archivedIssueId as string) ?? (issueId as string)} */} issueId={(archivedIssueId as string) ?? (issueId as string)}
{/* user={user} */} user={user}
{/* disabled={uneditable} */} disabled={uneditable}
{/* /> */} />
</div> </div>
</> </>
); );