mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Ensure add comment tooltip doesnt show up without comment permissions (#27273)
* Ensure add comment tooltip doesnt show up without comment permissions * disable comment option when no permissions in new editor * add e2e tests * use server pro for project sharing * use findByRole for add comment * remove .only GitOrigin-RevId: fbef78e0db7678a00d6c602069e16ddeaf23b2f3
This commit is contained in:
committed by
Copybot
parent
7c97cbbfe4
commit
9228f2248b
@@ -14,9 +14,9 @@ import { throttledRecompile } from './helpers/compile'
|
|||||||
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
import { beforeWithReRunOnTestRetry } from './helpers/beforeWithReRunOnTestRetry'
|
||||||
|
|
||||||
describe('Project Sharing', function () {
|
describe('Project Sharing', function () {
|
||||||
if (isExcludedBySharding('CE_CUSTOM_2')) return
|
if (isExcludedBySharding('PRO_CUSTOM_2')) return
|
||||||
ensureUserExists({ email: 'user@example.com' })
|
ensureUserExists({ email: 'user@example.com' })
|
||||||
startWith({ withDataDir: true })
|
startWith({ withDataDir: true, pro: true })
|
||||||
|
|
||||||
let projectName: string
|
let projectName: string
|
||||||
beforeWithReRunOnTestRetry(function () {
|
beforeWithReRunOnTestRetry(function () {
|
||||||
@@ -135,22 +135,57 @@ describe('Project Sharing', function () {
|
|||||||
cy.findByText('History').should('not.exist')
|
cy.findByText('History').should('not.exist')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function expectCommentAccess() {
|
||||||
|
cy.findByRole('textbox', { name: /Source Editor editing/i }).should(
|
||||||
|
'contain.text',
|
||||||
|
'\\maketitle'
|
||||||
|
)
|
||||||
|
|
||||||
|
cy.findByText('\\maketitle').parent().dblclick()
|
||||||
|
|
||||||
|
cy.findByRole('button', { name: 'Add comment' }).should('be.visible')
|
||||||
|
|
||||||
|
cy.findByRole('textbox', { name: /Source Editor editing/i }).click()
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectNoCommentAccess() {
|
||||||
|
cy.findByRole('textbox', { name: /Source Editor editing/i }).should(
|
||||||
|
'contain.text',
|
||||||
|
'\\maketitle'
|
||||||
|
)
|
||||||
|
|
||||||
|
cy.findByText('\\maketitle').parent().dblclick()
|
||||||
|
|
||||||
|
cy.findByRole('button', { name: 'Add comment' }).should('not.exist')
|
||||||
|
cy.findByRole('textbox', { name: /Source Editor editing/i }).click()
|
||||||
|
}
|
||||||
|
|
||||||
function expectFullReadOnlyAccess() {
|
function expectFullReadOnlyAccess() {
|
||||||
expectContentReadOnlyAccess()
|
expectContentReadOnlyAccess()
|
||||||
expectChatAccess()
|
expectChatAccess()
|
||||||
expectHistoryAccess()
|
expectHistoryAccess()
|
||||||
|
expectNoCommentAccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectRestrictedReadOnlyAccess() {
|
function expectRestrictedReadOnlyAccess() {
|
||||||
expectContentReadOnlyAccess()
|
expectContentReadOnlyAccess()
|
||||||
expectNoChatAccess()
|
expectNoChatAccess()
|
||||||
expectNoHistoryAccess()
|
expectNoHistoryAccess()
|
||||||
|
expectNoCommentAccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectReadAndWriteAccess() {
|
function expectFullReadAndWriteAccess() {
|
||||||
expectContentWriteAccess()
|
expectContentWriteAccess()
|
||||||
expectChatAccess()
|
expectChatAccess()
|
||||||
expectHistoryAccess()
|
expectHistoryAccess()
|
||||||
|
expectCommentAccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectAnonymousReadAndWriteAccess() {
|
||||||
|
expectContentWriteAccess()
|
||||||
|
expectChatAccess()
|
||||||
|
expectHistoryAccess()
|
||||||
|
expectNoCommentAccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
function expectProjectDashboardEntry() {
|
function expectProjectDashboardEntry() {
|
||||||
@@ -209,7 +244,7 @@ describe('Project Sharing', function () {
|
|||||||
it('should grant the collaborator write access', () => {
|
it('should grant the collaborator write access', () => {
|
||||||
login(email)
|
login(email)
|
||||||
openProjectByName(projectName)
|
openProjectByName(projectName)
|
||||||
expectReadAndWriteAccess()
|
expectFullReadAndWriteAccess()
|
||||||
expectEditAuthoredAs('You')
|
expectEditAuthoredAs('You')
|
||||||
expectProjectDashboardEntry()
|
expectProjectDashboardEntry()
|
||||||
})
|
})
|
||||||
@@ -244,7 +279,7 @@ describe('Project Sharing', function () {
|
|||||||
projectName,
|
projectName,
|
||||||
email
|
email
|
||||||
)
|
)
|
||||||
expectReadAndWriteAccess()
|
expectFullReadAndWriteAccess()
|
||||||
expectEditAuthoredAs('You')
|
expectEditAuthoredAs('You')
|
||||||
expectProjectDashboardEntry()
|
expectProjectDashboardEntry()
|
||||||
})
|
})
|
||||||
@@ -254,6 +289,7 @@ describe('Project Sharing', function () {
|
|||||||
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=false', () => {
|
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=false', () => {
|
||||||
describe('wrap startup', () => {
|
describe('wrap startup', () => {
|
||||||
startWith({
|
startWith({
|
||||||
|
pro: true,
|
||||||
vars: {
|
vars: {
|
||||||
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'false',
|
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'false',
|
||||||
},
|
},
|
||||||
@@ -266,6 +302,7 @@ describe('Project Sharing', function () {
|
|||||||
|
|
||||||
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', () => {
|
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', () => {
|
||||||
startWith({
|
startWith({
|
||||||
|
pro: true,
|
||||||
vars: {
|
vars: {
|
||||||
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'false',
|
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'false',
|
||||||
OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING: 'true',
|
OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING: 'true',
|
||||||
@@ -281,6 +318,7 @@ describe('Project Sharing', function () {
|
|||||||
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=true', () => {
|
describe('with OVERLEAF_ALLOW_PUBLIC_ACCESS=true', () => {
|
||||||
describe('wrap startup', () => {
|
describe('wrap startup', () => {
|
||||||
startWith({
|
startWith({
|
||||||
|
pro: true,
|
||||||
vars: {
|
vars: {
|
||||||
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'true',
|
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'true',
|
||||||
},
|
},
|
||||||
@@ -299,6 +337,7 @@ describe('Project Sharing', function () {
|
|||||||
|
|
||||||
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', () => {
|
describe('with OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING=true', () => {
|
||||||
startWith({
|
startWith({
|
||||||
|
pro: true,
|
||||||
vars: {
|
vars: {
|
||||||
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'true',
|
OVERLEAF_ALLOW_PUBLIC_ACCESS: 'true',
|
||||||
OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING: 'true',
|
OVERLEAF_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING: 'true',
|
||||||
@@ -313,7 +352,7 @@ describe('Project Sharing', function () {
|
|||||||
|
|
||||||
it('should grant write access with write link', () => {
|
it('should grant write access with write link', () => {
|
||||||
openProjectViaLinkSharingAsAnon(linkSharingReadAndWrite)
|
openProjectViaLinkSharingAsAnon(linkSharingReadAndWrite)
|
||||||
expectReadAndWriteAccess()
|
expectAnonymousReadAndWriteAccess()
|
||||||
expectEditAuthoredAs('Anonymous')
|
expectEditAuthoredAs('Anonymous')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+3
-2
@@ -23,7 +23,7 @@ export const useToolbarMenuBarEditorCommands = () => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { view: layoutView } = useLayoutContext()
|
const { view: layoutView } = useLayoutContext()
|
||||||
const editorIsVisible = layoutView === 'editor'
|
const editorIsVisible = layoutView === 'editor'
|
||||||
const { trackedWrite } = usePermissionsContext()
|
const { trackedWrite, comment } = usePermissionsContext()
|
||||||
const languageName = state.facet(language)?.name
|
const languageName = state.facet(language)?.name
|
||||||
const isTeXFile = languageName === 'latex'
|
const isTeXFile = languageName === 'latex'
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ export const useToolbarMenuBarEditorCommands = () => {
|
|||||||
handler: () => {
|
handler: () => {
|
||||||
commands.addComment()
|
commands.addComment()
|
||||||
},
|
},
|
||||||
disabled: state.selection.main.empty,
|
disabled: !comment || state.selection.main.empty,
|
||||||
},
|
},
|
||||||
/************************************
|
/************************************
|
||||||
* Format menu
|
* Format menu
|
||||||
@@ -288,6 +288,7 @@ export const useToolbarMenuBarEditorCommands = () => {
|
|||||||
trackedWrite,
|
trackedWrite,
|
||||||
isTeXFile,
|
isTeXFile,
|
||||||
state.selection.main.empty,
|
state.selection.main.empty,
|
||||||
|
comment,
|
||||||
])
|
])
|
||||||
|
|
||||||
const { toggleSymbolPalette } = useEditorPropertiesContext()
|
const { toggleSymbolPalette } = useEditorPropertiesContext()
|
||||||
|
|||||||
+5
-5
@@ -18,7 +18,6 @@ import {
|
|||||||
reviewTooltipStateField,
|
reviewTooltipStateField,
|
||||||
} from '@/features/source-editor/extensions/review-tooltip'
|
} from '@/features/source-editor/extensions/review-tooltip'
|
||||||
import { EditorView, getTooltip } from '@codemirror/view'
|
import { EditorView, getTooltip } from '@codemirror/view'
|
||||||
import useViewerPermissions from '@/shared/hooks/use-viewer-permissions'
|
|
||||||
import usePreviousValue from '@/shared/hooks/use-previous-value'
|
import usePreviousValue from '@/shared/hooks/use-previous-value'
|
||||||
import { useLayoutContext } from '@/shared/context/layout-context'
|
import { useLayoutContext } from '@/shared/context/layout-context'
|
||||||
import { useReviewPanelViewActionsContext } from '../context/review-panel-view-context'
|
import { useReviewPanelViewActionsContext } from '../context/review-panel-view-context'
|
||||||
@@ -35,6 +34,7 @@ import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-
|
|||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import useEventListener from '@/shared/hooks/use-event-listener'
|
import useEventListener from '@/shared/hooks/use-event-listener'
|
||||||
import useReviewPanelLayout from '../hooks/use-review-panel-layout'
|
import useReviewPanelLayout from '../hooks/use-review-panel-layout'
|
||||||
|
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
|
||||||
|
|
||||||
const EDIT_MODE_SWITCH_WIDGET_HEIGHT = 40
|
const EDIT_MODE_SWITCH_WIDGET_HEIGHT = 40
|
||||||
const CM_LINE_RIGHT_PADDING = 8
|
const CM_LINE_RIGHT_PADDING = 8
|
||||||
@@ -43,7 +43,7 @@ const TOOLTIP_SHOW_DELAY = 120
|
|||||||
const ReviewTooltipMenu: FC = () => {
|
const ReviewTooltipMenu: FC = () => {
|
||||||
const state = useCodeMirrorStateContext()
|
const state = useCodeMirrorStateContext()
|
||||||
const view = useCodeMirrorViewContext()
|
const view = useCodeMirrorViewContext()
|
||||||
const isViewer = useViewerPermissions()
|
const permissions = usePermissionsContext()
|
||||||
const [show, setShow] = useState(true)
|
const [show, setShow] = useState(true)
|
||||||
const { setView } = useReviewPanelViewActionsContext()
|
const { setView } = useReviewPanelViewActionsContext()
|
||||||
const { openReviewPanel } = useReviewPanelLayout()
|
const { openReviewPanel } = useReviewPanelLayout()
|
||||||
@@ -58,7 +58,7 @@ const ReviewTooltipMenu: FC = () => {
|
|||||||
|
|
||||||
const addComment = useCallback(() => {
|
const addComment = useCallback(() => {
|
||||||
const { main } = view.state.selection
|
const { main } = view.state.selection
|
||||||
if (main.empty) {
|
if (main.empty || !permissions.comment) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,11 +74,11 @@ const ReviewTooltipMenu: FC = () => {
|
|||||||
|
|
||||||
view.dispatch({ effects })
|
view.dispatch({ effects })
|
||||||
setShow(false)
|
setShow(false)
|
||||||
}, [openReviewPanel, setView, setShow, view])
|
}, [view, permissions.comment, openReviewPanel, setView])
|
||||||
|
|
||||||
useEventListener('add-new-review-comment', addComment)
|
useEventListener('add-new-review-comment', addComment)
|
||||||
|
|
||||||
if (isViewer || !show || !tooltipState) {
|
if (!permissions.comment || !show || !tooltipState) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -16,6 +16,7 @@ import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
|||||||
import { isMac } from '@/shared/utils/os'
|
import { isMac } from '@/shared/utils/os'
|
||||||
import { useProjectContext } from '@/shared/context/project-context'
|
import { useProjectContext } from '@/shared/context/project-context'
|
||||||
import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
|
import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
|
||||||
|
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
|
||||||
|
|
||||||
export const ToolbarItems: FC<{
|
export const ToolbarItems: FC<{
|
||||||
state: EditorState
|
state: EditorState
|
||||||
@@ -35,6 +36,7 @@ export const ToolbarItems: FC<{
|
|||||||
useEditorPropertiesContext()
|
useEditorPropertiesContext()
|
||||||
const { writefullInstance } = useEditorContext()
|
const { writefullInstance } = useEditorContext()
|
||||||
const { features } = useProjectContext()
|
const { features } = useProjectContext()
|
||||||
|
const permissions = usePermissionsContext()
|
||||||
const isActive = withinFormattingCommand(state)
|
const isActive = withinFormattingCommand(state)
|
||||||
|
|
||||||
const symbolPaletteAvailable = getMeta('ol-symbolPaletteAvailable')
|
const symbolPaletteAvailable = getMeta('ol-symbolPaletteAvailable')
|
||||||
@@ -131,7 +133,7 @@ export const ToolbarItems: FC<{
|
|||||||
command={commands.wrapInHref}
|
command={commands.wrapInHref}
|
||||||
icon="add_link"
|
icon="add_link"
|
||||||
/>
|
/>
|
||||||
{features.trackChangesVisible && (
|
{features.trackChangesVisible && permissions.comment && (
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
id="toolbar-add-comment"
|
id="toolbar-add-comment"
|
||||||
label={t('add_comment')}
|
label={t('add_comment')}
|
||||||
|
|||||||
Reference in New Issue
Block a user