diff --git a/docs/data/data-core-edit-post.md b/docs/data/data-core-edit-post.md index 93e658e91d479..c12cf62a83d63 100644 --- a/docs/data/data-core-edit-post.md +++ b/docs/data/data-core-edit-post.md @@ -89,6 +89,20 @@ Returns true if the publish sidebar is opened. Whether the publish sidebar is open. +### isEditorPanelRemoved + +Returns true if the given panel was programmatically removed, or false otherwise. +All panels are not removed by default. + +*Parameters* + + * state: Global application state. + * panelName: A string that identifies the panel. + +*Returns* + +Whether or not the panel is removed. + ### isEditorPanelEnabled Returns true if the given panel is enabled, or false otherwise. Panels are @@ -301,6 +315,14 @@ Returns an action object used to open or close a panel in the editor. * panelName: A string that identifies the panel to open or close. +### removeEditorPanel + +Returns an action object used to remove a panel from the editor. + +*Parameters* + + * panelName: A string that identifies the panel to remove. + ### toggleFeature Returns an action object used to toggle a feature flag. diff --git a/packages/edit-post/src/components/options-modal/options/enable-panel.js b/packages/edit-post/src/components/options-modal/options/enable-panel.js index d21f1051cb039..d47ab67e7e6d9 100644 --- a/packages/edit-post/src/components/options-modal/options/enable-panel.js +++ b/packages/edit-post/src/components/options-modal/options/enable-panel.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { compose } from '@wordpress/compose'; +import { compose, ifCondition } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; /** @@ -10,9 +10,14 @@ import { withSelect, withDispatch } from '@wordpress/data'; import BaseOption from './base'; export default compose( - withSelect( ( select, { panelName } ) => ( { - isChecked: select( 'core/edit-post' ).isEditorPanelEnabled( panelName ), - } ) ), + withSelect( ( select, { panelName } ) => { + const { isEditorPanelEnabled, isEditorPanelRemoved } = select( 'core/edit-post' ); + return { + isRemoved: isEditorPanelRemoved( panelName ), + isChecked: isEditorPanelEnabled( panelName ), + }; + } ), + ifCondition( ( { isRemoved } ) => ! isRemoved ), withDispatch( ( dispatch, { panelName } ) => ( { onChange: () => dispatch( 'core/edit-post' ).toggleEditorPanelEnabled( panelName ), } ) ) diff --git a/packages/edit-post/src/components/options-modal/test/__snapshots__/index.js.snap b/packages/edit-post/src/components/options-modal/test/__snapshots__/index.js.snap index 67df8a5bd6089..f5764f8ab4acc 100644 --- a/packages/edit-post/src/components/options-modal/test/__snapshots__/index.js.snap +++ b/packages/edit-post/src/components/options-modal/test/__snapshots__/index.js.snap @@ -28,22 +28,22 @@ exports[`OptionsModal should match snapshot when the modal is active 1`] = ` - - - - diff --git a/packages/edit-post/src/components/options-modal/test/__snapshots__/meta-boxes-section.js.snap b/packages/edit-post/src/components/options-modal/test/__snapshots__/meta-boxes-section.js.snap index 42c22d9030718..b30ba56cfdb8f 100644 --- a/packages/edit-post/src/components/options-modal/test/__snapshots__/meta-boxes-section.js.snap +++ b/packages/edit-post/src/components/options-modal/test/__snapshots__/meta-boxes-section.js.snap @@ -17,12 +17,12 @@ exports[`MetaBoxesSection renders a Custom Fields option and meta box options 1` - - - - { } ); } ); + describe( 'removeEditorPanel', () => { + it( 'should return a REMOVE_PANEL action', () => { + expect( removeEditorPanel( 'post-status' ) ).toEqual( { + type: 'REMOVE_PANEL', + panelName: 'post-status', + } ); + } ); + } ); + describe( 'toggleEditorPanelEnabled', () => { it( 'should return a TOGGLE_PANEL_ENABLED action', () => { expect( toggleEditorPanelEnabled( 'post-status' ) ).toEqual( { diff --git a/packages/edit-post/src/store/test/reducer.js b/packages/edit-post/src/store/test/reducer.js index c64d90f48d155..66027cd21dc44 100644 --- a/packages/edit-post/src/store/test/reducer.js +++ b/packages/edit-post/src/store/test/reducer.js @@ -13,6 +13,7 @@ import { activeModal, isSavingMetaBoxes, metaBoxLocations, + removedPanels, } from '../reducer'; describe( 'state', () => { @@ -313,4 +314,24 @@ describe( 'state', () => { } ); } ); } ); + + describe( 'removedPanels', () => { + it( 'should remove panel', () => { + const original = deepFreeze( [] ); + const state = removedPanels( original, { + type: 'REMOVE_PANEL', + panelName: 'post-status', + } ); + expect( state ).toEqual( [ 'post-status' ] ); + } ); + + it( 'should not remove already removed panel', () => { + const original = deepFreeze( [ 'post-status' ] ); + const state = removedPanels( original, { + type: 'REMOVE_PANEL', + panelName: 'post-status', + } ); + expect( state ).toBe( original ); + } ); + } ); } ); diff --git a/packages/edit-post/src/store/test/selectors.js b/packages/edit-post/src/store/test/selectors.js index 4a13ec8e4392c..b035169b3044d 100644 --- a/packages/edit-post/src/store/test/selectors.js +++ b/packages/edit-post/src/store/test/selectors.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import deepFreeze from 'deep-freeze'; + /** * Internal dependencies */ @@ -16,6 +21,7 @@ import { getActiveMetaBoxLocations, isMetaBoxLocationActive, isEditorPanelEnabled, + isEditorPanelRemoved, } from '../selectors'; describe( 'selectors', () => { @@ -195,6 +201,26 @@ describe( 'selectors', () => { } ); } ); + describe( 'isEditorPanelRemoved', () => { + it( 'should return false by default', () => { + const state = deepFreeze( { + removedPanels: [], + } ); + + expect( isEditorPanelRemoved( state, 'post-status' ) ).toBe( false ); + } ); + + it( 'should return true when panel was removed', () => { + const state = deepFreeze( { + removedPanels: [ + 'post-status', + ], + } ); + + expect( isEditorPanelRemoved( state, 'post-status' ) ).toBe( true ); + } ); + } ); + describe( 'isEditorPanelEnabled', () => { it( 'should return true by default', () => { const state = { @@ -229,6 +255,21 @@ describe( 'selectors', () => { expect( isEditorPanelEnabled( state, 'post-status' ) ).toBe( false ); } ); + + it( 'should return false when a panel is enabled but removed', () => { + const state = deepFreeze( { + preferences: { + panels: { + 'post-status': { + enabled: true, + }, + }, + }, + removedPanels: [ 'post-status' ], + } ); + + expect( isEditorPanelEnabled( state, 'post-status' ) ).toBe( false ); + } ); } ); describe( 'isEditorPanelOpened', () => { diff --git a/test/e2e/specs/new-post-default-content.test.js b/test/e2e/specs/new-post-default-content.test.js index 8d5adbe95f9ef..28949da44f1b4 100644 --- a/test/e2e/specs/new-post-default-content.test.js +++ b/test/e2e/specs/new-post-default-content.test.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { newPost, getEditedPostContent, openDocumentSettingsSidebar } from '../support/utils'; +import { findSidebarPanelWithTitle, newPost, getEditedPostContent, openDocumentSettingsSidebar } from '../support/utils'; import { activatePlugin, deactivatePlugin } from '../support/plugins'; describe( 'new editor filtered state', () => { @@ -27,7 +27,7 @@ describe( 'new editor filtered state', () => { // open the sidebar, we want to see the excerpt. await openDocumentSettingsSidebar(); - const [ excerptButton ] = await page.$x( '//div[@class="edit-post-sidebar"]//button[@class="components-button components-panel__body-toggle"][contains(text(),"Excerpt")]' ); + const excerptButton = await findSidebarPanelWithTitle( 'Excerpt' ); if ( excerptButton ) { await excerptButton.click( 'button' ); } diff --git a/test/e2e/specs/sidebar.test.js b/test/e2e/specs/sidebar.test.js index 237c81cdba2d9..69c36fcf6ff29 100644 --- a/test/e2e/specs/sidebar.test.js +++ b/test/e2e/specs/sidebar.test.js @@ -2,8 +2,10 @@ * Internal dependencies */ import { + findSidebarPanelWithTitle, newPost, observeFocusLoss, + openDocumentSettingsSidebar, pressWithModifier, setViewport, } from '../support/utils'; @@ -12,12 +14,12 @@ const SIDEBAR_SELECTOR = '.edit-post-sidebar'; const ACTIVE_SIDEBAR_TAB_SELECTOR = '.edit-post-sidebar__panel-tab.is-active'; const ACTIVE_SIDEBAR_BUTTON_TEXT = 'Document'; -describe( 'Publishing', () => { +describe( 'Sidebar', () => { beforeAll( () => { observeFocusLoss(); } ); - it( 'Should have sidebar visible at the start with document sidebar active on desktop', async () => { + it( 'should have sidebar visible at the start with document sidebar active on desktop', async () => { await setViewport( 'large' ); await newPost(); const { nodesCount, content, height, width } = await page.$$eval( ACTIVE_SIDEBAR_TAB_SELECTOR, ( nodes ) => { @@ -41,14 +43,14 @@ describe( 'Publishing', () => { expect( height ).toBeGreaterThan( 10 ); } ); - it( 'Should have the sidebar closed by default on mobile', async () => { + it( 'should have the sidebar closed by default on mobile', async () => { await setViewport( 'small' ); await newPost(); const sidebar = await page.$( SIDEBAR_SELECTOR ); expect( sidebar ).toBeNull(); } ); - it( 'Should close the sidebar when resizing from desktop to mobile', async () => { + it( 'should close the sidebar when resizing from desktop to mobile', async () => { await setViewport( 'large' ); await newPost(); @@ -62,7 +64,7 @@ describe( 'Publishing', () => { expect( sidebarsMobile ).toHaveLength( 0 ); } ); - it( 'Should reopen sidebar the sidebar when resizing from mobile to desktop if the sidebar was closed automatically', async () => { + it( 'should reopen sidebar the sidebar when resizing from mobile to desktop if the sidebar was closed automatically', async () => { await setViewport( 'large' ); await newPost(); await setViewport( 'small' ); @@ -76,7 +78,7 @@ describe( 'Publishing', () => { expect( sidebarsDesktop ).toHaveLength( 1 ); } ); - it( 'Should preserve tab order while changing active tab', async () => { + it( 'should preserve tab order while changing active tab', async () => { await newPost(); // Region navigate to Sidebar. @@ -102,4 +104,32 @@ describe( 'Publishing', () => { ) ); expect( isActiveBlockTab ).toBe( true ); } ); + + it( 'should be possible to programmatically remove Document Settings panels', async () => { + await newPost(); + + await openDocumentSettingsSidebar(); + + expect( await findSidebarPanelWithTitle( 'Categories' ) ).toBeDefined(); + expect( await findSidebarPanelWithTitle( 'Tags' ) ).toBeDefined(); + expect( await findSidebarPanelWithTitle( 'Featured Image' ) ).toBeDefined(); + expect( await findSidebarPanelWithTitle( 'Excerpt' ) ).toBeDefined(); + expect( await findSidebarPanelWithTitle( 'Discussion' ) ).toBeDefined(); + + await page.evaluate( () => { + const { removeEditorPanel } = wp.data.dispatch( 'core/edit-post' ); + + removeEditorPanel( 'taxonomy-panel-category' ); + removeEditorPanel( 'taxonomy-panel-post_tag' ); + removeEditorPanel( 'featured-image' ); + removeEditorPanel( 'post-excerpt' ); + removeEditorPanel( 'discussion-panel' ); + } ); + + expect( await findSidebarPanelWithTitle( 'Categories' ) ).toBeUndefined(); + expect( await findSidebarPanelWithTitle( 'Tags' ) ).toBeUndefined(); + expect( await findSidebarPanelWithTitle( 'Featured Image' ) ).toBeUndefined(); + expect( await findSidebarPanelWithTitle( 'Excerpt' ) ).toBeUndefined(); + expect( await findSidebarPanelWithTitle( 'Discussion' ) ).toBeUndefined(); + } ); } ); diff --git a/test/e2e/support/utils/find-sidebar-panel-with-title.js b/test/e2e/support/utils/find-sidebar-panel-with-title.js new file mode 100644 index 0000000000000..fae3f33b53910 --- /dev/null +++ b/test/e2e/support/utils/find-sidebar-panel-with-title.js @@ -0,0 +1,15 @@ +/** + * External dependencies + */ +import { first } from 'lodash'; + +/** + * Finds a sidebar panel with the provided title. + * + * @param {string} panelTitle The name of sidebar panel. + * + * @return {?ElementHandle} Object that represents an in-page DOM element. + */ +export async function findSidebarPanelWithTitle( panelTitle ) { + return first( await page.$x( `//div[@class="edit-post-sidebar"]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ panelTitle }")]` ) ); +} diff --git a/test/e2e/support/utils/index.js b/test/e2e/support/utils/index.js index a8010c897a974..693bf990d74e9 100644 --- a/test/e2e/support/utils/index.js +++ b/test/e2e/support/utils/index.js @@ -8,6 +8,7 @@ export { disablePrePublishChecks } from './disable-pre-publish-checks'; export { enablePageDialogAccept } from './enable-page-dialog-accept'; export { enablePrePublishChecks } from './enable-pre-publish-checks'; export { ensureSidebarOpened } from './ensure-sidebar-opened'; +export { findSidebarPanelWithTitle } from './find-sidebar-panel-with-title'; export { getAllBlocks } from './get-all-blocks'; export { getEditedPostContent } from './get-edited-post-content'; export { getUrl } from './get-url';