Skip to content

Commit 6003c88

Browse files
authored
fix: disable comment submit while uploading an image (#6445)
1 parent 74913a6 commit 6003c88

File tree

2 files changed

+46
-33
lines changed

2 files changed

+46
-33
lines changed

web/core/components/editor/lite-text-editor/toolbar.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ export const IssueCommentToolbar: React.FC<Props> = (props) => {
5757
showSubmitButton,
5858
editorRef,
5959
} = props;
60-
6160
// State to manage active states of toolbar items
6261
const [activeStates, setActiveStates] = useState<Record<string, boolean>>({});
6362

@@ -86,6 +85,9 @@ export const IssueCommentToolbar: React.FC<Props> = (props) => {
8685
return () => unsubscribe();
8786
}, [editorRef, updateActiveStates]);
8887

88+
const isEditorReadyToDiscard = editorRef?.isEditorReadyToDiscard();
89+
const isSubmitButtonDisabled = isCommentEmpty || !isEditorReadyToDiscard;
90+
8991
return (
9092
<div className="flex h-9 w-full items-stretch gap-1.5 bg-custom-background-90 overflow-x-scroll">
9193
{showAccessSpecifier && (
@@ -166,7 +168,7 @@ export const IssueCommentToolbar: React.FC<Props> = (props) => {
166168
variant="primary"
167169
className="px-2.5 py-1.5 text-xs"
168170
onClick={handleSubmit}
169-
disabled={isCommentEmpty}
171+
disabled={isSubmitButtonDisabled}
170172
loading={isSubmitting}
171173
>
172174
Comment

web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ import { FC, useEffect, useRef, useState } from "react";
44
import { observer } from "mobx-react";
55
import { useForm } from "react-hook-form";
66
import { Check, Globe2, Lock, Pencil, Trash2, X } from "lucide-react";
7+
// plane constants
78
import { EIssueCommentAccessSpecifier } from "@plane/constants";
9+
// plane editor
810
import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor";
11+
// plane types
912
import { TIssueComment } from "@plane/types";
10-
// ui
13+
// plane ui
1114
import { CustomMenu } from "@plane/ui";
15+
// plane utils
16+
import { cn } from "@plane/utils";
1217
// components
1318
import { LiteTextEditor, LiteTextReadOnlyEditor } from "@/components/editor";
1419
// helpers
@@ -42,21 +47,21 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
4247
showAccessSpecifier = false,
4348
disabled = false,
4449
} = props;
45-
// hooks
50+
// states
51+
const [isEditing, setIsEditing] = useState(false);
52+
// refs
53+
const editorRef = useRef<EditorRefApi>(null);
54+
const showEditorRef = useRef<EditorReadOnlyRefApi>(null);
55+
// store hooks
4656
const {
4757
comment: { getCommentById },
4858
} = useIssueDetail();
4959
const { data: currentUser } = useUser();
50-
// refs
51-
const editorRef = useRef<EditorRefApi>(null);
52-
const showEditorRef = useRef<EditorReadOnlyRefApi>(null);
53-
// state
54-
const [isEditing, setIsEditing] = useState(false);
55-
60+
// derived values
5661
const comment = getCommentById(commentId);
5762
const workspaceStore = useWorkspace();
5863
const workspaceId = workspaceStore.getWorkspaceBySlug(comment?.workspace_detail?.slug as string)?.id as string;
59-
64+
// form info
6065
const {
6166
formState: { isSubmitting },
6267
handleSubmit,
@@ -66,6 +71,11 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
6671
} = useForm<Partial<TIssueComment>>({
6772
defaultValues: { comment_html: comment?.comment_html },
6873
});
74+
// derived values
75+
const commentHTML = watch("comment_html");
76+
const isEmpty = isCommentEmpty(commentHTML);
77+
const isEditorReadyToDiscard = editorRef.current?.isEditorReadyToDiscard();
78+
const isSubmitButtonDisabled = isSubmitting || !isEditorReadyToDiscard;
6979

7080
const onEnter = async (formData: Partial<TIssueComment>) => {
7181
if (isSubmitting || !comment) return;
@@ -83,10 +93,8 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
8393
}
8494
}, [isEditing, setFocus]);
8595

86-
const commentHTML = watch("comment_html");
87-
const isEmpty = isCommentEmpty(commentHTML);
88-
8996
if (!comment || !currentUser) return <></>;
97+
9098
return (
9199
<IssueCommentBlock
92100
commentId={commentId}
@@ -95,8 +103,8 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
95103
{!disabled && currentUser?.id === comment.actor && (
96104
<CustomMenu ellipsis closeOnSelect>
97105
<CustomMenu.MenuItem onClick={() => setIsEditing(true)} className="flex items-center gap-1">
98-
<Pencil className="h-3 w-3" />
99-
Edit comment
106+
<Pencil className="flex-shrink-0 size-3" />
107+
Edit
100108
</CustomMenu.MenuItem>
101109
{showAccessSpecifier && (
102110
<>
@@ -107,7 +115,7 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
107115
}
108116
className="flex items-center gap-1"
109117
>
110-
<Globe2 className="h-3 w-3" />
118+
<Globe2 className="flex-shrink-0 size-3" />
111119
Switch to public comment
112120
</CustomMenu.MenuItem>
113121
) : (
@@ -117,7 +125,7 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
117125
}
118126
className="flex items-center gap-1"
119127
>
120-
<Lock className="h-3 w-3" />
128+
<Lock className="flex-shrink-0 size-3" />
121129
Switch to private comment
122130
</CustomMenu.MenuItem>
123131
)}
@@ -127,8 +135,8 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
127135
onClick={() => activityOperations.removeComment(comment.id)}
128136
className="flex items-center gap-1"
129137
>
130-
<Trash2 className="h-3 w-3" />
131-
Delete comment
138+
<Trash2 className="flex-shrink-0 size-3" />
139+
Delete
132140
</CustomMenu.MenuItem>
133141
</CustomMenu>
134142
)}
@@ -166,24 +174,27 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
166174
/>
167175
</div>
168176
<div className="flex gap-1 self-end">
169-
<button
170-
type="button"
171-
onClick={handleSubmit(onEnter)}
172-
disabled={isSubmitting || isEmpty}
173-
className={`group rounded border border-green-500 bg-green-500/20 p-2 shadow-md duration-300 ${
174-
isEmpty ? "cursor-not-allowed bg-gray-200" : "hover:bg-green-500"
175-
}`}
176-
>
177-
<Check
178-
className={`h-3 w-3 text-green-500 duration-300 ${isEmpty ? "text-black" : "group-hover:text-white"}`}
179-
/>
180-
</button>
177+
{!isEmpty && (
178+
<button
179+
type="button"
180+
onClick={handleSubmit(onEnter)}
181+
disabled={isSubmitButtonDisabled}
182+
className={cn(
183+
"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",
184+
{
185+
"pointer-events-none": isSubmitButtonDisabled,
186+
}
187+
)}
188+
>
189+
<Check className="size-3" />
190+
</button>
191+
)}
181192
<button
182193
type="button"
183194
className="group rounded border border-red-500 bg-red-500/20 p-2 shadow-md duration-300 hover:bg-red-500"
184195
onClick={() => setIsEditing(false)}
185196
>
186-
<X className="h-3 w-3 text-red-500 duration-300 group-hover:text-white" />
197+
<X className="size-3 text-red-500 duration-300 group-hover:text-white" />
187198
</button>
188199
</div>
189200
</form>

0 commit comments

Comments
 (0)