[WEB-1689] fix: command enter submits the form (#4986)

* fix: command enter submits the form

* fix: build errors
This commit is contained in:
Aaryan Khandelwal 2024-07-01 17:00:53 +05:30 committed by GitHub
parent 936c21d65e
commit e78263e01f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 46 additions and 41 deletions

View file

@ -1,6 +1,6 @@
import { Extension } from "@tiptap/core"; import { Extension } from "@tiptap/core";
export const EnterKeyExtension = (onEnterKeyPress?: () => void) => export const EnterKeyExtension = (onEnterKeyPress?: (descriptionHTML: string) => void) =>
Extension.create({ Extension.create({
name: "enterKey", name: "enterKey",
@ -8,9 +8,7 @@ export const EnterKeyExtension = (onEnterKeyPress?: () => void) =>
return { return {
Enter: () => { Enter: () => {
if (!this.editor.storage.mentionsOpen) { if (!this.editor.storage.mentionsOpen) {
if (onEnterKeyPress) { onEnterKeyPress?.(this.editor.getHTML());
onEnterKeyPress();
}
return true; return true;
} }
return false; return false;

View file

@ -38,7 +38,7 @@ export interface IEditorProps {
suggestions?: () => Promise<IMentionSuggestion[]>; suggestions?: () => Promise<IMentionSuggestion[]>;
}; };
onChange?: (json: object, html: string) => void; onChange?: (json: object, html: string) => void;
onEnterKeyPress?: (e?: any) => void; onEnterKeyPress?: (descriptionHTML: string) => void;
placeholder?: string | ((isFocused: boolean, value: string) => string); placeholder?: string | ((isFocused: boolean, value: string) => string);
tabIndex?: number; tabIndex?: number;
value?: string | null; value?: string | null;

View file

@ -64,7 +64,11 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
}} }}
isSubmitting={isSubmitting} isSubmitting={isSubmitting}
showSubmitButton={showSubmitButton} showSubmitButton={showSubmitButton}
handleSubmit={(e) => rest.onEnterKeyPress?.(e)} handleSubmit={() => {
if (isMutableRefObject<EditorRefApi>(ref)) {
rest.onEnterKeyPress?.(ref.current?.getHTML() ?? "");
}
}}
isCommentEmpty={isEmpty} isCommentEmpty={isEmpty}
editorRef={isMutableRefObject<EditorRefApi>(ref) ? ref : null} editorRef={isMutableRefObject<EditorRefApi>(ref) ? ref : null}
/> />

View file

@ -12,7 +12,7 @@ import { cn } from "@/helpers/common.helper";
type Props = { type Props = {
executeCommand: (commandName: EditorMenuItemNames) => void; executeCommand: (commandName: EditorMenuItemNames) => void;
handleSubmit: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void; handleSubmit: () => void;
isCommentEmpty: boolean; isCommentEmpty: boolean;
isSubmitting: boolean; isSubmitting: boolean;
showSubmitButton: boolean; showSubmitButton: boolean;
@ -95,7 +95,7 @@ export const IssueCommentToolbar: React.FC<Props> = (props) => {
{showSubmitButton && ( {showSubmitButton && (
<div className="sticky right-1"> <div className="sticky right-1">
<Button <Button
type="submit" type="button"
variant="primary" variant="primary"
className="px-2.5 py-1.5 text-xs" className="px-2.5 py-1.5 text-xs"
onClick={handleSubmit} onClick={handleSubmit}

View file

@ -66,8 +66,8 @@ export const AddComment: React.FC<Props> = observer((props) => {
control={control} control={control}
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<LiteTextEditor <LiteTextEditor
onEnterKeyPress={(e) => { onEnterKeyPress={() => {
if (currentUser) handleSubmit(onSubmit)(e); if (currentUser) handleSubmit(onSubmit)();
}} }}
workspaceId={workspaceID?.toString() ?? ""} workspaceId={workspaceID?.toString() ?? ""}
workspaceSlug={workspaceSlug?.toString() ?? ""} workspaceSlug={workspaceSlug?.toString() ?? ""}

View file

@ -103,7 +103,7 @@ export const CommentCard: React.FC<Props> = observer((props) => {
<LiteTextEditor <LiteTextEditor
workspaceId={workspaceID?.toString() ?? ""} workspaceId={workspaceID?.toString() ?? ""}
workspaceSlug={workspaceSlug?.toString() ?? ""} workspaceSlug={workspaceSlug?.toString() ?? ""}
onEnterKeyPress={handleSubmit(handleCommentUpdate)} onEnterKeyPress={() => handleSubmit(handleCommentUpdate)()}
ref={editorRef} ref={editorRef}
initialValue={value} initialValue={value}
value={null} value={null}

View file

@ -92,7 +92,11 @@ export const LiteTextEditor = React.forwardRef<EditorRefApi, LiteTextEditorWrapp
} }
}} }}
handleAccessChange={handleAccessChange} handleAccessChange={handleAccessChange}
handleSubmit={(e) => rest.onEnterKeyPress?.(e)} handleSubmit={() => {
if (isMutableRefObject<EditorRefApi>(ref)) {
rest.onEnterKeyPress?.(ref.current?.getHTML() ?? "");
}
}}
isCommentEmpty={isEmpty} isCommentEmpty={isEmpty}
isSubmitting={isSubmitting} isSubmitting={isSubmitting}
showAccessSpecifier={showAccessSpecifier} showAccessSpecifier={showAccessSpecifier}

View file

@ -81,7 +81,6 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
}, [isEditing, setFocus]); }, [isEditing, setFocus]);
const isEmpty = const isEmpty =
watch("comment_html") === "" ||
watch("comment_html")?.trim() === "" || watch("comment_html")?.trim() === "" ||
watch("comment_html") === "<p></p>" || watch("comment_html") === "<p></p>" ||
isEmptyHtmlString(watch("comment_html") ?? ""); isEmptyHtmlString(watch("comment_html") ?? "");
@ -138,11 +137,7 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
> >
<> <>
<form className={`flex-col gap-2 ${isEditing ? "flex" : "hidden"}`}> <form className={`flex-col gap-2 ${isEditing ? "flex" : "hidden"}`}>
<div <div>
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey && !isEmpty) handleSubmit(onEnter)(e);
}}
>
<LiteTextEditor <LiteTextEditor
workspaceId={workspaceId} workspaceId={workspaceId}
projectId={projectId} projectId={projectId}
@ -151,6 +146,15 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
initialValue={watch("comment_html") ?? ""} initialValue={watch("comment_html") ?? ""}
value={null} value={null}
onChange={(comment_json, comment_html) => setValue("comment_html", comment_html)} onChange={(comment_json, comment_html) => setValue("comment_html", comment_html)}
onEnterKeyPress={(commentHTML) => {
const isCommentEmpty =
commentHTML?.trim() === "" ||
commentHTML === "<p></p>" ||
(isEmptyHtmlString(commentHTML ?? "") && !commentHTML?.includes("mention-component"));
if (!isCommentEmpty && !isSubmitting) {
handleSubmit(onEnter)();
}
}}
showSubmitButton={false} showSubmitButton={false}
/> />
</div> </div>

View file

@ -33,7 +33,6 @@ export const IssueCommentCreate: FC<TIssueCommentCreate> = (props) => {
const { const {
handleSubmit, handleSubmit,
control, control,
watch,
formState: { isSubmitting }, formState: { isSubmitting },
reset, reset,
} = useForm<Partial<TIssueComment>>({ } = useForm<Partial<TIssueComment>>({
@ -50,19 +49,8 @@ export const IssueCommentCreate: FC<TIssueCommentCreate> = (props) => {
editorRef.current?.clearEditor(); editorRef.current?.clearEditor();
}); });
const commentHTML = watch("comment_html");
const isEmpty =
commentHTML?.trim() === "" ||
commentHTML === "<p></p>" ||
(isEmptyHtmlString(commentHTML ?? "") && !commentHTML?.includes("mention-component"));
return ( return (
<div <div>
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey && !isEmpty && !isSubmitting) handleSubmit(onSubmit)(e);
}}
>
<Controller <Controller
name="access" name="access"
control={control} control={control}
@ -77,8 +65,15 @@ export const IssueCommentCreate: FC<TIssueCommentCreate> = (props) => {
value={"<p></p>"} value={"<p></p>"}
projectId={projectId} projectId={projectId}
workspaceSlug={workspaceSlug} workspaceSlug={workspaceSlug}
onEnterKeyPress={(e) => { onEnterKeyPress={(commentHTML) => {
if (!isEmpty && !isSubmitting) handleSubmit(onSubmit)(e); console.log("commentHTML", commentHTML);
const isEmpty =
commentHTML?.trim() === "" ||
commentHTML === "<p></p>" ||
(isEmptyHtmlString(commentHTML ?? "") && !commentHTML?.includes("mention-component"));
if (!isEmpty && !isSubmitting) {
handleSubmit(onSubmit)();
}
}} }}
ref={editorRef} ref={editorRef}
initialValue={value ?? "<p></p>"} initialValue={value ?? "<p></p>"}

View file

@ -351,7 +351,7 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
className="grid place-items-center p-0.5 text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80 rounded" className="grid place-items-center p-0.5 text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-80 rounded"
onClick={() => setIsMenuActive(!isMenuActive)} onClick={() => setIsMenuActive(!isMenuActive)}
> >
<MoreHorizontal className="size-3.5" /> <MoreHorizontal className="size-4" />
</span> </span>
} }
className={cn( className={cn(
@ -443,7 +443,7 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
)} )}
> >
<ChevronRight <ChevronRight
className={cn("size-3.5 flex-shrink-0 text-custom-sidebar-text-400 transition-transform", { className={cn("size-4 flex-shrink-0 text-custom-sidebar-text-400 transition-transform", {
"rotate-90": open, "rotate-90": open,
})} })}
/> />

View file

@ -193,7 +193,7 @@ export const SidebarProjectsList: FC = observer(() => {
<> <>
<div <div
className={cn( className={cn(
"group w-full flex items-center justify-between px-2 py-0.5 rounded text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-90", "group w-full flex items-center justify-between px-2 py-1.5 rounded text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-90",
{ {
"p-0 justify-center w-fit mx-auto bg-custom-sidebar-background-90 hover:bg-custom-sidebar-background-80": "p-0 justify-center w-fit mx-auto bg-custom-sidebar-background-90 hover:bg-custom-sidebar-background-80":
isCollapsed, isCollapsed,
@ -221,7 +221,7 @@ export const SidebarProjectsList: FC = observer(() => {
</Tooltip> </Tooltip>
</Disclosure.Button> </Disclosure.Button>
{!isCollapsed && ( {!isCollapsed && (
<div className="flex items-center opacity-0 group-hover:opacity-100"> <div className="flex items-center opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto">
{isAuthorizedUser && ( {isAuthorizedUser && (
<Tooltip tooltipHeading="Create project" tooltipContent=""> <Tooltip tooltipHeading="Create project" tooltipContent="">
<button <button
@ -244,7 +244,7 @@ export const SidebarProjectsList: FC = observer(() => {
onClick={() => toggleListDisclosure(!section.isOpen, section.key)} onClick={() => toggleListDisclosure(!section.isOpen, section.key)}
> >
<ChevronRight <ChevronRight
className={cn("flex-shrink-0 size-3.5 transition-all", { className={cn("flex-shrink-0 size-4 transition-all", {
"rotate-90": section.isOpen, "rotate-90": section.isOpen,
})} })}
/> />

View file

@ -56,13 +56,13 @@ export const SidebarWorkspaceMenu = observer(() => {
{!sidebarCollapsed && ( {!sidebarCollapsed && (
<Disclosure.Button <Disclosure.Button
as="button" as="button"
className="group/workspace-button w-full px-2 py-0.5 flex items-center justify-between gap-1 text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-90 rounded text-sm font-semibold" className="group/workspace-button w-full px-2 py-1.5 flex items-center justify-between gap-1 text-custom-sidebar-text-400 hover:bg-custom-sidebar-background-90 rounded text-sm font-semibold"
onClick={() => toggleWorkspaceMenu(!isWorkspaceMenuOpen)} onClick={() => toggleWorkspaceMenu(!isWorkspaceMenuOpen)}
> >
<span>Workspace</span> <span>Workspace</span>
<span className="flex-shrink-0 hidden group-hover/workspace-button:inline-block rounded p-0.5 hover:bg-custom-sidebar-background-80"> <span className="flex-shrink-0 opacity-0 pointer-events-none group-hover/workspace-button:opacity-100 group-hover/workspace-button:pointer-events-auto rounded p-0.5 hover:bg-custom-sidebar-background-80">
<ChevronRight <ChevronRight
className={cn("size-3.5 flex-shrink-0 text-custom-sidebar-text-400 transition-transform", { className={cn("size-4 flex-shrink-0 text-custom-sidebar-text-400 transition-transform", {
"rotate-90": isWorkspaceMenuOpen, "rotate-90": isWorkspaceMenuOpen,
})} })}
/> />