فهرست منبع

Merge pull request #18161 from overleaf/jel-subscription-dash-admin

[web] Subscription dash message when viewing as admin

GitOrigin-RevId: 699a523d7ac8d1a71e9ba14c7b8a66b39142958a
Jessica Lawshe 2 سال پیش
والد
کامیت
cbe5cefb9a

+ 2 - 0
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": "",

+ 79 - 35
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 (
+      <Trans
+        i18nKey="you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z"
+        components={[
+          // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
+          <a href="/user/subscription/plans" />,
+          // eslint-disable-next-line react/jsx-key
+          <strong />,
+        ]}
+        values={values}
+        shouldUnescape
+        tOptions={{ interpolation: { escapeValue: true } }}
+      />
+    )
+  } else if (subscription.userIsGroupMember && isAdmin) {
+    return (
+      <Trans
+        i18nKey="you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you"
+        components={[
+          // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
+          <a href="/user/subscription/plans" />,
+          // eslint-disable-next-line react/jsx-key
+          <strong />,
+        ]}
+        values={values}
+        shouldUnescape
+        tOptions={{ interpolation: { escapeValue: true } }}
+      />
+    )
+  } else if (isAdmin) {
+    return (
+      <Trans
+        i18nKey="you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you"
+        components={[
+          // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
+          <a href="/user/subscription/plans" />,
+          // eslint-disable-next-line react/jsx-key
+          <strong />,
+        ]}
+        values={values}
+        shouldUnescape
+        tOptions={{ interpolation: { escapeValue: true } }}
+      />
+    )
+  }
+
+  return (
+    <Trans
+      i18nKey="you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z"
+      components={[
+        // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
+        <a href="/user/subscription/plans" />,
+        // eslint-disable-next-line react/jsx-key
+        <strong />,
+      ]}
+      values={values}
+      shouldUnescape
+      tOptions={{ interpolation: { escapeValue: true } }}
+    />
+  )
+}
 
 export default function ManagedGroupSubscriptions() {
   const { t } = useTranslation()
@@ -23,41 +101,7 @@ export default function ManagedGroupSubscriptions() {
         return (
           <div key={`managed-group-${subscription._id}`}>
             <p>
-              {subscription.userIsGroupMember ? (
-                <Trans
-                  i18nKey="you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z"
-                  components={[
-                    // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
-                    <a href="/user/subscription/plans" />,
-                    // eslint-disable-next-line react/jsx-key
-                    <strong />,
-                  ]}
-                  values={{
-                    planName: subscription.planLevelName,
-                    groupName: subscription.teamName || '',
-                    adminEmail: subscription.admin_id.email,
-                  }}
-                  shouldUnescape
-                  tOptions={{ interpolation: { escapeValue: true } }}
-                />
-              ) : (
-                <Trans
-                  i18nKey="you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z"
-                  components={[
-                    // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
-                    <a href="/user/subscription/plans" />,
-                    // eslint-disable-next-line react/jsx-key
-                    <strong />,
-                  ]}
-                  values={{
-                    planName: subscription.planLevelName,
-                    groupName: subscription.teamName || '',
-                    adminEmail: subscription.admin_id.email,
-                  }}
-                  shouldUnescape
-                  tOptions={{ interpolation: { escapeValue: true } }}
-                />
-              )}
+              <ManagedGroupAdministrator subscription={subscription} />
             </p>
             <RowLink
               href={`/manage/groups/${subscription._id}/members`}

+ 4 - 2
services/web/locales/en.json

@@ -2203,10 +2203,12 @@
   "you_already_have_a_subscription": "You already have a subscription",
   "you_and_collaborators_get_access_to": "You and your project collaborators get access to",
   "you_and_collaborators_get_access_to_info": "These features are available to you and your collaborators (other Overleaf users that you invite to your projects).",
-  "you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager</1> and <1>member</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>",
+  "you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager</1> and <1>member</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>.",
+  "you_are_a_manager_and_member_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "You are a <1>manager</1> and <1>member</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>you (__adminEmail__)</1>.",
   "you_are_a_manager_of_commons_at_institution_x": "You are a <0>manager</0> of the Overleaf Commons subscription at <0>__institutionName__</0>",
   "you_are_a_manager_of_publisher_x": "You are a <0>manager</0> of <0>__publisherName__</0>",
-  "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>",
+  "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>.",
+  "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "You are a <1>manager</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>you (__adminEmail__</1>).",
   "you_are_currently_logged_in_as": "You are currently logged in as <b>__email__</b>.",
   "you_are_on_a_paid_plan_contact_support_to_find_out_more": "You’re on an __appName__ Paid plan. <0>Contact support</0> to find out more.",
   "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "You are on our <0>__planName__</0> plan as a <1>confirmed member</1> of <1>__institutionName__</1>",

+ 65 - 13
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('<ManagedGroupSubscriptions />', 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('<ManagedGroupSubscriptions />', 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 () {

+ 6 - 2
services/web/types/subscription/dashboard/subscription.ts

@@ -73,14 +73,18 @@ export type GroupSubscription = RecurlySubscription & {
   teamNotice?: string
 }
 
-export type ManagedGroupSubscription = Omit<GroupSubscription, 'admin_id'> & {
+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<GroupSubscription, 'admin_id'> & {