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:
parent
a0278af8ad
commit
ac78e74ef6
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: Fix
|
||||||
|
|
||||||
|
Hide the extensions header when no available plugins in the category. #8089
|
|
@ -159,8 +159,44 @@ const BundleExtensionCheckbox = ( { onChange, description, isChecked } ) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const baseValues = { install_extensions: true };
|
export const ExtensionSection = ( {
|
||||||
export const createInitialValues = ( extensions ) => {
|
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 ) => {
|
return extensions.reduce( ( acc, curr ) => {
|
||||||
const plugins = curr.plugins.reduce(
|
const plugins = curr.plugins.reduce(
|
||||||
( pluginAcc, { key, selected } ) => {
|
( pluginAcc, { key, selected } ) => {
|
||||||
|
@ -173,7 +209,7 @@ export const createInitialValues = ( extensions ) => {
|
||||||
...acc,
|
...acc,
|
||||||
...plugins,
|
...plugins,
|
||||||
};
|
};
|
||||||
}, baseValues );
|
}, defaultInstallExtensionOptions );
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SelectiveExtensionsBundle = ( {
|
export const SelectiveExtensionsBundle = ( {
|
||||||
|
@ -181,7 +217,9 @@ export const SelectiveExtensionsBundle = ( {
|
||||||
onSubmit,
|
onSubmit,
|
||||||
} ) => {
|
} ) => {
|
||||||
const [ showExtensions, setShowExtensions ] = useState( false );
|
const [ showExtensions, setShowExtensions ] = useState( false );
|
||||||
const [ values, setValues ] = useState( baseValues );
|
const [ installExtensionOptions, setInstallExtensionOptions ] = useState(
|
||||||
|
createInstallExtensionOptions()
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
countryCode,
|
countryCode,
|
||||||
|
@ -224,19 +262,20 @@ export const SelectiveExtensionsBundle = ( {
|
||||||
}
|
}
|
||||||
return ALLOWED_PLUGIN_LISTS.includes( list.key );
|
return ALLOWED_PLUGIN_LISTS.includes( list.key );
|
||||||
} );
|
} );
|
||||||
}, [ freeExtensions, profileItems ] );
|
}, [ freeExtensions, profileItems, countryCode ] );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
if ( ! isInstallingActivating ) {
|
if ( ! isInstallingActivating ) {
|
||||||
const initialValues = createInitialValues( installableExtensions );
|
setInstallExtensionOptions(
|
||||||
setValues( initialValues );
|
createInstallExtensionOptions( installableExtensions )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [ installableExtensions ] );
|
}, [ installableExtensions, isInstallingActivating ] );
|
||||||
|
|
||||||
const getCheckboxChangeHandler = ( key ) => {
|
const getCheckboxChangeHandler = ( key ) => {
|
||||||
return ( checked ) => {
|
return ( checked ) => {
|
||||||
const newState = {
|
const newState = {
|
||||||
...values,
|
...installExtensionOptions,
|
||||||
[ key ]: checked,
|
[ key ]: checked,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -246,13 +285,13 @@ export const SelectiveExtensionsBundle = ( {
|
||||||
|
|
||||||
if ( allExtensionsDisabled ) {
|
if ( allExtensionsDisabled ) {
|
||||||
// If all the extensions are disabled then disable the "Install Extensions" checkbox too
|
// If all the extensions are disabled then disable the "Install Extensions" checkbox too
|
||||||
setValues( {
|
setInstallExtensionOptions( {
|
||||||
...newState,
|
...newState,
|
||||||
install_extensions: false,
|
install_extensions: false,
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
setValues( {
|
setInstallExtensionOptions( {
|
||||||
...values,
|
...installExtensionOptions,
|
||||||
[ key ]: checked,
|
[ key ]: checked,
|
||||||
install_extensions: true,
|
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">
|
||||||
<div className="woocommerce-admin__business-details__selective-extensions-bundle__extension">
|
<div className="woocommerce-admin__business-details__selective-extensions-bundle__extension">
|
||||||
<CheckboxControl
|
<CheckboxControl
|
||||||
checked={ values.install_extensions }
|
checked={
|
||||||
|
installExtensionOptions.install_extensions
|
||||||
|
}
|
||||||
onChange={ ( checked ) => {
|
onChange={ ( checked ) => {
|
||||||
setValues(
|
setInstallExtensionOptions(
|
||||||
setAllPropsToValue( values, checked )
|
setAllPropsToValue(
|
||||||
|
installExtensionOptions,
|
||||||
|
checked
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} }
|
} }
|
||||||
/>
|
/>
|
||||||
|
@ -308,41 +352,25 @@ export const SelectiveExtensionsBundle = ( {
|
||||||
</div>
|
</div>
|
||||||
{ showExtensions &&
|
{ showExtensions &&
|
||||||
installableExtensions.map(
|
installableExtensions.map(
|
||||||
( { plugins, key: sectionKey, title } ) => (
|
( { plugins, key, title } ) => (
|
||||||
<div key={ sectionKey }>
|
<ExtensionSection
|
||||||
{ isResolving ? (
|
|
||||||
<Spinner />
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="woocommerce-admin__business-details__selective-extensions-bundle__category">
|
|
||||||
{ title }
|
|
||||||
</div>
|
|
||||||
{ plugins.map(
|
|
||||||
( { description, key } ) => (
|
|
||||||
<BundleExtensionCheckbox
|
|
||||||
key={ key }
|
key={ key }
|
||||||
description={
|
title={ title }
|
||||||
description
|
extensions={ plugins }
|
||||||
|
installExtensionOptions={
|
||||||
|
installExtensionOptions
|
||||||
}
|
}
|
||||||
isChecked={
|
onCheckboxChange={
|
||||||
values[ key ]
|
getCheckboxChangeHandler
|
||||||
}
|
}
|
||||||
onChange={ getCheckboxChangeHandler(
|
|
||||||
key
|
|
||||||
) }
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
) }
|
) }
|
||||||
</>
|
|
||||||
) }
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
) }
|
|
||||||
</div>
|
</div>
|
||||||
<div className="woocommerce-profile-wizard__business-details__free-features__action">
|
<div className="woocommerce-profile-wizard__business-details__free-features__action">
|
||||||
<Button
|
<Button
|
||||||
onClick={ () => {
|
onClick={ () => {
|
||||||
onSubmit( values );
|
onSubmit( installExtensionOptions );
|
||||||
} }
|
} }
|
||||||
isBusy={ isInstallingActivating || isResolving }
|
isBusy={ isInstallingActivating || isResolving }
|
||||||
disabled={ isInstallingActivating || isResolving }
|
disabled={ isInstallingActivating || isResolving }
|
||||||
|
@ -353,7 +381,7 @@ export const SelectiveExtensionsBundle = ( {
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
{ renderBusinessExtensionHelpText(
|
{ renderBusinessExtensionHelpText(
|
||||||
values,
|
installExtensionOptions,
|
||||||
isInstallingActivating
|
isInstallingActivating
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { pluginNames } from '@woocommerce/data';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { SelectiveExtensionsBundle } from '../';
|
import { SelectiveExtensionsBundle, ExtensionSection } from '../';
|
||||||
|
|
||||||
jest.mock( '../../app-illustration', () => ( {
|
jest.mock( '../../app-illustration', () => ( {
|
||||||
AppIllustration: jest.fn().mockReturnValue( '[illustration]' ),
|
AppIllustration: jest.fn().mockReturnValue( '[illustration]' ),
|
||||||
|
@ -129,4 +129,39 @@ describe( 'Selective extensions bundle', () => {
|
||||||
expect( queryByText( 'Google Description' ) ).toBeInTheDocument();
|
expect( queryByText( 'Google Description' ) ).toBeInTheDocument();
|
||||||
expect( queryByText( 'Random Description' ) ).not.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();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
filterBusinessExtensions,
|
filterBusinessExtensions,
|
||||||
prepareExtensionTrackingData,
|
prepareExtensionTrackingData,
|
||||||
} from '../flows/selective-bundle';
|
} from '../flows/selective-bundle';
|
||||||
import { createInitialValues } from '../flows/selective-bundle/selective-extensions-bundle';
|
import { createInstallExtensionOptions } from '../flows/selective-bundle/selective-extensions-bundle';
|
||||||
|
|
||||||
describe( 'BusinessDetails', () => {
|
describe( 'BusinessDetails', () => {
|
||||||
test( 'filtering extensions', () => {
|
test( 'filtering extensions', () => {
|
||||||
|
@ -101,7 +101,7 @@ describe( 'BusinessDetails', () => {
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
describe( 'createInitialValues', () => {
|
describe( 'createInstallExtensionOptions', () => {
|
||||||
test( 'selected by default', () => {
|
test( 'selected by default', () => {
|
||||||
const extensions = [
|
const extensions = [
|
||||||
{
|
{
|
||||||
|
@ -125,7 +125,12 @@ describe( 'BusinessDetails', () => {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const values = createInitialValues( extensions, 'US', '', [] );
|
const values = createInstallExtensionOptions(
|
||||||
|
extensions,
|
||||||
|
'US',
|
||||||
|
'',
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
expect( values ).toEqual(
|
expect( values ).toEqual(
|
||||||
expect.objectContaining( {
|
expect.objectContaining( {
|
||||||
|
|
Loading…
Reference in New Issue