fix: disable comment submit while uploading an image (#6445)

This commit is contained in:
Aaryan Khandelwal 2025-01-28 20:19:01 +05:30 committed by GitHub
parent 74913a6659
commit 6003c88d62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 33 deletions

View file

@ -57,7 +57,6 @@ export const IssueCommentToolbar: React.FC<Props> = (props) => {
showSubmitButton,
editorRef,
} = props;
// State to manage active states of toolbar items
const [activeStates, setActiveStates] = useState<Record<string, boolean>>({});
@ -86,6 +85,9 @@ export const IssueCommentToolbar: React.FC<Props> = (props) => {
return () => unsubscribe();
}, [editorRef, updateActiveStates]);
const isEditorReadyToDiscard = editorRef?.isEditorReadyToDiscard();
const isSubmitButtonDisabled = isCommentEmpty || !isEditorReadyToDiscard;
return (
<div className="flex h-9 w-full items-stretch gap-1.5 bg-custom-background-90 overflow-x-scroll">
{showAccessSpecifier && (
@ -166,7 +168,7 @@ export const IssueCommentToolbar: React.FC<Props> = (props) => {
variant="primary"
className="px-2.5 py-1.5 text-xs"
onClick={handleSubmit}
disabled={isCommentEmpty}
disabled={isSubmitButtonDisabled}
loading={isSubmitting}
>
Comment

View file

@ -4,11 +4,16 @@ import { FC, useEffect, useRef, useState } from "react";
import { observer } from "mobx-react";
import { useForm } from "react-hook-form";
import { Check, Globe2, Lock, Pencil, Trash2, X } from "lucide-react";
// plane constants
import { EIssueCommentAccessSpecifier } from "@plane/constants";
// plane editor
import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor";
// plane types
import { TIssueComment } from "@plane/types";
// ui
// plane ui
import { CustomMenu } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// components
import { LiteTextEditor, LiteTextReadOnlyEditor } from "@/components/editor";
// helpers
@ -42,21 +47,21 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
showAccessSpecifier = false,
disabled = false,
} = props;
// hooks
// states
const [isEditing, setIsEditing] = useState(false);
// refs
const editorRef = useRef<EditorRefApi>(null);
const showEditorRef = useRef<EditorReadOnlyRefApi>(null);
// store hooks
const {
comment: { getCommentById },
} = useIssueDetail();
const { data: currentUser } = useUser();
// refs
const editorRef = useRef<EditorRefApi>(null);
const showEditorRef = useRef<EditorReadOnlyRefApi>(null);
// state
const [isEditing, setIsEditing] = useState(false);
// derived values
const comment = getCommentById(commentId);
const workspaceStore = useWorkspace();
const workspaceId = workspaceStore.getWorkspaceBySlug(comment?.workspace_detail?.slug as string)?.id as string;
// form info
const {
formState: { isSubmitting },
handleSubmit,
@ -66,6 +71,11 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
} = useForm<Partial<TIssueComment>>({
defaultValues: { comment_html: comment?.comment_html },
});
// derived values
const commentHTML = watch("comment_html");
const isEmpty = isCommentEmpty(commentHTML);
const isEditorReadyToDiscard = editorRef.current?.isEditorReadyToDiscard();
const isSubmitButtonDisabled = isSubmitting || !isEditorReadyToDiscard;
const onEnter = async (formData: Partial<TIssueComment>) => {
if (isSubmitting || !comment) return;
@ -83,10 +93,8 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
}
}, [isEditing, setFocus]);
const commentHTML = watch("comment_html");
const isEmpty = isCommentEmpty(commentHTML);
if (!comment || !currentUser) return <></>;
return (
<IssueCommentBlock
commentId={commentId}
@ -95,8 +103,8 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
{!disabled && currentUser?.id === comment.actor && (
<CustomMenu ellipsis closeOnSelect>
<CustomMenu.MenuItem onClick={() => setIsEditing(true)} className="flex items-center gap-1">
<Pencil className="h-3 w-3" />
Edit comment
<Pencil className="flex-shrink-0 size-3" />
Edit
</CustomMenu.MenuItem>
{showAccessSpecifier && (
<>
@ -107,7 +115,7 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
}
className="flex items-center gap-1"
>
<Globe2 className="h-3 w-3" />
<Globe2 className="flex-shrink-0 size-3" />
Switch to public comment
</CustomMenu.MenuItem>
) : (
@ -117,7 +125,7 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
}
className="flex items-center gap-1"
>
<Lock className="h-3 w-3" />
<Lock className="flex-shrink-0 size-3" />
Switch to private comment
</CustomMenu.MenuItem>
)}
@ -127,8 +135,8 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
onClick={() => activityOperations.removeComment(comment.id)}
className="flex items-center gap-1"
>
<Trash2 className="h-3 w-3" />
Delete comment
<Trash2 className="flex-shrink-0 size-3" />
Delete
</CustomMenu.MenuItem>
</CustomMenu>
)}
@ -166,24 +174,27 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
/>
</div>
<div className="flex gap-1 self-end">
<button
type="button"
onClick={handleSubmit(onEnter)}
disabled={isSubmitting || isEmpty}
className={`group rounded border border-green-500 bg-green-500/20 p-2 shadow-md duration-300 ${
isEmpty ? "cursor-not-allowed bg-gray-200" : "hover:bg-green-500"
}`}
>
<Check
className={`h-3 w-3 text-green-500 duration-300 ${isEmpty ? "text-black" : "group-hover:text-white"}`}
/>
</button>
{!isEmpty && (
<button
type="button"
onClick={handleSubmit(onEnter)}
disabled={isSubmitButtonDisabled}
className={cn(
"group rounded border border-green-500 text-green-500 hover:text-white bg-green-500/20 hover:bg-green-500 p-2 shadow-md duration-300",
{
"pointer-events-none": isSubmitButtonDisabled,
}
)}
>
<Check className="size-3" />
</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)}
>
<X className="h-3 w-3 text-red-500 duration-300 group-hover:text-white" />
<X className="size-3 text-red-500 duration-300 group-hover:text-white" />
</button>
</div>
</form>