diff --git a/plugins/woocommerce-admin/changelogs/update-7751 b/plugins/woocommerce-admin/changelogs/update-7751 new file mode 100644 index 00000000000..3cbb48aaba1 --- /dev/null +++ b/plugins/woocommerce-admin/changelogs/update-7751 @@ -0,0 +1,4 @@ +Significance: patch +Type: Fix + +Replace old task list option calls with data store selectors #7820 diff --git a/plugins/woocommerce-admin/client/header/activity-panel/display-options/index.js b/plugins/woocommerce-admin/client/header/activity-panel/display-options/index.js index 92694ca155f..c9ac8f448db 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/display-options/index.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/display-options/index.js @@ -9,7 +9,11 @@ import { } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; -import { useUserPreferences, OPTIONS_STORE_NAME } from '@woocommerce/data'; +import { + useUserPreferences, + ONBOARDING_STORE_NAME, + OPTIONS_STORE_NAME, +} from '@woocommerce/data'; import { recordEvent } from '@woocommerce/tracks'; /** @@ -53,14 +57,15 @@ export const DisplayOptions = () => { isTaskListHidden, } = useSelect( ( select ) => { const { getOption } = select( OPTIONS_STORE_NAME ); + const { getTaskList } = select( ONBOARDING_STORE_NAME ); + const taskList = getTaskList( 'setup' ); + return { defaultHomescreenLayout: getOption( 'woocommerce_default_homepage_layout' ) || 'single_column', - taskListComplete: - getOption( 'woocommerce_task_list_complete' ) === 'yes', - isTaskListHidden: - getOption( 'woocommerce_task_list_hidden' ) === 'yes', + taskListComplete: taskList?.isComplete, + isTaskListHidden: taskList?.isHidden, }; } ); const { diff --git a/plugins/woocommerce-admin/client/header/activity-panel/display-options/test/index.js b/plugins/woocommerce-admin/client/header/activity-panel/display-options/test/index.js index e4206ba261d..6891113362c 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/display-options/test/index.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/display-options/test/index.js @@ -17,6 +17,19 @@ jest.mock( '@woocommerce/data', () => ( { .fn() .mockReturnValue( { updateUserPreferences: jest.fn() } ), } ) ); +jest.mock( '@wordpress/data', () => { + const originalModule = jest.requireActual( '@wordpress/data' ); + + return { + __esModule: true, + ...originalModule, + useSelect: jest.fn().mockReturnValue( { + defaultHomescreenLayout: 'single_column', + taskListComplete: false, + isTaskListHidde: false, + } ), + }; +} ); describe( 'Activity Panel - Homescreen Display Options', () => { it( 'correctly tracks opening the options', () => { diff --git a/plugins/woocommerce-admin/client/header/activity-panel/index.js b/plugins/woocommerce-admin/client/header/activity-panel/index.js index 0a41ecfb943..f1d888b473f 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/index.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/index.js @@ -20,7 +20,6 @@ import { } from '@woocommerce/data'; import { getHistory, getNewPath } from '@woocommerce/navigation'; import { recordEvent } from '@woocommerce/tracks'; -import { applyFilters } from '@wordpress/hooks'; import { useSlot } from '@woocommerce/experimental'; /** @@ -85,19 +84,16 @@ export const ActivityPanel = ( { isEmbedded, query, userPreferencesData } ) => { return trackData; }; - function getThingsToDoNextCount( - tasks, - dismissedTasks, - isExtendedTaskListHidden - ) { - if ( ! tasks || isExtendedTaskListHidden ) { + function getThingsToDoNextCount( extendedTaskList ) { + if ( + ! extendedTaskList || + ! extendedTaskList.tasks.length || + extendedTaskList.isHidden + ) { return 0; } - return tasks.filter( - ( task ) => - task.visible && - ! task.completed && - ! dismissedTasks.includes( task.key ) + return extendedTaskList.tasks.filter( + ( task ) => task.canView && ! task.isComplete && ! task.isDismissed ).length; } @@ -133,31 +129,23 @@ export const ActivityPanel = ( { isEmbedded, query, userPreferencesData } ) => { const { hasUnreadNotes, hasAbbreviatedNotifications, + isCompletedTask, thingsToDoNextCount, requestingTaskListOptions, setupTaskListComplete, setupTaskListHidden, - trackedCompletedTasks, previewSiteBtnTrackData, } = useSelect( ( select ) => { - const { getOption, isResolving } = select( OPTIONS_STORE_NAME ); - const isSetupTaskListHidden = - getOption( 'woocommerce_task_list_hidden' ) === 'yes'; - const isExtendedTaskListHidden = - getOption( 'woocommerce_extended_task_list_hidden' ) === 'yes'; - const extendedTaskList = applyFilters( - 'woocommerce_admin_onboarding_task_list', - [], - query - ); - const dismissedTasks = - getOption( 'woocommerce_task_list_dismissed_tasks' ) || []; - const thingsToDoCount = getThingsToDoNextCount( - extendedTaskList, - dismissedTasks, - isExtendedTaskListHidden + const { getOption } = select( OPTIONS_STORE_NAME ); + const { getTask, getTaskList, hasFinishedResolution } = select( + ONBOARDING_STORE_NAME ); + const isSetupTaskListHidden = getTaskList( 'setup' )?.isHidden; + const extendedTaskList = getTaskList( 'extended' ); + + const thingsToDoCount = getThingsToDoNextCount( extendedTaskList ); + return { hasUnreadNotes: isNotesPanelVisible( select ), hasAbbreviatedNotifications: isAbbreviatedPanelVisible( @@ -166,24 +154,21 @@ export const ActivityPanel = ( { isEmbedded, query, userPreferencesData } ) => { thingsToDoCount ), thingsToDoNextCount: thingsToDoCount, - requestingTaskListOptions: - isResolving( 'getOption', [ - 'woocommerce_task_list_complete', - ] ) || - isResolving( 'getOption', [ 'woocommerce_task_list_hidden' ] ), - setupTaskListComplete: - getOption( 'woocommerce_task_list_complete' ) === 'yes', + requestingTaskListOptions: ! hasFinishedResolution( + 'getTaskLists' + ), + setupTaskListComplete: getTaskList( 'setup' )?.isComplete, setupTaskListHidden: isSetupTaskListHidden, - trackedCompletedTasks: - getOption( 'woocommerce_task_list_tracked_completed_tasks' ) || - [], + isCompletedTask: Boolean( + query.task && getTask( query.task )?.isComplete + ), previewSiteBtnTrackData: getPreviewSiteBtnTrackData( select, getOption ), }; } ); - const { updateOptions } = useDispatch( OPTIONS_STORE_NAME ); + const { unhideTaskList } = useDispatch( ONBOARDING_STORE_NAME ); const { currentUserCan } = useUser(); const togglePanel = ( { name: tabName }, isTabOpen ) => { @@ -265,9 +250,7 @@ export const ActivityPanel = ( { isEmbedded, query, userPreferencesData } ) => { if ( setupTaskListHidden === 'no' ) { redirectToHomeScreen(); } else { - updateOptions( { - woocommerce_task_list_hidden: 'no', - } ).then( redirectToHomeScreen ); + unhideTaskList( 'setup' ).then( redirectToHomeScreen ); } } @@ -275,6 +258,7 @@ export const ActivityPanel = ( { isEmbedded, query, userPreferencesData } ) => { }, visible: currentUserCan( 'manage_woocommerce' ) && + ! requestingTaskListOptions && ! setupTaskListComplete && ! setupTaskListHidden && ! isPerformingSetupTask() && @@ -365,7 +349,7 @@ export const ActivityPanel = ( { isEmbedded, query, userPreferencesData } ) => { task && highlightShown !== 'yes' && ( startedTasks || {} )[ task ] > 1 && - ! trackedCompletedTasks.includes( task ) + ! isCompletedTask ) { return true; } diff --git a/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox/abbreviated-notifications-panel.js b/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox/abbreviated-notifications-panel.js index e2e8c91cffc..0d8939f0149 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox/abbreviated-notifications-panel.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox/abbreviated-notifications-panel.js @@ -6,7 +6,7 @@ import { Text } from '@woocommerce/experimental'; import { recordEvent } from '@woocommerce/tracks'; import { AbbreviatedCard } from '@woocommerce/components'; import { useSelect } from '@wordpress/data'; -import { OPTIONS_STORE_NAME } from '@woocommerce/data'; +import { ONBOARDING_STORE_NAME } from '@woocommerce/data'; import { box, comment, page } from '@wordpress/icons'; import { createSlotFill } from '@wordpress/components'; @@ -37,16 +37,15 @@ export const AbbreviatedNotificationsPanel = ( { thingsToDoNextCount } ) => { isSetupTaskListHidden, isExtendedTaskListHidden, } = useSelect( ( select ) => { - const { getOption } = select( OPTIONS_STORE_NAME ); + const { getTaskList } = select( ONBOARDING_STORE_NAME ); const orderStatuses = getOrderStatuses( select ); + return { ordersToProcessCount: getUnreadOrders( select, orderStatuses ), reviewsToModerateCount: getUnapprovedReviews( select ), stockNoticesCount: getLowStockCount( select ), - isSetupTaskListHidden: - getOption( 'woocommerce_task_list_hidden' ) === 'yes', - isExtendedTaskListHidden: - getOption( 'woocommerce_extended_task_list_hidden' ) === 'yes', + isSetupTaskListHidden: getTaskList( 'setup' )?.isHidden, + isExtendedTaskListHidden: getTaskList( 'extended' )?.isHidden, }; } ); diff --git a/plugins/woocommerce-admin/client/header/activity-panel/test/index.js b/plugins/woocommerce-admin/client/header/activity-panel/test/index.js index 7c7fbb42bac..ae236f5c075 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/test/index.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/test/index.js @@ -264,7 +264,7 @@ describe( 'Activity Panel', () => { requestingTaskListOptions: false, setupTaskListComplete: false, setupTaskListHidden: false, - trackedCompletedTasks: [ 'payment' ], + isCompletedTask: true, } ) ); const { queryByText } = render( diff --git a/plugins/woocommerce-admin/client/homescreen/activity-panel/index.js b/plugins/woocommerce-admin/client/homescreen/activity-panel/index.js index b25319c4062..8ace562f6c1 100644 --- a/plugins/woocommerce-admin/client/homescreen/activity-panel/index.js +++ b/plugins/woocommerce-admin/client/homescreen/activity-panel/index.js @@ -39,16 +39,14 @@ export const ActivityPanel = () => { const countLowStockProducts = getLowStockCount( select ); const countUnapprovedReviews = getUnapprovedReviews( select ); const publishedProductCount = getSetting( 'publishedProductCount', 0 ); - const taskLists = select( ONBOARDING_STORE_NAME ).getTaskLists(); + const taskList = select( ONBOARDING_STORE_NAME ).getTaskList( 'setup' ); return { countLowStockProducts, countUnapprovedReviews, countUnreadOrders, manageStock, - isTaskListHidden: Boolean( taskLists.length ) - ? ! taskLists.find( ( list ) => list.id === 'setup' ).isVisible - : null, + isTaskListHidden: taskList?.isHidden, publishedProductCount, reviewsEnabled, totalOrderCount, @@ -66,7 +64,7 @@ export const ActivityPanel = () => { acc[ panelId ] = true; return acc; }, - { task_list: ! panelsData.isTaskListHidden } + { task_list: panelsData.isTaskListHidden } ); recordEvent( 'activity_panel_visible_panels', visiblePanels ); } diff --git a/plugins/woocommerce-admin/client/homescreen/activity-panel/test/index.js b/plugins/woocommerce-admin/client/homescreen/activity-panel/test/index.js index 104dc82d346..124f1984530 100644 --- a/plugins/woocommerce-admin/client/homescreen/activity-panel/test/index.js +++ b/plugins/woocommerce-admin/client/homescreen/activity-panel/test/index.js @@ -8,6 +8,18 @@ import { render, screen } from '@testing-library/react'; */ import { ActivityPanel } from '../'; +jest.mock( '@wordpress/data', () => { + const originalModule = jest.requireActual( '@wordpress/data' ); + + return { + __esModule: true, + ...originalModule, + useSelect: jest.fn().mockReturnValue( { + isTaskListHidden: false, + } ), + }; +} ); + // Mock the panels. jest.mock( '../panels', () => { return { diff --git a/plugins/woocommerce-admin/client/homescreen/layout.js b/plugins/woocommerce-admin/client/homescreen/layout.js index d2fb613fd9f..fba4a7c4576 100644 --- a/plugins/woocommerce-admin/client/homescreen/layout.js +++ b/plugins/woocommerce-admin/client/homescreen/layout.js @@ -16,6 +16,7 @@ import PropTypes from 'prop-types'; import { useUserPreferences, NOTES_STORE_NAME, + ONBOARDING_STORE_NAME, OPTIONS_STORE_NAME, } from '@woocommerce/data'; import { __ } from '@wordpress/i18n'; @@ -61,7 +62,7 @@ export const Layout = ( { isBatchUpdating, query, taskListComplete, - bothTaskListsHidden, + hasTaskList, shouldShowWelcomeModal, shouldShowWelcomeFromCalypsoModal, isTaskListHidden, @@ -72,8 +73,6 @@ export const Layout = ( { const hasTwoColumnContent = shouldShowStoreLinks || window.wcAdminFeatures.analytics; const [ showInbox, setShowInbox ] = useState( true ); - - const isTaskListEnabled = bothTaskListsHidden === false; const isDashboardShown = ! query.task; const momentDate = moment().utc(); @@ -164,7 +163,7 @@ export const Layout = ( { /> ) } { ! isRunningTaskListExperiment && } - { isTaskListEnabled && renderTaskList() } + { hasTaskList && renderTaskList() } @@ -254,9 +253,9 @@ Layout.propTypes = { */ taskListComplete: PropTypes.bool, /** - * If the task list is hidden. + * If any task list is visible. */ - bothTaskListsHidden: PropTypes.bool, + hasTaskList: PropTypes.bool, /** * Page query, used to determine the current task if any. */ @@ -281,6 +280,8 @@ export default compose( const { getOption, hasFinishedResolution } = select( OPTIONS_STORE_NAME ); + const { getTaskList, getTaskLists } = select( ONBOARDING_STORE_NAME ); + const taskLists = getTaskLists(); const welcomeFromCalypsoModalDismissed = getOption( WELCOME_FROM_CALYPSO_MODAL_DISMISSED_OPTION_NAME ) === @@ -315,20 +316,15 @@ export default compose( const defaultHomescreenLayout = getOption( 'woocommerce_default_homepage_layout' ) || 'single_column'; - const isTaskListHidden = - getOption( 'woocommerce_task_list_hidden' ) === 'yes'; return { defaultHomescreenLayout, isBatchUpdating: isNotesRequesting( 'batchUpdateNotes' ), shouldShowWelcomeModal, shouldShowWelcomeFromCalypsoModal, - isTaskListHidden, - bothTaskListsHidden: - isTaskListHidden && - getOption( 'woocommerce_extended_task_list_hidden' ) === 'yes', - taskListComplete: - getOption( 'woocommerce_task_list_complete' ) === 'yes', + isTaskListHidden: getTaskList( 'setup' )?.isHidden, + hasTaskList: taskLists.find( ( list ) => list.isVisible ), + taskListComplete: getTaskList( 'setup' )?.isComplete, }; } ), withDispatch( ( dispatch ) => ( { diff --git a/plugins/woocommerce-admin/client/homescreen/test/index.js b/plugins/woocommerce-admin/client/homescreen/test/index.js index d33e6a68c3f..0c63acf1af2 100644 --- a/plugins/woocommerce-admin/client/homescreen/test/index.js +++ b/plugins/woocommerce-admin/client/homescreen/test/index.js @@ -47,7 +47,7 @@ describe( 'Homescreen Layout', () => { {} } /> @@ -68,7 +68,7 @@ describe( 'Homescreen Layout', () => { const { container } = render( { render( {} } /> @@ -105,7 +105,7 @@ describe( 'Homescreen Layout', () => { render( {} } @@ -126,7 +126,7 @@ describe( 'Homescreen Layout', () => { {} } /> @@ -149,7 +149,7 @@ describe( 'Homescreen Layout', () => { const { container } = render( {} } /> @@ -172,7 +172,7 @@ describe( 'Homescreen Layout', () => { const { container } = render( {} } /> @@ -194,7 +194,7 @@ describe( 'Homescreen Layout', () => { {} } /> @@ -236,7 +236,7 @@ describe( 'Homescreen Layout', () => { {} } diff --git a/plugins/woocommerce-admin/client/profile-wizard/index.js b/plugins/woocommerce-admin/client/profile-wizard/index.js index 25b4f4c02df..2d3fd7226c9 100644 --- a/plugins/woocommerce-admin/client/profile-wizard/index.js +++ b/plugins/woocommerce-admin/client/profile-wizard/index.js @@ -152,7 +152,7 @@ class ProfileWizard extends Component { } async goToNextStep() { - const { activePlugins, dismissedTasks, updateOptions } = this.props; + const { activePlugins } = this.props; const currentStep = this.getCurrentStep(); const currentStepIndex = this.getSteps().findIndex( ( s ) => s.key === currentStep.key @@ -162,12 +162,6 @@ class ProfileWizard extends Component { step: currentStep.key, } ); - if ( dismissedTasks.length ) { - updateOptions( { - woocommerce_task_list_dismissed_tasks: [], - } ); - } - // Update the activePlugins cache in case plugins were installed // in the current step that affect the visibility of the next step. this.cachedActivePlugins = activePlugins; @@ -269,7 +263,6 @@ class ProfileWizard extends Component { export default compose( withSelect( ( select ) => { const { getNotes } = select( NOTES_STORE_NAME ); - const { getOption } = select( OPTIONS_STORE_NAME ); const { getProfileItems, getOnboardingError } = select( ONBOARDING_STORE_NAME ); @@ -289,11 +282,8 @@ export default compose( }; const notes = getNotes( notesQuery ); const activePlugins = getActivePlugins(); - const dismissedTasks = - getOption( 'woocommerce_task_list_dismissed_tasks' ) || []; return { - dismissedTasks, getPluginsError, isError: Boolean( getOnboardingError( 'updateProfileItems' ) ), isJetpackConnected: isJetpackConnected(), diff --git a/plugins/woocommerce-admin/docs/features/onboarding-tasks.md b/plugins/woocommerce-admin/docs/features/onboarding-tasks.md index 27789931f85..08539273920 100644 --- a/plugins/woocommerce-admin/docs/features/onboarding-tasks.md +++ b/plugins/woocommerce-admin/docs/features/onboarding-tasks.md @@ -94,7 +94,7 @@ $list = new TaskList( $args ); * `$task_list->is_hidden()` - Check if a task list is hidden * `$task_list->is_visible()` - Check if a task list is visible (opposite value of `is_hidden()`) * `$task_list->hide()` - Hide a task list -* `$task_list->show()` - Undo hiding of a task list +* `$task_list->unhide()` - Undo hiding of a task list * `$task_list->is_complete()` - Check if a task list is complete * `$task_list->add_task( $args )` - Add a task to a task list * `$task_list->get_viewable_tasks()` - Get tasks that are marked as `can_view` for the store diff --git a/plugins/woocommerce-admin/packages/admin-e2e-tests/src/fixtures/options.ts b/plugins/woocommerce-admin/packages/admin-e2e-tests/src/fixtures/options.ts index becf2b8a79b..f7056cd7554 100644 --- a/plugins/woocommerce-admin/packages/admin-e2e-tests/src/fixtures/options.ts +++ b/plugins/woocommerce-admin/packages/admin-e2e-tests/src/fixtures/options.ts @@ -11,3 +11,10 @@ export async function updateOption( optionName: string, optionValue: string ) { } ); expect( response.statusCode ).toEqual( 200 ); } + +export async function unhideTaskList( id: string ) { + const response = await httpClient.post( + `/wc-admin/onboarding/tasks/${ id }/unhide` + ); + expect( response.statusCode ).toEqual( 200 ); +} diff --git a/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/activity-panel.ts b/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/activity-panel.ts index f4469637b7d..a093795d25f 100644 --- a/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/activity-panel.ts +++ b/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/activity-panel.ts @@ -9,7 +9,7 @@ import { createSimpleProduct, withRestApi } from '@woocommerce/e2e-utils'; import { Login } from '../../pages/Login'; import { OnboardingWizard } from '../../pages/OnboardingWizard'; import { WcHomescreen } from '../../pages/WcHomescreen'; -import { createOrder, removeAllOrders, updateOption } from '../../fixtures'; +import { createOrder, removeAllOrders, unhideTaskList } from '../../fixtures'; import { OrdersActivityPanel } from '../../elements/OrdersActivityPanel'; import { waitForElementByText } from '../../utils/actions'; @@ -30,7 +30,7 @@ const testAdminHomescreenActivityPanel = () => { await withRestApi.deleteAllProducts(); await removeAllOrders(); - await updateOption( 'woocommerce_task_list_hidden', 'no' ); + await unhideTaskList( 'setup' ); await profileWizard.navigate(); await profileWizard.skipStoreSetup(); @@ -41,7 +41,7 @@ const testAdminHomescreenActivityPanel = () => { afterAll( async () => { await withRestApi.deleteAllProducts(); await removeAllOrders(); - await updateOption( 'woocommerce_task_list_hidden', 'no' ); + await unhideTaskList( 'setup' ); await login.logout(); } ); diff --git a/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/task-list.ts b/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/task-list.ts index bf821b3c356..a9008e9a246 100644 --- a/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/task-list.ts +++ b/plugins/woocommerce-admin/packages/admin-e2e-tests/src/specs/homescreen/task-list.ts @@ -12,7 +12,7 @@ import { WcHomescreen } from '../../pages/WcHomescreen'; import { TaskTitles } from '../../constants/taskTitles'; import { HelpMenu } from '../../elements/HelpMenu'; import { WcSettings } from '../../pages/WcSettings'; -import { updateOption } from '../../fixtures'; +import { unhideTaskList } from '../../fixtures'; /* eslint-disable @typescript-eslint/no-var-requires */ const { afterAll, beforeAll, describe, it } = require( '@jest/globals' ); @@ -42,7 +42,7 @@ const testAdminHomescreenTasklist = () => { } ); afterAll( async () => { - await updateOption( 'woocommerce_task_list_hidden', 'no' ); + await unhideTaskList( 'setup' ); await login.logout(); } ); diff --git a/plugins/woocommerce-admin/packages/data/src/onboarding/action-types.js b/plugins/woocommerce-admin/packages/data/src/onboarding/action-types.js index 4696b31da71..cb3363686e1 100644 --- a/plugins/woocommerce-admin/packages/data/src/onboarding/action-types.js +++ b/plugins/woocommerce-admin/packages/data/src/onboarding/action-types.js @@ -25,6 +25,9 @@ const TYPES = { HIDE_TASK_LIST_ERROR: 'HIDE_TASK_LIST_ERROR', HIDE_TASK_LIST_REQUEST: 'HIDE_TASK_LIST_REQUEST', HIDE_TASK_LIST_SUCCESS: 'HIDE_TASK_LIST_SUCCESS', + UNHIDE_TASK_LIST_ERROR: 'UNHIDE_TASK_LIST_ERROR', + UNHIDE_TASK_LIST_REQUEST: 'UNHIDE_TASK_LIST_REQUEST', + UNHIDE_TASK_LIST_SUCCESS: 'UNHIDE_TASK_LIST_SUCCESS', OPTIMISTICALLY_COMPLETE_TASK_REQUEST: 'OPTIMISTICALLY_COMPLETE_TASK_REQUEST', ACTION_TASK_ERROR: 'ACTION_TASK_ERROR', diff --git a/plugins/woocommerce-admin/packages/data/src/onboarding/actions.js b/plugins/woocommerce-admin/packages/data/src/onboarding/actions.js index fbda3f0ce42..271c76674a1 100644 --- a/plugins/woocommerce-admin/packages/data/src/onboarding/actions.js +++ b/plugins/woocommerce-admin/packages/data/src/onboarding/actions.js @@ -172,6 +172,28 @@ export function hideTaskListSuccess( taskList ) { }; } +export function unhideTaskListError( taskListId, error ) { + return { + type: TYPES.UNHIDE_TASK_LIST_ERROR, + taskListId, + error, + }; +} + +export function unhideTaskListRequest( taskListId ) { + return { + type: TYPES.UNHIDE_TASK_LIST_REQUEST, + taskListId, + }; +} + +export function unhideTaskListSuccess( taskList ) { + return { + type: TYPES.UNHIDE_TASK_LIST_SUCCESS, + taskList, + }; +} + export function optimisticallyCompleteTaskRequest( taskId ) { return { type: TYPES.OPTIMISTICALLY_COMPLETE_TASK_REQUEST, @@ -356,6 +378,22 @@ export function* hideTaskList( id ) { } } +export function* unhideTaskList( id ) { + yield unhideTaskListRequest( id ); + + try { + const taskList = yield apiFetch( { + path: `${ WC_ADMIN_NAMESPACE }/onboarding/tasks/${ id }/unhide`, + method: 'POST', + } ); + + yield unhideTaskListSuccess( taskList ); + } catch ( error ) { + yield unhideTaskListError( id, error ); + throw new Error(); + } +} + export function* optimisticallyCompleteTask( id ) { yield optimisticallyCompleteTaskRequest( id ); } diff --git a/plugins/woocommerce-admin/packages/data/src/onboarding/reducer.js b/plugins/woocommerce-admin/packages/data/src/onboarding/reducer.js index 5ad5c81014d..848166dded4 100644 --- a/plugins/woocommerce-admin/packages/data/src/onboarding/reducer.js +++ b/plugins/woocommerce-admin/packages/data/src/onboarding/reducer.js @@ -283,6 +283,7 @@ const onboarding = ( if ( taskListId === list.id ) { return { ...list, + isHidden: false, isVisible: true, }; } @@ -300,6 +301,7 @@ const onboarding = ( if ( taskListId === list.id ) { return { ...list, + isHidden: true, isVisible: false, }; } @@ -317,6 +319,53 @@ const onboarding = ( return taskListId === list.id ? taskList : list; } ), }; + case TYPES.UNHIDE_TASK_LIST_ERROR: + return { + ...state, + errors: { + ...state.errors, + unhideTaskList: error, + }, + taskLists: state.taskLists.map( ( list ) => { + if ( taskListId === list.id ) { + return { + ...list, + isHidden: true, + isVisible: false, + }; + } + return list; + } ), + }; + case TYPES.UNHIDE_TASK_LIST_REQUEST: + return { + ...state, + requesting: { + ...state.requesting, + unhideTaskList: true, + }, + taskLists: state.taskLists.map( ( list ) => { + if ( taskListId === list.id ) { + return { + ...list, + isHidden: false, + isVisible: true, + }; + } + return list; + } ), + }; + case TYPES.UNHIDE_TASK_LIST_SUCCESS: + return { + ...state, + requesting: { + ...state.requesting, + unhideTaskList: false, + }, + taskLists: state.taskLists.map( ( list ) => { + return taskListId === list.id ? taskList : list; + } ), + }; case TYPES.OPTIMISTICALLY_COMPLETE_TASK_REQUEST: return { ...state, diff --git a/plugins/woocommerce-admin/packages/data/src/onboarding/resolvers.js b/plugins/woocommerce-admin/packages/data/src/onboarding/resolvers.js index 3c752b04aea..a8a052768bd 100644 --- a/plugins/woocommerce-admin/packages/data/src/onboarding/resolvers.js +++ b/plugins/woocommerce-admin/packages/data/src/onboarding/resolvers.js @@ -1,11 +1,13 @@ /** * External dependencies */ -import { apiFetch } from '@wordpress/data-controls'; +import { apiFetch, select } from '@wordpress/data-controls'; +import { controls } from '@wordpress/data'; /** * Internal dependencies */ +import { STORE_NAME } from './constants'; import { WC_ADMIN_NAMESPACE } from '../constants'; import { getFreeExtensionsError, @@ -21,6 +23,9 @@ import { } from './actions'; import { DeprecatedTasks } from './deprecated-tasks'; +const resolveSelect = + controls && controls.resolveSelect ? controls.resolveSelect : select; + export function* getProfileItems() { try { const results = yield apiFetch( { @@ -66,6 +71,14 @@ export function* getTaskLists() { } } +export function* getTaskList() { + yield resolveSelect( STORE_NAME, 'getTaskLists' ); +} + +export function* getTask() { + yield resolveSelect( STORE_NAME, 'getTaskLists' ); +} + export function* getPaymentGatewaySuggestions() { try { const results = yield apiFetch( { diff --git a/plugins/woocommerce-admin/packages/data/src/onboarding/selectors.ts b/plugins/woocommerce-admin/packages/data/src/onboarding/selectors.ts index afe06d50588..b231ce0a785 100644 --- a/plugins/woocommerce-admin/packages/data/src/onboarding/selectors.ts +++ b/plugins/woocommerce-admin/packages/data/src/onboarding/selectors.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { TaskListType } from './types'; +import { TaskType, TaskListType } from './types'; import { WPDataSelectors, RuleProcessor } from '../types'; export const getFreeExtensions = ( @@ -23,6 +23,25 @@ export const getTaskLists = ( state: OnboardingState ): TaskListType[] => { return state.taskLists || initialTaskLists; }; +export const getTaskList = ( + state: OnboardingState, + selector: string +): TaskListType | undefined => { + return state.taskLists.find( ( list ) => list.id === selector ); +}; + +export const getTask = ( + state: OnboardingState, + selector: string +): TaskType | undefined => { + return state.taskLists.reduce( + ( value: TaskType | undefined, list: TaskListType ) => { + return value || list.tasks.find( ( task ) => task.id === selector ); + }, + undefined + ); +}; + export const getPaymentGatewaySuggestions = ( state: OnboardingState ): PaymentMethodsState[] => { diff --git a/plugins/woocommerce-admin/src/API/OnboardingTasks.php b/plugins/woocommerce-admin/src/API/OnboardingTasks.php index 18b4f79e3b9..733d77c0daa 100644 --- a/plugins/woocommerce-admin/src/API/OnboardingTasks.php +++ b/plugins/woocommerce-admin/src/API/OnboardingTasks.php @@ -130,6 +130,19 @@ class OnboardingTasks extends \WC_REST_Data_Controller { ) ); + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[a-z0-9_\-]+)/unhide', + array( + array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'unhide_task_list' ), + 'permission_callback' => array( $this, 'hide_task_list_permission_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[a-z0-9_\-]+)/dismiss', @@ -869,6 +882,33 @@ class OnboardingTasks extends \WC_REST_Data_Controller { return rest_ensure_response( $json ); } + /** + * Unhide a task list. + * + * @param WP_REST_Request $request Request data. + * + * @return WP_REST_Response|WP_Error + */ + public function unhide_task_list( $request ) { + $id = $request->get_param( 'id' ); + $task_list = TaskLists::get_list( $id ); + + if ( ! $task_list ) { + return new \WP_Error( + 'woocommerce_tasks_invalid_task_list', + __( 'Sorry, that task list was not found', 'woocommerce-admin' ), + array( + 'status' => 404, + ) + ); + } + + $update = $task_list->unhide(); + $json = $task_list->get_json(); + + return rest_ensure_response( $json ); + } + /** * Action a single task. * diff --git a/plugins/woocommerce-admin/src/Features/Onboarding.php b/plugins/woocommerce-admin/src/Features/Onboarding.php index dc6c4c9ea98..f057ffde608 100644 --- a/plugins/woocommerce-admin/src/Features/Onboarding.php +++ b/plugins/woocommerce-admin/src/Features/Onboarding.php @@ -879,7 +879,7 @@ class Onboarding { return; } $show = 1 === absint( $_GET['reset_task_list'] ); - $update = $show ? $task_list->show() : $task_list->hide(); // phpcs:ignore CSRF ok. + $update = $show ? $task_list->unhide() : $task_list->hide(); // phpcs:ignore CSRF ok. if ( $update ) { wc_admin_record_tracks_event( @@ -911,7 +911,7 @@ class Onboarding { return; } $show = 1 === absint( $_GET['reset_extended_task_list'] ); - $update = $show ? $task_list->show() : $task_list->hide(); // phpcs:ignore CSRF ok. + $update = $show ? $task_list->unhide() : $task_list->hide(); // phpcs:ignore CSRF ok. if ( $update ) { wc_admin_record_tracks_event( diff --git a/plugins/woocommerce-admin/src/Features/OnboardingTasks/DeprecatedOptions.php b/plugins/woocommerce-admin/src/Features/OnboardingTasks/DeprecatedOptions.php index 900f7ba7031..035fa35c2d7 100644 --- a/plugins/woocommerce-admin/src/Features/OnboardingTasks/DeprecatedOptions.php +++ b/plugins/woocommerce-admin/src/Features/OnboardingTasks/DeprecatedOptions.php @@ -59,7 +59,7 @@ class DeprecatedOptions { if ( ! $task_list ) { return; } - $update = 'yes' === $value ? $task_list->hide() : $task_list->show(); + $update = 'yes' === $value ? $task_list->hide() : $task_list->unhide(); delete_option( 'woocommerce_task_list_hidden' ); return false; case 'woocommerce_extended_task_list_hidden': @@ -67,7 +67,7 @@ class DeprecatedOptions { if ( ! $task_list ) { return; } - $update = 'yes' === $value ? $task_list->hide() : $task_list->show(); + $update = 'yes' === $value ? $task_list->hide() : $task_list->unhide(); delete_option( 'woocommerce_extended_task_list_hidden' ); return false; } diff --git a/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskList.php b/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskList.php index 3e2d2e0a97d..6134ebb8225 100644 --- a/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskList.php +++ b/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskList.php @@ -132,7 +132,7 @@ class TaskList { * * @return bool */ - public function show() { + public function unhide() { $hidden = get_option( self::HIDDEN_OPTION, array() ); $hidden = array_diff( $hidden, array( $this->id ) ); return update_option( self::HIDDEN_OPTION, $hidden ); diff --git a/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskLists.php b/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskLists.php index 1e014977f12..0d9997b2cdd 100644 --- a/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskLists.php +++ b/plugins/woocommerce-admin/src/Features/OnboardingTasks/TaskLists.php @@ -66,7 +66,7 @@ class TaskLists { public static function init() { self::init_default_lists(); add_action( 'admin_init', array( __CLASS__, 'set_active_task' ), 5 ); - add_action( 'admin_init', array( __CLASS__, 'init_tasks' ) ); + add_action( 'init', array( __CLASS__, 'init_tasks' ) ); } /** diff --git a/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Purchase.php b/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Purchase.php index 28f6bc06a25..4909b9c6aae 100644 --- a/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Purchase.php +++ b/plugins/woocommerce-admin/src/Features/OnboardingTasks/Tasks/Purchase.php @@ -4,11 +4,37 @@ namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks; use Automattic\WooCommerce\Admin\Features\Onboarding; use Automattic\WooCommerce\Admin\PluginsHelper; +use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task; /** * Purchase Task */ class Purchase { + /** + * Initialize. + */ + public static function init() { + add_action( 'update_option_woocommerce_onboarding_profile', array( __CLASS__, 'clear_dismissal' ), 10, 2 ); + } + + /** + * Clear dismissal on onboarding product type changes. + * + * @param array $old_value Old value. + * @param array $new_value New value. + */ + public static function clear_dismissal( $old_value, $new_value ) { + $product_types = isset( $new_value['product_types'] ) ? (array) $new_value['product_types'] : array(); + $previous_product_types = isset( $old_value['product_types'] ) ? (array) $old_value['product_types'] : array(); + + if ( empty( array_diff( $product_types, $previous_product_types ) ) ) { + return; + } + + $task = new Task( self::get_task() ); + $task->undo_dismiss(); + } + /** * Get the task arguments. * diff --git a/plugins/woocommerce-admin/tests/features/onboarding-tasks/task-list.php b/plugins/woocommerce-admin/tests/features/onboarding-tasks/task-list.php index 55ce177e9d4..013d2660fdf 100644 --- a/plugins/woocommerce-admin/tests/features/onboarding-tasks/task-list.php +++ b/plugins/woocommerce-admin/tests/features/onboarding-tasks/task-list.php @@ -76,9 +76,9 @@ class WC_Tests_OnboardingTasks_TaskList extends WC_Unit_Test_Case { /** * Tests that lists can be shown after hiding. */ - public function test_show() { + public function test_unhide() { $this->list->hide(); - $this->list->show(); + $this->list->unhide(); $this->assertFalse( $this->list->is_hidden() ); }