From fee3b97326198ff0d0829f117c2677201d786ecb Mon Sep 17 00:00:00 2001
From: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com>
Date: Tue, 4 Jul 2023 14:05:12 +0300
Subject: [PATCH] Merge pull request #13641 from
overleaf/ii-review-panel-migration-overview-view
[web] Create overview view shell for review panel
GitOrigin-RevId: 21cc8a744253aec53f089ec6e6c1221d7153f3a4
---
.../components/review-panel/container.tsx | 8 --
.../review-panel/current-file-container.tsx | 106 +++++++++--------
.../review-panel/entries/comment-entry.tsx | 13 ++-
.../review-panel/hooks/use-collapse-height.ts | 26 +++++
.../review-panel/overview-container.tsx | 72 ++++++------
.../components/review-panel/overview-file.tsx | 109 ++++++++++++++++++
.../components/review-panel/review-panel.tsx | 9 +-
.../toolbar/resolved-comments-dropdown.tsx | 2 +-
.../review-panel/toolbar/toggle-menu.tsx | 19 +--
.../hooks/use-angular-review-panel-state.ts | 5 +
.../review-panel/types/review-panel-state.ts | 9 +-
.../stylesheets/app/editor/review-panel.less | 15 +--
.../editor-left-menu.spec.tsx | 4 +-
.../settings/settings-document.test.tsx | 2 +-
.../review-panel/review-panel.spec.tsx | 8 ++
services/web/types/project-settings.ts | 4 +-
services/web/types/review-panel/entry.ts | 2 +-
.../web/types/review-panel/review-panel.ts | 2 +-
18 files changed, 274 insertions(+), 141 deletions(-)
create mode 100644 services/web/frontend/js/features/source-editor/components/review-panel/hooks/use-collapse-height.ts
create mode 100644 services/web/frontend/js/features/source-editor/components/review-panel/overview-file.tsx
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/container.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/container.tsx
index bba2364bc0..21f4dd32ab 100644
--- a/services/web/frontend/js/features/source-editor/components/review-panel/container.tsx
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/container.tsx
@@ -1,6 +1,3 @@
-import Toggler from './toggler'
-import Toolbar from './toolbar/toolbar'
-import Nav from './nav'
import classnames from 'classnames'
const reviewPanelClasses = ['ol-cm-review-panel']
@@ -18,11 +15,6 @@ function Container({ children, classNames, ...rest }: ContainerProps) {
{...rest}
data-testid="review-panel"
>
-
-
- {openDocId &&
- objectEntries.map(([id, entry]) => {
- if (!entry.visible) {
- return null
- }
-
- if (entry.type === 'insert' || entry.type === 'delete') {
- return
- }
-
- if (entry.type === 'aggregate-change') {
- return
- }
-
- if (entry.type === 'comment' && !loadingThreads) {
- return (
-
- )
- }
-
- if (entry.type === 'add-comment' && permissions.comment) {
- return
- }
-
- if (entry.type === 'bulk-actions') {
- return
- }
-
- return null
- })}
+
+
+
+
-
+
+
+
+ {openDocId &&
+ objectEntries.map(([id, entry]) => {
+ if (!entry.visible) {
+ return null
+ }
+
+ if (entry.type === 'insert' || entry.type === 'delete') {
+ return
+ }
+
+ if (entry.type === 'aggregate-change') {
+ return
+ }
+
+ if (entry.type === 'comment' && !loadingThreads) {
+ return (
+
+ )
+ }
+
+ if (entry.type === 'add-comment' && permissions.comment) {
+ return
+ }
+
+ if (entry.type === 'bulk-actions') {
+ return
+ }
+
+ return null
+ })}
+
+
+
)
}
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/entries/comment-entry.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/entries/comment-entry.tsx
index a01cac81a6..9871b37c3b 100644
--- a/services/web/frontend/js/features/source-editor/components/review-panel/entries/comment-entry.tsx
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/entries/comment-entry.tsx
@@ -14,22 +14,29 @@ import {
import classnames from 'classnames'
import { ReviewPanelCommentEntry } from '../../../../../../../types/review-panel/entry'
import {
- DocId,
ReviewPanelCommentThreads,
+ ReviewPanelPermissions,
ThreadId,
} from '../../../../../../../types/review-panel/review-panel'
+import { DocId } from '../../../../../../../types/project-settings'
type CommentEntryProps = {
docId: DocId
entry: ReviewPanelCommentEntry
entryId: ThreadId
+ permissions: ReviewPanelPermissions
threads: ReviewPanelCommentThreads
}
-function CommentEntry({ docId, entry, entryId, threads }: CommentEntryProps) {
+function CommentEntry({
+ docId,
+ entry,
+ entryId,
+ permissions,
+ threads,
+}: CommentEntryProps) {
const { t } = useTranslation()
const {
- permissions,
gotoEntry,
toggleReviewPanel,
resolveComment,
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/hooks/use-collapse-height.ts b/services/web/frontend/js/features/source-editor/components/review-panel/hooks/use-collapse-height.ts
new file mode 100644
index 0000000000..431ce8ac96
--- /dev/null
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/hooks/use-collapse-height.ts
@@ -0,0 +1,26 @@
+import { useEffect } from 'react'
+
+function useCollapseHeight(
+ elRef: React.MutableRefObject
,
+ shouldCollapse: boolean
+) {
+ useEffect(() => {
+ if (elRef.current) {
+ const neededHeight = elRef.current.scrollHeight
+
+ if (neededHeight > 0) {
+ const height = shouldCollapse ? 0 : neededHeight
+ // This might result in a too big height if the element has css prop of
+ // `box-sizing` set to `content-box`. To fix that, values of props such as
+ // box-sizing, padding and border could be extracted from `height` to compensate.
+ elRef.current.style.height = `${height}px`
+ } else {
+ if (shouldCollapse) {
+ elRef.current.style.height = '0'
+ }
+ }
+ }
+ }, [elRef, shouldCollapse])
+}
+
+export default useCollapseHeight
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/overview-container.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/overview-container.tsx
index 9122163bb8..32bdb3f628 100644
--- a/services/web/frontend/js/features/source-editor/components/review-panel/overview-container.tsx
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/overview-container.tsx
@@ -1,41 +1,41 @@
+import Container from './container'
+import Toggler from './toggler'
+import Toolbar from './toolbar/toolbar'
+import Nav from './nav'
+import Icon from '../../../../shared/components/icon'
+import OverviewFile from './overview-file'
+import { useReviewPanelValueContext } from '../../context/review-panel/review-panel-context'
+
function OverviewContainer() {
+ const { loading, docs } = useReviewPanelValueContext()
+
return (
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
- tempor incididunt ut labore et dolore magna aliqua. Et malesuada fames ac
- turpis egestas integer eget aliquet nibh. Et leo duis ut diam quam nulla
- porttitor massa id. Risus quis varius quam quisque id diam vel quam
- elementum. Nibh venenatis cras sed felis. Sit amet commodo nulla facilisi
- nullam vehicula ipsum a arcu. Dui ut ornare lectus sit amet est placerat
- in. Aliquam ultrices sagittis orci a. Leo a diam sollicitudin tempor id eu
- nisl nunc mi. Quis ipsum suspendisse ultrices gravida dictum fusce. Ut
- etiam sit amet nisl purus in mollis nunc sed. Rhoncus est pellentesque
- elit ullamcorper dignissim cras. Faucibus turpis in eu mi bibendum. Proin
- libero nunc consequat interdum. Ac placerat vestibulum lectus mauris
- ultrices eros in cursus turpis. Ac felis donec et odio. Nullam ac tortor
- vitae purus faucibus. Consectetur lorem donec massa sapien faucibus et
- molestie. Praesent elementum facilisis leo vel fringilla est ullamcorper
- eget nulla. Adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus
- urna. Cursus metus aliquam eleifend mi in nulla posuere sollicitudin
- aliquam. Eget nullam non nisi est sit amet facilisis magna. Donec
- adipiscing tristique risus nec feugiat in fermentum posuere. Gravida
- rutrum quisque non tellus orci ac auctor augue. Euismod in pellentesque
- massa placerat duis ultricies lacus. Pellentesque diam volutpat commodo
- sed egestas. Tempus iaculis urna id volutpat lacus laoreet. Lorem ipsum
- dolor sit amet consectetur. Tincidunt id aliquet risus feugiat in ante
- metus. Risus ultricies tristique nulla aliquet enim tortor at auctor urna.
- Purus in mollis nunc sed. In ante metus dictum at. Magna eget est lorem
- ipsum dolor sit. Fusce id velit ut tortor pretium viverra. Augue neque
- gravida in fermentum et sollicitudin ac. Et malesuada fames ac turpis.
- Felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices.
- Varius vel pharetra vel turpis nunc eget.
-
+
+
+
+
+ {loading ? (
+
+
+
+ ) : (
+ docs?.map(doc => (
+
+ ))
+ )}
+
+
+
)
}
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/overview-file.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/overview-file.tsx
new file mode 100644
index 0000000000..1349c931d3
--- /dev/null
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/overview-file.tsx
@@ -0,0 +1,109 @@
+import { useMemo, useRef } from 'react'
+import Icon from '../../../../shared/components/icon'
+import ChangeEntry from './entries/change-entry'
+import AggregateChangeEntry from './entries/aggregate-change-entry'
+import CommentEntry from './entries/comment-entry'
+import {
+ useReviewPanelUpdaterFnsContext,
+ useReviewPanelValueContext,
+} from '../../context/review-panel/review-panel-context'
+import classnames from 'classnames'
+import { ThreadId } from '../../../../../../types/review-panel/review-panel'
+import { MainDocument } from '../../../../../../types/project-settings'
+import { ReviewPanelEntry } from '../../../../../../types/review-panel/entry'
+import useCollapseHeight from './hooks/use-collapse-height'
+
+type OverviewFileProps = {
+ docId: MainDocument['doc']['id']
+ docPath: MainDocument['path']
+}
+
+function OverviewFile({ docId, docPath }: OverviewFileProps) {
+ const { entries, collapsed, commentThreads, permissions } =
+ useReviewPanelValueContext()
+ const { setCollapsed } = useReviewPanelUpdaterFnsContext()
+
+ const docCollapsed = collapsed[docId]
+ const docEntries = useMemo(
+ () => (docId in entries ? entries[docId] : {}),
+ [docId, entries]
+ )
+ const objectEntries = useMemo(() => {
+ const entries = Object.entries(docEntries) as Array<
+ [ThreadId, ReviewPanelEntry]
+ >
+
+ const orderedEntries = entries.sort(([, entryA], [, entryB]) => {
+ return entryA.offset - entryB.offset
+ })
+
+ return orderedEntries
+ }, [docEntries])
+ const entryCount = Object.keys(docEntries).length
+
+ const handleToggleCollapsed = () => {
+ setCollapsed({ ...collapsed, [docId]: !docCollapsed })
+ }
+
+ const entriesContainerRef = useRef(null)
+ useCollapseHeight(entriesContainerRef, docCollapsed)
+
+ return (
+
+ {entryCount > 0 && (
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
+
+
+
+
+ {docPath}
+ {docCollapsed && (
+ <>
+
+
+ ({entryCount})
+
+ >
+ )}
+
+ )}
+
+ {objectEntries.map(([id, entry]) => {
+ if (entry.type === 'insert' || entry.type === 'delete') {
+ return
+ }
+
+ if (entry.type === 'aggregate-change') {
+ return
+ }
+
+ if (entry.type === 'comment') {
+ if (!commentThreads[entry.thread_id]?.resolved) {
+ return (
+
+ )
+ }
+ }
+
+ return null
+ })}
+
+
+ )
+}
+
+export default OverviewFile
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/review-panel.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/review-panel.tsx
index a57ef21c65..6ede53330c 100644
--- a/services/web/frontend/js/features/source-editor/components/review-panel/review-panel.tsx
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/review-panel.tsx
@@ -1,5 +1,4 @@
import ReactDOM from 'react-dom'
-import Container from './container'
import CurrentFileContainer from './current-file-container'
import OverviewContainer from './overview-container'
import { useCodeMirrorViewContext } from '../codemirror-editor'
@@ -19,13 +18,9 @@ function ReviewPanelView({ parentDomNode }: ReviewPanelViewProps) {
return ReactDOM.createPortal(
<>
{isCurrentFileView(subView) ? (
-
-
-
+
) : (
-
-
-
+
)}
>,
parentDomNode
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/resolved-comments-dropdown.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/resolved-comments-dropdown.tsx
index 2df2285d9e..0f11e10b0a 100644
--- a/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/resolved-comments-dropdown.tsx
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/resolved-comments-dropdown.tsx
@@ -6,11 +6,11 @@ import ResolvedCommentsScroller from './resolved-comments-scroller'
import classnames from 'classnames'
import { useReviewPanelValueContext } from '../../../context/review-panel/review-panel-context'
import {
- DocId,
ReviewPanelDocEntries,
ThreadId,
} from '../../../../../../../types/review-panel/review-panel'
import { ReviewPanelResolvedCommentThread } from '../../../../../../../types/review-panel/comment-thread'
+import { DocId } from '../../../../../../../types/project-settings'
export interface FilteredResolvedComments
extends ReviewPanelResolvedCommentThread {
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/toggle-menu.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/toggle-menu.tsx
index d5e4ad726f..ead055cf1e 100644
--- a/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/toggle-menu.tsx
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/toolbar/toggle-menu.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useRef } from 'react'
+import { useRef } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import Tooltip from '../../../../../shared/components/tooltip'
import Icon from '../../../../../shared/components/icon'
@@ -9,6 +9,7 @@ import {
useReviewPanelValueContext,
} from '../../../context/review-panel/review-panel-context'
import classnames from 'classnames'
+import useCollapseHeight from '../hooks/use-collapse-height'
function ToggleMenu() {
const { t } = useTranslation()
@@ -29,21 +30,7 @@ function ToggleMenu() {
} = useReviewPanelValueContext()
const containerRef = useRef(null)
-
- useEffect(() => {
- if (containerRef.current) {
- const neededHeight = containerRef.current.scrollHeight
-
- if (neededHeight > 0) {
- const height = shouldCollapse ? 0 : neededHeight
- containerRef.current.style.height = `${height}px`
- } else {
- if (shouldCollapse) {
- containerRef.current.style.height = '0'
- }
- }
- }
- }, [shouldCollapse])
+ useCollapseHeight(containerRef, shouldCollapse)
return (
<>
diff --git a/services/web/frontend/js/features/source-editor/context/review-panel/hooks/use-angular-review-panel-state.ts b/services/web/frontend/js/features/source-editor/context/review-panel/hooks/use-angular-review-panel-state.ts
index 8ed973b340..afb46ac797 100644
--- a/services/web/frontend/js/features/source-editor/context/review-panel/hooks/use-angular-review-panel-state.ts
+++ b/services/web/frontend/js/features/source-editor/context/review-panel/hooks/use-angular-review-panel-state.ts
@@ -13,6 +13,9 @@ function useAngularReviewPanelState(): ReviewPanelState {
const [subView, setSubView] = useScopeValue>(
'reviewPanel.subView'
)
+ const [loading] = useScopeValue>(
+ 'reviewPanel.overview.loading'
+ )
const [collapsed, setCollapsed] = useScopeValue<
ReviewPanel.Value<'collapsed'>
>('reviewPanel.overview.docsCollapsedState')
@@ -130,6 +133,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
submitReply,
subView,
wantTrackChanges,
+ loading,
openDocId,
toggleTrackChangesForEveryone,
toggleTrackChangesForUser,
@@ -162,6 +166,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
submitReply,
subView,
wantTrackChanges,
+ loading,
openDocId,
toggleTrackChangesForEveryone,
toggleTrackChangesForUser,
diff --git a/services/web/frontend/js/features/source-editor/context/review-panel/types/review-panel-state.ts b/services/web/frontend/js/features/source-editor/context/review-panel/types/review-panel-state.ts
index 74aa493b67..d62e4e0152 100644
--- a/services/web/frontend/js/features/source-editor/context/review-panel/types/review-panel-state.ts
+++ b/services/web/frontend/js/features/source-editor/context/review-panel/types/review-panel-state.ts
@@ -1,6 +1,5 @@
import {
CommentId,
- DocId,
ReviewPanelCommentThreads,
ReviewPanelEntries,
ReviewPanelPermissions,
@@ -8,11 +7,14 @@ import {
ThreadId,
} from '../../../../../../../types/review-panel/review-panel'
import { ReviewPanelCommentEntry } from '../../../../../../../types/review-panel/entry'
-import { MainDocument } from '../../../../../../../types/project-settings'
+import {
+ DocId,
+ MainDocument,
+} from '../../../../../../../types/project-settings'
export interface ReviewPanelState {
values: {
- collapsed: Record
+ collapsed: Record
commentThreads: ReviewPanelCommentThreads
deleteComment: (threadId: ThreadId, commentId: CommentId) => void
docs: MainDocument[] | undefined
@@ -33,6 +35,7 @@ export interface ReviewPanelState {
submitReply: (entry: ReviewPanelCommentEntry, replyContent: string) => void
subView: SubView
wantTrackChanges: boolean
+ loading: boolean
openDocId: DocId | null
toggleTrackChangesForEveryone: (isOn: boolean) => unknown
toggleTrackChangesForUser: (isOn: boolean, memberId: string) => unknown
diff --git a/services/web/frontend/stylesheets/app/editor/review-panel.less b/services/web/frontend/stylesheets/app/editor/review-panel.less
index e1f3b7e2b5..dfcf9520c0 100644
--- a/services/web/frontend/stylesheets/app/editor/review-panel.less
+++ b/services/web/frontend/stylesheets/app/editor/review-panel.less
@@ -1260,6 +1260,7 @@ button when (@is-overleaf-light = true) {
top: 0;
display: flex;
flex-direction: column;
+ height: 100%;
}
.rp-overview-file {
@@ -1267,20 +1268,6 @@ button when (@is-overleaf-light = true) {
//height: auto;
transition: height ease-in-out 0.15s; //, display 0.15s 0s;
}
-
- .rp-overview-file-num-entries {
- display: none;
- }
-
- &.rp-overview-file-collapse {
- .rp-overview-file-num-entries {
- display: inline;
- }
-
- .rp-overview-file-entries {
- // height: 0;
- }
- }
}
.rp-nav-item {
diff --git a/services/web/test/frontend/components/editor-left-menu/editor-left-menu.spec.tsx b/services/web/test/frontend/components/editor-left-menu/editor-left-menu.spec.tsx
index 88afe127cb..223c6656b7 100644
--- a/services/web/test/frontend/components/editor-left-menu/editor-left-menu.spec.tsx
+++ b/services/web/test/frontend/components/editor-left-menu/editor-left-menu.spec.tsx
@@ -352,7 +352,7 @@ describe(' ', function () {
id: 'id1',
type: 'doc',
selected: false,
- },
+ } as MainDocument['doc'],
},
{
path: 'main2.tex',
@@ -361,7 +361,7 @@ describe(' ', function () {
id: 'id2',
type: 'doc',
selected: false,
- },
+ } as MainDocument['doc'],
},
]
diff --git a/services/web/test/frontend/features/editor-left-menu/components/settings/settings-document.test.tsx b/services/web/test/frontend/features/editor-left-menu/components/settings/settings-document.test.tsx
index 4a1618b124..1694e2fc91 100644
--- a/services/web/test/frontend/features/editor-left-menu/components/settings/settings-document.test.tsx
+++ b/services/web/test/frontend/features/editor-left-menu/components/settings/settings-document.test.tsx
@@ -17,7 +17,7 @@ describe(' ', function () {
id: '123abc',
type: 'doc',
selected: false,
- },
+ } as MainDocument['doc'],
},
]
diff --git a/services/web/test/frontend/features/review-panel/review-panel.spec.tsx b/services/web/test/frontend/features/review-panel/review-panel.spec.tsx
index aad0cda4c7..767c0055e2 100644
--- a/services/web/test/frontend/features/review-panel/review-panel.spec.tsx
+++ b/services/web/test/frontend/features/review-panel/review-panel.spec.tsx
@@ -192,4 +192,12 @@ describe(' ', function () {
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('resolves comment', function () {})
})
+
+ describe('overview mode', function () {
+ // eslint-disable-next-line mocha/no-skipped-tests
+ it.skip('shows list of files changed', function () {})
+
+ // eslint-disable-next-line mocha/no-skipped-tests
+ it.skip('renders comments', function () {})
+ })
})
diff --git a/services/web/types/project-settings.ts b/services/web/types/project-settings.ts
index e8e10faa45..2595367150 100644
--- a/services/web/types/project-settings.ts
+++ b/services/web/types/project-settings.ts
@@ -1,14 +1,16 @@
import { OverallTheme } from '../frontend/js/features/source-editor/extensions/theme'
+import { Brand } from './helpers/brand'
export type AllowedImageName = {
imageDesc: string
imageName: string
}
+export type DocId = Brand
export type MainDocument = {
doc: {
name: string
- id: string
+ id: DocId
type: string
selected: boolean
}
diff --git a/services/web/types/review-panel/entry.ts b/services/web/types/review-panel/entry.ts
index 800c559c27..055604c80b 100644
--- a/services/web/types/review-panel/entry.ts
+++ b/services/web/types/review-panel/entry.ts
@@ -8,6 +8,7 @@ interface ReviewPanelEntryScreenPos {
interface ReviewPanelBaseEntry {
visible: boolean
+ offset: number
}
export interface ReviewPanelCommentEntry extends ReviewPanelBaseEntry {
@@ -15,7 +16,6 @@ export interface ReviewPanelCommentEntry extends ReviewPanelBaseEntry {
content: string
entry_ids: string[]
focused: boolean
- offset: number
screenPos: ReviewPanelEntryScreenPos
thread_id: ThreadId
replyContent?: string // angular specific
diff --git a/services/web/types/review-panel/review-panel.ts b/services/web/types/review-panel/review-panel.ts
index afd4804bd8..0a14870bfa 100644
--- a/services/web/types/review-panel/review-panel.ts
+++ b/services/web/types/review-panel/review-panel.ts
@@ -1,4 +1,5 @@
import { Brand } from '../helpers/brand'
+import { DocId } from '../project-settings'
import { ReviewPanelEntry } from './entry'
import { ReviewPanelCommentThread } from './comment-thread'
@@ -14,7 +15,6 @@ export interface ReviewPanelPermissions {
export type ThreadId = Brand
export type ReviewPanelDocEntries = Record
-export type DocId = Brand
export type ReviewPanelEntries = Record
export type UserId = Brand