diff --git a/web/components/issues/title-input.tsx b/web/components/issues/title-input.tsx index dbd18aaaa..4a4057a6a 100644 --- a/web/components/issues/title-input.tsx +++ b/web/components/issues/title-input.tsx @@ -19,11 +19,10 @@ export type IssueTitleInputProps = { }; export const IssueTitleInput: FC = observer((props) => { - const { disabled, value, workspaceSlug, setIsSubmitting, issueId, issueOperations, projectId } = props; + const { disabled, value, workspaceSlug, isSubmitting, setIsSubmitting, issueId, issueOperations, projectId } = props; // states const [title, setTitle] = useState(""); // hooks - const debouncedValue = useDebounce(title, 1500); useEffect(() => { @@ -31,15 +30,41 @@ export const IssueTitleInput: FC = observer((props) => { }, [value]); useEffect(() => { + const textarea = document.querySelector("#title-input"); if (debouncedValue && debouncedValue !== value) { issueOperations.update(workspaceSlug, projectId, issueId, { name: debouncedValue }, false).finally(() => { setIsSubmitting("saved"); + if (textarea && !textarea.matches(":focus")) { + const trimmedTitle = debouncedValue.trim(); + if (trimmedTitle !== title) setTitle(trimmedTitle); + } }); } // DO NOT Add more dependencies here. It will cause multiple requests to be sent. // eslint-disable-next-line react-hooks/exhaustive-deps }, [debouncedValue]); + useEffect(() => { + const handleBlur = () => { + const trimmedTitle = title.trim(); + if (trimmedTitle !== title && isSubmitting !== "submitting") { + setTitle(trimmedTitle); + setIsSubmitting("submitting"); + } + }; + + const textarea = document.querySelector("#title-input"); // You might need to change this selector according to your TextArea component + if (textarea) { + textarea.addEventListener("blur", handleBlur); + } + + return () => { + if (textarea) { + textarea.removeEventListener("blur", handleBlur); + } + }; + }, [title, isSubmitting, setIsSubmitting]); + const handleTitleChange = useCallback( (e: React.ChangeEvent) => { setIsSubmitting("submitting"); @@ -53,6 +78,7 @@ export const IssueTitleInput: FC = observer((props) => { return (