mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
[web] View menu tweaks (#34548)
* [web] Add missing translation * [web] Group PDF zoom options in view menu * [web] Add review panel toggle to view menu * [web] Address review comments * [web] Show disabled buttons to anonymous users * [web] Add e2e tests for editing mode in view menu GitOrigin-RevId: d13dc307f1bcb7c50c76afbaa397c3aca8b96029
This commit is contained in:
committed by
Copybot
parent
efd12c8feb
commit
b7f984fc8d
@@ -2,6 +2,8 @@ import {
|
||||
createNewFile,
|
||||
createProjectAndOpenInNewEditor,
|
||||
openProjectById,
|
||||
openProjectByName,
|
||||
shareProjectByEmailAndAcceptInviteViaDash,
|
||||
testNewFileUpload,
|
||||
} from './helpers/project'
|
||||
import { isExcludedBySharding, startWith } from './helpers/config'
|
||||
@@ -321,6 +323,124 @@ describe('editor', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('editing mode', function () {
|
||||
if (isExcludedBySharding('PRO_DEFAULT_1')) return
|
||||
startWith({ pro: true })
|
||||
|
||||
const OWNER = USER
|
||||
const EDITOR = COLLABORATOR
|
||||
const REVIEWER = 'reviewer@example.com'
|
||||
const VIEWER = 'viewer@example.com'
|
||||
ensureUserExists({ email: OWNER })
|
||||
ensureUserExists({ email: EDITOR })
|
||||
ensureUserExists({ email: REVIEWER })
|
||||
ensureUserExists({ email: VIEWER })
|
||||
|
||||
let projectName: string
|
||||
|
||||
function openEditingModeMenu() {
|
||||
cy.findByRole('button', { name: 'View' }).click()
|
||||
cy.findByRole('menuitem', { name: 'Editing mode' }).click()
|
||||
}
|
||||
|
||||
beforeWithReRunOnTestRetry(() => {
|
||||
projectName = `project-${uuid()}`
|
||||
login(OWNER)
|
||||
createProjectAndOpenInNewEditor(projectName, { type: 'Example project' })
|
||||
|
||||
shareProjectByEmailAndAcceptInviteViaDash(
|
||||
projectName,
|
||||
EDITOR,
|
||||
'Editor',
|
||||
true
|
||||
)
|
||||
login(OWNER)
|
||||
shareProjectByEmailAndAcceptInviteViaDash(
|
||||
projectName,
|
||||
REVIEWER,
|
||||
'Reviewer',
|
||||
true
|
||||
)
|
||||
login(OWNER)
|
||||
shareProjectByEmailAndAcceptInviteViaDash(
|
||||
projectName,
|
||||
VIEWER,
|
||||
'Viewer',
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('lets an editor switch between editing and reviewing', function () {
|
||||
login(EDITOR)
|
||||
openProjectByName(projectName, true)
|
||||
|
||||
openEditingModeMenu()
|
||||
cy.findByRole('menuitem', { name: 'Editing' })
|
||||
.should('have.attr', 'aria-selected', 'true')
|
||||
.and('not.have.attr', 'aria-disabled')
|
||||
cy.findByRole('menuitem', { name: 'Reviewing' })
|
||||
.should('have.attr', 'aria-selected', 'false')
|
||||
.and('not.have.attr', 'aria-disabled')
|
||||
cy.findByRole('menuitem', { name: 'Viewing' }).should('not.exist')
|
||||
|
||||
cy.findByRole('menuitem', { name: 'Reviewing' }).click()
|
||||
cy.findByRole('button', { name: 'Reviewing' }).should('exist')
|
||||
|
||||
openEditingModeMenu()
|
||||
cy.findByRole('menuitem', { name: 'Reviewing' }).should(
|
||||
'have.attr',
|
||||
'aria-selected',
|
||||
'true'
|
||||
)
|
||||
cy.findByRole('menuitem', { name: 'Editing' }).should(
|
||||
'have.attr',
|
||||
'aria-selected',
|
||||
'false'
|
||||
)
|
||||
|
||||
cy.findByRole('menuitem', { name: 'Editing' }).click()
|
||||
cy.findByRole('button', { name: 'Editing' }).should('exist')
|
||||
})
|
||||
|
||||
it('shows a reviewer in reviewing mode with editing disabled', function () {
|
||||
login(REVIEWER)
|
||||
openProjectByName(projectName, true)
|
||||
|
||||
openEditingModeMenu()
|
||||
cy.findByRole('menuitem', { name: 'Reviewing' })
|
||||
.should('have.attr', 'aria-selected', 'true')
|
||||
.and('not.have.attr', 'aria-disabled')
|
||||
cy.findByRole('menuitem', { name: 'Editing' }).should(
|
||||
'have.attr',
|
||||
'aria-disabled',
|
||||
'true'
|
||||
)
|
||||
cy.findByRole('menuitem', { name: 'Viewing' }).should('not.exist')
|
||||
})
|
||||
|
||||
it('shows a viewer in viewing mode with editing and reviewing disabled', function () {
|
||||
login(VIEWER)
|
||||
openProjectByName(projectName, true)
|
||||
|
||||
openEditingModeMenu()
|
||||
cy.findByRole('menuitem', { name: 'Viewing' }).should(
|
||||
'have.attr',
|
||||
'aria-selected',
|
||||
'true'
|
||||
)
|
||||
cy.findByRole('menuitem', { name: 'Editing' }).should(
|
||||
'have.attr',
|
||||
'aria-disabled',
|
||||
'true'
|
||||
)
|
||||
cy.findByRole('menuitem', { name: 'Reviewing' }).should(
|
||||
'have.attr',
|
||||
'aria-disabled',
|
||||
'true'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function createRandomLetterString() {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz'
|
||||
let result = ''
|
||||
|
||||
@@ -206,7 +206,7 @@ export function openProjectViaInviteNotification(
|
||||
function shareProjectByEmail(
|
||||
projectName: string,
|
||||
email: string,
|
||||
level: 'Viewer' | 'Editor',
|
||||
level: 'Viewer' | 'Editor' | 'Reviewer',
|
||||
newEditor: boolean = false
|
||||
) {
|
||||
openProjectByName(projectName, newEditor)
|
||||
@@ -231,7 +231,7 @@ function shareProjectByEmail(
|
||||
export function shareProjectByEmailAndAcceptInviteViaDash(
|
||||
projectName: string,
|
||||
email: string,
|
||||
level: 'Viewer' | 'Editor',
|
||||
level: 'Viewer' | 'Editor' | 'Reviewer',
|
||||
newEditor: boolean = false
|
||||
) {
|
||||
shareProjectByEmail(projectName, email, level, newEditor)
|
||||
|
||||
@@ -585,6 +585,7 @@
|
||||
"edited": "",
|
||||
"editing": "",
|
||||
"editing_captions": "",
|
||||
"editing_mode": "",
|
||||
"editor": "",
|
||||
"editor_disconected_click_to_reconnect": "",
|
||||
"editor_font_family": "",
|
||||
@@ -592,6 +593,7 @@
|
||||
"editor_limit_exceeded_in_this_project": "",
|
||||
"editor_line_height": "",
|
||||
"editor_only": "",
|
||||
"editor_settings": "",
|
||||
"editor_theme": "",
|
||||
"editor_theme_dark": "",
|
||||
"editor_theme_light": "",
|
||||
@@ -1453,6 +1455,7 @@
|
||||
"pdf_unavailable_for_download": "",
|
||||
"pdf_viewer": "",
|
||||
"pdf_viewer_error": "",
|
||||
"pdf_zoom": "",
|
||||
"pdf_zoom_level": "",
|
||||
"pending": "",
|
||||
"pending_additional_licenses": "",
|
||||
|
||||
@@ -26,6 +26,7 @@ import EditorCloneProjectModalWrapper from '@/features/clone-project-modal/compo
|
||||
import useOpenProject from '@/shared/hooks/use-open-project'
|
||||
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
import ReviewModeOptions from './review-mode-options'
|
||||
|
||||
const menubarExtraComponents = importOverleafModules(
|
||||
'menubarExtraComponents'
|
||||
@@ -205,11 +206,17 @@ export const ToolbarMenuBar = () => {
|
||||
id: 'pdf-controls',
|
||||
children: [
|
||||
'view-pdf-presentation-mode',
|
||||
{
|
||||
id: 'pdf-zoom-control-group',
|
||||
title: t('pdf_zoom'),
|
||||
children: [
|
||||
'view-pdf-zoom-in',
|
||||
'view-pdf-zoom-out',
|
||||
'view-pdf-fit-width',
|
||||
'view-pdf-fit-height',
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
[t]
|
||||
)
|
||||
@@ -262,8 +269,9 @@ export const ToolbarMenuBar = () => {
|
||||
className="ide-redesign-toolbar-dropdown-toggle-subdued ide-redesign-toolbar-button-subdued"
|
||||
>
|
||||
<ChangeLayoutOptions />
|
||||
<ReviewModeOptions />
|
||||
<DropdownDivider />
|
||||
<DropdownHeader>Editor settings</DropdownHeader>
|
||||
<DropdownHeader>{t('editor_settings')}</DropdownHeader>
|
||||
<MenuBarOption
|
||||
eventKey="show_breadcrumbs"
|
||||
title={t('show_breadcrumbs')}
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
import { DropdownDivider } from '@/shared/components/dropdown/dropdown-menu'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useEditorPropertiesContext } from '../../context/editor-properties-context'
|
||||
import OLDropdownMenuItem from '@/shared/components/ol/ol-dropdown-menu-item'
|
||||
import { sendMB } from '@/infrastructure/event-tracking'
|
||||
import { useIdeReactContext } from '../../context/ide-react-context'
|
||||
import { usePermissionsContext } from '../../context/permissions-context'
|
||||
import { useProjectContext } from '@/shared/context/project-context'
|
||||
import { useEditorContext } from '@/shared/context/editor-context'
|
||||
import { NestedMenuBarDropdown } from '@/shared/components/menu-bar/menu-bar-dropdown'
|
||||
import { useUserContext } from '@/shared/context/user-context'
|
||||
|
||||
function getMode(permissionsLevel: string, wantTrackChanges: boolean) {
|
||||
if (permissionsLevel === 'readOnly') {
|
||||
return 'view'
|
||||
}
|
||||
if (permissionsLevel === 'review') {
|
||||
return 'review'
|
||||
}
|
||||
if (wantTrackChanges) {
|
||||
return 'review'
|
||||
}
|
||||
return 'edit'
|
||||
}
|
||||
|
||||
const ReviewModeOptions: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { wantTrackChanges } = useEditorPropertiesContext()
|
||||
const { write, trackedWrite } = usePermissionsContext()
|
||||
const { permissionsLevel } = useIdeReactContext()
|
||||
const { features } = useProjectContext()
|
||||
const { setUpgradeTrackChangesModal } = useEditorContext()
|
||||
const user = useUserContext()
|
||||
|
||||
const mode = getMode(permissionsLevel, wantTrackChanges)
|
||||
const showViewOption = mode === 'view'
|
||||
|
||||
if (!features.trackChangesVisible) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownDivider />
|
||||
<NestedMenuBarDropdown id="editing-mode-group" title={t('editing_mode')}>
|
||||
<OLDropdownMenuItem
|
||||
as="button"
|
||||
disabled={!write || !user.id}
|
||||
onClick={() => {
|
||||
if (mode === 'edit') {
|
||||
return
|
||||
}
|
||||
sendMB('editing-mode-change', {
|
||||
role: permissionsLevel,
|
||||
previousMode: mode,
|
||||
newMode: 'edit',
|
||||
})
|
||||
window.dispatchEvent(new Event('toggle-track-changes'))
|
||||
}}
|
||||
leadingIcon="edit"
|
||||
active={write && mode === 'edit'}
|
||||
>
|
||||
{t('editing')}
|
||||
</OLDropdownMenuItem>
|
||||
<OLDropdownMenuItem
|
||||
as="button"
|
||||
disabled={permissionsLevel === 'readOnly' || !user.id}
|
||||
onClick={() => {
|
||||
if (mode === 'review') {
|
||||
return
|
||||
}
|
||||
if (!features.trackChanges) {
|
||||
setUpgradeTrackChangesModal({
|
||||
show: true,
|
||||
location: 'menu-bar',
|
||||
})
|
||||
} else {
|
||||
sendMB('editing-mode-change', {
|
||||
role: permissionsLevel,
|
||||
previousMode: mode,
|
||||
newMode: mode,
|
||||
})
|
||||
window.dispatchEvent(new Event('toggle-track-changes'))
|
||||
}
|
||||
}}
|
||||
leadingIcon="rate_review"
|
||||
active={trackedWrite && mode === 'review'}
|
||||
>
|
||||
{t('reviewing')}
|
||||
</OLDropdownMenuItem>
|
||||
{showViewOption && (
|
||||
<OLDropdownMenuItem
|
||||
as="button"
|
||||
leadingIcon="visibility"
|
||||
active={mode === 'view'}
|
||||
>
|
||||
{t('viewing')}
|
||||
</OLDropdownMenuItem>
|
||||
)}
|
||||
</NestedMenuBarDropdown>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ReviewModeOptions
|
||||
@@ -761,6 +761,7 @@
|
||||
"editing": "Editing",
|
||||
"editing_and_collaboration": "Editing and collaboration",
|
||||
"editing_captions": "Editing captions",
|
||||
"editing_mode": "Editing mode",
|
||||
"editing_tools": "Editing tools",
|
||||
"editor": "Editor",
|
||||
"editor_disconected_click_to_reconnect": "Editor disconnected, click anywhere to reconnect.",
|
||||
@@ -769,6 +770,7 @@
|
||||
"editor_limit_exceeded_in_this_project": "Too many editors in this project",
|
||||
"editor_line_height": "Editor line height",
|
||||
"editor_only": "Editor only",
|
||||
"editor_settings": "Editor settings",
|
||||
"editor_theme": "Editor theme",
|
||||
"editor_theme_dark": "Dark editor theme",
|
||||
"editor_theme_light": "Light editor theme",
|
||||
@@ -1911,6 +1913,7 @@
|
||||
"pdf_unavailable_for_download": "PDF unavailable for download",
|
||||
"pdf_viewer": "PDF Viewer",
|
||||
"pdf_viewer_error": "There was a problem displaying the PDF for this project.",
|
||||
"pdf_zoom": "PDF zoom",
|
||||
"pdf_zoom_level": "PDF zoom level",
|
||||
"pending": "Pending",
|
||||
"pending_additional_licenses": "Your subscription is changing to include <0>__pendingAdditionalLicenses__</0> additional license(s) for a total of <1>__pendingTotalLicenses__</1> licenses.",
|
||||
|
||||
Reference in New Issue
Block a user