Skip to content

Commit

Permalink
Boost: Improve ISA UI feedback when interacting (#40096)
Browse files Browse the repository at this point in the history
  • Loading branch information
dilirity authored Nov 11, 2024
1 parent 6b71241 commit 023a565
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
useDataSyncAction,
} from '@automattic/jetpack-react-data-sync-client';
import { type isaGroupKeys } from '../isa-groups';
import { IsaReport, IsaCounts } from './types';
import { IsaReport, IsaCounts, ISAStatus } from './types';
import { z } from 'zod';
import { useMemo } from 'react';

Expand Down Expand Up @@ -80,6 +80,11 @@ export function useImageAnalysisRequest() {
queryKey: [ 'image_size_analysis_summary' ],
} );
},
optimisticUpdate: () => {
return {
status: ISAStatus.New,
};
},
},
} );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,20 @@ export enum ISAStatus {
}

export const IsaReport = z.object( {
status: z.nativeEnum( ISAStatus ).default( ISAStatus.NotFound ),
status: z.nativeEnum( ISAStatus ),
message: z.string().optional(),
report_id: z.number().optional(),
groups: z
.object( {
core_front_page: IsaCounts,
singular_page: IsaCounts.optional(),
singular_post: IsaCounts.optional(),
other: IsaCounts.optional(),
fixed: IsaCounts.optional(),
singular_page: IsaCounts,
singular_post: IsaCounts,
other: IsaCounts,
fixed: IsaCounts,
} )
.optional(),
.partial()
.optional()
.catch( {} ),
} );

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '$features/image-size-analysis';
import clsx from 'clsx';
import styles from './recommendations-meta.module.scss';
import { useEffect, useState } from 'react';

