mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-29 11:53:40 -05:00
Merge pull request #15815 from overleaf/td-persist-unsaved-comment
Persist unsaved comment in the front end after not submitting GitOrigin-RevId: a7ffee6f5fbfb7151a2ef7233ba4412d0db33e19
This commit is contained in:
parent
7029a0822b
commit
86c06d8c99
5 changed files with 44 additions and 17 deletions
|
@ -509,6 +509,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
|
||||||
const [navHeight, setNavHeight] = useState(0)
|
const [navHeight, setNavHeight] = useState(0)
|
||||||
const [toolbarHeight, setToolbarHeight] = useState(0)
|
const [toolbarHeight, setToolbarHeight] = useState(0)
|
||||||
const [layoutSuspended, setLayoutSuspended] = useState(false)
|
const [layoutSuspended, setLayoutSuspended] = useState(false)
|
||||||
|
const [unsavedComment, setUnsavedComment] = useState('')
|
||||||
|
|
||||||
// listen for events from the CodeMirror 6 track changes extension
|
// listen for events from the CodeMirror 6 track changes extension
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -573,6 +574,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
|
||||||
trackChangesForGuestsAvailable,
|
trackChangesForGuestsAvailable,
|
||||||
formattedProjectMembers,
|
formattedProjectMembers,
|
||||||
layoutSuspended,
|
layoutSuspended,
|
||||||
|
unsavedComment,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
collapsed,
|
collapsed,
|
||||||
|
@ -599,6 +601,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
|
||||||
trackChangesForGuestsAvailable,
|
trackChangesForGuestsAvailable,
|
||||||
formattedProjectMembers,
|
formattedProjectMembers,
|
||||||
layoutSuspended,
|
layoutSuspended,
|
||||||
|
unsavedComment,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -630,6 +633,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
|
||||||
setNavHeight,
|
setNavHeight,
|
||||||
setToolbarHeight,
|
setToolbarHeight,
|
||||||
setLayoutSuspended,
|
setLayoutSuspended,
|
||||||
|
setUnsavedComment,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
handleSetSubview,
|
handleSetSubview,
|
||||||
|
@ -657,6 +661,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
|
||||||
setNavHeight,
|
setNavHeight,
|
||||||
setToolbarHeight,
|
setToolbarHeight,
|
||||||
setLayoutSuspended,
|
setLayoutSuspended,
|
||||||
|
setUnsavedComment,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ function CurrentFileContainer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.type === 'add-comment' && permissions.comment) {
|
if (entry.type === 'add-comment' && permissions.comment) {
|
||||||
return <AddCommentEntry key={id} entryId={entry.type} />
|
return <AddCommentEntry key={id} />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.type === 'bulk-actions') {
|
if (entry.type === 'bulk-actions') {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import EntryContainer from './entry-container'
|
import EntryContainer from './entry-container'
|
||||||
import EntryCallout from './entry-callout'
|
import EntryCallout from './entry-callout'
|
||||||
import EntryActions from './entry-actions'
|
import EntryActions from './entry-actions'
|
||||||
|
@ -11,20 +11,19 @@ import {
|
||||||
useReviewPanelValueContext,
|
useReviewPanelValueContext,
|
||||||
} from '../../../context/review-panel/review-panel-context'
|
} from '../../../context/review-panel/review-panel-context'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { ReviewPanelAddCommentEntry } from '../../../../../../../types/review-panel/entry'
|
|
||||||
|
|
||||||
type AddCommentEntryProps = {
|
function AddCommentEntry() {
|
||||||
entryId: ReviewPanelAddCommentEntry['type']
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddCommentEntry({ entryId }: AddCommentEntryProps) {
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { isAddingComment } = useReviewPanelValueContext()
|
const { isAddingComment, unsavedComment } = useReviewPanelValueContext()
|
||||||
const { setIsAddingComment, submitNewComment, handleLayoutChange } =
|
const {
|
||||||
useReviewPanelUpdaterFnsContext()
|
setIsAddingComment,
|
||||||
|
submitNewComment,
|
||||||
|
handleLayoutChange,
|
||||||
|
setUnsavedComment,
|
||||||
|
} = useReviewPanelUpdaterFnsContext()
|
||||||
|
|
||||||
const [content, setContent] = useState('')
|
const [content, setContent] = useState(unsavedComment)
|
||||||
const [isSubmitting, setIsSubmiting] = useState(false)
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||||
|
|
||||||
const handleStartNewComment = () => {
|
const handleStartNewComment = () => {
|
||||||
setIsAddingComment(true)
|
setIsAddingComment(true)
|
||||||
|
@ -32,14 +31,14 @@ function AddCommentEntry({ entryId }: AddCommentEntryProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmitNewComment = async () => {
|
const handleSubmitNewComment = async () => {
|
||||||
setIsSubmiting(true)
|
setIsSubmitting(true)
|
||||||
try {
|
try {
|
||||||
await submitNewComment(content)
|
await submitNewComment(content)
|
||||||
setIsSubmiting(false)
|
setIsSubmitting(false)
|
||||||
setIsAddingComment(false)
|
setIsAddingComment(false)
|
||||||
setContent('')
|
setContent('')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setIsSubmiting(false)
|
setIsSubmitting(false)
|
||||||
}
|
}
|
||||||
handleLayoutChange({ async: true })
|
handleLayoutChange({ async: true })
|
||||||
}
|
}
|
||||||
|
@ -56,6 +55,20 @@ function AddCommentEntry({ entryId }: AddCommentEntryProps) {
|
||||||
}
|
}
|
||||||
}, [setIsAddingComment])
|
}, [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 = (
|
const handleCommentKeyPress = (
|
||||||
e: React.KeyboardEvent<HTMLTextAreaElement>
|
e: React.KeyboardEvent<HTMLTextAreaElement>
|
||||||
) => {
|
) => {
|
||||||
|
@ -76,7 +89,7 @@ function AddCommentEntry({ entryId }: AddCommentEntryProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EntryContainer id={entryId}>
|
<EntryContainer id="add-comment">
|
||||||
<EntryCallout className="rp-entry-callout-add-comment" />
|
<EntryCallout className="rp-entry-callout-add-comment" />
|
||||||
<div
|
<div
|
||||||
className={classnames('rp-entry', 'rp-entry-add-comment', {
|
className={classnames('rp-entry', 'rp-entry-add-comment', {
|
||||||
|
|
|
@ -137,6 +137,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
||||||
const [navHeight, setNavHeight] = useState(0)
|
const [navHeight, setNavHeight] = useState(0)
|
||||||
const [toolbarHeight, setToolbarHeight] = useState(0)
|
const [toolbarHeight, setToolbarHeight] = useState(0)
|
||||||
const [layoutSuspended, setLayoutSuspended] = useState(false)
|
const [layoutSuspended, setLayoutSuspended] = useState(false)
|
||||||
|
const [unsavedComment, setUnsavedComment] = useState('')
|
||||||
|
|
||||||
const values = useMemo<ReviewPanelState['values']>(
|
const values = useMemo<ReviewPanelState['values']>(
|
||||||
() => ({
|
() => ({
|
||||||
|
@ -164,6 +165,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
||||||
trackChangesForGuestsAvailable,
|
trackChangesForGuestsAvailable,
|
||||||
formattedProjectMembers,
|
formattedProjectMembers,
|
||||||
layoutSuspended,
|
layoutSuspended,
|
||||||
|
unsavedComment,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
collapsed,
|
collapsed,
|
||||||
|
@ -190,6 +192,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
||||||
trackChangesForGuestsAvailable,
|
trackChangesForGuestsAvailable,
|
||||||
formattedProjectMembers,
|
formattedProjectMembers,
|
||||||
layoutSuspended,
|
layoutSuspended,
|
||||||
|
unsavedComment,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -221,6 +224,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
||||||
setNavHeight,
|
setNavHeight,
|
||||||
setToolbarHeight,
|
setToolbarHeight,
|
||||||
setLayoutSuspended,
|
setLayoutSuspended,
|
||||||
|
setUnsavedComment,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
handleSetSubview,
|
handleSetSubview,
|
||||||
|
@ -248,6 +252,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
||||||
setNavHeight,
|
setNavHeight,
|
||||||
setToolbarHeight,
|
setToolbarHeight,
|
||||||
setLayoutSuspended,
|
setLayoutSuspended,
|
||||||
|
setUnsavedComment,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ export interface ReviewPanelState {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
layoutSuspended: boolean
|
layoutSuspended: boolean
|
||||||
|
unsavedComment: string
|
||||||
}
|
}
|
||||||
updaterFns: {
|
updaterFns: {
|
||||||
handleSetSubview: (subView: SubView) => void
|
handleSetSubview: (subView: SubView) => void
|
||||||
|
@ -88,6 +89,9 @@ export interface ReviewPanelState {
|
||||||
setLayoutSuspended: React.Dispatch<
|
setLayoutSuspended: React.Dispatch<
|
||||||
React.SetStateAction<Value<'layoutSuspended'>>
|
React.SetStateAction<Value<'layoutSuspended'>>
|
||||||
>
|
>
|
||||||
|
setUnsavedComment: React.Dispatch<
|
||||||
|
React.SetStateAction<Value<'unsavedComment'>>
|
||||||
|
>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* eslint-enable no-use-before-define */
|
/* eslint-enable no-use-before-define */
|
||||||
|
|
Loading…
Reference in a new issue