diff --git a/services/web/app/src/Features/Project/ProjectController.mjs b/services/web/app/src/Features/Project/ProjectController.mjs
index 75bb479fa1..de991e6297 100644
--- a/services/web/app/src/Features/Project/ProjectController.mjs
+++ b/services/web/app/src/Features/Project/ProjectController.mjs
@@ -17,6 +17,7 @@ import { User } from '../../models/User.mjs'
import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs'
import SubscriptionHelper from '../Subscription/SubscriptionHelper.mjs'
import LimitationsManager from '../Subscription/LimitationsManager.mjs'
+import { isProfessionalGroupPlan } from '../Subscription/PlansHelper.mjs'
import Settings from '@overleaf/settings'
import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
import InactiveProjectManager from '../InactiveData/InactiveProjectManager.mjs'
@@ -932,6 +933,9 @@ const _ProjectController = {
planCode,
planName: planDetails?.name,
isAnnualPlan: planCode && planDetails?.annual,
+ isProfessionalGroupPlan: Boolean(
+ subscription && isProfessionalGroupPlan(subscription)
+ ),
isMemberOfGroupSubscription: userIsMemberOfGroupSubscription,
hasInstitutionLicence: userHasInstitutionLicence,
},
diff --git a/services/web/frontend/js/features/share-project-modal/components/give-feedback-link.tsx b/services/web/frontend/js/features/share-project-modal/components/give-feedback-link.tsx
new file mode 100644
index 0000000000..2199c0b8e0
--- /dev/null
+++ b/services/web/frontend/js/features/share-project-modal/components/give-feedback-link.tsx
@@ -0,0 +1,25 @@
+import { useTranslation } from 'react-i18next'
+import OLButton from '@/shared/components/ol/ol-button'
+import getMeta from '@/utils/meta'
+
+export default function GiveFeedbackLink() {
+ const { t } = useTranslation()
+ const isProfessionalGroupPlan = getMeta('ol-user')?.isProfessionalGroupPlan
+
+ const link = isProfessionalGroupPlan
+ ? 'https://forms.gle/rz1JDMuNajWG4ZY49'
+ : 'https://forms.gle/WLEjzG4Ayp8zFscM9'
+
+ return (
+
+ {t('give_feedback')}
+
+ )
+}
diff --git a/services/web/frontend/js/features/share-project-modal/components/share-project-modal-content.tsx b/services/web/frontend/js/features/share-project-modal/components/share-project-modal-content.tsx
index a45b21f3c4..a26de262d0 100644
--- a/services/web/frontend/js/features/share-project-modal/components/share-project-modal-content.tsx
+++ b/services/web/frontend/js/features/share-project-modal/components/share-project-modal-content.tsx
@@ -15,6 +15,7 @@ import OLButton from '@/shared/components/ol/ol-button'
import OLSpinner from '@/shared/components/ol/ol-spinner'
import MaterialIcon from '@/shared/components/material-icon'
import ErrorMessage from '@/features/share-project-modal/components/error-message'
+import GiveFeedbackLink from '@/features/share-project-modal/components/give-feedback-link'
import classNames from 'classnames'
import { useFeatureFlag } from '@/shared/context/split-test-context'
import { useShareProjectContext } from '@/features/share-project-modal/components/share-project-modal'
@@ -49,8 +50,7 @@ export default function ShareProjectModalContent({
const isSharingUpdatesEnabled = useFeatureFlag('sharing-updates')
const [isInvitedPeopleScreen, setIsInvitedPeopleScreen] = useState(false)
const { successActionMessage } = useShareProjectContext()
-
- const { isRestrictedTokenMember } = useEditorContext()
+ const { isRestrictedTokenMember, isProjectOwner } = useEditorContext()
return (
@@ -71,6 +71,7 @@ export default function ShareProjectModalContent({
: t('share_project')}
)}
+ {isSharingUpdatesEnabled && isProjectOwner && }
diff --git a/services/web/test/frontend/features/share-project-modal/components/share-project-modal.test.tsx b/services/web/test/frontend/features/share-project-modal/components/share-project-modal.test.tsx
index a7671307fb..01146fecea 100644
--- a/services/web/test/frontend/features/share-project-modal/components/share-project-modal.test.tsx
+++ b/services/web/test/frontend/features/share-project-modal/components/share-project-modal.test.tsx
@@ -1053,6 +1053,15 @@ describe('', function () {
})
})
+ it('does not show the "Give feedback" link when the "sharing-updates" feature flag is disabled', async function () {
+ renderWithEditorContext(
+ ,
+ createContextProps()
+ )
+
+ expect(screen.queryByRole('link', { name: 'Give feedback' })).to.be.null
+ })
+
describe('with "sharing-updates" feature flag', function () {
beforeEach(function () {
window.metaAttributesCache.set('ol-splitTestVariants', {
@@ -1174,5 +1183,64 @@ describe('', function () {
await screen.findByText('Invitation(s) sent.')
})
+
+ it('shows the "Give feedback" link for the project owner', async function () {
+ renderWithEditorContext(
+ ,
+ createContextProps()
+ )
+
+ await screen.findByRole('link', { name: 'Give feedback' })
+ })
+
+ it('does not show the "Give feedback" link for non-owners', async function () {
+ renderWithEditorContext(, {
+ ...createContextProps(),
+ user: {
+ id: 'non-project-owner',
+ email: 'non-project-owner@example.com',
+ },
+ })
+
+ expect(screen.queryByRole('link', { name: 'Give feedback' })).to.be.null
+ })
+
+ describe('"Give feedback" link URL based on subscription plan', function () {
+ it('links to the professional feedback URL when the user has a professional group plan', async function () {
+ renderWithEditorContext(, {
+ ...createContextProps(),
+ user: {
+ id: USER_ID,
+ email: USER_EMAIL,
+ isProfessionalGroupPlan: true,
+ },
+ })
+
+ const feedbackLink = await screen.findByRole('link', {
+ name: 'Give feedback',
+ })
+ expect(feedbackLink.getAttribute('href')).to.equal(
+ 'https://forms.gle/rz1JDMuNajWG4ZY49'
+ )
+ })
+
+ it('links to the standard feedback URL when the user does not have a professional group plan', async function () {
+ renderWithEditorContext(, {
+ ...createContextProps(),
+ user: {
+ id: USER_ID,
+ email: USER_EMAIL,
+ isProfessionalGroupPlan: false,
+ },
+ })
+
+ const feedbackLink = await screen.findByRole('link', {
+ name: 'Give feedback',
+ })
+ expect(feedbackLink.getAttribute('href')).to.equal(
+ 'https://forms.gle/WLEjzG4Ayp8zFscM9'
+ )
+ })
+ })
})
})
diff --git a/services/web/test/frontend/helpers/editor-providers.tsx b/services/web/test/frontend/helpers/editor-providers.tsx
index 0330ca63c0..d81e4716e7 100644
--- a/services/web/test/frontend/helpers/editor-providers.tsx
+++ b/services/web/test/frontend/helpers/editor-providers.tsx
@@ -70,7 +70,12 @@ const defaultUserSettings = {
} satisfies UserSettings
export type EditorProvidersProps = {
- user?: { id: string; email: string; signUpDate?: string }
+ user?: {
+ id: string
+ email: string
+ signUpDate?: string
+ isProfessionalGroupPlan?: boolean
+ }
projectId?: string
projectName?: string
projectOwner?: ProjectMetadata['owner']
diff --git a/services/web/types/user.ts b/services/web/types/user.ts
index 071600d33b..ebb9f8eb17 100644
--- a/services/web/types/user.ts
+++ b/services/web/types/user.ts
@@ -62,6 +62,7 @@ export type User = {
planName?: string
isAnnualPlan?: boolean
isMemberOfGroupSubscription?: boolean
+ isProfessionalGroupPlan?: boolean
hasInstitutionLicence?: boolean
}