Merge pull request #13687 from overleaf/ii-review-panel-migration-add-comment-entry

[web] Create add comment entry

GitOrigin-RevId: 019f508eeb3982fce082df153e56d6c3c3e3bae5
This commit is contained in:
ilkin-overleaf 2023-07-07 13:13:25 +03:00 committed by Copybot
parent 254422180e
commit 225de683c7
12 changed files with 146 additions and 14 deletions

View file

@ -28,6 +28,7 @@
"add_another_email": "",
"add_another_token": "",
"add_comma_separated_emails_help": "",
"add_comment": "",
"add_company_details": "",
"add_email_to_claim_features": "",
"add_files": "",
@ -36,6 +37,7 @@
"add_or_remove_project_from_tag": "",
"add_role_and_department": "",
"add_to_tag": "",
"add_your_comment_here": "",
"add_your_first_group_member_now": "",
"added_by_on": "",
"adding": "",
@ -137,6 +139,7 @@
"collabs_per_proj": "",
"collabs_per_proj_single": "",
"collapse": "",
"comment": "",
"commit": "",
"common": "",
"commons_plan_tooltip": "",

View file

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

View file

@ -1,7 +1,112 @@
import { useTranslation } from 'react-i18next'
import { useState } from 'react'
import EntryContainer from './entry-container'
import EntryCallout from './entry-callout'
import EntryActions from './entry-actions'
import AutoExpandingTextArea from '../../../../../shared/components/auto-expanding-text-area'
import Icon from '../../../../../shared/components/icon'
import { useReviewPanelValueContext } from '../../../context/review-panel/review-panel-context'
import classnames from 'classnames'
import { ReviewPanelAddCommentEntry } from '../../../../../../../types/review-panel/entry'
function AddCommentEntry() {
return <EntryContainer>Add comment entry</EntryContainer>
type AddCommentEntryProps = {
entry: ReviewPanelAddCommentEntry
}
function AddCommentEntry({ entry }: AddCommentEntryProps) {
const { t } = useTranslation()
const { submitNewComment, handleLayoutChange } = useReviewPanelValueContext()
const [content, setContent] = useState('')
const [isAdding, setIsAdding] = useState(false)
const handleStartNewComment = () => {
setIsAdding(true)
handleLayoutChange()
}
const handleSubmitNewComment = () => {
submitNewComment(content)
setIsAdding(false)
setContent('')
}
const handleCancelNewComment = () => {
setIsAdding(false)
setContent('')
handleLayoutChange()
}
const handleCommentKeyPress = (
e: React.KeyboardEvent<HTMLTextAreaElement>
) => {
const target = e.target as HTMLTextAreaElement
if (e.key === 'Enter' && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
e.preventDefault()
if (content.length) {
handleSubmitNewComment()
}
}
if (['PageDown', 'PageUp'].includes(e.key)) {
if (target.closest('textarea')) {
e.preventDefault()
}
}
}
return (
<EntryContainer>
<EntryCallout className="rp-entry-callout-add-comment" />
<div
className={classnames('rp-entry', 'rp-entry-add-comment', {
'rp-entry-adding-comment': isAdding,
})}
style={{
top: entry.screenPos.y + 'px',
visibility: entry.visible ? 'visible' : 'hidden',
}}
>
{isAdding ? (
<>
<div className="rp-new-comment">
<AutoExpandingTextArea
className="rp-comment-input"
onChange={e => setContent(e.target.value)}
onKeyPress={handleCommentKeyPress}
onResize={handleLayoutChange}
placeholder={t('add_your_comment_here')}
value={content}
autoFocus // eslint-disable-line jsx-a11y/no-autofocus
/>
</div>
<EntryActions>
<EntryActions.Button
className="rp-entry-button-cancel"
onClick={handleCancelNewComment}
>
<Icon type="times" /> {t('cancel')}
</EntryActions.Button>
<EntryActions.Button
onClick={handleSubmitNewComment}
disabled={!content.length}
>
<Icon type="comment" /> {t('comment')}
</EntryActions.Button>
</EntryActions>
</>
) : (
<button
className="rp-add-comment-btn"
onClick={handleStartNewComment}
>
<Icon type="comment" /> {t('add_comment')}
</button>
)}
</div>
</EntryContainer>
)
}
export default AddCommentEntry

View file

@ -1,6 +1,7 @@
import { useTranslation } from 'react-i18next'
import { useState } from 'react'
import EntryContainer from './entry-container'
import EntryCallout from './entry-callout'
import EntryActions from './entry-actions'
import Icon from '../../../../../shared/components/icon'
import { useReviewPanelValueContext } from '../../../context/review-panel/review-panel-context'
@ -85,8 +86,8 @@ function AggregateChangeEntry({
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<div
className="rp-entry-callout rp-entry-callout-aggregate"
<EntryCallout
className="rp-entry-callout-aggregate"
style={{
top: entry.screenPos
? entry.screenPos.y + entry.screenPos.height - 1 + 'px'

View file

@ -1,6 +1,7 @@
import { useTranslation } from 'react-i18next'
import { useState } from 'react'
import EntryContainer from './entry-container'
import EntryCallout from './entry-callout'
import EntryActions from './entry-actions'
import Icon from '../../../../../shared/components/icon'
import { useReviewPanelValueContext } from '../../../context/review-panel/review-panel-context'
@ -75,11 +76,8 @@ function ChangeEntry({
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<div
className={classnames(
'rp-entry-callout',
`rp-entry-callout-${entry.type}`
)}
<EntryCallout
className={`rp-entry-callout-${entry.type}`}
style={{
top: entry.screenPos
? entry.screenPos.y + entry.screenPos.height - 1 + 'px'

View file

@ -1,8 +1,9 @@
import { useState, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import EntryContainer from './entry-container'
import Comment from './comment'
import EntryCallout from './entry-callout'
import EntryActions from './entry-actions'
import Comment from './comment'
import AutoExpandingTextArea, {
resetHeight,
} from '../../../../../shared/components/auto-expanding-text-area'
@ -118,8 +119,8 @@ function CommentEntry({
'rp-comment-wrapper-resolving': animating,
})}
>
<div
className="rp-entry-callout rp-entry-callout-comment"
<EntryCallout
className="rp-entry-callout-comment"
style={{
top: entry.screenPos
? entry.screenPos.y + entry.screenPos.height - 1 + 'px'

View file

@ -71,6 +71,7 @@ function Comment({ thread, threadId, comment }: CommentProps) {
onBlur={handleSaveEdit}
onClick={e => e.stopPropagation()}
onResize={handleLayoutChange}
autoFocus // eslint-disable-line jsx-a11y/no-autofocus
/>
) : (
<>

View file

@ -0,0 +1,7 @@
import classnames from 'classnames'
function EntryCallout({ className, ...rest }: React.ComponentProps<'div'>) {
return <div className={classnames('rp-entry-callout', className)} {...rest} />
}
export default EntryCallout

View file

@ -71,6 +71,8 @@ function useAngularReviewPanelState(): ReviewPanelState {
>('reviewPanel.trackChangesForGuestsAvailable')
const [resolveComment] =
useScopeValue<ReviewPanel.Value<'resolveComment'>>('resolveComment')
const [submitNewComment] =
useScopeValue<ReviewPanel.Value<'submitNewComment'>>('submitNewComment')
const [deleteComment] =
useScopeValue<ReviewPanel.Value<'deleteComment'>>('deleteComment')
const [gotoEntry] = useScopeValue<ReviewPanel.Value<'gotoEntry'>>('gotoEntry')
@ -155,6 +157,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
refreshResolvedCommentsDropdown,
acceptChanges,
rejectChanges,
submitNewComment,
}),
[
collapsed,
@ -191,6 +194,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
refreshResolvedCommentsDropdown,
acceptChanges,
rejectChanges,
submitNewComment,
]
)

View file

@ -59,6 +59,7 @@ export interface ReviewPanelState {
refreshResolvedCommentsDropdown: () => Promise<void>
acceptChanges: (entryIds: unknown) => void
rejectChanges: (entryIds: unknown) => void
submitNewComment: (content: string) => void
}
updaterFns: {
handleSetSubview: (subView: SubView) => void

View file

@ -221,6 +221,17 @@ describe('<ReviewPanel />', function () {
it.skip('renders changed entries in overview mode', function () {})
})
describe('add comment entry', function () {
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('renders `add comment button`', function () {})
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('cancels adding comment', function () {})
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('adds comment', function () {})
})
describe('overview mode', function () {
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('shows list of files changed', function () {})

View file

@ -53,7 +53,7 @@ export interface ReviewPanelAggregateChangeEntry extends ReviewPanelBaseEntry {
}
}
interface ReviewPanelAddCommentEntry extends ReviewPanelBaseEntry {
export interface ReviewPanelAddCommentEntry extends ReviewPanelBaseEntry {
type: 'add-comment'
}