Merge branch 'trunk' into e2e/release-plugins-0
This commit is contained in:
commit
06da097968
|
@ -0,0 +1,168 @@
|
|||
name: Run tests against trunk after PR merge
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
api:
|
||||
name: Run API tests
|
||||
runs-on: ubuntu-20.04
|
||||
if: (github.event.pull_request.merged == true) && (github.event.pull_request.base.ref == 'trunk')
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
ALLURE_RESULTS_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/api-core-tests/test-results/allure-results
|
||||
ALLURE_REPORT_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/api-core-tests/test-results/allure-report
|
||||
ARTIFACT_NAME: api-pr-merge-${{ github.event.pull_request.number }}-run-${{ github.run_number }}
|
||||
steps:
|
||||
- name: Checkout merge commit on trunk
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
|
||||
- name: Setup WooCommerce Monorepo
|
||||
uses: ./.github/actions/setup-woocommerce-monorepo
|
||||
with:
|
||||
build-filters: woocommerce
|
||||
|
||||
- name: Setup local test environment
|
||||
uses: ./.github/actions/tests/setup-local-test-environment
|
||||
with:
|
||||
test-type: api
|
||||
|
||||
- name: Run API tests
|
||||
id: run-api-composite-action
|
||||
uses: ./.github/actions/tests/run-api-tests
|
||||
with:
|
||||
report-name: ${{ env.ARTIFACT_NAME }}
|
||||
|
||||
- name: Upload Allure files to bucket
|
||||
if: success() || ( failure() && steps.run-api-composite-action.conclusion == 'failure' )
|
||||
uses: ./.github/actions/tests/upload-allure-files-to-bucket
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.REPORTS_AWS_ACCESS_KEY_ID }}
|
||||
aws-region: ${{ secrets.REPORTS_AWS_REGION }}
|
||||
aws-secret-access-key: ${{ secrets.REPORTS_AWS_SECRET_ACCESS_KEY }}
|
||||
destination-dir: ${{ env.ARTIFACT_NAME }}
|
||||
s3-bucket: ${{ secrets.REPORTS_BUCKET }}
|
||||
|
||||
- name: Publish Allure report
|
||||
if: success() || ( failure() && steps.run-api-composite-action.conclusion == 'failure' )
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPORTS_TOKEN }}
|
||||
run: |
|
||||
gh workflow run publish-test-reports-trunk-merge.yml \
|
||||
-f run_id=${{ github.run_id }} \
|
||||
-f artifact=${{ env.ARTIFACT_NAME }} \
|
||||
-f pr_number=${{ github.event.pull_request.number }} \
|
||||
-f test_type="api" \
|
||||
--repo woocommerce/woocommerce-test-reports
|
||||
|
||||
- name: Send Slack alert on test failure
|
||||
if: failure() && steps.run-api-composite-action.conclusion == 'failure'
|
||||
uses: ./.github/actions/tests/slack-alert-on-pr-merge
|
||||
with:
|
||||
slack-bot-token: ${{ secrets.E2E_SLACK_TOKEN }}
|
||||
channel-id: ${{ secrets.E2E_TRUNK_SLACK_CHANNEL }}
|
||||
test-type: API
|
||||
|
||||
e2e:
|
||||
name: Run E2E tests
|
||||
needs: [api]
|
||||
runs-on: ubuntu-20.04
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
ALLURE_RESULTS_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/test-results/allure-results
|
||||
ALLURE_REPORT_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/test-results/allure-report
|
||||
ARTIFACT_NAME: e2e-pr-merge-${{ github.event.pull_request.number }}-run-${{ github.run_number }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
|
||||
- name: Setup WooCommerce Monorepo
|
||||
uses: ./.github/actions/setup-woocommerce-monorepo
|
||||
with:
|
||||
build-filters: woocommerce
|
||||
|
||||
- name: Setup local test environment
|
||||
uses: ./.github/actions/tests/setup-local-test-environment
|
||||
with:
|
||||
test-type: e2e
|
||||
|
||||
- name: Run E2E tests
|
||||
id: run-e2e-composite-action
|
||||
timeout-minutes: 60
|
||||
uses: ./.github/actions/tests/run-e2e-tests
|
||||
env:
|
||||
E2E_MAX_FAILURES: 15
|
||||
with:
|
||||
report-name: ${{ env.ARTIFACT_NAME }}
|
||||
|
||||
- name: Upload Allure files to bucket
|
||||
if: success() || ( failure() && steps.run-e2e-composite-action.conclusion == 'failure' )
|
||||
uses: ./.github/actions/tests/upload-allure-files-to-bucket
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.REPORTS_AWS_ACCESS_KEY_ID }}
|
||||
aws-region: ${{ secrets.REPORTS_AWS_REGION }}
|
||||
aws-secret-access-key: ${{ secrets.REPORTS_AWS_SECRET_ACCESS_KEY }}
|
||||
destination-dir: ${{ env.ARTIFACT_NAME }}
|
||||
s3-bucket: ${{ secrets.REPORTS_BUCKET }}
|
||||
include-allure-results: false
|
||||
|
||||
- name: Publish Allure report
|
||||
if: success() || ( failure() && steps.run-e2e-composite-action.conclusion == 'failure' )
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPORTS_TOKEN }}
|
||||
run: |
|
||||
gh workflow run publish-test-reports-trunk-merge.yml \
|
||||
-f run_id=${{ github.run_id }} \
|
||||
-f artifact=${{ env.ARTIFACT_NAME }} \
|
||||
-f pr_number=${{ github.event.pull_request.number }} \
|
||||
-f test_type="e2e" \
|
||||
--repo woocommerce/woocommerce-test-reports
|
||||
|
||||
- name: Send Slack alert on test failure
|
||||
if: failure() && steps.run-e2e-composite-action.conclusion == 'failure'
|
||||
uses: ./.github/actions/tests/slack-alert-on-pr-merge
|
||||
with:
|
||||
slack-bot-token: ${{ secrets.E2E_SLACK_TOKEN }}
|
||||
channel-id: ${{ secrets.E2E_TRUNK_SLACK_CHANNEL }}
|
||||
test-type: E2E
|
||||
|
||||
k6:
|
||||
name: Run k6 Performance tests
|
||||
needs: [api]
|
||||
runs-on: ubuntu-20.04
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
|
||||
- name: Setup WooCommerce Monorepo
|
||||
uses: ./.github/actions/setup-woocommerce-monorepo
|
||||
|
||||
- name: Setup local test environment
|
||||
uses: ./.github/actions/tests/setup-local-test-environment
|
||||
with:
|
||||
test-type: k6
|
||||
|
||||
- name: Run k6 performance tests
|
||||
id: run-k6-composite-action
|
||||
uses: './.github/actions/tests/run-k6-tests'
|
||||
|
||||
- name: Send Slack alert on test failure
|
||||
if: failure() && steps.run-k6-composite-action.conclusion == 'failure'
|
||||
uses: ./.github/actions/tests/slack-alert-on-pr-merge
|
||||
with:
|
||||
slack-bot-token: ${{ secrets.E2E_SLACK_TOKEN }}
|
||||
channel-id: ${{ secrets.E2E_TRUNK_SLACK_CHANNEL }}
|
||||
test-type: k6
|
|
@ -1,5 +1,5 @@
|
|||
export { useIntroductionBanner } from './useIntroductionBanner';
|
||||
export { useInstalledPlugins } from './useInstalledPlugins';
|
||||
export { useInstalledPluginsWithoutChannels } from './useInstalledPluginsWithoutChannels';
|
||||
export { useRegisteredChannels } from './useRegisteredChannels';
|
||||
export { useRecommendedChannels } from './useRecommendedChannels';
|
||||
export { useCampaignTypes } from './useCampaignTypes';
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { STORE_KEY } from '~/marketing/data/constants';
|
||||
import { InstalledPlugin } from '~/marketing/types';
|
||||
|
||||
export type UseInstalledPlugins = {
|
||||
installedPlugins: InstalledPlugin[];
|
||||
activatingPlugins: string[];
|
||||
activateInstalledPlugin: ( slug: string ) => void;
|
||||
loadInstalledPluginsAfterActivation: ( slug: string ) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to return plugins and methods for "Installed extensions" card.
|
||||
*/
|
||||
export const useInstalledPlugins = (): UseInstalledPlugins => {
|
||||
const { installedPlugins, activatingPlugins } = useSelect( ( select ) => {
|
||||
const { getInstalledPlugins, getActivatingPlugins } =
|
||||
select( STORE_KEY );
|
||||
|
||||
return {
|
||||
installedPlugins: getInstalledPlugins(),
|
||||
activatingPlugins: getActivatingPlugins(),
|
||||
};
|
||||
}, [] );
|
||||
const { activateInstalledPlugin, loadInstalledPluginsAfterActivation } =
|
||||
useDispatch( STORE_KEY );
|
||||
|
||||
return {
|
||||
installedPlugins,
|
||||
activatingPlugins,
|
||||
activateInstalledPlugin,
|
||||
loadInstalledPluginsAfterActivation,
|
||||
};
|
||||
};
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { chain } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { STORE_KEY } from '~/marketing/data/constants';
|
||||
import { InstalledPlugin } from '~/marketing/types';
|
||||
import { useRecommendedChannels } from './useRecommendedChannels';
|
||||
import { useRegisteredChannels } from './useRegisteredChannels';
|
||||
|
||||
export type UseInstalledPluginsWithoutChannels = {
|
||||
data: InstalledPlugin[];
|
||||
activatingPlugins: string[];
|
||||
activateInstalledPlugin: ( slug: string ) => void;
|
||||
loadInstalledPluginsAfterActivation: ( slug: string ) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to return plugins and methods for "Installed extensions" card.
|
||||
* The list of installed plugins does not include registered and recommended marketing channels.
|
||||
*/
|
||||
export const useInstalledPluginsWithoutChannels =
|
||||
(): UseInstalledPluginsWithoutChannels => {
|
||||
const { installedPlugins, activatingPlugins } = useSelect(
|
||||
( select ) => {
|
||||
const { getInstalledPlugins, getActivatingPlugins } =
|
||||
select( STORE_KEY );
|
||||
|
||||
return {
|
||||
installedPlugins:
|
||||
getInstalledPlugins< InstalledPlugin[] >(),
|
||||
activatingPlugins: getActivatingPlugins(),
|
||||
};
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const {
|
||||
loading: loadingRegisteredChannels,
|
||||
data: dataRegisteredChannels,
|
||||
} = useRegisteredChannels();
|
||||
const {
|
||||
loading: loadingRecommendedChannels,
|
||||
data: dataRecommendedChannels,
|
||||
} = useRecommendedChannels();
|
||||
|
||||
const { activateInstalledPlugin, loadInstalledPluginsAfterActivation } =
|
||||
useDispatch( STORE_KEY );
|
||||
|
||||
const loading = loadingRegisteredChannels || loadingRecommendedChannels;
|
||||
const installedPluginsWithoutChannels = chain( installedPlugins )
|
||||
.differenceWith(
|
||||
dataRegisteredChannels || [],
|
||||
( a, b ) => a.slug === b.slug
|
||||
)
|
||||
.differenceWith(
|
||||
dataRecommendedChannels || [],
|
||||
( a, b ) => a.slug === b.product
|
||||
)
|
||||
.value();
|
||||
|
||||
return {
|
||||
data: loading ? [] : installedPluginsWithoutChannels,
|
||||
activatingPlugins,
|
||||
activateInstalledPlugin,
|
||||
loadInstalledPluginsAfterActivation,
|
||||
};
|
||||
};
|
|
@ -6,8 +6,7 @@ import { render, screen } from '@testing-library/react';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { useInstalledPlugins } from '../../hooks';
|
||||
import { useRecommendedPlugins } from './useRecommendedPlugins';
|
||||
import { useRecommendedPluginsWithoutChannels } from './useRecommendedPluginsWithoutChannels';
|
||||
import { DiscoverTools } from './DiscoverTools';
|
||||
|
||||
jest.mock( '@woocommerce/components', () => {
|
||||
|
@ -20,23 +19,20 @@ jest.mock( '@woocommerce/components', () => {
|
|||
};
|
||||
} );
|
||||
|
||||
jest.mock( './useRecommendedPlugins', () => ( {
|
||||
useRecommendedPlugins: jest.fn(),
|
||||
jest.mock( './useRecommendedPluginsWithoutChannels', () => ( {
|
||||
useRecommendedPluginsWithoutChannels: jest.fn(),
|
||||
} ) );
|
||||
|
||||
jest.mock( '../../hooks', () => ( {
|
||||
useInstalledPlugins: jest.fn(),
|
||||
jest.mock( '~/marketing/hooks', () => ( {
|
||||
useInstalledPluginsWithoutChannels: jest.fn( () => ( {} ) ),
|
||||
} ) );
|
||||
|
||||
describe( 'DiscoverTools component', () => {
|
||||
it( 'should render a Spinner when loading is in progress', () => {
|
||||
( useRecommendedPlugins as jest.Mock ).mockReturnValue( {
|
||||
( useRecommendedPluginsWithoutChannels as jest.Mock ).mockReturnValue( {
|
||||
isInitializing: true,
|
||||
isLoading: true,
|
||||
plugins: [],
|
||||
} );
|
||||
( useInstalledPlugins as jest.Mock ).mockReturnValue( {
|
||||
loadInstalledPluginsAfterActivation: jest.fn(),
|
||||
data: [],
|
||||
} );
|
||||
render( <DiscoverTools /> );
|
||||
|
||||
|
@ -44,13 +40,10 @@ describe( 'DiscoverTools component', () => {
|
|||
} );
|
||||
|
||||
it( 'should render message and link when loading is finish and there are no plugins', () => {
|
||||
( useRecommendedPlugins as jest.Mock ).mockReturnValue( {
|
||||
( useRecommendedPluginsWithoutChannels as jest.Mock ).mockReturnValue( {
|
||||
isInitializing: false,
|
||||
isLoading: false,
|
||||
plugins: [],
|
||||
} );
|
||||
( useInstalledPlugins as jest.Mock ).mockReturnValue( {
|
||||
loadInstalledPluginsAfterActivation: jest.fn(),
|
||||
data: [],
|
||||
} );
|
||||
render( <DiscoverTools /> );
|
||||
|
||||
|
@ -66,10 +59,12 @@ describe( 'DiscoverTools component', () => {
|
|||
|
||||
describe( 'With plugins loaded', () => {
|
||||
it( 'should render `direct_install: true` plugins with "Install plugin" button', () => {
|
||||
( useRecommendedPlugins as jest.Mock ).mockReturnValue( {
|
||||
(
|
||||
useRecommendedPluginsWithoutChannels as jest.Mock
|
||||
).mockReturnValue( {
|
||||
isInitializing: false,
|
||||
isLoading: false,
|
||||
plugins: [
|
||||
data: [
|
||||
{
|
||||
title: 'Google Listings and Ads',
|
||||
description:
|
||||
|
@ -95,9 +90,6 @@ describe( 'DiscoverTools component', () => {
|
|||
},
|
||||
],
|
||||
} );
|
||||
( useInstalledPlugins as jest.Mock ).mockReturnValue( {
|
||||
loadInstalledPluginsAfterActivation: jest.fn(),
|
||||
} );
|
||||
render( <DiscoverTools /> );
|
||||
|
||||
// Assert that we have the "Sales channels" tab, the plugin name, the "Built by WooCommerce" pill, and the "Install plugin" button.
|
||||
|
@ -112,10 +104,12 @@ describe( 'DiscoverTools component', () => {
|
|||
} );
|
||||
|
||||
it( 'should render `direct_install: false` plugins with "View details" button', () => {
|
||||
( useRecommendedPlugins as jest.Mock ).mockReturnValue( {
|
||||
(
|
||||
useRecommendedPluginsWithoutChannels as jest.Mock
|
||||
).mockReturnValue( {
|
||||
isInitializing: false,
|
||||
isLoading: false,
|
||||
plugins: [
|
||||
data: [
|
||||
{
|
||||
title: 'WooCommerce Zapier',
|
||||
description:
|
||||
|
@ -136,9 +130,6 @@ describe( 'DiscoverTools component', () => {
|
|||
},
|
||||
],
|
||||
} );
|
||||
( useInstalledPlugins as jest.Mock ).mockReturnValue( {
|
||||
loadInstalledPluginsAfterActivation: jest.fn(),
|
||||
} );
|
||||
render( <DiscoverTools /> );
|
||||
|
||||
// Assert that we have the CRM tab, plugin name, and "View details" button.
|
||||
|
|
|
@ -14,13 +14,13 @@ import {
|
|||
CardBody,
|
||||
CenteredSpinner,
|
||||
} from '~/marketing/components';
|
||||
import { useRecommendedPlugins } from './useRecommendedPlugins';
|
||||
import { useRecommendedPluginsWithoutChannels } from './useRecommendedPluginsWithoutChannels';
|
||||
import { PluginsTabPanel } from './PluginsTabPanel';
|
||||
import './DiscoverTools.scss';
|
||||
|
||||
export const DiscoverTools = () => {
|
||||
const { isInitializing, isLoading, plugins, installAndActivate } =
|
||||
useRecommendedPlugins();
|
||||
const { isInitializing, isLoading, data, installAndActivate } =
|
||||
useRecommendedPluginsWithoutChannels();
|
||||
|
||||
/**
|
||||
* Renders card body.
|
||||
|
@ -38,7 +38,7 @@ export const DiscoverTools = () => {
|
|||
);
|
||||
}
|
||||
|
||||
if ( plugins.length === 0 ) {
|
||||
if ( data.length === 0 ) {
|
||||
return (
|
||||
<CardBody className="woocommerce-marketing-discover-tools-card-body-empty-content">
|
||||
<Icon icon={ trendingUp } size={ 32 } />
|
||||
|
@ -66,7 +66,7 @@ export const DiscoverTools = () => {
|
|||
|
||||
return (
|
||||
<PluginsTabPanel
|
||||
plugins={ plugins }
|
||||
plugins={ data }
|
||||
isLoading={ isLoading }
|
||||
onInstallAndActivate={ installAndActivate }
|
||||
/>
|
||||
|
|
|
@ -14,7 +14,7 @@ import { flatMapDeep, uniqBy } from 'lodash';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { CardDivider, PluginCardBody } from '~/marketing/components';
|
||||
import { useInstalledPlugins } from '~/marketing/hooks';
|
||||
import { useInstalledPluginsWithoutChannels } from '~/marketing/hooks';
|
||||
import { RecommendedPlugin } from '~/marketing/types';
|
||||
import { getInAppPurchaseUrl } from '~/lib/in-app-purchase';
|
||||
import { createNoticesFromResponse } from '~/lib/notices';
|
||||
|
@ -60,7 +60,8 @@ export const PluginsTabPanel = ( {
|
|||
null
|
||||
);
|
||||
const { installAndActivatePlugins } = useDispatch( PLUGINS_STORE_NAME );
|
||||
const { loadInstalledPluginsAfterActivation } = useInstalledPlugins();
|
||||
const { loadInstalledPluginsAfterActivation } =
|
||||
useInstalledPluginsWithoutChannels();
|
||||
|
||||
/**
|
||||
* Install and activate a plugin.
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { STORE_KEY } from '~/marketing/data/constants';
|
||||
import { RecommendedPlugin } from '~/marketing/types';
|
||||
|
||||
const selector = 'getRecommendedPlugins';
|
||||
const category = 'marketing';
|
||||
|
||||
export const useRecommendedPlugins = () => {
|
||||
const { invalidateResolution, installAndActivateRecommendedPlugin } =
|
||||
useDispatch( STORE_KEY );
|
||||
|
||||
const installAndActivate = ( plugin: string ) => {
|
||||
installAndActivateRecommendedPlugin( plugin, category );
|
||||
invalidateResolution( selector, [ category ] );
|
||||
};
|
||||
|
||||
return useSelect( ( select ) => {
|
||||
const { getRecommendedPlugins, hasFinishedResolution } =
|
||||
select( STORE_KEY );
|
||||
const plugins =
|
||||
getRecommendedPlugins< RecommendedPlugin[] >( category );
|
||||
const isLoading = ! hasFinishedResolution( selector, [ category ] );
|
||||
|
||||
return {
|
||||
isInitializing: ! plugins.length && isLoading,
|
||||
isLoading,
|
||||
plugins,
|
||||
installAndActivate,
|
||||
};
|
||||
}, [] );
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { differenceWith } from 'lodash';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { STORE_KEY } from '~/marketing/data/constants';
|
||||
import { useRecommendedChannels } from '~/marketing/hooks';
|
||||
import { RecommendedPlugin } from '~/marketing/types';
|
||||
|
||||
type UseRecommendedPluginsWithoutChannels = {
|
||||
/**
|
||||
* Boolean indicating whether it is initializing.
|
||||
*/
|
||||
isInitializing: boolean;
|
||||
|
||||
/**
|
||||
* Boolean indicating whether it is loading.
|
||||
*
|
||||
* This will be true when data is being refetched
|
||||
* after `invalidateResolution` is called in the `installAndActivate` method.
|
||||
*/
|
||||
isLoading: boolean;
|
||||
|
||||
/**
|
||||
* An array of recommended marketing plugins without marketing channels.
|
||||
*/
|
||||
data: RecommendedPlugin[];
|
||||
|
||||
/**
|
||||
* Install and activate a plugin.
|
||||
*/
|
||||
installAndActivate: ( slug: string ) => void;
|
||||
};
|
||||
|
||||
const selector = 'getRecommendedPlugins';
|
||||
const category = 'marketing';
|
||||
|
||||
/**
|
||||
* A hook to return a list of recommended plugins without marketing channels,
|
||||
* and related methods, to be used with the `DiscoverTools` component.
|
||||
*/
|
||||
export const useRecommendedPluginsWithoutChannels =
|
||||
(): UseRecommendedPluginsWithoutChannels => {
|
||||
const {
|
||||
loading: loadingRecommendedPlugins,
|
||||
data: dataRecommendedPlugins,
|
||||
} = useSelect( ( select ) => {
|
||||
const { getRecommendedPlugins, hasFinishedResolution } =
|
||||
select( STORE_KEY );
|
||||
|
||||
return {
|
||||
loading: ! hasFinishedResolution( selector, [ category ] ),
|
||||
data: getRecommendedPlugins< RecommendedPlugin[] >( category ),
|
||||
};
|
||||
}, [] );
|
||||
|
||||
const {
|
||||
loading: loadingRecommendedChannels,
|
||||
data: dataRecommendedChannels,
|
||||
} = useRecommendedChannels();
|
||||
|
||||
const { invalidateResolution, installAndActivateRecommendedPlugin } =
|
||||
useDispatch( STORE_KEY );
|
||||
|
||||
const isInitializing =
|
||||
( loadingRecommendedPlugins && ! dataRecommendedPlugins.length ) ||
|
||||
( loadingRecommendedChannels && ! dataRecommendedChannels );
|
||||
|
||||
const loading = loadingRecommendedPlugins || loadingRecommendedChannels;
|
||||
|
||||
const recommendedPluginsWithoutChannels = differenceWith(
|
||||
dataRecommendedPlugins,
|
||||
dataRecommendedChannels || [],
|
||||
( a, b ) => a.product === b.product
|
||||
);
|
||||
|
||||
const installAndActivate = ( slug: string ) => {
|
||||
installAndActivateRecommendedPlugin( slug, category );
|
||||
invalidateResolution( selector, [ category ] );
|
||||
};
|
||||
|
||||
return {
|
||||
isInitializing,
|
||||
isLoading: loading,
|
||||
data: isInitializing ? [] : recommendedPluginsWithoutChannels,
|
||||
installAndActivate,
|
||||
};
|
||||
};
|
|
@ -16,13 +16,13 @@ import {
|
|||
PluginCardBody,
|
||||
} from '~/marketing/components';
|
||||
import { InstalledPlugin } from '~/marketing/types';
|
||||
import { useInstalledPlugins } from '~/marketing/hooks';
|
||||
import { useInstalledPluginsWithoutChannels } from '~/marketing/hooks';
|
||||
|
||||
export const InstalledExtensions = () => {
|
||||
const { installedPlugins, activatingPlugins, activateInstalledPlugin } =
|
||||
useInstalledPlugins();
|
||||
const { data, activatingPlugins, activateInstalledPlugin } =
|
||||
useInstalledPluginsWithoutChannels();
|
||||
|
||||
if ( installedPlugins.length === 0 ) {
|
||||
if ( data.length === 0 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ export const InstalledExtensions = () => {
|
|||
|
||||
return (
|
||||
<CollapsibleCard header={ __( 'Installed extensions', 'woocommerce' ) }>
|
||||
{ installedPlugins.map( ( el, idx ) => {
|
||||
{ data.map( ( el, idx ) => {
|
||||
return (
|
||||
<Fragment key={ el.slug }>
|
||||
<PluginCardBody
|
||||
|
@ -90,9 +90,7 @@ export const InstalledExtensions = () => {
|
|||
description={ el.description }
|
||||
button={ getButton( el ) }
|
||||
/>
|
||||
{ idx !== installedPlugins.length - 1 && (
|
||||
<CardDivider />
|
||||
) }
|
||||
{ idx !== data.length - 1 && <CardDivider /> }
|
||||
</Fragment>
|
||||
);
|
||||
} ) }
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
|
||||
Run E2E tests on PR merge to trunk.
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
Filter out marketing channels in "Installed extensions" and "Discover more marketing tools" cards.
|
Loading…
Reference in New Issue