Skip to content

Commit

Permalink
Domain management: Match component design for Google mailbox usecase (#…
Browse files Browse the repository at this point in the history
…97348)

* Extend ListHeader component to support action disabling

* Show notice when mailbox is configuring state

* Extend ListItemLink to support readonly mode

* Set mailbox link in readonly mode when google is configuring

* Hide EmailMailboxActionMenu component when google is configuring

* Isolate isConfiguring state

* Introduce configuringStateMode to switch between message and notice modes

* Extend EmailPlanWarnings component to support custom CTA props

* Integrate existing EmailPlanWarnings component

* Disable action if isGoogleConfiguring flag is true

* Adjust style of disabled links

* Apply styles only for the readonly mode

* Show the domain empty state when isGoogleConfiguring is in progress

* Show in progress message when warnings array is empty

* Add missing variant link

* Improve logic for showing warning

* Create reusable component content
  • Loading branch information
bogiii authored Dec 16, 2024
1 parent 1a56a5d commit 267b541
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 49 deletions.
1 change: 1 addition & 0 deletions client/my-sites/email/email-management/email-home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ const EmailHome = ( props: EmailManagementHomeProps ) => {
hideMailPoetUpsell={ isAllDomainManagementContext }
selectedSite={ selectedSite }
source={ source }
context={ context }
/>
</ContentWithHeader>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Badge, MaterialIcon } from '@automattic/components';
import { useTranslate } from 'i18n-calypso';
import Notice from 'calypso/components/notice';
import { isRecentlyRegistered } from 'calypso/lib/domains/utils';
import { isEmailUserAdmin } from 'calypso/lib/emails';
import { getGSuiteSubscriptionStatus } from 'calypso/lib/gsuite';
import EmailMailboxActionMenu from 'calypso/my-sites/email/email-management/home/email-mailbox-action-menu';
import EmailMailboxWarnings from 'calypso/my-sites/email/email-management/home/email-mailbox-warnings';
import EmailPlanWarnings from 'calypso/my-sites/email/email-management/home/email-plan-warnings';
import EmailForwardSecondaryDetails from './email-plan-mailboxes/email-forward-secondary-details';
import MailboxListHeader from './email-plan-mailboxes/list-header';
import MailboxListItem from './email-plan-mailboxes/list-item';
Expand All @@ -18,20 +20,28 @@ type Props = {
mailboxes: Mailbox[];
addMailboxPath: string;
isLoadingEmails: boolean;
configuringStateMode?: 'message' | 'notice';
};
function EmailPlanMailboxesList( {
domain,
account,
mailboxes,
addMailboxPath,
isLoadingEmails,
configuringStateMode = 'message',
}: Props ) {
const translate = useTranslate();
const accountType = account?.account_type;

const isNoMailboxes = ! mailboxes || mailboxes.length < 1;
const isAccountWarningPresent = !! account?.warnings.length;
const isGoogleConfiguring =
isRecentlyRegistered( domain.registrationDate, 45 ) &&
getGSuiteSubscriptionStatus( domain ) === 'unknown';

if ( isLoadingEmails ) {
return (
<MailboxListHeader isPlaceholder accountType={ accountType } domain={ domain }>
<MailboxListHeader isPlaceholder>
<MailboxListItem isPlaceholder>
<MaterialIcon icon="email" />
<span />
Expand All @@ -40,63 +50,114 @@ function EmailPlanMailboxesList( {
);
}

if ( ! mailboxes || mailboxes.length < 1 ) {
let missingMailboxesText = translate( 'No mailboxes' );
if ( isGoogleConfiguring && configuringStateMode === 'message' ) {
return <MailboxContent type="configuring" />;
}

if (
isRecentlyRegistered( domain.registrationDate, 45 ) &&
getGSuiteSubscriptionStatus( domain ) === 'unknown'
) {
missingMailboxesText = translate(
'We are configuring your mailboxes. You will receive an email shortly when they are ready to use.'
);
if ( isNoMailboxes && configuringStateMode === 'message' ) {
return <MailboxContent type="no-mailboxes" />;
}

function MailboxItemsEmpty() {
return (
<MailboxListItem>
<div className="email-plan-mailboxes-list__mailbox-list-item-main">
<div className="email-plan-mailboxes-list__mailbox-list-link">
<span>{ domain.domain }</span>
</div>
</div>
</MailboxListItem>
);
}

function MailboxContent( { type }: { type: 'configuring' | 'no-mailboxes' } ) {
let message;

switch ( type ) {
case 'no-mailboxes':
message = translate( 'No mailboxes' );
break;
case 'configuring':
message = translate(
'We are configuring your mailboxes. You will receive an email shortly when they are ready to use.'
);
break;
}

return (
<MailboxListHeader accountType={ accountType }>
<MailboxListItem hasNoEmails>
<span>{ missingMailboxesText }</span>
<span>{ message }</span>
</MailboxListItem>
</MailboxListHeader>
);
}

const mailboxItems = mailboxes.map( ( mailbox ) => {
const mailboxHasWarnings = Boolean( mailbox?.warnings?.length );

return (
<MailboxListItem key={ mailbox.mailbox } isError={ mailboxHasWarnings }>
<div className="email-plan-mailboxes-list__mailbox-list-item-main">
<MailboxLink account={ account } mailbox={ mailbox } />
<EmailForwardSecondaryDetails mailbox={ mailbox } />
</div>

{ isEmailUserAdmin( mailbox ) && (
<Badge type="info">
{ translate( 'Admin', {
comment: 'Email user role displayed as a badge',
} ) }
</Badge>
) }
function MailboxItems() {
return mailboxes.map( ( mailbox ) => {
const mailboxHasWarnings = Boolean( mailbox?.warnings?.length );

<EmailMailboxWarnings account={ account } mailbox={ mailbox } />
return (
<>
<MailboxListItem key={ mailbox.mailbox } isError={ mailboxHasWarnings }>
<div className="email-plan-mailboxes-list__mailbox-list-item-main">
<MailboxLink
account={ account }
mailbox={ mailbox }
readonly={ isGoogleConfiguring }
/>
<EmailForwardSecondaryDetails mailbox={ mailbox } />
</div>
{ isEmailUserAdmin( mailbox ) && (
<Badge type="info">
{ translate( 'Admin', {
comment: 'Email user role displayed as a badge',
} ) }
</Badge>
) }

{ ! mailbox.temporary && (
<EmailMailboxActionMenu account={ account } domain={ domain } mailbox={ mailbox } />
) }
</MailboxListItem>
);
} );
<EmailMailboxWarnings account={ account } mailbox={ mailbox } />
{ ! mailbox.temporary && ! isGoogleConfiguring && (
<EmailMailboxActionMenu account={ account } domain={ domain } mailbox={ mailbox } />
) }
</MailboxListItem>
</>
);
} );
}

return (
<MailboxListHeader
accountType={ accountType }
addMailboxPath={ addMailboxPath }
showIcon={ !! addMailboxPath }
domain={ domain }
>
{ mailboxItems }
</MailboxListHeader>
<>
{ ( isGoogleConfiguring || isAccountWarningPresent ) && configuringStateMode === 'notice' && (
<Notice
className="email-plan-mailboxes-list__notice"
status="is-warning"
showDismiss={ false }
>
{ isAccountWarningPresent ? (
<EmailPlanWarnings
domain={ domain }
emailAccount={ account }
ctaBtnProps={ { primary: false, plain: true } }
/>
) : (
translate(
'We are configuring your mailboxes. You will receive an email shortly when they are ready to use.'
)
) }
</Notice>
) }

<MailboxListHeader
accountType={ accountType }
addMailboxPath={ addMailboxPath }
showIcon={ !! addMailboxPath }
domain={ domain }
disableActions={ isGoogleConfiguring }
>
{ isNoMailboxes ? <MailboxItemsEmpty /> : <MailboxItems /> }
</MailboxListHeader>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Props = React.PropsWithChildren< {
addMailboxPath?: string;
domain?: ResponseDomain;
showIcon?: boolean;
disableActions?: boolean;
} >;
const MailboxListHeader = ( {
accountType = null,
Expand All @@ -20,6 +21,7 @@ const MailboxListHeader = ( {
addMailboxPath,
domain,
showIcon,
disableActions,
}: Props ) => {
const translate = useTranslate();

Expand Down Expand Up @@ -56,7 +58,9 @@ const MailboxListHeader = ( {
}
>
{ addMailboxPath && (
<Button isLink href={ addMailboxPath }>
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
<Button href={ addMailboxPath } variant="link" disabled={ !! disableActions }>
{ translate( 'Add mailbox' ) }
</Button>
) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import type { EmailAccount, Mailbox } from 'calypso/data/emails/types';
type Props = {
account: EmailAccount;
mailbox: Mailbox;
readonly?: boolean;
};
function MailboxLink( { account, mailbox }: Props ) {
function MailboxLink( { account, mailbox, readonly }: Props ) {
const titanAppsUrlPrefix = useTitanAppsUrlPrefix();
const emailAddress = getEmailAddress( mailbox );
const isReadonly = readonly || isEmailForwardAccount( account );

if ( isEmailForwardAccount( account ) ) {
if ( isReadonly ) {
return (
<div className="email-plan-mailboxes-list__mailbox-list-link">
<span>{ emailAddress }</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, Gridicon } from '@automattic/components';
import { Button, ButtonProps, Gridicon } from '@automattic/components';
import { useTranslate } from 'i18n-calypso';
import { recordTracksEvent } from 'calypso/lib/analytics/tracks';
import { canCurrentUserAddEmail, getCurrentUserCannotAddEmailReason } from 'calypso/lib/domains';
Expand All @@ -18,9 +18,10 @@ import type { ResponseDomain } from 'calypso/lib/domains/types';
type EmailPlanWarningsProps = {
domain: ResponseDomain;
emailAccount: EmailAccount;
ctaBtnProps?: ButtonProps;
};

const EmailPlanWarnings = ( { domain, emailAccount }: EmailPlanWarningsProps ) => {
const EmailPlanWarnings = ( { domain, emailAccount, ctaBtnProps }: EmailPlanWarningsProps ) => {
const translate = useTranslate();
const selectedSite = useSelector( getSelectedSite );
const selectedSiteSlug = selectedSite?.slug ?? '';
Expand All @@ -37,7 +38,12 @@ const EmailPlanWarnings = ( { domain, emailAccount }: EmailPlanWarningsProps ) =

if ( hasUnusedMailboxWarning( emailAccount ) && isTitanMailAccount( emailAccount ) ) {
cta = (
<Button compact primary href={ getTitanSetUpMailboxPath( selectedSiteSlug, domain.name ) }>
<Button
compact
primary
href={ getTitanSetUpMailboxPath( selectedSiteSlug, domain.name ) }
{ ...ctaBtnProps }
>
{ translate( 'Set up mailbox' ) }
</Button>
);
Expand All @@ -51,6 +57,7 @@ const EmailPlanWarnings = ( { domain, emailAccount }: EmailPlanWarningsProps ) =
recordTracksEvent( 'calypso_email_management_google_workspace_accept_tos_link_click' );
} }
target="_blank"
{ ...ctaBtnProps }
>
{ translate( 'Finish setup' ) }
<Gridicon icon="external" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ function EmailPlan( {
domain,
selectedSite,
source,
context,
hideHeader = false,
hideHeaderCake = false,
hidePlanActions = false,
Expand Down Expand Up @@ -365,6 +366,7 @@ function EmailPlan( {
mailboxes={ getMailboxes( emailAccounts ) }
isLoadingEmails={ isLoading }
addMailboxPath={ hidePlanActions && getAddMailboxProps()?.path }
configuringStateMode={ context === 'domains' && 'notice' }
/>
{ ! hidePlanActions && (
<div className="email-plan__actions">
Expand All @@ -388,6 +390,7 @@ EmailPlan.propTypes = {
domain: PropTypes.object.isRequired,
selectedSite: PropTypes.object.isRequired,
source: PropTypes.string,
context: PropTypes.string,
hideHeader: PropTypes.bool,
hideHeaderCake: PropTypes.bool,
hidePlanActions: PropTypes.bool,
Expand Down
51 changes: 51 additions & 0 deletions client/my-sites/email/email-management/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -511,4 +511,55 @@
.email-plan-mailboxes-list__mailbox-list-item > div {
flex-grow: initial;
}

div.email-plan-mailboxes-list__mailbox-list-link span,
.section-header__actions button[disabled] {
color: var(--theme-highlight-color-50);
opacity: 0.5;
}

.email-plan-mailboxes-list__notice {
margin-top: 1rem;
margin-bottom: 2rem;

.email-plan-warnings__container {
margin: 0;
}

.email-plan-warnings__warning {
display: flex;
padding: 0;

.email-plan-warnings__message,
.email-plan-warnings__cta {
display: inline;
}

.email-plan-warnings__message {
flex-grow: 1;

span {
display: inline-block;
max-width: 700px;
}
}

.email-plan-warnings__cta {
margin: 0;
flex-grow: 0;
align-self: center;
white-space: nowrap;

svg {
height: 14px;
vertical-align: middle;
}

a {
color: var(--studio-gray-20);
text-decoration: none;
}
}
}
}
}

0 comments on commit 267b541

Please sign in to comment.