diff --git a/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx b/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx index 1514a87b7b1da..865dc896ad551 100644 --- a/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx +++ b/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx @@ -1,21 +1,13 @@ import classNames from 'classnames'; import { createInterpolateElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { - describeErrorSet, - suggestion, - rawError, -} from '../lib/describe-critical-css-recommendations'; -import actionLinkInterpolateVar from '$lib/utils/action-link-interpolate-var'; -import { type InterpolateVars } from '$lib/utils/interplate-vars-types'; -import supportLinkInterpolateVar from '$lib/utils/support-link-interpolate-var'; +import { describeErrorSet, rawError } from '../lib/describe-critical-css-recommendations'; import FoldingElement from '../folding-element/folding-element'; import MoreList from '../more-list/more-list'; import styles from './error-description.module.scss'; import Suggestion from '../suggestion/suggestion'; import { CriticalCssErrorDescriptionTypes, FormattedURL } from './types'; -import { useRegenerateCriticalCssAction } from '../lib/stores/critical-css-state'; -import { useNavigate } from 'react-router-dom'; +import getCriticalCssErrorSetInterpolateVars from '$lib/utils/get-critical-css-error-set-interpolate-vars'; /** * Remove GET parameters that are used to cache-bust from display URLs, as they add visible noise @@ -23,7 +15,7 @@ import { useNavigate } from 'react-router-dom'; * * @param url The URL to strip cache parameters from. */ -function stripCacheParams( url: string ): string { +export function stripCacheParams( url: string ): string { const urlObj = new URL( url ); urlObj.searchParams.delete( 'donotcachepage' ); return urlObj.toString(); @@ -49,26 +41,7 @@ const CriticalCssErrorDescription: React.FC< CriticalCssErrorDescriptionTypes > } ); const rawErrors = rawError( errorSet ); - const regenerateAction = useRegenerateCriticalCssAction(); - const navigate = useNavigate(); - - function retry() { - regenerateAction.mutate(); - navigate( '/' ); - } - - const intepolateVars: InterpolateVars = { - ...actionLinkInterpolateVar( retry, 'retry' ), - ...supportLinkInterpolateVar(), - b: , - }; - - if ( 'listLink' in suggestion( errorSet ) ) { - intepolateVars.link = ( - // eslint-disable-next-line jsx-a11y/anchor-has-content - - ); - } + const intepolateVars = getCriticalCssErrorSetInterpolateVars( errorSet ); return (
diff --git a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss index e3466bac0440b..747d8ec4e901d 100644 --- a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss +++ b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss @@ -2,7 +2,6 @@ &.foldable-element-control { color: var( --primary-black ); font-size: 16px; - margin-bottom: 24px; } } @@ -27,6 +26,16 @@ animation-name: fadeIn; } -.expanded { - margin-bottom: 24px; +.expanded p { + padding-top: 1em; + padding-bottom: 1em; + margin: 0 !important; +} + +.expanded p:last-child { + padding-bottom: 0; +} + +.foldable-element-control { + font-weight: 600; } diff --git a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx index b48f3cda684d9..b48e641edf509 100644 --- a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx +++ b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx @@ -2,6 +2,8 @@ import useMeasure from 'react-use-measure'; import { animated, useSpring } from '@react-spring/web'; import classNames from 'classnames'; import { useState } from 'react'; +import ChevronDown from '$svg/chevron-down'; +import ChevronUp from '$svg/chevron-up'; import styles from './folding-element.module.scss'; type PropTypes = { @@ -34,6 +36,7 @@ const FoldingElement: React.FC< PropTypes > = ( { onClick={ () => setExpanded( ! expanded ) } > { label } + { expanded ? : } = ( { showRetry, } ) => { const primaryErrorSet = getPrimaryErrorSet( cssState ); - const showErrorDescription = primaryErrorSet && cssState.status === 'generated'; - const showFoldingElement = showErrorDescription || cssState.status_error; + const showLearnSection = primaryErrorSet && cssState.status === 'generated'; + return ( + <> + + { showLearnSection ? ( + <> + + +
+

{ __( 'Please follow the troubleshooting steps below', 'jetpack-boost' ) }

+ + +
+
+ + ) : ( + + ) } +
+ + ); +}; + +const Description = ( { errorSet }: { errorSet: ErrorSet } ) => { + const displayUrls = formatErrorSetUrls( errorSet ); + + return ( +

+ { createInterpolateElement( describeErrorSet( errorSet ), { + b: , + } ) }{ ' ' } + { displayUrls.map( ( { href, label }, index ) => ( + + { label } + + ) ) } +

+ ); +}; + +const Steps = ( { errorSet }: { errorSet: ErrorSet } ) => { + const details = suggestion( errorSet ); + if ( ! details.list ) { + return null; + } + + const interpolateVars = getCriticalCssErrorSetInterpolateVars( errorSet ); + + return ; +}; + +const DocumentationSection = ( { + message, + errorType, +}: { + message?: string; + errorType: string; +} ) => { + if ( message === undefined ) { + message = __( + 'If you are still experiencing this issue, learn more from our documentation.', + 'jetpack-boost' + ); + } + + return ( +

+ { createInterpolateElement( message, { + link: ( + // eslint-disable-next-line jsx-a11y/anchor-has-content + + ), + } ) } +

+ ); +}; + +const OtherErrors = ( { cssState, retry, showRetry, supportLink }: ShowStopperErrorTypes ) => { const firstTimeError = __( 'An unexpected error has occurred. As this error may be temporary, please try and refresh the Critical CSS.', 'jetpack-boost' @@ -33,47 +131,61 @@ const ShowStopperError: React.FC< ShowStopperErrorTypes > = ( { ); return ( - - { __( 'Refresh', 'jetpack-boost' ) } - - ) : ( - - { __( 'Contact Support', 'jetpack-boost' ) } - - ) - } - > -

{ showRetry ? firstTimeError : secondTimeError }

- { showFoldingElement && ( - -
- { showErrorDescription ? ( - - ) : ( + <> + { cssState.status_error === 'css-gen-library-failure' ? ( + <> +

+ { __( + 'Critical CSS Generator library is either not found or invalid.', + 'jetpack-boost' + ) } +

+ Learn how to fix this by visiting our documentation.', + 'jetpack-boost' + ) } + errorType={ cssState.status_error } + /> +

+ { createInterpolateElement( + __( + 'If the problem has been resolved, refresh the page and click here to try regenerating critical css.', + 'jetpack-boost' + ), + { + ...actionLinkInterpolateVar( retry, 'retry' ), + } + ) } +

+ + ) : ( + <> +

{ showRetry ? firstTimeError : secondTimeError }

+

+ { sprintf( + /* translators: %s: error message */ + __( `Error: %s`, 'jetpack-boost' ), cssState.status_error ) } -

-
+

+ { showRetry ? ( + + ) : ( + + { __( 'Contact Support', 'jetpack-boost' ) } + + ) } + ) } - + ); }; diff --git a/projects/plugins/boost/app/assets/src/js/lib/utils/format-error-set-urls.ts b/projects/plugins/boost/app/assets/src/js/lib/utils/format-error-set-urls.ts new file mode 100644 index 0000000000000..9089700387dd3 --- /dev/null +++ b/projects/plugins/boost/app/assets/src/js/lib/utils/format-error-set-urls.ts @@ -0,0 +1,18 @@ +import { stripCacheParams } from '$features/critical-css/error-description/error-description'; +import { FormattedURL } from '$features/critical-css/error-description/types'; +import { ErrorSet } from '$features/critical-css/lib/critical-css-errors'; + +function formatErrorSetUrls( errorSet: ErrorSet ): FormattedURL[] { + return Object.entries( errorSet.byUrl ).map( ( [ url, error ] ) => { + let href = url; + if ( error.meta.url && typeof error.meta.url === 'string' ) { + href = error.meta.url; + } + return { + href, + label: stripCacheParams( url ), + }; + } ); +} + +export default formatErrorSetUrls; diff --git a/projects/plugins/boost/app/assets/src/js/lib/utils/get-critical-css-error-set-interpolate-vars.tsx b/projects/plugins/boost/app/assets/src/js/lib/utils/get-critical-css-error-set-interpolate-vars.tsx new file mode 100644 index 0000000000000..005fba934c65c --- /dev/null +++ b/projects/plugins/boost/app/assets/src/js/lib/utils/get-critical-css-error-set-interpolate-vars.tsx @@ -0,0 +1,34 @@ +import { useNavigate } from 'react-router-dom'; +import actionLinkInterpolateVar from '$lib/utils/action-link-interpolate-var'; +import { InterpolateVars } from '$lib/utils/interplate-vars-types'; +import supportLinkInterpolateVar from '$lib/utils/support-link-interpolate-var'; +import { useRegenerateCriticalCssAction } from '$features/critical-css/lib/stores/critical-css-state'; +import { suggestion } from '$features/critical-css/lib/describe-critical-css-recommendations'; +import { ErrorSet } from '$features/critical-css/lib/critical-css-errors'; + +function getCriticalCssErrorSetInterpolateVars( errorSet: ErrorSet ) { + const regenerateAction = useRegenerateCriticalCssAction(); + const navigate = useNavigate(); + + function retry() { + regenerateAction.mutate(); + navigate( '/' ); + } + + const interpolateVars: InterpolateVars = { + ...actionLinkInterpolateVar( retry, 'retry' ), + ...supportLinkInterpolateVar(), + b: , + }; + + if ( 'listLink' in suggestion( errorSet ) ) { + interpolateVars.link = ( + // eslint-disable-next-line jsx-a11y/anchor-has-content + + ); + } + + return interpolateVars; +} + +export default getCriticalCssErrorSetInterpolateVars; diff --git a/projects/plugins/boost/app/assets/src/js/lib/utils/get-support-link-critical-css.ts b/projects/plugins/boost/app/assets/src/js/lib/utils/get-support-link-critical-css.ts new file mode 100644 index 0000000000000..8c51371296e23 --- /dev/null +++ b/projects/plugins/boost/app/assets/src/js/lib/utils/get-support-link-critical-css.ts @@ -0,0 +1,24 @@ +function getPrettyError( error: string ) { + const errorMap: { [ key: string ]: string } = { + SuccessTargetError: 'success-target-error', + UrlError: 'url-error', + HttpError: 'http-error', + UnknownError: 'unknown-error', + CrossDomainError: 'cross-domain-error', + LoadTimeoutError: 'load-timeout-error', + RedirectError: 'redirect-error', + UrlVerifyError: 'url-verify-error', + EmptyCSSError: 'empty-css-error', + XFrameDenyError: 'x-frame-deny-error', + }; + + return errorMap[ error as keyof typeof errorMap ] || error; +} + +function getSupportLinkCriticalCss( errorType: string ) { + return `https://jetpack.com/support/jetpack-boost/troubleshooting-critical-css-issues/#${ getPrettyError( + errorType + ) }`; +} + +export default getSupportLinkCriticalCss; diff --git a/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss b/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss index 67aba8e308924..a8705bd93ab49 100644 --- a/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss +++ b/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss @@ -18,7 +18,7 @@ position: relative; border: 1px solid $gray_5; border-radius: 4px; - padding: 24px 69px 0 27px; + padding: 24px 69px 24px 27px; li { @include word-wrap(); diff --git a/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx b/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx index 82b720c686961..11fc5ccb964cb 100644 --- a/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx +++ b/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx @@ -11,7 +11,7 @@ const ChevronUp = () => ( /> - + ); diff --git a/projects/plugins/boost/changelog/update-critical-css-error-ui b/projects/plugins/boost/changelog/update-critical-css-error-ui new file mode 100644 index 0000000000000..20e9294575b43 --- /dev/null +++ b/projects/plugins/boost/changelog/update-critical-css-error-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Critical CSS: Improve UI when errors are present.