mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
Merge pull request #24225 from overleaf/em-reviewers-share-modal
Count reviewers towards collaborator limit in share modal GitOrigin-RevId: 27ec3a787124be7590791412d914ec6da78bab35
This commit is contained in:
@@ -897,6 +897,10 @@
|
|||||||
"limited_document_history": "",
|
"limited_document_history": "",
|
||||||
"limited_offer": "",
|
"limited_offer": "",
|
||||||
"limited_to_n_editors": "",
|
"limited_to_n_editors": "",
|
||||||
|
"limited_to_n_editors_or_reviewers": "",
|
||||||
|
"limited_to_n_editors_or_reviewers_per_project": "",
|
||||||
|
"limited_to_n_editors_or_reviewers_per_project_plural": "",
|
||||||
|
"limited_to_n_editors_or_reviewers_plural": "",
|
||||||
"limited_to_n_editors_per_project": "",
|
"limited_to_n_editors_per_project": "",
|
||||||
"limited_to_n_editors_per_project_plural": "",
|
"limited_to_n_editors_per_project_plural": "",
|
||||||
"limited_to_n_editors_plural": "",
|
"limited_to_n_editors_plural": "",
|
||||||
|
|||||||
+4
-2
@@ -52,7 +52,7 @@ export default function AddCollaborators({ readOnly }) {
|
|||||||
const { reset, selectedItems } = multipleSelectionProps
|
const { reset, selectedItems } = multipleSelectionProps
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (readOnly && privileges === 'readAndWrite') {
|
if (readOnly && privileges !== 'readOnly') {
|
||||||
setPrivileges('readOnly')
|
setPrivileges('readOnly')
|
||||||
}
|
}
|
||||||
}, [privileges, readOnly])
|
}, [privileges, readOnly])
|
||||||
@@ -171,7 +171,9 @@ export default function AddCollaborators({ readOnly }) {
|
|||||||
{t('can_edit')}
|
{t('can_edit')}
|
||||||
</option>
|
</option>
|
||||||
{getMeta('ol-isReviewerRoleEnabled') && (
|
{getMeta('ol-isReviewerRoleEnabled') && (
|
||||||
<option value="review">{t('can_review')}</option>
|
<option disabled={readOnly} value="review">
|
||||||
|
{t('can_review')}
|
||||||
|
</option>
|
||||||
)}
|
)}
|
||||||
<option value="readOnly">{t('can_view')}</option>
|
<option value="readOnly">{t('can_view')}</option>
|
||||||
</OLFormSelect>
|
</OLFormSelect>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import OLCol from '@/features/ui/components/ol/ol-col'
|
|||||||
import MaterialIcon from '@/shared/components/material-icon'
|
import MaterialIcon from '@/shared/components/material-icon'
|
||||||
import getMeta from '@/utils/meta'
|
import getMeta from '@/utils/meta'
|
||||||
import { useUserContext } from '@/shared/context/user-context'
|
import { useUserContext } from '@/shared/context/user-context'
|
||||||
|
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||||
|
|
||||||
type PermissionsOption = PermissionsLevel | 'removeAccess' | 'downgraded'
|
type PermissionsOption = PermissionsLevel | 'removeAccess' | 'downgraded'
|
||||||
|
|
||||||
@@ -249,28 +250,41 @@ function SelectPrivilege({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getPrivilegeSubtitle(privilege: PermissionsOption) {
|
function getPrivilegeSubtitle(privilege: PermissionsOption) {
|
||||||
if (!hasBeenDowngraded) {
|
if (!['readAndWrite', 'review'].includes(privilege)) {
|
||||||
return !canAddCollaborators &&
|
return ''
|
||||||
privilege === 'readAndWrite' &&
|
|
||||||
value !== 'readAndWrite'
|
|
||||||
? t('limited_to_n_editors_per_project', {
|
|
||||||
count: features.collaborators,
|
|
||||||
})
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return privilege === 'readAndWrite'
|
if (hasBeenDowngraded) {
|
||||||
? t('limited_to_n_editors', {
|
if (isSplitTestEnabled('reviewer-role')) {
|
||||||
|
return t('limited_to_n_editors_or_reviewers', {
|
||||||
count: features.collaborators,
|
count: features.collaborators,
|
||||||
})
|
})
|
||||||
: ''
|
} else {
|
||||||
|
return t('limited_to_n_editors', { count: features.collaborators })
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
!canAddCollaborators &&
|
||||||
|
!['readAndWrite', 'review'].includes(value)
|
||||||
|
) {
|
||||||
|
if (isSplitTestEnabled('reviewer-role')) {
|
||||||
|
return t('limited_to_n_editors_or_reviewers_per_project', {
|
||||||
|
count: features.collaborators,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return t('limited_to_n_editors_per_project', {
|
||||||
|
count: features.collaborators,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPrivilegeDisabled(privilege: PermissionsOption) {
|
function isPrivilegeDisabled(privilege: PermissionsOption) {
|
||||||
return (
|
return (
|
||||||
!canAddCollaborators &&
|
!canAddCollaborators &&
|
||||||
privilege === 'readAndWrite' &&
|
['readAndWrite', 'review'].includes(privilege) &&
|
||||||
(hasBeenDowngraded || value !== 'readAndWrite')
|
(hasBeenDowngraded || !['readAndWrite', 'review'].includes(value))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -27,11 +27,11 @@ export default function ShareModalBody() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const editorInvites = invites.filter(
|
const editorInvites = invites.filter(
|
||||||
invite => invite.privileges === 'readAndWrite'
|
invite => invite.privileges !== 'readOnly'
|
||||||
).length
|
).length
|
||||||
|
|
||||||
return (
|
return (
|
||||||
members.filter(member => member.privileges === 'readAndWrite').length +
|
members.filter(member => member.privileges !== 'readOnly').length +
|
||||||
editorInvites <
|
editorInvites <
|
||||||
(features.collaborators ?? 1)
|
(features.collaborators ?? 1)
|
||||||
)
|
)
|
||||||
@@ -67,7 +67,7 @@ export default function ShareModalBody() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
members.filter(member => member.privileges === 'readAndWrite').length >
|
members.filter(member => member.privileges !== 'readOnly').length >
|
||||||
(features.collaborators ?? 1)
|
(features.collaborators ?? 1)
|
||||||
)
|
)
|
||||||
}, [features, isProjectOwner, members])
|
}, [features, isProjectOwner, members])
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { ProjectSnapshot } from '@/infrastructure/project-snapshot'
|
|||||||
|
|
||||||
export type ProjectContextMember = {
|
export type ProjectContextMember = {
|
||||||
_id: UserId
|
_id: UserId
|
||||||
privileges: 'readOnly' | 'readAndWrite'
|
privileges: 'readOnly' | 'readAndWrite' | 'review'
|
||||||
email: string
|
email: string
|
||||||
first_name: string
|
first_name: string
|
||||||
last_name: string
|
last_name: string
|
||||||
|
|||||||
@@ -1180,6 +1180,10 @@
|
|||||||
"license": "License",
|
"license": "License",
|
||||||
"limited_document_history": "Limited document history",
|
"limited_document_history": "Limited document history",
|
||||||
"limited_to_n_editors": "Limited to __count__ editor",
|
"limited_to_n_editors": "Limited to __count__ editor",
|
||||||
|
"limited_to_n_editors_or_reviewers": "Limited to __count__ editor or reviewer",
|
||||||
|
"limited_to_n_editors_or_reviewers_per_project": "Limited to __count__ editor or reviewer per project",
|
||||||
|
"limited_to_n_editors_or_reviewers_per_project_plural": "Limited to __count__ editors or reviewers per project",
|
||||||
|
"limited_to_n_editors_or_reviewers_plural": "Limited to __count__ editors or reviewers",
|
||||||
"limited_to_n_editors_per_project": "Limited to __count__ editor per project",
|
"limited_to_n_editors_per_project": "Limited to __count__ editor per project",
|
||||||
"limited_to_n_editors_per_project_plural": "Limited to __count__ editors per project",
|
"limited_to_n_editors_per_project_plural": "Limited to __count__ editors per project",
|
||||||
"limited_to_n_editors_plural": "Limited to __count__ editors",
|
"limited_to_n_editors_plural": "Limited to __count__ editors",
|
||||||
|
|||||||
+34
@@ -101,6 +101,7 @@ describe('<ShareProjectModal/>', function () {
|
|||||||
fetchMock.get('/user/contacts', { contacts })
|
fetchMock.get('/user/contacts', { contacts })
|
||||||
window.metaAttributesCache.set('ol-user', { allowedFreeTrial: true })
|
window.metaAttributesCache.set('ol-user', { allowedFreeTrial: true })
|
||||||
window.metaAttributesCache.set('ol-showUpgradePrompt', true)
|
window.metaAttributesCache.set('ol-showUpgradePrompt', true)
|
||||||
|
window.metaAttributesCache.set('ol-isReviewerRoleEnabled', true)
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
@@ -691,6 +692,39 @@ describe('<ShareProjectModal/>', function () {
|
|||||||
|
|
||||||
await screen.findByText('Add more editors')
|
await screen.findByText('Add more editors')
|
||||||
expect(screen.getByRole('option', { name: 'Can edit' }).disabled).to.be.true
|
expect(screen.getByRole('option', { name: 'Can edit' }).disabled).to.be.true
|
||||||
|
expect(screen.getByRole('option', { name: 'Can review' }).disabled).to.be
|
||||||
|
.true
|
||||||
|
expect(screen.getByRole('option', { name: 'Can view' }).disabled).to.be
|
||||||
|
.false
|
||||||
|
|
||||||
|
screen.getByText(
|
||||||
|
/Upgrade to add more editors and access collaboration features like track changes and full project history/
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('counts reviewers towards the collaborator limit', async function () {
|
||||||
|
renderWithEditorContext(<ShareProjectModal {...modalProps} />, {
|
||||||
|
scope: {
|
||||||
|
project: {
|
||||||
|
...project,
|
||||||
|
features: {
|
||||||
|
collaborators: 1,
|
||||||
|
},
|
||||||
|
members: [
|
||||||
|
{
|
||||||
|
_id: 'reviewer-id',
|
||||||
|
email: 'reviewer@example.com',
|
||||||
|
privileges: 'review',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await screen.findByText('Add more editors')
|
||||||
|
expect(screen.getByRole('option', { name: 'Can edit' }).disabled).to.be.true
|
||||||
|
expect(screen.getByRole('option', { name: 'Can review' }).disabled).to.be
|
||||||
|
.true
|
||||||
expect(screen.getByRole('option', { name: 'Can view' }).disabled).to.be
|
expect(screen.getByRole('option', { name: 'Can view' }).disabled).to.be
|
||||||
.false
|
.false
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user