mirror of
https://github.com/overleaf/overleaf.git
synced 2024-10-24 21:12:38 -04:00
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:
parent
c4b23b4d39
commit
1c5f5950fa
7 changed files with 84 additions and 20 deletions
|
@ -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'
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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',
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue