Add upgrade prompt for track changes in share modal (#24572)

* Add upgrade prompt for track changes in share modal

* remove message from invite.jsx

* Fix itemToDisabled in Select

GitOrigin-RevId: 5ba9e2b063c7e26a4c39b9e973eddce36a5b4733
This commit is contained in:
Domagoj Kriskovic
2025-04-04 12:31:08 +02:00
committed by Copybot
parent 6169a5d3df
commit 1fb18b092d
6 changed files with 29 additions and 6 deletions

View File

@@ -267,6 +267,7 @@
"comment": "",
"comment_only": "",
"comment_only_upgrade_for_track_changes": "",
"comment_only_upgrade_to_enable_track_changes": "",
"common": "",
"common_causes_of_compile_timeouts_include": "",
"commons_plan_tooltip": "",

View File

@@ -194,7 +194,7 @@ export default function AddCollaborators({ readOnly }) {
itemToKey={item => item.key}
itemToString={item => item.label}
itemToSubtitle={item => item.description || ''}
itemToDisabled={item => readOnly && item.key === 'readAndWrite'}
itemToDisabled={item => readOnly && item.key !== 'readOnly'}
selected={privilegeOptions.find(
option => option.key === privileges
)}

View File

@@ -1,6 +1,6 @@
import { useState, useEffect, useMemo } from 'react'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import { Trans, useTranslation } from 'react-i18next'
import { useShareProjectContext } from './share-project-modal'
import TransferOwnershipModal from './transfer-ownership-modal'
import { removeMemberFromProject, updateMember } from '../utils/api'
@@ -17,6 +17,7 @@ import MaterialIcon from '@/shared/components/material-icon'
import getMeta from '@/utils/meta'
import { useUserContext } from '@/shared/context/user-context'
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
import { upgradePlan } from '@/main/account-upgrade'
type PermissionsOption = PermissionsLevel | 'removeAccess' | 'downgraded'
@@ -25,6 +26,7 @@ type EditMemberProps = {
hasExceededCollaboratorLimit: boolean
hasBeenDowngraded: boolean
canAddCollaborators: boolean
isReviewerOnFreeProject?: boolean
}
type Privilege = {
@@ -37,6 +39,7 @@ export default function EditMember({
hasExceededCollaboratorLimit,
hasBeenDowngraded,
canAddCollaborators,
isReviewerOnFreeProject,
}: EditMemberProps) {
const [privileges, setPrivileges] = useState<PermissionsOption>(
member.privileges
@@ -144,7 +147,7 @@ export default function EditMember({
}}
>
<OLFormGroup className="project-member row">
<OLCol xs={7}>
<OLCol xs={8}>
<div className="project-member-email-icon">
<MaterialIcon
type={
@@ -179,11 +182,26 @@ export default function EditMember({
})}
</div>
)}
{isReviewerOnFreeProject && (
<div className="small">
<Trans
i18nKey="comment_only_upgrade_to_enable_track_changes"
components={[
// eslint-disable-next-line react/jsx-key
<OLButton
variant="link"
className="btn-inline-link"
onClick={() => upgradePlan('track-changes')}
/>,
]}
/>
</div>
)}
</div>
</div>
</OLCol>
<OLCol xs={5} className="project-member-actions">
<OLCol xs={4} className="project-member-actions">
{confirmRemoval && (
<ChangePrivilegesActions
handleReset={() => setPrivileges(member.privileges)}

View File

@@ -117,6 +117,9 @@ export default function ShareModalBody() {
member.pendingEditor || member.pendingReviewer
)}
canAddCollaborators={canAddCollaborators}
isReviewerOnFreeProject={
member.privileges === 'review' && !features.trackChanges
}
/>
) : (
<ViewMember key={member._id} member={member} />

View File

@@ -348,6 +348,7 @@
"comment": "Comment",
"comment_only": "Comment only",
"comment_only_upgrade_for_track_changes": "Comment only. Upgrade for track changes.",
"comment_only_upgrade_to_enable_track_changes": "Comment only. <0>Upgrade</0> to enable track changes.",
"common": "Common",
"common_causes_of_compile_timeouts_include": "Common causes of compile timeouts include",
"commons_plan_tooltip": "Youre on the __plan__ plan because of your affiliation with __institution__. Click to find out how to make the most of your Overleaf premium features.",

View File

@@ -700,7 +700,7 @@ describe('<ShareProjectModal/>', function () {
const viewerOption = screen.getByText('Viewer').closest('button')
expect(editorOption.classList.contains('disabled')).to.be.true
expect(reviewerOption.classList.contains('disabled')).to.be.false
expect(reviewerOption.classList.contains('disabled')).to.be.true
expect(viewerOption.classList.contains('disabled')).to.be.false
screen.getByText(
@@ -737,7 +737,7 @@ describe('<ShareProjectModal/>', function () {
const viewerOption = screen.getByText('Viewer').closest('button')
expect(editorOption.classList.contains('disabled')).to.be.true
expect(reviewerOption.classList.contains('disabled')).to.be.false
expect(reviewerOption.classList.contains('disabled')).to.be.true
expect(viewerOption.classList.contains('disabled')).to.be.false
screen.getByText(