fix: disable comment submit while uploading an image (#6445)
This commit is contained in:
parent
74913a6659
commit
6003c88d62
2 changed files with 46 additions and 33 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue