From 2a8e4461a82a9ffea939981821223bec31968bc5 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 15 Oct 2018 23:10:09 -0600 Subject: [PATCH 01/14] Add new actions for lockPostSaving and unlockPostSaving --- packages/editor/src/store/actions.js | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index f8eb4cdb36ec8..90b82f01e9597 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -808,3 +808,32 @@ export function disablePublishSidebar() { type: 'DISABLE_PUBLISH_SIDEBAR', }; } + +/** + * Returns an action object used to signal that post saving is locked. + * + * @param {string} lockName The lock name. + * + * @return {Object} Action object + */ +export function lockPostSaving( lockName ) { + return { + type: 'LOCK_POST_SAVING', + lockName, + }; +} + +/** + * Returns an action object used to signal that post saving is unlocked. + * + * @param {string} lockName The lock name. + * + * @return {Object} Action object + */ +export function unlockPostSaving( lockName ) { + return { + type: 'UNLOCK_POST_SAVING', + lockName, + }; +} + From b52adb72db46a7302951fcc7cc830a801c447114 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 15 Oct 2018 23:21:10 -0600 Subject: [PATCH 02/14] isPostSavingLocked selector --- packages/editor/src/store/selectors.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index afcfef291d5cf..34b8de8a640e4 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -1966,6 +1966,17 @@ export function isPostLocked( state ) { return state.postLock.isLocked; } +/** + * Returns whether post saving is locked. + * + * @param {Object} state Global application state. + * + * @return {boolean} Is locked. + */ +export function isPostSavingLocked( state ) { + return state.postSavingLock && state.postSavingLock.length > 0; +} + /** * Returns whether the edition of the post has been taken over. * From 8c532dd2cb299d0893197d8eaddf8d520ebb1da4 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 15 Oct 2018 23:22:51 -0600 Subject: [PATCH 03/14] postSavingLock reducer --- packages/editor/src/store/reducer.js | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 1bcfae88dab7b..fac42883c9d4f 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -913,6 +913,38 @@ export function postLock( state = { isLocked: false }, action ) { return state; } +/** + * Post saving lock. + * + * When post saving is locked, the post cannot be published or updated. + * + * @param {PostSavingLockState} state Current state. + * @param {Object} action Dispatched action. + * + * @return {PostLockState} Updated state. + */ +export function postSavingLock( state = [], action ) { + const { lockName } = action; + switch ( action.type ) { + case 'LOCK_POST_SAVING': + return [ + ...state, + lockName, + ]; + case 'UNLOCK_POST_SAVING': + const index = state.indexOf( lockName ); + if ( index === -1 ) { + return state; + } + + return [ + ...state.slice( 0, index ), + ...state.slice( index + 1 ), + ]; + } + return state; +} + export const reusableBlocks = combineReducers( { data( state = {}, action ) { switch ( action.type ) { @@ -1133,4 +1165,5 @@ export default optimist( combineReducers( { autosave, settings, tokens, + postSavingLock, } ) ); From 6db9774febc7cb212a53a0ea0ece99b4f19ee027 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 15 Oct 2018 23:23:28 -0600 Subject: [PATCH 04/14] check isPostSavingLocked in post publish button --- packages/editor/src/components/post-publish-button/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/editor/src/components/post-publish-button/index.js b/packages/editor/src/components/post-publish-button/index.js index 3cd74e24e9f13..842f04554c10d 100644 --- a/packages/editor/src/components/post-publish-button/index.js +++ b/packages/editor/src/components/post-publish-button/index.js @@ -82,6 +82,7 @@ export default compose( [ getEditedPostVisibility, isEditedPostSaveable, isEditedPostPublishable, + isPostSavingLocked, getCurrentPost, getCurrentPostType, } = select( 'core/editor' ); @@ -89,7 +90,7 @@ export default compose( [ isSaving: forceIsSaving || isSavingPost(), isBeingScheduled: isEditedPostBeingScheduled(), visibility: getEditedPostVisibility(), - isSaveable: isEditedPostSaveable(), + isSaveable: isEditedPostSaveable() && ! isPostSavingLocked(), isPublishable: forceIsDirty || isEditedPostPublishable(), hasPublishAction: get( getCurrentPost(), [ '_links', 'wp:action-publish' ], false ), postType: getCurrentPostType(), From 8fea9a0b1665ee73bec67bad457bfa5c4cc9f8d4 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 18 Oct 2018 22:34:19 -0600 Subject: [PATCH 05/14] simplify reducer with object --- packages/editor/src/store/reducer.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index fac42883c9d4f..df3d0b9336ef0 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -927,20 +927,11 @@ export function postSavingLock( state = [], action ) { const { lockName } = action; switch ( action.type ) { case 'LOCK_POST_SAVING': - return [ - ...state, - lockName, - ]; case 'UNLOCK_POST_SAVING': - const index = state.indexOf( lockName ); - if ( index === -1 ) { - return state; - } - - return [ - ...state.slice( 0, index ), - ...state.slice( index + 1 ), - ]; + return { + ...state, + [ lockName ]: action.type === 'LOCK_POST_SAVING', + }; } return state; } From 9117ace44cf980cc3d10583e53f574ddad56d55d Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 18 Oct 2018 22:35:30 -0600 Subject: [PATCH 06/14] adjust isPostSavingLocked for new state shape --- packages/editor/src/store/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index d5dfc24893477..632769a8e5905 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -2003,7 +2003,7 @@ export function isPostLocked( state ) { * @return {boolean} Is locked. */ export function isPostSavingLocked( state ) { - return state.postSavingLock && state.postSavingLock.length > 0; + return find( state.postSavingLock, ( lock ) => lock ); } /** From 14fe4a92718bb71abfbf8d0083289a52467890af Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 18 Oct 2018 22:36:50 -0600 Subject: [PATCH 07/14] build docs --- docs/data/data-core-editor.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/data/data-core-editor.md b/docs/data/data-core-editor.md index fd3e2fb5e376d..735d4428aa88f 100644 --- a/docs/data/data-core-editor.md +++ b/docs/data/data-core-editor.md @@ -1299,6 +1299,18 @@ Returns whether the post is locked. Is locked. +### isPostSavingLocked + +Returns whether post saving is locked. + +*Parameters* + + * state: Global application state. + +*Returns* + +Is locked. + ### isPostLockTakeover Returns whether the edition of the post has been taken over. @@ -1752,4 +1764,20 @@ Returns an action object used in signalling that the user has enabled the publis ### disablePublishSidebar -Returns an action object used in signalling that the user has disabled the publish sidebar. \ No newline at end of file +Returns an action object used in signalling that the user has disabled the publish sidebar. + +### lockPostSaving + +Returns an action object used to signal that post saving is locked. + +*Parameters* + + * lockName: The lock name. + +### unlockPostSaving + +Returns an action object used to signal that post saving is unlocked. + +*Parameters* + + * lockName: The lock name. \ No newline at end of file From e97e01a815fd3c50c4aebf65ae1e442a00948daf Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 19 Oct 2018 14:19:39 -0600 Subject: [PATCH 08/14] postSavingLock - initial state is an empty object --- packages/editor/src/store/reducer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index df3d0b9336ef0..ffd9a27661e3a 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -923,7 +923,7 @@ export function postLock( state = { isLocked: false }, action ) { * * @return {PostLockState} Updated state. */ -export function postSavingLock( state = [], action ) { +export function postSavingLock( state = {}, action ) { const { lockName } = action; switch ( action.type ) { case 'LOCK_POST_SAVING': From c9d80ad0968b1f788581aab00c59cc1dda3ffd58 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 25 Oct 2018 14:52:07 -0600 Subject: [PATCH 09/14] ensure the isPostSavingLocked selector returns a boolean --- packages/editor/src/store/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index 632769a8e5905..fa6a5fa6ac590 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -2003,7 +2003,7 @@ export function isPostLocked( state ) { * @return {boolean} Is locked. */ export function isPostSavingLocked( state ) { - return find( state.postSavingLock, ( lock ) => lock ); + return find( state.postSavingLock, ( lock ) => lock ) ? true : false; } /** From 34597e414884d6647e1c44a9a0961d8c92a7d208 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 25 Oct 2018 14:53:07 -0600 Subject: [PATCH 10/14] Add tests for isPostSavingLocked --- packages/editor/src/store/test/selectors.js | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/editor/src/store/test/selectors.js b/packages/editor/src/store/test/selectors.js index e7e6294b64fe0..6742a02aca7e9 100644 --- a/packages/editor/src/store/test/selectors.js +++ b/packages/editor/src/store/test/selectors.js @@ -111,6 +111,7 @@ const { INSERTER_UTILITY_HIGH, INSERTER_UTILITY_MEDIUM, INSERTER_UTILITY_LOW, + isPostSavingLocked, } = selectors; describe( 'selectors', () => { @@ -891,6 +892,28 @@ describe( 'selectors', () => { } ); } ); + describe( 'isPostSavingLocked', () => { + it( 'should return true if the post has postSavingLocks', () => { + const state = { + postSavingLock: [ { 1: true } ], + currentPost: {}, + saving: {}, + }; + + expect( isPostSavingLocked( state ) ).toBe( true ); + } ); + + it( 'should return false if the post has no postSavingLocks', () => { + const state = { + postSavingLock: [], + currentPost: {}, + saving: {}, + }; + + expect( isPostSavingLocked( state ) ).toBe( false ); + } ); + } ); + describe( 'isEditedPostSaveable', () => { it( 'should return false if the post has no title, excerpt, content', () => { const state = { From c85982e0996096ff6448c59f097698c0c27b319c Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 25 Oct 2018 15:40:00 -0600 Subject: [PATCH 11/14] Add tests for the postSavingLock reducer --- packages/editor/src/store/test/reducer.js | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js index 9913daf213ec2..4967ade36c902 100644 --- a/packages/editor/src/store/test/reducer.js +++ b/packages/editor/src/store/test/reducer.js @@ -35,6 +35,7 @@ import { template, blockListSettings, autosave, + postSavingLock, } from '../reducer'; describe( 'state', () => { @@ -2263,4 +2264,53 @@ describe( 'state', () => { } ); } ); } ); + + describe( 'postSavingLock', () => { + it( 'returns empty object by default', () => { + const state = postSavingLock( undefined, {} ); + + expect( state ).toEqual( {} ); + } ); + + it( 'returns correct post locks when locks added and removed', () => { + let state = postSavingLock( undefined, { + type: 'LOCK_POST_SAVING', + lockName: 'test-lock', + } ); + + expect( state ).toEqual( { + 'test-lock': true, + } ); + + state = postSavingLock( state, { + type: 'LOCK_POST_SAVING', + lockName: 'test-lock-2', + } ); + + expect( state ).toEqual( { + 'test-lock': true, + 'test-lock-2': true, + } ); + + state = postSavingLock( state, { + type: 'UNLOCK_POST_SAVING', + lockName: 'test-lock', + } ); + + expect( state ).toEqual( { + 'test-lock': false, + 'test-lock-2': true, + } ); + + state = postSavingLock( state, { + type: 'UNLOCK_POST_SAVING', + lockName: 'test-lock-2', + } ); + + expect( state ).toEqual( { + 'test-lock': false, + 'test-lock-2': false, + } ); + } ); + } ); } ); From 0696c0c9288ba5b8c9994a6c3b09be79abc4d65f Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 25 Oct 2018 16:37:53 -0600 Subject: [PATCH 12/14] postSavingLock: deepFreeze( state ) passed in tests --- packages/editor/src/store/test/reducer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js index 4967ade36c902..a45fc6b282e04 100644 --- a/packages/editor/src/store/test/reducer.js +++ b/packages/editor/src/store/test/reducer.js @@ -2282,7 +2282,7 @@ describe( 'state', () => { 'test-lock': true, } ); - state = postSavingLock( state, { + state = postSavingLock( deepFreeze( state ), { type: 'LOCK_POST_SAVING', lockName: 'test-lock-2', } ); @@ -2292,7 +2292,7 @@ describe( 'state', () => { 'test-lock-2': true, } ); - state = postSavingLock( state, { + state = postSavingLock( deepFreeze( state ), { type: 'UNLOCK_POST_SAVING', lockName: 'test-lock', } ); @@ -2302,7 +2302,7 @@ describe( 'state', () => { 'test-lock-2': true, } ); - state = postSavingLock( state, { + state = postSavingLock( deepFreeze( state ), { type: 'UNLOCK_POST_SAVING', lockName: 'test-lock-2', } ); From 949ed50506190992c40c175891bc3a397cd6c3ba Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 25 Oct 2018 16:51:03 -0600 Subject: [PATCH 13/14] simplify reducers, selectors & adjust tests --- packages/editor/src/store/reducer.js | 7 +++---- packages/editor/src/store/selectors.js | 2 +- packages/editor/src/store/test/reducer.js | 6 +----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index ffd9a27661e3a..e77a6a92a4f47 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -927,11 +927,10 @@ export function postSavingLock( state = {}, action ) { const { lockName } = action; switch ( action.type ) { case 'LOCK_POST_SAVING': + return { ...state, [ lockName ]: true }; + case 'UNLOCK_POST_SAVING': - return { - ...state, - [ lockName ]: action.type === 'LOCK_POST_SAVING', - }; + return omit( state, lockName ); } return state; } diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index fa6a5fa6ac590..93b89572dab0c 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -2003,7 +2003,7 @@ export function isPostLocked( state ) { * @return {boolean} Is locked. */ export function isPostSavingLocked( state ) { - return find( state.postSavingLock, ( lock ) => lock ) ? true : false; + return state.postSavingLock.length > 0; } /** diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js index a45fc6b282e04..a1ee2508ca2e0 100644 --- a/packages/editor/src/store/test/reducer.js +++ b/packages/editor/src/store/test/reducer.js @@ -2298,7 +2298,6 @@ describe( 'state', () => { } ); expect( state ).toEqual( { - 'test-lock': false, 'test-lock-2': true, } ); @@ -2307,10 +2306,7 @@ describe( 'state', () => { lockName: 'test-lock-2', } ); - expect( state ).toEqual( { - 'test-lock': false, - 'test-lock-2': false, - } ); + expect( state ).toEqual( {} ); } ); } ); } ); From 50d5a49c906e9c724f0fc06644fdf323a9f1ace1 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 25 Oct 2018 16:54:35 -0600 Subject: [PATCH 14/14] move lockName into case handlers --- packages/editor/src/store/reducer.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index e77a6a92a4f47..df9f7bda24194 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -924,13 +924,12 @@ export function postLock( state = { isLocked: false }, action ) { * @return {PostLockState} Updated state. */ export function postSavingLock( state = {}, action ) { - const { lockName } = action; switch ( action.type ) { case 'LOCK_POST_SAVING': - return { ...state, [ lockName ]: true }; + return { ...state, [ action.lockName ]: true }; case 'UNLOCK_POST_SAVING': - return omit( state, lockName ); + return omit( state, action.lockName ); } return state; }