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 4b49f1c05c..62a1db89f0 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,3 +1,4 @@
+import Toggler from './toggler'
import Toolbar from './toolbar/toolbar'
import Nav from './nav'
import classnames from 'classnames'
@@ -17,6 +18,7 @@ function Container({ children, classNames, ...rest }: ContainerProps) {
{...rest}
data-testid="review-panel"
>
+
{children}
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/nav.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/nav.tsx
index 4762551b6c..d5c146bb11 100644
--- a/services/web/frontend/js/features/source-editor/components/review-panel/nav.tsx
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/nav.tsx
@@ -1,7 +1,9 @@
-export type SubView = 'cur_file' | 'overview'
-
function Nav() {
- return
Nav
+ return (
+
+ Nav
+
+ )
}
export default Nav
diff --git a/services/web/frontend/js/features/source-editor/components/review-panel/toggler.tsx b/services/web/frontend/js/features/source-editor/components/review-panel/toggler.tsx
new file mode 100644
index 0000000000..a465ddfd84
--- /dev/null
+++ b/services/web/frontend/js/features/source-editor/components/review-panel/toggler.tsx
@@ -0,0 +1,25 @@
+import { useTranslation } from 'react-i18next'
+import { useReviewPanelValueContext } from '../../context/review-panel/review-panel-context'
+
+function Toggler() {
+ const { t } = useTranslation()
+ const { toggleReviewPanel } = useReviewPanelValueContext()
+
+ const handleTogglerClick = (event: React.MouseEvent) => {
+ const target = event.target as HTMLButtonElement
+ target.blur()
+ toggleReviewPanel()
+ }
+
+ return (
+
+ )
+}
+
+export default Toggler
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 092cd4c41d..93ef3ea4de 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
@@ -47,6 +47,9 @@ function useAngularReviewPanelState(): ReviewPanelState {
ReviewPanel.Value<'formattedProjectMembers'>
>('reviewPanel.formattedProjectMembers')
+ const [toggleReviewPanel] =
+ useScopeValue>('toggleReviewPanel')
+
const values = useMemo(
() => ({
collapsed,
@@ -62,6 +65,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
trackChangesOnForGuests,
trackChangesForGuestsAvailable,
formattedProjectMembers,
+ toggleReviewPanel,
}),
[
collapsed,
@@ -77,6 +81,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
trackChangesOnForGuests,
trackChangesForGuestsAvailable,
formattedProjectMembers,
+ toggleReviewPanel,
]
)
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 bd0428aaba..caf1a7b76a 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,5 +1,7 @@
-import { SubView } from '../../../components/review-panel/nav'
-import { ReviewPanelPermissions } from '../../../../../../../types/review-panel'
+import {
+ SubView,
+ ReviewPanelPermissions,
+} from '../../../../../../../types/review-panel'
export interface ReviewPanelState {
values: {
@@ -22,6 +24,7 @@ export interface ReviewPanelState {
name: string
}
>
+ toggleReviewPanel: () => void
}
updaterFns: {
setCollapsed: React.Dispatch<
diff --git a/services/web/frontend/stylesheets/app/editor/review-panel.less b/services/web/frontend/stylesheets/app/editor/review-panel.less
index 8403971066..d5bf443e28 100644
--- a/services/web/frontend/stylesheets/app/editor/review-panel.less
+++ b/services/web/frontend/stylesheets/app/editor/review-panel.less
@@ -1222,6 +1222,19 @@ button when (@is-overleaf-light = true) {
}
}
+ .review-panel-toggler {
+ display: flex;
+ flex-direction: column;
+ padding: 0;
+ border: 0;
+
+ &:after {
+ position: sticky;
+ top: 50%;
+ bottom: 50%;
+ }
+ }
+
.rp-state-current-file & {
.review-panel-tools {
display: flex;
@@ -1243,25 +1256,13 @@ button when (@is-overleaf-light = true) {
position: sticky;
bottom: 0;
}
-
- .review-panel-toggler {
- position: sticky;
- top: 0;
- }
}
- .rp-state-overview & {
+ .rp-state-overview {
position: sticky;
top: 0;
display: flex;
flex-direction: column;
-
- .review-panel-toggler {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- }
}
.rp-nav-item {
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 190b70920d..778fed13f3 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
@@ -22,15 +22,11 @@ describe('', function () {
const scope = mockScope('')
scope.editor.showVisual = true
- // Making a shallow copy, otherwise cannot spy on an object declared outside the test file
- const newScope = { ...scope }
- cy.spy(newScope, 'toggleTrackChangesForEveryone').as(
- 'toggleTrackChangesForEveryone'
- )
+ cy.wrap(scope).as('scope')
cy.mount(
-
+
@@ -90,7 +86,9 @@ describe('', function () {
cy.findByLabelText(/track changes for everyone/i).click({
force: true,
})
- cy.get('@toggleTrackChangesForEveryone').should('be.calledOnce')
+ cy.get('@scope')
+ .its('toggleTrackChangesForEveryone')
+ .should('be.calledOnce')
})
})
@@ -118,4 +116,19 @@ describe('', function () {
})
})
})
+
+ describe('toggler', function () {
+ it('renders toggler button', function () {
+ cy.get('@review-panel').within(() => {
+ cy.findByRole('button', { name: /toggle review panel/i })
+ })
+ })
+
+ it('calls the toggler function on click', function () {
+ cy.get('@review-panel').within(() => {
+ cy.findByRole('button', { name: /toggle review panel/i }).click()
+ cy.get('@scope').its('toggleReviewPanel').should('be.calledOnce')
+ })
+ })
+ })
})
diff --git a/services/web/test/frontend/features/source-editor/helpers/mock-scope.ts b/services/web/test/frontend/features/source-editor/helpers/mock-scope.ts
index 341714df9e..9535a8c6c3 100644
--- a/services/web/test/frontend/features/source-editor/helpers/mock-scope.ts
+++ b/services/web/test/frontend/features/source-editor/helpers/mock-scope.ts
@@ -82,7 +82,8 @@ export const mockScope = (content?: string) => {
ui: {
reviewPanelOpen: true,
},
- toggleTrackChangesForEveryone() {},
+ toggleReviewPanel: cy.stub(),
+ toggleTrackChangesForEveryone: cy.stub(),
onlineUserCursorHighlights: {},
permissionsLevel: 'owner',
$on: cy.stub(),
diff --git a/services/web/types/review-panel.ts b/services/web/types/review-panel.ts
index f768b477c4..ad871e3b52 100644
--- a/services/web/types/review-panel.ts
+++ b/services/web/types/review-panel.ts
@@ -1,3 +1,5 @@
+export type SubView = 'cur_file' | 'overview'
+
export interface ReviewPanelPermissions {
read: boolean
write: boolean