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

Studio: Improve offline mode for Sync tab #666

Open
wants to merge 10 commits into
base: trunk
Choose a base branch
from
2 changes: 1 addition & 1 deletion src/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type ButtonProps = MappedOmit< ComponentProps< typeof Button >, 'variant'
tooltipText?: string;
};

type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'outlined' | 'link' | 'icon';
export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'outlined' | 'link' | 'icon';

/**
* The arbitrary Tailwind variants below (e.g., `[&.is-secondary]`) are used to
Expand Down
65 changes: 65 additions & 0 deletions src/components/connect-create-buttons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { __ } from '@wordpress/i18n';
import { cx } from '../lib/cx';
import { getIpcApi } from '../lib/get-ipc-api';
import { ArrowIcon } from './arrow-icon';
import Button, { ButtonVariant } from './button';
import offlineIcon from './offline-icon';
import Tooltip from './tooltip';

interface ConnectCreateButtonsProps {
connectSite: () => void;
isOffline: boolean;
connectButtonVariant: ButtonVariant;
createButtonVariant: ButtonVariant;
disableConnectButtonStyle?: boolean;
}

export const ConnectCreateButtons = ( {
connectSite,
isOffline,
createButtonVariant,
connectButtonVariant,
disableConnectButtonStyle,
}: ConnectCreateButtonsProps ) => {
return (
<>
<Tooltip
disabled={ ! isOffline }
text={ __( 'Connecting a site requires an internet connection.' ) }
icon={ offlineIcon }
>
<Button
onClick={ connectSite }
disabled={ isOffline }
aria-disabled={ isOffline }
variant={ connectButtonVariant }
className={ cx(
! disableConnectButtonStyle &&
! isOffline &&
'!text-a8c-blueberry !shadow-a8c-blueberry'
) }
>
{ __( 'Connect site' ) }
</Button>
</Tooltip>
<Tooltip
disabled={ ! isOffline }
text={ __( 'Creating a site requires an internet connection.' ) }
icon={ offlineIcon }
>
<Button
onClick={ () => {
getIpcApi().openURL( 'https://wordpress.com/start/new-site' );
} }
variant={ createButtonVariant }
className={ cx( ! isOffline && '!text-a8c-blueberry !shadow-a8c-blueberry' ) }
disabled={ isOffline }
aria-disabled={ isOffline }
>
{ __( 'Create new site' ) }
<ArrowIcon />
</Button>
</Tooltip>
</>
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to extract these two buttons in the common component as we are using them in two places and the code is quite repetitive

};
42 changes: 8 additions & 34 deletions src/components/content-tab-sync.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { useSyncSites } from '../hooks/sync-sites';
import { useAuth } from '../hooks/use-auth';
import { SyncSite } from '../hooks/use-fetch-wpcom-sites';
import { useOffline } from '../hooks/use-offline';
import { cx } from '../lib/cx';
import { getIpcApi } from '../lib/get-ipc-api';
import { ArrowIcon } from './arrow-icon';
import Button from './button';
import { ConnectCreateButtons } from './connect-create-buttons';
import offlineIcon from './offline-icon';
import { SyncConnectedSites } from './sync-connected-sites';
import { SyncSitesModalSelector } from './sync-sites-modal-selector';
Expand Down Expand Up @@ -60,42 +60,16 @@ function CreateConnectSite( {
const { __ } = useI18n();
const isOffline = useOffline();

const offlineMessageCreate = __( 'Creating new site requires an internet connection.' );
const offlineMessageConnect = __( 'Connecting a site requires an internet connection.' );

return (
<div className="mt-8">
<div className="flex gap-4">
<Tooltip disabled={ ! isOffline } text={ offlineMessageConnect }>
<Button
aria-disabled={ isOffline }
variant="primary"
onClick={ () => {
if ( isOffline ) {
return;
}
openSitesSyncSelector();
} }
>
{ __( 'Connect site' ) }
</Button>
</Tooltip>
<Tooltip disabled={ ! isOffline } text={ offlineMessageCreate }>
<Button
aria-disabled={ isOffline }
className={ cx( ! isOffline && '!text-a8c-blueberry !shadow-a8c-blueberry' ) }
variant="secondary"
onClick={ async () => {
if ( isOffline ) {
return;
}
await getIpcApi().openURL( 'https://wordpress.com/start/new-site' );
} }
>
{ __( 'Create new site' ) }
<ArrowIcon />
</Button>
</Tooltip>
<ConnectCreateButtons
connectSite={ openSitesSyncSelector }
isOffline={ isOffline }
connectButtonVariant="primary"
createButtonVariant="secondary"
disableConnectButtonStyle={ true }
/>
</div>
</div>
);
Expand Down
109 changes: 60 additions & 49 deletions src/components/sync-connected-sites.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import { useMemo } from 'react';
import { useSyncSites } from '../hooks/sync-sites';
import { useConfirmationDialog } from '../hooks/use-confirmation-dialog';
import { SyncSite } from '../hooks/use-fetch-wpcom-sites';
import { useOffline } from '../hooks/use-offline';
import { useSyncStatesProgressInfo } from '../hooks/use-sync-states-progress-info';
import { cx } from '../lib/cx';
import { getIpcApi } from '../lib/get-ipc-api';
import { ArrowIcon } from './arrow-icon';
import { Badge } from './badge';
import Button from './button';
import { ConnectCreateButtons } from './connect-create-buttons';
import offlineIcon from './offline-icon';
import ProgressBar from './progress-bar';
import { SyncPullPushClear } from './sync-pull-push-clear';
import Tooltip from './tooltip';
Expand All @@ -35,6 +39,7 @@ export function SyncConnectedSites( {
selectedSite: SiteDetails;
} ) {
const { __ } = useI18n();
const isOffline = useOffline();
const {
pullSite,
clearPullState,
Expand Down Expand Up @@ -224,7 +229,6 @@ export function SyncConnectedSites( {
<ProgressBar value={ pushState.status.progress } maxValue={ 100 } />
</div>
) }

{ pushState.status && pushState.hasFinished && (
<SyncPullPushClear
onClick={ () => clearPushState( selectedSite.id, connectedSite.id ) }
Expand All @@ -238,37 +242,55 @@ export function SyncConnectedSites( {
! pushState.isInProgress &&
! pushState.isError &&
! pushState.hasFinished && (
<div className="flex gap-2 pl-4 ml-auto shrink-0 h-5">
<Button
variant="link"
className="!text-black hover:!text-a8c-blueberry"
onClick={ () => {
const detail = connectedSite.isStaging
? __(
"Pulling will replace your Studio site's files and database with a copy from your staging site."
)
: __(
"Pulling will replace your Studio site's files and database with a copy from your production site."
);
showPullConfirmation( () => pullSite( connectedSite, selectedSite ), {
detail,
} );
} }
disabled={ isAnySitePulling || isAnySitePushing }
>
<Icon icon={ cloudDownload } />
{ __( 'Pull' ) }
</Button>
<Button
variant="link"
className="!text-black hover:!text-a8c-blueberry"
onClick={ () => handlePushSite( connectedSite ) }
disabled={ isAnySitePulling || isAnySitePushing }
>
<Icon icon={ cloudUpload } />
{ __( 'Push' ) }
</Button>
</div>
<Tooltip
disabled={ ! isOffline }
text={ __(
'Pulling or pushing a site requires an internet connection.'
) }
icon={ offlineIcon }
placement="top-start"
>
<div className="flex gap-2 pl-4 ml-auto shrink-0 h-5">
<Button
variant="link"
className={ cx(
! isOffline && '!text-black hover:!text-a8c-blueberry'
) }
onClick={ () => {
const detail = connectedSite.isStaging
? __(
"Pulling will replace your Studio site's files and database with a copy from your staging site."
)
: __(
"Pulling will replace your Studio site's files and database with a copy from your production site."
);
showPullConfirmation(
() => pullSite( connectedSite, selectedSite ),
{
detail,
}
);
} }
disabled={ isAnySitePulling || isAnySitePushing || isOffline }
aria-disabled={ isOffline }
>
<Icon icon={ cloudDownload } />
{ __( 'Pull' ) }
</Button>
<Button
variant="link"
className={ cx(
! isOffline && '!text-black hover:!text-a8c-blueberry'
) }
onClick={ () => handlePushSite( connectedSite ) }
disabled={ isAnySitePulling || isAnySitePushing || isOffline }
aria-disabled={ isOffline }
>
<Icon icon={ cloudUpload } />
{ __( 'Push' ) }
</Button>
</div>
</Tooltip>
) }
</div>
</div>
Expand All @@ -279,23 +301,12 @@ export function SyncConnectedSites( {
</div>

<div className="flex mt-auto gap-4 py-5 px-8 border-t border-a8c-gray-5 flex-shrink-0">
<Button
onClick={ openSitesSyncSelector }
variant="secondary"
className="!text-a8c-blueberry !shadow-a8c-blueberry"
>
{ __( 'Connect site' ) }
</Button>
<Button
onClick={ () => {
getIpcApi().openURL( 'https://wordpress.com/start/new-site' );
} }
variant="secondary"
className="!text-a8c-blueberry !shadow-a8c-blueberry"
>
{ __( 'Create new site' ) }
<ArrowIcon />
</Button>
<ConnectCreateButtons
connectSite={ openSitesSyncSelector }
isOffline={ isOffline }
connectButtonVariant="secondary"
createButtonVariant="secondary"
/>
</div>
</div>
);
Expand Down
Loading
Loading