Преглед изворни кода

Merge pull request #15815 from overleaf/td-persist-unsaved-comment

Persist unsaved comment in the front end after not submitting

GitOrigin-RevId: a7ffee6f5fbfb7151a2ef7233ba4412d0db33e19
Tim Down пре 2 година
родитељ
комит
86c06d8c99

+ 5 - 0
services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts

@@ -509,6 +509,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
   const [navHeight, setNavHeight] = useState(0)
   const [toolbarHeight, setToolbarHeight] = useState(0)
   const [layoutSuspended, setLayoutSuspended] = useState(false)
+  const [unsavedComment, setUnsavedComment] = useState('')
 
   // listen for events from the CodeMirror 6 track changes extension
   useEffect(() => {
@@ -573,6 +574,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
       trackChangesForGuestsAvailable,
       formattedProjectMembers,
       layoutSuspended,
+      unsavedComment,
     }),
     [
       collapsed,
@@ -599,6 +601,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
       trackChangesForGuestsAvailable,
       formattedProjectMembers,
       layoutSuspended,
+      unsavedComment,
     ]
   )
 
@@ -630,6 +633,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
       setNavHeight,
       setToolbarHeight,
       setLayoutSuspended,
+      setUnsavedComment,
     }),
     [
       handleSetSubview,
@@ -657,6 +661,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
       setNavHeight,
       setToolbarHeight,
       setLayoutSuspended,
+      setUnsavedComment,
     ]
   )
 

+ 1 - 1
services/web/frontend/js/features/source-editor/components/review-panel/current-file-container.tsx

@@ -130,7 +130,7 @@ function CurrentFileContainer() {
               }
 
               if (entry.type === 'add-comment' && permissions.comment) {
-                return <AddCommentEntry key={id} entryId={entry.type} />
+                return <AddCommentEntry key={id} />
               }
 
               if (entry.type === 'bulk-actions') {

+ 29 - 16
services/web/frontend/js/features/source-editor/components/review-panel/entries/add-comment-entry.tsx

@@ -1,5 +1,5 @@
 import { useTranslation } from 'react-i18next'
-import { useEffect, useState } from 'react'
+import { useEffect, useRef, useState } from 'react'
 import EntryContainer from './entry-container'
 import EntryCallout from './entry-callout'
 import EntryActions from './entry-actions'
@@ -11,20 +11,19 @@ import {
   useReviewPanelValueContext,
 } from '../../../context/review-panel/review-panel-context'
 import classnames from 'classnames'
-import { ReviewPanelAddCommentEntry } from '../../../../../../../types/review-panel/entry'
 
-type AddCommentEntryProps = {
-  entryId: ReviewPanelAddCommentEntry['type']
-}
-
-function AddCommentEntry({ entryId }: AddCommentEntryProps) {
+function AddCommentEntry() {
   const { t } = useTranslation()
-  const { isAddingComment } = useReviewPanelValueContext()
-  const { setIsAddingComment, submitNewComment, handleLayoutChange } =
-    useReviewPanelUpdaterFnsContext()
+  const { isAddingComment, unsavedComment } = useReviewPanelValueContext()
+  const {
+    setIsAddingComment,
+    submitNewComment,
+    handleLayoutChange,
+    setUnsavedComment,
+  } = useReviewPanelUpdaterFnsContext()
 
-  const [content, setContent] = useState('')
-  const [isSubmitting, setIsSubmiting] = useState(false)
+  const [content, setContent] = useState(unsavedComment)
+  const [isSubmitting, setIsSubmitting] = useState(false)
 
   const handleStartNewComment = () => {
     setIsAddingComment(true)
@@ -32,14 +31,14 @@ function AddCommentEntry({ entryId }: AddCommentEntryProps) {
   }
 
   const handleSubmitNewComment = async () => {
-    setIsSubmiting(true)
+    setIsSubmitting(true)
     try {
       await submitNewComment(content)
-      setIsSubmiting(false)
+      setIsSubmitting(false)
       setIsAddingComment(false)
       setContent('')
     } catch (err) {
-      setIsSubmiting(false)
+      setIsSubmitting(false)
     }
     handleLayoutChange({ async: true })
   }
@@ -56,6 +55,20 @@ function AddCommentEntry({ entryId }: AddCommentEntryProps) {
     }
   }, [setIsAddingComment])
 
+  const unsavedCommentRef = useRef(unsavedComment)
+
+  // Keep unsaved comment ref up to date for use when the component unmounts
+  useEffect(() => {
+    unsavedCommentRef.current = content
+  }, [content])
+
+  // Store the unsaved comment in the context on unmount
+  useEffect(() => {
+    return () => {
+      setUnsavedComment(unsavedCommentRef.current)
+    }
+  }, [setUnsavedComment])
+
   const handleCommentKeyPress = (
     e: React.KeyboardEvent<HTMLTextAreaElement>
   ) => {
@@ -76,7 +89,7 @@ function AddCommentEntry({ entryId }: AddCommentEntryProps) {
   }
 
   return (
-    <EntryContainer id={entryId}>
+    <EntryContainer id="add-comment">
       <EntryCallout className="rp-entry-callout-add-comment" />
       <div
         className={classnames('rp-entry', 'rp-entry-add-comment', {

+ 5 - 0
services/web/frontend/js/features/source-editor/context/review-panel/hooks/use-angular-review-panel-state.ts

@@ -137,6 +137,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
   const [navHeight, setNavHeight] = useState(0)
   const [toolbarHeight, setToolbarHeight] = useState(0)
   const [layoutSuspended, setLayoutSuspended] = useState(false)
+  const [unsavedComment, setUnsavedComment] = useState('')
 
   const values = useMemo<ReviewPanelState['values']>(
     () => ({
@@ -164,6 +165,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
       trackChangesForGuestsAvailable,
       formattedProjectMembers,
       layoutSuspended,
+      unsavedComment,
     }),
     [
       collapsed,
@@ -190,6 +192,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
       trackChangesForGuestsAvailable,
       formattedProjectMembers,
       layoutSuspended,
+      unsavedComment,
     ]
   )
 
@@ -221,6 +224,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
       setNavHeight,
       setToolbarHeight,
       setLayoutSuspended,
+      setUnsavedComment,
     }),
     [
       handleSetSubview,
@@ -248,6 +252,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
       setNavHeight,
       setToolbarHeight,
       setLayoutSuspended,
+      setUnsavedComment,
     ]
   )
 

+ 4 - 0
services/web/frontend/js/features/source-editor/context/review-panel/types/review-panel-state.ts

@@ -46,6 +46,7 @@ export interface ReviewPanelState {
       }
     >
     layoutSuspended: boolean
+    unsavedComment: string
   }
   updaterFns: {
     handleSetSubview: (subView: SubView) => void
@@ -88,6 +89,9 @@ export interface ReviewPanelState {
     setLayoutSuspended: React.Dispatch<
       React.SetStateAction<Value<'layoutSuspended'>>
     >
+    setUnsavedComment: React.Dispatch<
+      React.SetStateAction<Value<'unsavedComment'>>
+    >
   }
 }
 /* eslint-enable no-use-before-define */