Skip to content

Commit bdceb69

Browse files
committed
Disable remove button with tooltip
1 parent dc5c8fd commit bdceb69

3 files changed

Lines changed: 57 additions & 20 deletions

File tree

packages/localizations/src/en-US.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ export const enUS: LocalizationResource = {
282282
badge__verified: 'Verified',
283283
badge__unverified: 'Unverified',
284284
verifiedAtLabel: "Verified on {{ date | shortDate('en-US') }}",
285+
removeButtonTooltip__lastVerifiedDomain: 'At least one verified domain is required to set up SSO.',
286+
removeButtonTooltip__lastVerifiedDomainActive: 'At least one verified domain is required to keep SSO enabled.',
285287
txtRecord: {
286288
instructions: "Add this TXT record to your DNS provider. We'll verify automatically once the record is live.",
287289
typeLabel: 'Type',

packages/shared/src/types/localization.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,8 @@ export type __internal_LocalizationResource = {
13811381
badge__verified: LocalizationValue;
13821382
badge__unverified: LocalizationValue;
13831383
verifiedAtLabel: LocalizationValue<'date'>;
1384+
removeButtonTooltip__lastVerifiedDomain: LocalizationValue;
1385+
removeButtonTooltip__lastVerifiedDomainActive: LocalizationValue;
13841386
txtRecord: {
13851387
instructions: LocalizationValue;
13861388
typeLabel: LocalizationValue;

packages/ui/src/components/ConfigureSSO/steps/OrganizationDomainsStep.tsx

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { ClipboardInput } from '@/elements/ClipboardInput';
2323
import { useCardState } from '@/elements/contexts';
2424
import { Field } from '@/elements/FieldControl';
2525
import { Form } from '@/elements/Form';
26+
import { Tooltip } from '@/elements/Tooltip';
2627
import { Checkmark, Clipboard, Close } from '@/icons';
2728
import { common } from '@/styledSystem';
2829
import { useFormControl } from '@/ui/utils/useFormControl';
@@ -75,6 +76,15 @@ export const OrganizationDomainsStep = (): JSX.Element => {
7576

7677
const hasAllDomainsVerified = areAllOrganizationDomainsVerified(organizationDomains);
7778

79+
// A connection needs at least one verified domain to point at, so the last
80+
// remaining verified domain cannot be removed while a connection exists
81+
const verifiedDomainCount =
82+
organizationDomains?.filter(domain => domain.ownershipVerification?.status === 'verified').length ?? 0;
83+
const lockLastVerifiedDomain = Boolean(enterpriseConnection);
84+
const lastVerifiedDomainTooltip = enterpriseConnection?.active
85+
? localizationKeys('configureSSO.organizationDomainsStep.domainCard.removeButtonTooltip__lastVerifiedDomainActive')
86+
: localizationKeys('configureSSO.organizationDomainsStep.domainCard.removeButtonTooltip__lastVerifiedDomain');
87+
7888
return (
7989
<Flow.Part part='organizationDomains'>
8090
<Step
@@ -122,13 +132,20 @@ export const OrganizationDomainsStep = (): JSX.Element => {
122132
...common.unstyledScrollbar(t),
123133
})}
124134
>
125-
{organizationDomains.map(domain => (
126-
<DomainCard
127-
key={domain.id}
128-
domain={domain}
129-
onRemove={() => setDomainToRemove(domain)}
130-
/>
131-
))}
135+
{organizationDomains.map(domain => {
136+
const isVerified = domain.ownershipVerification?.status === 'verified';
137+
const isLastVerifiedDomain = isVerified && verifiedDomainCount === 1;
138+
const isRemoveDisabled = lockLastVerifiedDomain && isLastVerifiedDomain;
139+
return (
140+
<DomainCard
141+
key={domain.id}
142+
domain={domain}
143+
onRemove={() => setDomainToRemove(domain)}
144+
isRemoveDisabled={isRemoveDisabled}
145+
removeDisabledTooltip={lastVerifiedDomainTooltip}
146+
/>
147+
);
148+
})}
132149
</Col>
133150
)}
134151
</Step.Section>
@@ -319,9 +336,13 @@ const DomainSuggestion = ({ onSubmit }: { onSubmit: (domain: string) => Promise<
319336
const DomainCard = ({
320337
domain,
321338
onRemove,
339+
isRemoveDisabled = false,
340+
removeDisabledTooltip,
322341
}: {
323342
domain: OrganizationDomainResource;
324343
onRemove: () => void;
344+
isRemoveDisabled?: boolean;
345+
removeDisabledTooltip?: ReturnType<typeof localizationKeys>;
325346
}): JSX.Element | null => {
326347
if (!domain.name) {
327348
return null;
@@ -331,6 +352,23 @@ const DomainCard = ({
331352
const isVerified = ownershipVerification?.status === 'verified';
332353
const cardId = isVerified ? 'verified' : 'unverified';
333354

355+
const removeButton = (
356+
<Button
357+
elementDescriptor={descriptors.configureSSOVerifyDomainCardRemoveButton}
358+
variant='ghost'
359+
colorScheme='neutral'
360+
aria-label='Remove domain'
361+
onClick={onRemove}
362+
isDisabled={isRemoveDisabled}
363+
sx={t => ({ flexShrink: 0, padding: t.space.$1 })}
364+
>
365+
<Icon
366+
icon={Close}
367+
sx={t => ({ width: t.sizes.$4, height: t.sizes.$4, color: t.colors.$colorMutedForeground })}
368+
/>
369+
</Button>
370+
);
371+
334372
return (
335373
<Col
336374
elementDescriptor={descriptors.configureSSOVerifyDomainCard}
@@ -384,19 +422,14 @@ const DomainCard = ({
384422
)}
385423
</Flex>
386424

387-
<Button
388-
elementDescriptor={descriptors.configureSSOVerifyDomainCardRemoveButton}
389-
variant='ghost'
390-
colorScheme='neutral'
391-
aria-label='Remove domain'
392-
onClick={onRemove}
393-
sx={t => ({ flexShrink: 0, padding: t.space.$1 })}
394-
>
395-
<Icon
396-
icon={Close}
397-
sx={t => ({ width: t.sizes.$4, height: t.sizes.$4, color: t.colors.$colorMutedForeground })}
398-
/>
399-
</Button>
425+
{isRemoveDisabled && removeDisabledTooltip ? (
426+
<Tooltip.Root>
427+
<Tooltip.Trigger>{removeButton}</Tooltip.Trigger>
428+
<Tooltip.Content text={removeDisabledTooltip} />
429+
</Tooltip.Root>
430+
) : (
431+
removeButton
432+
)}
400433
</Flex>
401434

402435
<Box sx={{ overflow: 'hidden' }}>

0 commit comments

Comments
 (0)