@@ -23,6 +23,7 @@ import { ClipboardInput } from '@/elements/ClipboardInput';
2323import { useCardState } from '@/elements/contexts' ;
2424import { Field } from '@/elements/FieldControl' ;
2525import { Form } from '@/elements/Form' ;
26+ import { Tooltip } from '@/elements/Tooltip' ;
2627import { Checkmark , Clipboard , Close } from '@/icons' ;
2728import { common } from '@/styledSystem' ;
2829import { 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<
319336const 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