From e0d77271c28f88bab2539170326116f055408fca Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 15 Jul 2026 12:12:26 +0200 Subject: [PATCH] Merge pull request #35452 from overleaf/tm-commons-ai-label [WEB] Show "Commons AI" label when the AI assist bundle is active GitOrigin-RevId: f49722b94be9b12c7ed5f031dc98182e3a761273 --- .../web/frontend/extracted-translations.json | 1 + .../current-plan-widget/commons-plan.tsx | 3 ++ .../settings/components/emails/email.tsx | 7 +++- .../dashboard/institution-memberships.tsx | 7 ++-- .../dashboard/states/active/active.tsx | 4 ++- services/web/locales/da.json | 2 +- services/web/locales/de.json | 2 +- services/web/locales/en.json | 3 +- services/web/locales/fr.json | 2 +- services/web/locales/zh-CN.json | 2 +- .../components/current-plan-widget.test.tsx | 32 +++++++++++++++++++ .../components/emails/emails-section.test.tsx | 22 ++++++++++++- .../institution-memberships.test.tsx | 19 +++++++++++ .../types/project/dashboard/subscription.ts | 5 ++- 14 files changed, 100 insertions(+), 11 deletions(-) diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 96fdb893f0..229002342b 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -333,6 +333,7 @@ "comment_only_upgrade_to_enable_track_changes": "", "common": "", "commons": "", + "commons_ai": "", "commons_plan_tooltip": "", "compact": "", "company_name": "", diff --git a/services/web/frontend/js/features/project-list/components/current-plan-widget/commons-plan.tsx b/services/web/frontend/js/features/project-list/components/current-plan-widget/commons-plan.tsx index 94a89c646c..920d39d0ae 100644 --- a/services/web/frontend/js/features/project-list/components/current-plan-widget/commons-plan.tsx +++ b/services/web/frontend/js/features/project-list/components/current-plan-widget/commons-plan.tsx @@ -22,6 +22,9 @@ function CommonsPlan({ featuresPageURL, subscription }: CommonsPlanProps) { {currentPlanLabel} )} {hasInstitutionalSubscription && ( - {t('commons')} + + {hasCommonsAI ? t('commons_ai') : t('commons')} + )} )} diff --git a/services/web/frontend/js/features/subscription/components/dashboard/institution-memberships.tsx b/services/web/frontend/js/features/subscription/components/dashboard/institution-memberships.tsx index 2356a3e8ec..bd86367b5d 100644 --- a/services/web/frontend/js/features/subscription/components/dashboard/institution-memberships.tsx +++ b/services/web/frontend/js/features/subscription/components/dashboard/institution-memberships.tsx @@ -1,9 +1,10 @@ -import { Trans } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' import { Institution } from '../../../../../../types/institution' import { useSubscriptionDashboardContext } from '../../context/subscription-dashboard-context' import Notification from '@/shared/components/notification' function InstitutionMemberships() { + const { t } = useTranslation() const { institutionMemberships } = useSubscriptionDashboardContext() // memberships is undefined when data failed to load. If user has no memberships, then an empty array is returned @@ -34,7 +35,9 @@ function InstitutionMemberships() { 0) { - planName = 'Overleaf Commons' + planName = institutionMemberships.some(m => m.writefullCommonsAccount) + ? `Overleaf ${t('commons_ai')}` + : `Overleaf ${t('commons')}` } if (memberGroupSubscriptions.length > 0) { if (memberGroupSubscriptions.some(s => s.planLevelName === 'Pro')) { diff --git a/services/web/locales/da.json b/services/web/locales/da.json index 1d80672e72..55a43507d9 100644 --- a/services/web/locales/da.json +++ b/services/web/locales/da.json @@ -266,7 +266,7 @@ "column_width_is_x_click_to_resize": "Kolonnebredden er __width__. Klik for at ændre", "comment": "Kommentar", "common": "Almindelig", - "commons_plan_tooltip": "Du er på Commons abonnementet gennem din tilknytning til __institution__. Klik for at finde ud af hvordan du bedst udnytter dine Overlaf Premium-funktioner.", + "commons_plan_tooltip": "Du er på __plan__ abonnementet gennem din tilknytning til __institution__. Klik for at finde ud af hvordan du bedst udnytter dine Overlaf Premium-funktioner.", "compact": "Kompakt", "company_name": "Virksomhedsnavn", "compare": "Sammenlign", diff --git a/services/web/locales/de.json b/services/web/locales/de.json index 61f64dff81..3134981b50 100644 --- a/services/web/locales/de.json +++ b/services/web/locales/de.json @@ -306,7 +306,7 @@ "comment": "Kommentar", "comment_only": "Nur Kommentare", "common": "Häufige", - "commons_plan_tooltip": "Du hast Zugriff auf ein Commons Abonnement über deine Angehörigkeit bei __institution__. Klicke hier um herauszufinden was die Overleaf Premiumfunktionen Dir ermöglichen.", + "commons_plan_tooltip": "Du hast Zugriff auf ein __plan__ Abonnement über deine Angehörigkeit bei __institution__. Klicke hier um herauszufinden was die Overleaf Premiumfunktionen Dir ermöglichen.", "compact": "Kompakt", "company_name": "Firmenname", "compare": "Vergleichen", diff --git a/services/web/locales/en.json b/services/web/locales/en.json index d8e5b619a2..9714f48750 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -431,7 +431,8 @@ "comment_only_upgrade_to_enable_track_changes": "Comment only. <0>Upgrade to enable track changes.", "common": "Common", "commons": "Commons", - "commons_plan_tooltip": "You’re on the Commons plan provided by __institution__. Click to find out how to make the most of your Overleaf premium features.", + "commons_ai": "Commons AI", + "commons_plan_tooltip": "You’re on the __plan__ plan provided by __institution__. Click to find out how to make the most of your Overleaf premium features.", "community_articles": "Community articles", "community_articles_lowercase": "community articles", "compact": "Compact", diff --git a/services/web/locales/fr.json b/services/web/locales/fr.json index 9ce39d5c55..5531cf1cbc 100644 --- a/services/web/locales/fr.json +++ b/services/web/locales/fr.json @@ -222,7 +222,7 @@ "column_width_is_x_click_to_resize": "La largeur de la colonne est __width__. Cliquez pour redimensionner", "comment": "Commentaire", "common": "Commun", - "commons_plan_tooltip": "Vous bénéficiez de l’offre Commons en raison de votre affiliation avec __institution__. Cliquez pour découvrir comment profiter au mieux de vos fonctionnalités Overleaf premium.", + "commons_plan_tooltip": "Vous bénéficiez de l’offre __plan__ en raison de votre affiliation avec __institution__. Cliquez pour découvrir comment profiter au mieux de vos fonctionnalités Overleaf premium.", "compact": "Compact", "company_name": "Nom de l’entreprise", "comparing_from_x_to_y": "Différence entre <0>__startTime__ et <0>__endTime__", diff --git a/services/web/locales/zh-CN.json b/services/web/locales/zh-CN.json index 906f76f7ad..5788711be0 100644 --- a/services/web/locales/zh-CN.json +++ b/services/web/locales/zh-CN.json @@ -310,7 +310,7 @@ "comment_only_upgrade_for_track_changes": "仅评论。升级可跟踪更改。", "comment_only_upgrade_to_enable_track_changes": "仅评论。<0>升级以启用跟踪更改。", "common": "通用", - "commons_plan_tooltip": "由于您与 __institution__ 的隶属关系,您加入了 Commons 计划。 单击以了解如何充分利用 Overleaf 高级功能。", + "commons_plan_tooltip": "由于您与 __institution__ 的隶属关系,您加入了 __plan__ 计划。 单击以了解如何充分利用 Overleaf 高级功能。", "community_articles": "社区文章", "community_articles_lowercase": "社区文章", "compact": "紧凑的", diff --git a/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx b/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx index 53910062d2..3862b822c6 100644 --- a/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx +++ b/services/web/test/frontend/features/project-list/components/current-plan-widget.test.tsx @@ -295,6 +295,38 @@ describe('', function () { }) await screen.findByRole('tooltip', { name: paidPlanTooltipMessage }) }) + + it('shows the Commons AI label when institution has writefull commons', async function () { + const subscription = { + type: 'commons', + plan: { + name: 'Abc', + }, + subscription: { + name: 'Example Name', + writefullCommonsAccount: true, + }, + } as DeepReadonly + + window.metaAttributesCache.set('ol-usersBestSubscription', { + ...subscription, + }) + + render() + + const link = screen.getByRole('link', { + name: /you’re using overleaf premium/i, + }) + fireEvent.mouseOver(link) + + await screen.findByRole('tooltip', { + name: new RegExp( + `on the Commons AI plan provided by ${subscription.subscription.name}`, + 'i' + ), + }) + await screen.findByRole('tooltip', { name: paidPlanTooltipMessage }) + }) }) }) diff --git a/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx b/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx index 746a4c6ead..5505d66ac3 100644 --- a/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx +++ b/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx @@ -118,7 +118,27 @@ describe('', function () { const node = await screen.findByText(professionalUserData.email, { exact: false, }) - expect(within(node).getByText(/commons/i)).to.exist + expect(within(node).getByText('Commons')).to.exist + }) + + it('renders commons AI label when institution has writefull commons', async function () { + const commonsAIUserData = { + ...professionalUserData, + affiliation: { + ...professionalUserData.affiliation, + institution: { + ...professionalUserData.affiliation.institution, + writefullCommonsAccount: true, + }, + }, + } + fetchMock.get('/user/emails?ensureAffiliation=true', [commonsAIUserData]) + renderEmailsSection() + + const node = await screen.findByText(commonsAIUserData.email, { + exact: false, + }) + expect(within(node).getByText('Commons AI')).to.exist }) it('shows loader when resending email', async function () { diff --git a/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx index c5933163e9..ebdeac5138 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx @@ -58,6 +58,25 @@ describe('', function () { ) }) + it('renders the Commons AI label when the institution has writefull commons', function () { + const commonsAIMemberships: Institution[] = [ + { ...memberships[0], writefullCommonsAccount: true }, + ] + renderWithSubscriptionDashContext(, { + metaTags: [ + { + name: 'ol-currentInstitutionsWithLicence', + value: commonsAIMemberships, + }, + ], + }) + + const element = screen.getByText('You are on our', { exact: false }) + expect(element.textContent).to.equal( + 'You are on our Commons AI plan as a confirmed member of Test University' + ) + }) + it('renders error message when failed to check commons licenses', function () { renderWithSubscriptionDashContext() screen.getByText( diff --git a/services/web/types/project/dashboard/subscription.ts b/services/web/types/project/dashboard/subscription.ts index c8f8835b34..0c9390cfaa 100644 --- a/services/web/types/project/dashboard/subscription.ts +++ b/services/web/types/project/dashboard/subscription.ts @@ -41,7 +41,10 @@ export type GroupPlanSubscription = { export type CommonsPlanSubscription = { type: 'commons' -} & PaidSubscriptionBase + subscription: PaidSubscriptionBase['subscription'] & { + writefullCommonsAccount?: boolean + } +} & Omit type PaidSubscription = | IndividualPlanSubscription