Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 2c2ec72

Browse files
authored
feat(plg): remove seats from subscription (#63408)
Closes https://github.com/sourcegraph/sourcegraph/issues/63234 [Design](https://www.figma.com/design/FMSdn1oKccJRHQPgf7053o/Cody-PLG-GA?node-id=5556-13856&t=f13ek1ZSgoUdrH6z-0) Adds a button to remove the remaining invites from a subscription. https://github.com/sourcegraph/sourcegraph/assets/25318659/679e19dd-0e0e-4561-8ac1-af1b6979ee73 **Known deviation from design (cc: @rrhyne)** The “Remove User” success message and the “Remove Seats from Subscription” alerts are positioned differently than in the design. The “Remove User” banner, along with other user and invite list alerts, is placed above the users list, below the page title or the invites textbox if rendered. The “Remove Seats from Subscription” banner, along with other invite textbox alerts, is located above the invites textbox instead of above the page title and all the page content. These issues will be addressed in follow-up PRs, as we need to refactor the existing Team Members page layout. Created an issue to address it: - https://github.com/sourcegraph/sourcegraph/issues/63411 <!-- 💡 To write a useful PR description, make sure that your description covers: - WHAT this PR is changing: - How was it PREVIOUSLY. - How it will be from NOW on. - WHY this PR is needed. - CONTEXT, i.e. to which initiative, project or RFC it belongs. The structure of the description doesn't matter as much as covering these points, so use your best judgement based on your context. Learn how to write good pull request description: https://www.notion.so/sourcegraph/Write-a-good-pull-request-description-610a7fd3e613496eb76f450db5a49b6e?pvs=4 --> ## Test plan - Run a Sourcegraph instance in dotcom mode - Sign in as a team admin - Ensure there are free seats on your team (invites remaining) - Ensure "Remove invites from plan" button is rendered - Check the number of invites remaining - Click the button - Ensure the subscription has been updated and now the max seats reduced by the number of remaining invites - Ensure the success banner is rendered <!-- All pull requests REQUIRE a test plan: https://docs-legacy.sourcegraph.com/dev/background-information/testing_principles --> ## Changelog <!-- 1. Ensure your pull request title is formatted as: $type($domain): $what 2. Add bullet list items for each additional detail you want to cover (see example below) 3. You can edit this after the pull request was merged, as long as release shipping it hasn't been promoted to the public. 4. For more information, please see this how-to https://www.notion.so/sourcegraph/Writing-a-changelog-entry-dd997f411d524caabf0d8d38a24a878c? Audience: TS/CSE > Customers > Teammates (in that order). Cheat sheet: $type = chore|fix|feat $domain: source|search|ci|release|plg|cody|local|... --> <!-- Example: Title: fix(search): parse quotes with the appropriate context Changelog section: ## Changelog - When a quote is used with regexp pattern type, then ... - Refactored underlying code. -->
1 parent 78622cb commit 2c2ec72

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

client/web/src/cody/components/CodyAlert.module.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,15 @@
4141
background-color: #51cf66;
4242
}
4343
&::after {
44+
top: calc(50% - 16px);
45+
left: 1.5rem;
46+
/* stylelint-disable-next-line declaration-property-unit-allowed-list */
47+
width: 32px;
48+
/* stylelint-disable-next-line declaration-property-unit-allowed-list */
49+
height: 32px;
4450
// Green checkmark SVG
4551
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 31 25'><path fill='%23319E44' d='M27 .4a3.4 3.4 0 0 0-2.4 1.1L12 15.6 7 9.3a3.4 3.4 0 0 0-5-.6 3.4 3.4 0 0 0-.5 4.9L9.2 23a3.4 3.4 0 0 0 5.3.1l15.2-17a3.4 3.4 0 0 0-.3-4.9 3.4 3.4 0 0 0-2.5-.8Z'/></svg>");
52+
background-repeat: no-repeat;
4653
}
4754
}
4855

client/web/src/cody/invites/InviteUsers.tsx

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import React, { useState, useCallback, useMemo } from 'react'
22

