Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Domain management: Match component design for Google mailbox usecase #97348

Merged
merged 17 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
}
}
}
}
Loading