Skip to content

Commit

Permalink
Publish Button: Show Publishing label if publish in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Nov 27, 2017
1 parent 534c5e5 commit ec4dc7c
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 6 deletions.
3 changes: 2 additions & 1 deletion editor/components/post-publish-button/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
isCurrentPostPublished,
isEditedPostBeingScheduled,
isSavingPost,
isPublishingPost,
} from '../../selectors';

export function PublishButtonLabel( {
Expand Down Expand Up @@ -52,7 +53,7 @@ const applyConnect = connect(
isBeingScheduled: isEditedPostBeingScheduled( state ),
isSaving: isSavingPost( state ),
// Need a selector
isPublishing: false,
isPublishing: isPublishingPost( state ),
} )
);

Expand Down
10 changes: 10 additions & 0 deletions editor/components/post-publish-button/test/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ describe( 'PublishButtonLabel', () => {
},
} );

it( 'should show publishing if publishing in progress', () => {
const label = PublishButtonLabel( { user, isPublishing: true } );
expect( label ).toBe( 'Publishing…' );
} );

it( 'should show updating if saving in progress', () => {
const label = PublishButtonLabel( { user, isSaving: true } );
expect( label ).toBe( 'Updating…' );
} );

it( 'should show publish if user unknown', () => {
const label = PublishButtonLabel( { user: {} } );
expect( label ).toBe( 'Publish' );
Expand Down
10 changes: 5 additions & 5 deletions editor/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import { BEGIN, COMMIT, REVERT } from 'redux-optimist';
import { get, uniqueId, map, filter, some, castArray } from 'lodash';
import { get, map, filter, some, castArray } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -54,6 +54,7 @@ import {
const SAVE_POST_NOTICE_ID = 'SAVE_POST_NOTICE_ID';
const TRASH_POST_NOTICE_ID = 'TRASH_POST_NOTICE_ID';
const SAVE_REUSABLE_BLOCK_NOTICE_ID = 'SAVE_REUSABLE_BLOCK_NOTICE_ID';
export const POST_UPDATE_TRANSACTION_ID = 'post-update';

export default {
REQUEST_POST_UPDATE( action, store ) {
Expand All @@ -66,12 +67,11 @@ export default {
content: getEditedPostContent( state ),
id: post.id,
};
const transactionId = uniqueId();

dispatch( {
type: 'UPDATE_POST',
edits: toSend,
optimist: { type: BEGIN, id: transactionId },
optimist: { type: BEGIN, id: POST_UPDATE_TRANSACTION_ID },
} );
dispatch( removeNotice( SAVE_POST_NOTICE_ID ) );
const Model = wp.api.getPostTypeModel( getCurrentPostType( state ) );
Expand All @@ -84,7 +84,7 @@ export default {
type: 'REQUEST_POST_UPDATE_SUCCESS',
previousPost: post,
post: newPost,
optimist: { type: COMMIT, id: transactionId },
optimist: { type: COMMIT, id: POST_UPDATE_TRANSACTION_ID },
} );
} ).fail( ( err ) => {
dispatch( {
Expand All @@ -95,7 +95,7 @@ export default {
} ),
post,
edits,
optimist: { type: REVERT, id: transactionId },
optimist: { type: REVERT, id: POST_UPDATE_TRANSACTION_ID },
} );
} );
},
Expand Down
52 changes: 52 additions & 0 deletions editor/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
keys,
without,
compact,
find,
} from 'lodash';
import createSelector from 'rememo';