const getWaitNotice = ( isRequesting: boolean, currentStatus: string | undefined ) => {
if ( isRequesting ) {
Expand All @@ -35,150 +36,178 @@ interface Props {
}

const RecommendationsMeta: React.FC< Props > = ( { isCdnActive } ) => {
const [ { data: isaReport } ] = useIsaReport();
const [ uiState, setUiState ] = useState< 'loading' | 'polling' | 'idle' >( 'loading' );
const [ isaReportQuery ] = useIsaReport();
const isaRequest = useImageAnalysisRequest();

const status = isaReport?.status;
const groups = isaReport?.groups || {};
const isaReport = isaReportQuery.data;

const totalIssues = Object.entries( groups ).reduce( ( total, [ , group ] ) => {
const reportStatus = isaReport?.status;
const reportGroups = isaReport?.groups || {};

const totalIssues = Object.entries( reportGroups ).reduce( ( total, [ , group ] ) => {
const groupWithIssueCount = group as { issue_count: number };

return total + groupWithIssueCount.issue_count;
}, 0 );

const scannedPages = Object.values< IsaCounts >( groups )
const scannedPages = Object.values< IsaCounts >( reportGroups )
.map( group => group.scanned_pages )
.reduce( ( a, b ) => a + b, 0 );

const waitNotice = getWaitNotice( isaRequest.isPending, status );
const showCDNRecommendation =
! isCdnActive && ( totalIssues > 0 || status === ISAStatus.NotFound );
const waitNotice = getWaitNotice( isaRequest.isPending, reportStatus );
const showCDNRecommendation = ! isCdnActive && totalIssues > 0;

const handleAnalyzeClick = () => {
const eventName =
status === ISAStatus.Completed
reportStatus === ISAStatus.Completed
? 'clicked_restart_isa_on_report_page'
: 'clicked_start_isa_on_report_page';
recordBoostEvent( eventName, {} );
isaRequest.requestNewReport();
setUiState( 'polling' );
};

useEffect( () => {
if ( reportStatus === ISAStatus.Queued || reportStatus === ISAStatus.New ) {
setUiState( 'polling' );
} else if ( reportStatus ) {
setUiState( 'idle' );
}
}, [ reportStatus ] );

if ( uiState === 'loading' ) {
return <div className={ styles.summary }>{ __( 'Loading…', 'jetpack-boost' ) }</div>;
}

const showError =
reportStatus === ISAStatus.NotFound ||
reportStatus === ISAStatus.Stuck ||
reportStatus === ISAStatus.Error ||
isaRequest.isError;

const getErrorMessage = ( report: typeof isaReport ) => {
if ( report?.status === 'error' || report?.status === 'not-found' ) {
return report.message;
}

if ( isaRequest.error instanceof Error ) {
return isaRequest.error.message;
}

if ( reportStatus === ISAStatus.Stuck ) {
return __(
'Your Image Size Analysis task seems to have gotten stuck, or our system is under unusual load. Please try again. If the issue persists, please contact support.',
'jetpack-boost'
);
}

return null;
};

const errorMessage = getErrorMessage( isaReport );

return (
<div>
{ ! groups ? (
<div className={ styles.summary }>{ __( 'Loading…', 'jetpack-boost' ) }</div>
) : (
<>
{ status === ISAStatus.Stuck || isaRequest.isError ? (
<div className={ styles[ 'error-area' ] }>
<ErrorNotice title={ __( 'Something has gone wrong.', 'jetpack-boost' ) }>
{ isaRequest.error instanceof Error
? isaRequest.error.message
: __(
'Your Image Size Analysis task seems to have gotten stuck, or our system is under unusual load. Please try again. If the issue persists, please contact support.',
'jetpack-boost'
) }
</ErrorNotice>
</div>
) : waitNotice ? (
<div className={ clsx( styles[ 'summary-line' ], styles[ 'wait-notice' ] ) }>
{ waitNotice }
<>
{ showError && errorMessage ? (
<div className={ styles[ 'error-area' ] }>
<ErrorNotice title={ __( 'Something has gone wrong.', 'jetpack-boost' ) }>
{ errorMessage }
</ErrorNotice>
</div>
) : waitNotice ? (
<div className={ clsx( styles[ 'summary-line' ], styles[ 'wait-notice' ] ) }>
{ waitNotice }
</div>
) : null }

{ uiState === 'idle' && ! showError && (
<div className={ styles[ 'summary-line' ] }>
{ totalIssues > 0 ? (
<div className={ clsx( styles[ 'has-issues' ], styles.summary ) }>
<WarningIcon />
{ sprintf(
// translators: 1: Number of scanned issues found 2: Number of scanned pages
__(
'Found a total of %1$d issues after scanning your %2$d most recent pages.',
'jetpack-boost'
),
totalIssues,
scannedPages
) }
</div>
) : null }

{ ! isaRequest.isPending && status === ISAStatus.Completed && (
<div className={ styles[ 'summary-line' ] }>
{ totalIssues > 0 ? (
<div className={ clsx( styles[ 'has-issues' ], styles.summary ) }>
<WarningIcon />
{ sprintf(
// translators: 1: Number of scanned issues found 2: Number of scanned pages
__(
'Found a total of %1$d issues after scanning your %2$d most recent pages.',
'jetpack-boost'
),
totalIssues,
scannedPages
) }
</div>
) : (
<div className={ styles.summary }>
{ sprintf(
// translators: %d: Number of pages scanned
__(
'Congratulations; no issues found after scanning your %d most recent pages.',
'jetpack-boost'
),
scannedPages
) }
</div>
) : (
<div className={ styles.summary }>
{ sprintf(
// translators: %d: Number of pages scanned
__(
'Congratulations; no issues found after scanning your %d most recent pages.',
'jetpack-boost'
),
scannedPages
) }
<Button
variant="link"
size="small"
weight="regular"
icon={ <RefreshIcon /> }
onClick={ handleAnalyzeClick }
disabled={ isaRequest.isPending }
>
{ __( 'Analyze again', 'jetpack-boost' ) }
</Button>
</div>
) }
<Button
variant="link"
size="small"
weight="regular"
icon={ <RefreshIcon /> }
onClick={ handleAnalyzeClick }
disabled={ isaRequest.isPending }
>
{ __( 'Analyze again', 'jetpack-boost' ) }
</Button>
</div>
) }

{ ! isaRequest.isPending &&
status &&
[ ISAStatus.Completed, ISAStatus.Queued ].includes( status ) && (
<MultiProgress reportProgress={ getReportProgress( groups ) } />
) }

{ showCDNRecommendation && (
<div className={ styles.notice }>
<div>
<ImageCdnRecommendation />
</div>
</div>
) }
{ reportStatus && [ ISAStatus.Completed, ISAStatus.Queued ].includes( reportStatus ) && (
<MultiProgress reportProgress={ getReportProgress( reportGroups ) } />
) }

{ status &&
[ ISAStatus.Queued, ISAStatus.Completed ].includes( status ) &&
! isaRequest.isPending && (
<div className={ styles[ 'button-area' ] }>
<Button
variant="secondary"
disabled={ isaRequest.isPending }
onClick={ () =>
recordBoostEventAndRedirect(
'#image-size-analysis/all/1',
'clicked_view_isa_report_on_report_page',
{}
)
}
>
{ ( status as ISAStatus ) === ISAStatus.Completed
? __( 'See full report', 'jetpack-boost' )
: __( 'View report in progress', 'jetpack-boost' ) }
</Button>
</div>
) }

{ ( ! status ||
! [ ISAStatus.New, ISAStatus.Queued, ISAStatus.Completed ].includes( status ) ) && (
<div className={ styles[ 'button-area' ] }>
<Button
variant="secondary"
disabled={ isaRequest.isPending }
onClick={ handleAnalyzeClick }
>
{ status === ISAStatus.Completed
? __( 'Analyze again', 'jetpack-boost' )
: __( 'Start image analysis', 'jetpack-boost' ) }
</Button>
</div>
) }
</>
{ showCDNRecommendation && (
<div className={ styles.notice }>
<div>
<ImageCdnRecommendation />
</div>
</div>
) }

{ reportStatus && [ ISAStatus.Queued, ISAStatus.Completed ].includes( reportStatus ) && (
<div className={ styles[ 'button-area' ] }>
<Button
variant="secondary"
disabled={ isaRequest.isPending }
onClick={ () =>
recordBoostEventAndRedirect(
'#image-size-analysis/all/1',
'clicked_view_isa_report_on_report_page',
{}
)
}
>
{ reportStatus === ISAStatus.Completed
? __( 'See full report', 'jetpack-boost' )
: __( 'View report in progress', 'jetpack-boost' ) }
</Button>
</div>
) }

{ ( ! reportStatus ||
! [ ISAStatus.New, ISAStatus.Queued, ISAStatus.Completed ].includes( reportStatus ) ) && (
<div className={ styles[ 'button-area' ] }>
<Button
variant="secondary"
disabled={ isaRequest.isPending }
onClick={ handleAnalyzeClick }
>
{ reportStatus === ISAStatus.Completed
? __( 'Analyze again', 'jetpack-boost' )
: __( 'Start image analysis', 'jetpack-boost' ) }
</Button>
</div>
) }
</div>
</>
);
};

Expand Down
14 changes: 6 additions & 8 deletions projects/plugins/boost/app/lib/class-site-urls.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ private static function get_wp_core_urls() {
'modified' => get_post_modified_time( 'Y-m-d H:i:s', false, $front_page ),
'group' => 'core_front_page',
);
} else {
$urls['core_front_page'] = array(
'url' => home_url( '/' ),
'modified' => current_time( 'Y-m-d H:i:s' ),
'group' => 'core_front_page',
);
}

$posts_page = get_option( 'page_for_posts' );
Expand All @@ -45,14 +51,6 @@ private static function get_wp_core_urls() {
);
}

if ( empty( $front_page ) && empty( $posts_page ) ) {
$urls['core_posts_page'] = array(
'url' => home_url( '/' ),
'modified' => current_time( 'Y-m-d H:i:s' ),
'group' => 'core_front_page',
);
}

return $urls;
}

Expand Down
Loading

0 comments on commit 023a565

Please sign in to comment.