From cbe5cefb9a0eb29ecd9a802d38bac3a1262f443d Mon Sep 17 00:00:00 2001 From: Jessica Lawshe <5312836+lawshe@users.noreply.github.com> Date: Thu, 30 May 2024 07:35:56 -0500 Subject: [PATCH] Merge pull request #18161 from overleaf/jel-subscription-dash-admin [web] Subscription dash message when viewing as admin GitOrigin-RevId: 699a523d7ac8d1a71e9ba14c7b8a66b39142958a --- .../web/frontend/extracted-translations.json | 2 + .../dashboard/managed-group-subscriptions.tsx | 114 ++++++++++++------ services/web/locales/en.json | 6 +- .../managed-group-subscriptions.test.tsx | 78 ++++++++++-- .../subscription/dashboard/subscription.ts | 8 +- 5 files changed, 156 insertions(+), 52 deletions(-) diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index ccb705a800..78a04abb44 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -1581,9 +1581,11 @@ "you": "", "you_already_have_a_subscription": "", "you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "", + "you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "", "you_are_a_manager_of_commons_at_institution_x": "", "you_are_a_manager_of_publisher_x": "", "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "", + "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "", "you_are_on_a_paid_plan_contact_support_to_find_out_more": "", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "", "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "", diff --git a/services/web/frontend/js/features/subscription/components/dashboard/managed-group-subscriptions.tsx b/services/web/frontend/js/features/subscription/components/dashboard/managed-group-subscriptions.tsx index b7960b8d92..0742eb9a9a 100644 --- a/services/web/frontend/js/features/subscription/components/dashboard/managed-group-subscriptions.tsx +++ b/services/web/frontend/js/features/subscription/components/dashboard/managed-group-subscriptions.tsx @@ -3,6 +3,84 @@ import getMeta from '@/utils/meta' import { Trans, useTranslation } from 'react-i18next' import { useSubscriptionDashboardContext } from '../../context/subscription-dashboard-context' import { RowLink } from './row-link' +import { ManagedGroupSubscription } from '../../../../../../types/subscription/dashboard/subscription' + +function ManagedGroupAdministrator({ + subscription, +}: { + subscription: ManagedGroupSubscription +}) { + const usersEmail = getMeta('ol-usersEmail') as string + const values = { + planName: subscription.planLevelName, + groupName: subscription.teamName || '', + adminEmail: subscription.admin_id.email, + } + + const isAdmin = usersEmail === subscription.admin_id.email + + if (subscription.userIsGroupMember && !isAdmin) { + return ( + , + // eslint-disable-next-line react/jsx-key + , + ]} + values={values} + shouldUnescape + tOptions={{ interpolation: { escapeValue: true } }} + /> + ) + } else if (subscription.userIsGroupMember && isAdmin) { + return ( + , + // eslint-disable-next-line react/jsx-key + , + ]} + values={values} + shouldUnescape + tOptions={{ interpolation: { escapeValue: true } }} + /> + ) + } else if (isAdmin) { + return ( + , + // eslint-disable-next-line react/jsx-key + , + ]} + values={values} + shouldUnescape + tOptions={{ interpolation: { escapeValue: true } }} + /> + ) + } + + return ( + , + // eslint-disable-next-line react/jsx-key + , + ]} + values={values} + shouldUnescape + tOptions={{ interpolation: { escapeValue: true } }} + /> + ) +} export default function ManagedGroupSubscriptions() { const { t } = useTranslation() @@ -23,41 +101,7 @@ export default function ManagedGroupSubscriptions() { return (