Expand All @@ -21,6 +22,11 @@ import { serialize, getBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
*/
import { POST_UPDATE_TRANSACTION_ID } from './effects';

/***
* Module constants
*/
Expand Down Expand Up @@ -1072,3 +1078,49 @@ export function isSavingReusableBlock( state, ref ) {
export function getReusableBlocks( state ) {
return Object.values( state.reusableBlocks.data );
}

/**
* Returns state object prior to a specified optimist transaction ID, or `null`
* if the transaction corresponding to the given ID cannot be found.
*
* @param {Object} state Current global application state
* @param {Object} transactionId Optimist transaction ID
* @return {Object} Global application state prior to transaction
*/
export function getStateBeforeOptimisticTransaction( state, transactionId ) {
const transaction = find( state.optimist, ( entry ) => (
entry.beforeState &&
get( entry.action, [ 'optimist', 'id' ] ) === transactionId
) );

return transaction ? transaction.beforeState : null;
}

/**
* Returns true if the post is being published, or false otherwise
*
* @param {Object} state Global application state
* @return {Boolean} Whether post is being published
*/
export function isPublishingPost( state ) {
if ( ! isSavingPost( state ) ) {
return false;
}

// Saving is optimistic, so assume that current post would be marked as
// published if publishing
if ( ! isCurrentPostPublished( state ) ) {
return false;
}

// Use post update transaction ID to retrieve the state prior to the
// optimistic transaction
const stateBeforeRequest = getStateBeforeOptimisticTransaction(
state,
POST_UPDATE_TRANSACTION_ID
);

// Consider as publishing when current post prior to request was not
// considered published
return !! stateBeforeRequest && ! isCurrentPostPublished( stateBeforeRequest );
}
174 changes: 174 additions & 0 deletions editor/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ import {
getReusableBlock,
isSavingReusableBlock,
getReusableBlocks,
getStateBeforeOptimisticTransaction,
isPublishingPost,
} from '../selectors';
import { POST_UPDATE_TRANSACTION_ID } from '../effects';

describe( 'selectors', () => {
beforeAll( () => {
Expand Down Expand Up @@ -2187,4 +2190,175 @@ describe( 'selectors', () => {
expect( reusableBlocks ).toEqual( [] );
} );
} );

describe( 'getStateBeforeOptimisticTransaction', () => {
it( 'should return null if no transaction can be found', () => {
const beforeState = getStateBeforeOptimisticTransaction( {
optimist: [],
}, 'foo' );

expect( beforeState ).toBe( null );
} );

it( 'should return null if a transaction with ID can be found, but lacks before state', () => {
const beforeState = getStateBeforeOptimisticTransaction( {
optimist: [
{
action: {
optimist: {
id: 'foo',
},
},
},
],
}, 'foo' );

expect( beforeState ).toBe( null );
} );

it( 'should return the before state matching the given transaction id', () => {
const expectedBeforeState = {};
const beforeState = getStateBeforeOptimisticTransaction( {
optimist: [
{
beforeState: expectedBeforeState,
action: {
optimist: {
id: 'foo',
},
},
},
],
}, 'foo' );

expect( beforeState ).toBe( expectedBeforeState );
} );
} );

describe( 'isPublishingPost', () => {
it( 'should return false if the post is not being saved', () => {
const isPublishing = isPublishingPost( {
optimist: [],
saving: {
requesting: false,
},
editor: {
edits: {},
},
currentPost: {
status: 'publish',
},
} );

expect( isPublishing ).toBe( false );
} );

it( 'should return false if the current post is not considered published', () => {
const isPublishing = isPublishingPost( {
optimist: [],
saving: {
requesting: true,
},
editor: {
edits: {},
},
currentPost: {
status: 'draft',
},
} );

expect( isPublishing ).toBe( false );
} );

it( 'should return false if the optimistic transaction cannot be found', () => {
const isPublishing = isPublishingPost( {
optimist: [],
saving: {
requesting: true,
},
editor: {
edits: {},
},
currentPost: {
status: 'publish',
},
} );

expect( isPublishing ).toBe( false );
} );

it( 'should return false if the current post prior to request was already published', () => {
const isPublishing = isPublishingPost( {
optimist: [
{
beforeState: {
saving: {
requesting: false,
},
editor: {
edits: {},
},
currentPost: {
status: 'publish',
},
},
action: {
optimist: {
id: POST_UPDATE_TRANSACTION_ID,
},
},
},
],
saving: {
requesting: true,
},
editor: {
edits: {},
},
currentPost: {
status: 'publish',
},
} );

expect( isPublishing ).toBe( false );
} );

it( 'should return true if the current post prior to request was not published', () => {
const isPublishing = isPublishingPost( {
optimist: [
{
beforeState: {
saving: {
requesting: false,
},
editor: {
edits: {
status: 'publish',
},
},
currentPost: {
status: 'draft',
},
},
action: {
optimist: {
id: POST_UPDATE_TRANSACTION_ID,
},
},
},
],
saving: {
requesting: true,
},
editor: {
edits: {},
},
currentPost: {
status: 'publish',
},
} );

expect( isPublishing ).toBe( true );
} );
} );
} );

0 comments on commit ec4dc7c

Please sign in to comment.