33
import { pluralize } from '@sourcegraph/common'
44
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
5-
import { ButtonLink, H2, Link, Text, H3, TextArea } from '@sourcegraph/wildcard'
5+
import { H2, Link, Text, H3, TextArea, Button, H1 } from '@sourcegraph/wildcard'
66

77
import { CodyAlert } from '../components/CodyAlert'
88
import { CodyContainer } from '../components/CodyContainer'
99
import { CodyProBadgeDeck } from '../components/CodyProBadgeDeck'
1010
import { useSendInvite, useTeamInvites } from '../management/api/react-query/invites'
11-
import { useCurrentSubscription } from '../management/api/react-query/subscriptions'
11+
import { useCurrentSubscription, useUpdateCurrentSubscription } from '../management/api/react-query/subscriptions'
1212
import { useTeamMembers } from '../management/api/react-query/teams'
1313
import type { SubscriptionSummary } from '../management/api/teamSubscriptions'
1414
import { isValidEmailAddress } from '../util'
@@ -39,6 +39,7 @@ export const InviteUsers: React.FunctionComponent<InviteUsersProps> = ({ telemet
3939
const [emailAddressErrorMessage, setEmailAddressErrorMessage] = useState<string | null>(null)
4040

4141
const sendInviteMutation = useSendInvite()
42+
const updateSubscriptionMutation = useUpdateCurrentSubscription()
4243

4344
const verifyEmailList = useCallback((): Error | void => {
4445
if (emailAddresses.length === 0) {
@@ -104,10 +105,23 @@ export const InviteUsers: React.FunctionComponent<InviteUsersProps> = ({ telemet
104105
})
105106
}, [emailAddresses, sendInviteMutation.mutateAsync, teamId, telemetryRecorder, verifyEmailList])
106107

107-
if (!isAdmin || !remainingInviteCount) {
108+
if (updateSubscriptionMutation.isSuccess) {
109+
return (
110+
<CodyAlert variant="greenSuccess">
111+
<H1 as="p" className="mb-2">
112+
Remaining invites removed from plan
113+
</H1>
114+
<Text className="mb-0">You can add more seats at any time with the "Add seats" button.</Text>
115+
</CodyAlert>
116+
)
117+
}
118+
119+
if (!isAdmin || !remainingInviteCount || !subscriptionQueryResult.data) {
108120
return null
109121
}
110122

123+
const { maxSeats } = subscriptionQueryResult.data
124+
111125
return (
112126
<>
113127
{sendInviteMutation.status === 'success' && (
@@ -153,15 +167,33 @@ export const InviteUsers: React.FunctionComponent<InviteUsersProps> = ({ telemet
153167
isValid={emailAddressErrorMessage ? false : undefined}
154168
/>
155169
{emailAddressErrorMessage ? (
156-
<Text className="text-danger mb-2">{emailAddressErrorMessage}</Text>
170+
<Text className="text-danger">{emailAddressErrorMessage}</Text>
157171
) : (
158-
<Text className="text-muted mb-2">Enter email addresses separated by a comma.</Text>
172+
<Text className="text-muted">Enter email addresses separated by a comma.</Text>
159173
)}
160174

161175
<div>
162-
<ButtonLink variant="success" size="sm" onSelect={onSendInvitesClicked}>
176+
<Button
177+
disabled={updateSubscriptionMutation.isPending || sendInviteMutation.isPending}
178+
variant="success"
179+
onClick={onSendInvitesClicked}
180+
className="mr-2"
181+
>
163182
Send
164-
</ButtonLink>
183+
</Button>
184+
<Button
185+
variant="link"
186+
disabled={updateSubscriptionMutation.isPending || sendInviteMutation.isPending}
187+
onClick={() =>
188+
updateSubscriptionMutation.mutate({
189+
subscriptionUpdate: {
190+
newSeatCount: maxSeats - remainingInviteCount,
191+
},
192+
})
193+
}
194+
>
195+
Remove invites from plan
196+
</Button>
165197
</div>
166198
</div>
167199
</div>

0 commit comments

Comments
 (0)