- {subscription.userIsGroupMember ? ( - , - // eslint-disable-next-line react/jsx-key - , - ]} - values={{ - planName: subscription.planLevelName, - groupName: subscription.teamName || '', - adminEmail: subscription.admin_id.email, - }} - shouldUnescape - tOptions={{ interpolation: { escapeValue: true } }} - /> - ) : ( - , - // eslint-disable-next-line react/jsx-key - , - ]} - values={{ - planName: subscription.planLevelName, - groupName: subscription.teamName || '', - adminEmail: subscription.admin_id.email, - }} - shouldUnescape - tOptions={{ interpolation: { escapeValue: true } }} - /> - )} +

manager and <1>member of the <0>__planName__ group subscription <1>__groupName__ administered by <1>__adminEmail__", + "you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager and <1>member of the <0>__planName__ group subscription <1>__groupName__ administered by <1>__adminEmail__.", + "you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "You are a <1>manager and <1>member of the <0>__planName__ group subscription <1>__groupName__ administered by <1>you (__adminEmail__).", "you_are_a_manager_of_commons_at_institution_x": "You are a <0>manager of the Overleaf Commons subscription at <0>__institutionName__", "you_are_a_manager_of_publisher_x": "You are a <0>manager of <0>__publisherName__", - "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager of the <0>__planName__ group subscription <1>__groupName__ administered by <1>__adminEmail__", + "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager of the <0>__planName__ group subscription <1>__groupName__ administered by <1>__adminEmail__.", + "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "You are a <1>manager of the <0>__planName__ group subscription <1>__groupName__ administered by <1>you (__adminEmail__).", "you_are_currently_logged_in_as": "You are currently logged in as __email__.", "you_are_on_a_paid_plan_contact_support_to_find_out_more": "You’re on an __appName__ Paid plan. <0>Contact support to find out more.", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "You are on our <0>__planName__ plan as a <1>confirmed member of <1>__institutionName__", diff --git a/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx index 7521f94126..b9b550db84 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx @@ -1,49 +1,78 @@ import { expect } from 'chai' import { screen } from '@testing-library/react' -import { - groupActiveSubscription, - groupActiveSubscriptionWithPendingLicenseChange, -} from '../../fixtures/subscriptions' import ManagedGroupSubscriptions from '../../../../../../frontend/js/features/subscription/components/dashboard/managed-group-subscriptions' import { ManagedGroupSubscription } from '../../../../../../types/subscription/dashboard/subscription' import { cleanUpContext, renderWithSubscriptionDashContext, } from '../../helpers/render-with-subscription-dash-context' -import { UserId } from '../../../../../../types/user' function getManagedGroupSubscriptions( groupSSO: boolean | null, managedUsers: boolean | null ): ManagedGroupSubscription[] { const subscriptionOne = { - ...groupActiveSubscription, + _id: 'bcd567', userIsGroupMember: true, planLevelName: 'Professional', admin_id: { - id: 'abc123abc123' as UserId, email: 'you@example.com', }, features: { groupSSO, managedUsers, }, + teamName: 'GAS', } const subscriptionTwo = { - ...groupActiveSubscriptionWithPendingLicenseChange, + _id: 'def456', userIsGroupMember: false, planLevelName: 'Collaborator', admin_id: { - id: 'bcd456bcd456' as UserId, email: 'someone@example.com', }, features: { groupSSO, managedUsers, }, + teamName: 'GASWPLC', } - return [subscriptionOne, subscriptionTwo] + + const subscriptionMemberAndAdmin = { + _id: 'group2abc', + userIsGroupMember: true, + planLevelName: 'Collaborator', + admin_id: { + email: 'admin@example.com', + }, + features: { + groupSSO, + managedUsers, + }, + teamName: 'Testing', + } + + const subscriptionAdmin = { + _id: 'group123abc', + userIsGroupMember: false, + planLevelName: 'Collaborator', + admin_id: { + email: 'admin@example.com', + }, + features: { + groupSSO, + managedUsers, + }, + teamName: 'Testing Another', + } + + return [ + subscriptionOne, + subscriptionTwo, + subscriptionMemberAndAdmin, + subscriptionAdmin, + ] } const managedGroupSubscriptions: ManagedGroupSubscription[] = @@ -69,18 +98,25 @@ describe('', function () { name: 'ol-managedGroupSubscriptions', value: managedGroupSubscriptions, }, + { name: 'ol-usersEmail', value: 'admin@example.com' }, ], }) const elements = screen.getAllByText('You are a', { exact: false, }) - expect(elements.length).to.equal(2) + expect(elements.length).to.equal(4) expect(elements[0].textContent).to.equal( - 'You are a manager and member of the Professional group subscription GAS administered by you@example.com' + 'You are a manager and member of the Professional group subscription GAS administered by you@example.com.' ) expect(elements[1].textContent).to.equal( - 'You are a manager of the Collaborator group subscription GASWPLC administered by someone@example.com' + 'You are a manager of the Collaborator group subscription GASWPLC administered by someone@example.com.' + ) + expect(elements[2].textContent).to.equal( + 'You are a manager and member of the Collaborator group subscription Testing administered by you (admin@example.com).' + ) + expect(elements[3].textContent).to.equal( + 'You are a manager of the Collaborator group subscription Testing Another administered by you (admin@example.com).' ) const links = screen.getAllByRole('link') @@ -98,6 +134,22 @@ describe('', function () { '/manage/groups/def456/managers' ) expect(links[7].getAttribute('href')).to.equal('/metrics/groups/def456') + expect(links[9].getAttribute('href')).to.equal( + '/manage/groups/group2abc/members' + ) + expect(links[10].getAttribute('href')).to.equal( + '/manage/groups/group2abc/managers' + ) + expect(links[11].getAttribute('href')).to.equal('/metrics/groups/group2abc') + expect(links[13].getAttribute('href')).to.equal( + '/manage/groups/group123abc/members' + ) + expect(links[14].getAttribute('href')).to.equal( + '/manage/groups/group123abc/managers' + ) + expect(links[15].getAttribute('href')).to.equal( + '/metrics/groups/group123abc' + ) }) it('renders nothing when there are no group memberships', function () { diff --git a/services/web/types/subscription/dashboard/subscription.ts b/services/web/types/subscription/dashboard/subscription.ts index 8bcef0f908..b3c9b351a1 100644 --- a/services/web/types/subscription/dashboard/subscription.ts +++ b/services/web/types/subscription/dashboard/subscription.ts @@ -73,14 +73,18 @@ export type GroupSubscription = RecurlySubscription & { teamNotice?: string } -export type ManagedGroupSubscription = Omit & { +export type ManagedGroupSubscription = { + _id: string userIsGroupMember: boolean planLevelName: string - admin_id: User + admin_id: { + email: string + } features: { groupSSO: boolean | null managedUsers: boolean | null } + teamName?: string } export type MemberGroupSubscription = Omit & {