OBW: Hide the extensions header when no available plugins in the category (https://github.com/woocommerce/woocommerce-admin/pull/8089)

* Hide extension list header if no plugins under the category

* Refactor variable naming and add missing hook deps

* Add changelogs

* Add tests for <ExtensionSection />
This commit is contained in:
Chi-Hsuan Huang 2021-12-29 16:32:19 +08:00 committed by GitHub
parent a0278af8ad
commit ac78e74ef6
4 changed files with 121 additions and 49 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: Fix
Hide the extensions header when no available plugins in the category. #8089

View File

@ -159,8 +159,44 @@ const BundleExtensionCheckbox = ( { onChange, description, isChecked } ) => {
);
};
const baseValues = { install_extensions: true };
export const createInitialValues = ( extensions ) => {
export const ExtensionSection = ( {
isResolving,
title,
extensions,
installExtensionOptions,
onCheckboxChange,
} ) => {
if ( isResolving ) {
return (
<div>
<Spinner />
</div>
);
}
if ( extensions.length === 0 ) {
return null;
}
return (
<div>
<div className="woocommerce-admin__business-details__selective-extensions-bundle__category">
{ title }
</div>
{ extensions.map( ( { description, key } ) => (
<BundleExtensionCheckbox
key={ key }
description={ description }
isChecked={ installExtensionOptions[ key ] }
onChange={ onCheckboxChange( key ) }
/>
) ) }
</div>
);
};
export const createInstallExtensionOptions = ( extensions = [] ) => {
const defaultInstallExtensionOptions = { install_extensions: true };
return extensions.reduce( ( acc, curr ) => {
const plugins = curr.plugins.reduce(
( pluginAcc, { key, selected } ) => {
@ -173,7 +209,7 @@ export const createInitialValues = ( extensions ) => {
...acc,
...plugins,
};
}, baseValues );
}, defaultInstallExtensionOptions );
};
export const SelectiveExtensionsBundle = ( {
@ -181,7 +217,9 @@ export const SelectiveExtensionsBundle = ( {
onSubmit,
} ) => {
const [ showExtensions, setShowExtensions ] = useState( false );
const [ values, setValues ] = useState( baseValues );
const [ installExtensionOptions, setInstallExtensionOptions ] = useState(
createInstallExtensionOptions()
);
const {
countryCode,
@ -224,19 +262,20 @@ export const SelectiveExtensionsBundle = ( {
}
return ALLOWED_PLUGIN_LISTS.includes( list.key );
} );
}, [ freeExtensions, profileItems ] );
}, [ freeExtensions, profileItems, countryCode ] );
useEffect( () => {
if ( ! isInstallingActivating ) {
const initialValues = createInitialValues( installableExtensions );
setValues( initialValues );
setInstallExtensionOptions(
createInstallExtensionOptions( installableExtensions )
);
}
}, [ installableExtensions ] );
}, [ installableExtensions, isInstallingActivating ] );
const getCheckboxChangeHandler = ( key ) => {
return ( checked ) => {
const newState = {
...values,
...installExtensionOptions,
[ key ]: checked,
};
@ -246,13 +285,13 @@ export const SelectiveExtensionsBundle = ( {
if ( allExtensionsDisabled ) {
// If all the extensions are disabled then disable the "Install Extensions" checkbox too
setValues( {
setInstallExtensionOptions( {
...newState,
install_extensions: false,
} );
} else {
setValues( {
...values,
setInstallExtensionOptions( {
...installExtensionOptions,
[ key ]: checked,
install_extensions: true,
} );
@ -269,10 +308,15 @@ export const SelectiveExtensionsBundle = ( {
<div className="woocommerce-admin__business-details__selective-extensions-bundle">
<div className="woocommerce-admin__business-details__selective-extensions-bundle__extension">
<CheckboxControl
checked={ values.install_extensions }
checked={
installExtensionOptions.install_extensions
}
onChange={ ( checked ) => {
setValues(
setAllPropsToValue( values, checked )
setInstallExtensionOptions(
setAllPropsToValue(
installExtensionOptions,
checked
)
);
} }
/>
@ -308,41 +352,25 @@ export const SelectiveExtensionsBundle = ( {
</div>
{ showExtensions &&
installableExtensions.map(
( { plugins, key: sectionKey, title } ) => (
<div key={ sectionKey }>
{ isResolving ? (
<Spinner />
) : (
<>
<div className="woocommerce-admin__business-details__selective-extensions-bundle__category">
{ title }
</div>
{ plugins.map(
( { description, key } ) => (
<BundleExtensionCheckbox
( { plugins, key, title } ) => (
<ExtensionSection
key={ key }
description={
description
title={ title }
extensions={ plugins }
installExtensionOptions={
installExtensionOptions
}
isChecked={
values[ key ]
onCheckboxChange={
getCheckboxChangeHandler
}
onChange={ getCheckboxChangeHandler(
key
) }
/>
)
) }
</>
) }
</div>
)
) }
</div>
<div className="woocommerce-profile-wizard__business-details__free-features__action">
<Button
onClick={ () => {
onSubmit( values );
onSubmit( installExtensionOptions );
} }
isBusy={ isInstallingActivating || isResolving }
disabled={ isInstallingActivating || isResolving }
@ -353,7 +381,7 @@ export const SelectiveExtensionsBundle = ( {
</div>
</Card>
{ renderBusinessExtensionHelpText(
values,
installExtensionOptions,
isInstallingActivating
) }
</div>

View File

@ -9,7 +9,7 @@ import { pluginNames } from '@woocommerce/data';
/**
* Internal dependencies
*/
import { SelectiveExtensionsBundle } from '../';
import { SelectiveExtensionsBundle, ExtensionSection } from '../';
jest.mock( '../../app-illustration', () => ( {
AppIllustration: jest.fn().mockReturnValue( '[illustration]' ),
@ -129,4 +129,39 @@ describe( 'Selective extensions bundle', () => {
expect( queryByText( 'Google Description' ) ).toBeInTheDocument();
expect( queryByText( 'Random Description' ) ).not.toBeInTheDocument();
} );
describe( '<ExtensionSection />', () => {
it( 'should render title and extensions', () => {
const title = 'This is title';
const { queryByText } = render(
<ExtensionSection
isResolving={ false }
title={ title }
extensions={ freeExtensions[ 0 ].plugins }
installExtensionOptions={ {} }
onCheckboxChange={ () => {} }
/>
);
expect( queryByText( title ) ).toBeInTheDocument();
freeExtensions[ 0 ].plugins.forEach( ( { description } ) => {
expect( queryByText( description ) ).toBeInTheDocument();
} );
} );
it( 'should render not title when no plugins', () => {
const title = 'This is title';
const { queryByText } = render(
<ExtensionSection
isResolving={ false }
title={ title }
extensions={ [] }
installExtensionOptions={ {} }
onCheckboxChange={ () => {} }
/>
);
expect( queryByText( title ) ).not.toBeInTheDocument();
} );
} );
} );

View File

@ -5,7 +5,7 @@ import {
filterBusinessExtensions,
prepareExtensionTrackingData,
} from '../flows/selective-bundle';
import { createInitialValues } from '../flows/selective-bundle/selective-extensions-bundle';
import { createInstallExtensionOptions } from '../flows/selective-bundle/selective-extensions-bundle';
describe( 'BusinessDetails', () => {
test( 'filtering extensions', () => {
@ -101,7 +101,7 @@ describe( 'BusinessDetails', () => {
} );
} );
describe( 'createInitialValues', () => {
describe( 'createInstallExtensionOptions', () => {
test( 'selected by default', () => {
const extensions = [
{
@ -125,7 +125,12 @@ describe( 'BusinessDetails', () => {
},
];
const values = createInitialValues( extensions, 'US', '', [] );
const values = createInstallExtensionOptions(
extensions,
'US',
'',
[]
);
expect( values ).toEqual(
expect.objectContaining( {