Merge pull request #21208 from overleaf/dp-accept-reject-all-changes

Add options to accept/reject all changes to review tooltip

GitOrigin-RevId: 1cea76926d59d0354c8abaa6ba69b7e99c02fbe0
This commit is contained in:
David 2024-10-23 11:14:16 +01:00 committed by Copybot
parent c4b23b4d39
commit 1c5f5950fa
7 changed files with 84 additions and 20 deletions

View file

@ -6,7 +6,7 @@ import {
import { EditorSelection } from '@codemirror/state'
import { useTranslation } from 'react-i18next'
import { useThreadsActionsContext } from '../context/threads-context'
import { removeNewCommentRangeEffect } from '@/features/source-editor/extensions/add-comment'
import { removeNewCommentRangeEffect } from '@/features/source-editor/extensions/review-tooltip'
import useSubmittableTextInput from '../hooks/use-submittable-text-input'
import AutoExpandingTextArea from '@/shared/components/auto-expanding-text-area'
import { ReviewPanelEntry } from './review-panel-entry'

View file

@ -28,7 +28,7 @@ import { canAggregate } from '../utils/can-aggregate'
import ReviewPanelEmptyState from './review-panel-empty-state'
import useEventListener from '@/shared/hooks/use-event-listener'
import { hasActiveRange } from '@/features/review-panel-new/utils/has-active-range'
import { addCommentStateField } from '@/features/source-editor/extensions/add-comment'
import { reviewTooltipStateField } from '@/features/source-editor/extensions/review-tooltip'
import ReviewPanelMoreCommentsButton from './review-panel-more-comments-button'
import useMoreCommments from '../hooks/use-more-comments'
import { Decoration } from '@codemirror/view'
@ -111,7 +111,10 @@ const ReviewPanelCurrentFile: FC = () => {
const positionsRef = useRef<Map<string, number>>(new Map())
const addCommentRanges = state.field(addCommentStateField, false)?.ranges
const addCommentRanges = state.field(
reviewTooltipStateField,
false
)?.addCommentRanges
useEffect(() => {
if (aggregatedRanges) {

View file

@ -4,6 +4,7 @@ import {
SetStateAction,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'
import ReactDOM from 'react-dom'
@ -14,14 +15,19 @@ import {
useCodeMirrorViewContext,
} from '@/features/source-editor/components/codemirror-context'
import {
addCommentStateField,
buildAddNewCommentRangeEffect,
} from '@/features/source-editor/extensions/add-comment'
reviewTooltipStateField,
} from '@/features/source-editor/extensions/review-tooltip'
import { getTooltip } from '@codemirror/view'
import useViewerPermissions from '@/shared/hooks/use-viewer-permissions'
import usePreviousValue from '@/shared/hooks/use-previous-value'
import { useLayoutContext } from '@/shared/context/layout-context'
import { useReviewPanelViewActionsContext } from '../context/review-panel-view-context'
import {
useRangesActionsContext,
useRangesContext,
} from '../context/ranges-context'
import { isInsertOperation } from '@/utils/operations'
const ReviewTooltipMenu: FC = () => {
const state = useCodeMirrorStateContext()
@ -29,7 +35,7 @@ const ReviewTooltipMenu: FC = () => {
const isViewer = useViewerPermissions()
const [show, setShow] = useState(true)
const tooltipState = state.field(addCommentStateField, false)?.tooltip
const tooltipState = state.field(reviewTooltipStateField, false)?.tooltip
const previousTooltipState = usePreviousValue(tooltipState)
useEffect(() => {
@ -62,6 +68,8 @@ const ReviewTooltipMenuContent: FC<{
const state = useCodeMirrorStateContext()
const { setReviewPanelOpen } = useLayoutContext()
const { setView } = useReviewPanelViewActionsContext()
const ranges = useRangesContext()
const { acceptChanges, rejectChanges } = useRangesActionsContext()
const addComment = useCallback(() => {
setReviewPanelOpen(true)
@ -80,6 +88,28 @@ const ReviewTooltipMenuContent: FC<{
}
}, [addComment])
const changeIdsInSelection = useMemo(() => {
return (ranges?.changes ?? [])
.filter(({ op }) => {
const opFrom = op.p
const opLength = isInsertOperation(op) ? op.i.length : 0
const opTo = opFrom + opLength
const selection = state.selection.main
return opFrom >= selection.from && opTo <= selection.to
})
.map(({ id }) => id)
}, [ranges, state.selection.main])
const acceptChangesHandler = useCallback(() => {
acceptChanges(...changeIdsInSelection)
}, [acceptChanges, changeIdsInSelection])
const rejectChangesHandler = useCallback(() => {
rejectChanges(...changeIdsInSelection)
}, [rejectChanges, changeIdsInSelection])
const showChangesButtons = changeIdsInSelection.length > 0
return (
<div className="review-tooltip-menu">
<button
@ -89,6 +119,23 @@ const ReviewTooltipMenuContent: FC<{
<MaterialIcon type="chat" />
{t('add_comment')}
</button>
{showChangesButtons && (
<>
<div className="review-tooltip-menu-divider" />
<button
className="review-tooltip-menu-button"
onClick={acceptChangesHandler}
>
<MaterialIcon type="check" />
</button>
<button
className="review-tooltip-menu-button"
onClick={rejectChangesHandler}
>
<MaterialIcon type="clear" />
</button>
</>
)}
</div>
)
}

View file

@ -52,7 +52,7 @@ import { mathPreview } from './math-preview'
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
import { ranges } from './ranges'
import { trackDetachedComments } from './track-detached-comments'
import { addComment } from './add-comment'
import { reviewTooltip } from './review-tooltip'
const moduleExtensions: Array<(options: Record<string, any>) => Extension> =
importOverleafModules('sourceEditorExtensions').map(
@ -138,7 +138,7 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
trackDetachedComments(options.currentDoc),
visual(options.visual),
mathPreview(options.settings.mathPreview),
addComment(),
reviewTooltip(),
toolbarPanel(),
verticalOverflow(),
highlightActiveLine(options.visual.visual),

View file

@ -31,31 +31,31 @@ export const buildAddNewCommentRangeEffect = (range: SelectionRange) => {
)
}
export const addComment = (): Extension => {
export const reviewTooltip = (): Extension => {
if (!isSplitTestEnabled('review-panel-redesign')) {
return []
}
return [addCommentTheme, addCommentStateField, textSelected]
return [reviewTooltipTheme, reviewTooltipStateField, textSelected]
}
export const addCommentStateField = StateField.define<{
export const reviewTooltipStateField = StateField.define<{
tooltip: Tooltip | null
ranges: DecorationSet
addCommentRanges: DecorationSet
}>({
create() {
return { tooltip: null, ranges: Decoration.none }
return { tooltip: null, addCommentRanges: Decoration.none }
},
update(field, tr) {
let { tooltip, ranges } = field
let { tooltip, addCommentRanges } = field
ranges = ranges.map(tr.changes)
addCommentRanges = addCommentRanges.map(tr.changes)
for (const effect of tr.effects) {
if (effect.is(removeNewCommentRangeEffect)) {
const rangeToRemove = effect.value
ranges = ranges.update({
addCommentRanges = addCommentRanges.update({
// eslint-disable-next-line no-unused-vars
filter: (from, to, value) => {
return value.spec.id !== rangeToRemove.spec.id
@ -65,7 +65,7 @@ export const addCommentStateField = StateField.define<{
if (effect.is(addNewCommentRangeEffect)) {
const rangeToAdd = effect.value
ranges = ranges.update({
addCommentRanges = addCommentRanges.update({
add: [rangeToAdd],
})
}
@ -79,11 +79,11 @@ export const addCommentStateField = StateField.define<{
}
}
return { tooltip, ranges }
return { tooltip, addCommentRanges }
},
provide: field => [
EditorView.decorations.from(field, field => field.ranges),
EditorView.decorations.from(field, field => field.addCommentRanges),
showTooltip.compute([field], state => state.field(field).tooltip),
],
})
@ -109,7 +109,7 @@ function buildTooltip(range: SelectionRange): Tooltip | null {
/**
* Styles for the tooltip
*/
const addCommentTheme = EditorView.baseTheme({
const reviewTooltipTheme = EditorView.baseTheme({
'.review-tooltip-menu-container.cm-tooltip': {
backgroundColor: 'transparent',
border: 'none',

View file

@ -619,10 +619,12 @@
}
.review-tooltip-menu {
display: flex;
box-shadow: 0px 2px 4px 0px #1e253029;
border: none;
border-radius: 4px;
padding: 4px;
gap: 4px;
}
.review-tooltip-menu-button {
@ -635,6 +637,11 @@
border-radius: @border-radius-base;
}
.review-tooltip-menu-divider {
width: 1px;
background-color: #e7e9ee;
}
.review-tooltip-add-comment-button {
padding: 2px 8px;
}

View file

@ -623,10 +623,12 @@
}
.review-tooltip-menu {
display: flex;
box-shadow: 0 2px 4px 0 #1e253029;
border: none;
border-radius: var(--border-radius-base);
padding: var(--spacing-02);
gap: var(--spacing-02);
}
.review-tooltip-menu-button {
@ -644,6 +646,11 @@
padding: var(--spacing-01) var(--spacing-04);
}
.review-tooltip-menu-divider {
width: 1px;
background-color: #e7e9ee;
}
.review-panel-tooltip {
pointer-events: none; // this is to prevent mouseLeave event from firing when hovering over the tooltip
}