mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #12668 from overleaf/td-history-scroll-to-first-change
Scroll to first change in history document diff viewer GitOrigin-RevId: e135877ca440c5eb2732890e8723d9098444727f
This commit is contained in:
parent
99e1ff0804
commit
5f5e07a334
3 changed files with 85 additions and 20 deletions
|
@ -1,7 +1,12 @@
|
|||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import withErrorBoundary from '../../../../infrastructure/error-boundary'
|
||||
import { ErrorBoundaryFallback } from '../../../../shared/components/error-boundary-fallback'
|
||||
import { EditorState, Extension } from '@codemirror/state'
|
||||
import {
|
||||
EditorSelection,
|
||||
EditorState,
|
||||
Extension,
|
||||
StateEffect,
|
||||
} from '@codemirror/state'
|
||||
import { EditorView, lineNumbers } from '@codemirror/view'
|
||||
import { indentationMarkers } from '@replit/codemirror-indentation-markers'
|
||||
import { highlights, setHighlightsEffect } from '../../extensions/highlights'
|
||||
|
@ -100,9 +105,18 @@ function DocumentDiffViewer({
|
|||
const { before, after } = highlightLocations
|
||||
|
||||
useEffect(() => {
|
||||
const effects: StateEffect<unknown>[] = [setHighlightsEffect.of(highlights)]
|
||||
if (highlights.length > 0) {
|
||||
const { from, to } = highlights[0].range
|
||||
effects.push(
|
||||
EditorView.scrollIntoView(EditorSelection.range(from, to), {
|
||||
y: 'center',
|
||||
})
|
||||
)
|
||||
}
|
||||
view.dispatch({
|
||||
changes: { from: 0, to: view.state.doc.length, insert: doc },
|
||||
effects: setHighlightsEffect.of(highlights),
|
||||
effects,
|
||||
})
|
||||
}, [doc, highlights, view])
|
||||
|
||||
|
|
|
@ -3,23 +3,6 @@ import DocumentDiffViewer from '../../js/features/history/components/diff-view/d
|
|||
import React from 'react'
|
||||
import { Highlight } from '../../js/features/history/services/types/doc'
|
||||
|
||||
export default {
|
||||
title: 'History / Document Diff Viewer',
|
||||
component: DocumentDiffViewer,
|
||||
decorators: [
|
||||
ScopeDecorator,
|
||||
(Story: React.ComponentType) => (
|
||||
<div style={{ height: '90vh' }}>
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
export const Highlights = () => {
|
||||
return <DocumentDiffViewer doc={content} highlights={highlights} />
|
||||
}
|
||||
|
||||
const highlights: Highlight[] = [
|
||||
{
|
||||
type: 'addition',
|
||||
|
@ -47,7 +30,7 @@ const highlights: Highlight[] = [
|
|||
},
|
||||
]
|
||||
|
||||
const content = `\\documentclass{article}
|
||||
const doc = `\\documentclass{article}
|
||||
|
||||
% Language setting
|
||||
% Replace \`english' with e.g. \`spanish' to change the document language
|
||||
|
@ -131,3 +114,38 @@ Once you're familiar with the editor, you can find various project settings in t
|
|||
\\bibliography{sample}
|
||||
|
||||
\\end{document}`
|
||||
|
||||
export default {
|
||||
title: 'History / Document Diff Viewer',
|
||||
component: DocumentDiffViewer,
|
||||
args: { doc, highlights },
|
||||
argTypes: {
|
||||
doc: {
|
||||
table: { disable: true },
|
||||
},
|
||||
highlights: {
|
||||
table: { disable: true },
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
ScopeDecorator,
|
||||
(Story: React.ComponentType) => (
|
||||
<div style={{ height: '90vh' }}>
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
export const Highlights = (
|
||||
args: React.ComponentProps<typeof DocumentDiffViewer>
|
||||
) => {
|
||||
return <DocumentDiffViewer {...args} />
|
||||
}
|
||||
|
||||
export const ScrollToFirstHighlight = (
|
||||
args: React.ComponentProps<typeof DocumentDiffViewer>
|
||||
) => {
|
||||
const lastHighlightOnly = args.highlights.slice(-1)
|
||||
return <DocumentDiffViewer {...args} highlights={lastHighlightOnly} />
|
||||
}
|
||||
|
|
|
@ -144,4 +144,37 @@ describe('document diff viewer', function () {
|
|||
cy.get('.previous-highlight-button').should('have.length', 1)
|
||||
cy.get('.next-highlight-button').should('have.length', 1)
|
||||
})
|
||||
|
||||
it('scrolls to first change', function () {
|
||||
const scope = mockScope()
|
||||
const finalHighlightOnly = highlights.slice(-1)
|
||||
|
||||
cy.mount(
|
||||
<Container>
|
||||
<EditorProviders scope={scope}>
|
||||
<DocumentDiffViewer doc={doc} highlights={finalHighlightOnly} />
|
||||
</EditorProviders>
|
||||
</Container>
|
||||
)
|
||||
|
||||
cy.get('.cm-scroller').first().invoke('scrollTop').should('not.equal', 0)
|
||||
cy.get('.ol-addition-marker')
|
||||
.first()
|
||||
.then($marker => {
|
||||
cy.get('.cm-content')
|
||||
.first()
|
||||
.then($content => {
|
||||
const contentRect = $content[0].getBoundingClientRect()
|
||||
const markerRect = $marker[0].getBoundingClientRect()
|
||||
expect(markerRect.top).to.be.within(
|
||||
contentRect.top,
|
||||
contentRect.bottom
|
||||
)
|
||||
expect(markerRect.bottom).to.be.within(
|
||||
contentRect.top,
|
||||
contentRect.bottom
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue