Skip to content

Commit

Permalink
If a more recent revision/autosave exists, store its state on editor …
Browse files Browse the repository at this point in the history
…setup (#7945)

* Refactor autosave state into core-data

- Migrate state from core/editor to core
- Adjust selectors and action creators to take a post id.
- Store autosave state by the post id.
- Deprecate old action creators and selectors and forward to new implementation
- Update tests
- Update changelog

Add a resolver for fetching autosave data

Preload any autosaves for the current post

Improve isEditedPostAutosaveable selector deprecation

Pass entire parent post object into autosave selector functions to allow the getAutosave resolver to form a REST API path that incorporates both the post id and type

Use a selector to get the correct post type base url for the autosave

Rename resetAutosave to receiveAutosave for conformity

Render the post preview button as disabled until autosave has been fetched.

Comments/test description tidy up

Prefer `action` over `action creator` in copy

Remove unecessary if statement

Remove `autosave` prop overriding the prop of the same name in withDispatch

Fix deprecated resetAutosave function

Fix jsdoc formatting

Remove new getAutosaveAttribute in favour of deprecating and removing old version

Change autosave selector interface from func( post ) to func( postType, postId )

Store raw autosave from REST API in core, move transformation of autosave back to the core/editor package

Remove and deprecate hasAutosave in favour of getAutosave

Update docs

Rename reducer autosave -> autosaves

Fix erroneous changelog entry caused by bad merge conflict resolution

Update deprecations

Remove unnecessary new line

Use createRegistrySelector to select autosave data from correct registry for deprecated functions

Handle usage of registry selector in tests for isEditedPostAutosaveable

* Update deprecation version numbers

* Add resolveSelect control to core-data store

* Use resolveSelect to query for postType in getAutosave resolver

* Rework state for autosaves to reflect that multiple autosave can be received (one per user)

* Add state for the current user

* Add a selector/resolver for retrieving an autosave for an individual author

* Handle providing the current user id to the getAutosave selector

* Undeprecate isEditedPostAutosaveable, update tests to handle registrySelector

* Update changelog and deprecation version numbers

* Update docs

* Add JSDocs for currentUser reducer

* Minor renaming of functions/props

* Update deprecation version for action

* Change PostPreviewButton prop back to isSaveable.

* Do not consider a post autosaveable if existing autosaves have not yet been fetched from the REST API

* Use undefined as the fallback when no currentUser is fetched

* Move changelog entries to unreleased section, and bump minor instead of patch version

* Allow single or multiple autosaves to be passed to receiveAutosaves

* Update deprecation versions

* Use REDUCER_KEY as arg to select

Co-Authored-By: talldan <[email protected]>

* Update docs
  • Loading branch information
talldan authored Apr 18, 2019
1 parent 9132183 commit bb8deba
Show file tree
Hide file tree
Showing 21 changed files with 919 additions and 241 deletions.
32 changes: 27 additions & 5 deletions docs/designers-developers/developers/data/data-core-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,17 @@ saved state of the post.

Post attribute value.

### getAutosaveAttribute
### getAutosaveAttribute (deprecated)

Returns an attribute value of the current autosave revision for a post, or
null if there is no autosave for the post.

*Deprecated*

Deprecated since 5.6. Callers should use the `getAutosave( postType, postId, userId )` selector
from the '@wordpress/core-data' package and access properties on the returned
autosave object using getPostRawValue.

*Parameters*

* state: Global application state.
Expand Down Expand Up @@ -303,17 +309,23 @@ Returns true if the post can be autosaved, or false otherwise.
*Parameters*

* state: Global application state.
* autosave: A raw autosave object from the REST API.

*Returns*

Whether the post can be autosaved.

### getAutosave
### getAutosave (deprecated)

Returns the current autosave, or null if one is not set (i.e. if the post
has yet to be autosaved, or has been saved or published since the last
autosave).

*Deprecated*

Deprecated since 5.6. Callers should use the `getAutosave( postType, postId, userId )`
selector from the '@wordpress/core-data' package.

*Parameters*

* state: Editor state.
Expand All @@ -322,10 +334,15 @@ autosave).

Current autosave, if exists.

### hasAutosave
### hasAutosave (deprecated)

Returns the true if there is an existing autosave, otherwise false.

*Deprecated*

Deprecated since 5.6. Callers should use the `getAutosave( postType, postId, userId )` selector
from the '@wordpress/core-data' package and check for a truthy value.

*Parameters*

* state: Global application state.
Expand Down Expand Up @@ -752,14 +769,19 @@ post has been received, either by initialization or save.

* post: Post object.

### resetAutosave
### resetAutosave (deprecated)

Returns an action object used in signalling that the latest autosave of the
post has been received, by initialization or autosave.

*Deprecated*

Deprecated since 5.6. Callers should use the `receiveAutosaves( postId, autosave )`
selector from the '@wordpress/core-data' package.

*Parameters*

* post: Autosave post object.
* newAutosave: Autosave post object.

### __experimentalRequestPostUpdateStart

Expand Down
78 changes: 77 additions & 1 deletion docs/designers-developers/developers/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ Returns all available authors.

Authors list.

### getCurrentUser

Returns the current user.

*Parameters*

* state: Data state.

*Returns*

Current user object.

### getUserQueryResults

Returns all the users returned by a query ID.
Expand Down Expand Up @@ -181,6 +193,52 @@ https://developer.wordpress.org/rest-api/reference/
Whether or not the user can perform the action,
or `undefined` if the OPTIONS request is still being made.

### getAutosaves

Returns the latest autosaves for the post.

May return multiple autosaves since the backend stores one autosave per
author for each post.

*Parameters*

* state: State tree.
* postType: The type of the parent post.
* postId: The id of the parent post.

*Returns*

An array of autosaves for the post, or undefined if there is none.

### getAutosave

Returns the autosave for the post and author.

*Parameters*

* state: State tree.
* postType: The type of the parent post.
* postId: The id of the parent post.
* authorId: The id of the author.

*Returns*

The autosave for the post and author.

### hasFetchedAutosaves

Returns true if the REST request for autosaves has completed.

*Parameters*

* state: State tree.
* postType: The type of the parent post.
* postId: The id of the parent post.

*Returns*

True if the REST request was completed. False otherwise.

## Actions

### receiveUserQuery
Expand All @@ -192,6 +250,14 @@ Returns an action object used in signalling that authors have been received.
* queryID: Query ID.
* users: Users received.

### receiveCurrentUser

Returns an action used in signalling that the current user has been received.

*Parameters*

* currentUser: Current user object.

### addEntities

Returns an action object used in adding new entities.
Expand Down Expand Up @@ -256,4 +322,14 @@ permission to perform an action on a REST resource.
*Parameters*

* key: A key that represents the action and REST resource.
* isAllowed: Whether or not the user can perform the action.
* isAllowed: Whether or not the user can perform the action.

### receiveAutosaves

Returns an action object used in signalling that the autosaves for a
post have been received.

*Parameters*

* postId: The id of the post that is parent to the autosave.
* autosaves: An array of autosaves or singular autosave object.
6 changes: 6 additions & 0 deletions packages/core-data/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.1.0 (Unreleased)

### New features
- The `getAutosave`, `getAutosaves` and `getCurrentUser` selectors have been added.
- The `receiveAutosaves` and `receiveCurrentUser` actions have been added.

## 2.0.16 (2019-01-03)

### Bug Fixes
Expand Down
31 changes: 31 additions & 0 deletions packages/core-data/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ export function receiveUserQuery( queryID, users ) {
};
}

/**
* Returns an action used in signalling that the current user has been received.
*
* @param {Object} currentUser Current user object.
*
* @return {Object} Action object.
*/
export function receiveCurrentUser( currentUser ) {
return {
type: 'RECEIVE_CURRENT_USER',
currentUser,
};
}

/**
* Returns an action object used in adding new entities.
*
Expand Down Expand Up @@ -159,3 +173,20 @@ export function receiveUserPermission( key, isAllowed ) {
isAllowed,
};
}

/**
* Returns an action object used in signalling that the autosaves for a
* post have been received.
*
* @param {number} postId The id of the post that is parent to the autosave.
* @param {Array|Object} autosaves An array of autosaves or singular autosave object.
*
* @return {Object} Action object.
*/
export function receiveAutosaves( postId, autosaves ) {
return {
type: 'RECEIVE_AUTOSAVES',
postId,
autosaves: castArray( autosaves ),
};
}
41 changes: 41 additions & 0 deletions packages/core-data/src/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,23 @@ export function select( selectorName, ...args ) {
};
}

/**
* Dispatches a control action for triggering a registry select that has a
* resolver.
*
* @param {string} selectorName
* @param {Array} args Arguments for the select.
*
* @return {Object} control descriptor.
*/
export function resolveSelect( selectorName, ...args ) {
return {
type: 'RESOLVE_SELECT',
selectorName,
args,
};
}

const controls = {
API_FETCH( { request } ) {
return triggerApiFetch( request );
Expand All @@ -40,6 +57,30 @@ const controls = {
SELECT: createRegistryControl( ( registry ) => ( { selectorName, args } ) => {
return registry.select( 'core' )[ selectorName ]( ...args );
} ),

RESOLVE_SELECT: createRegistryControl(
( registry ) => ( { selectorName, args } ) => {
return new Promise( ( resolve ) => {
const hasFinished = () => registry.select( 'core/data' )
.hasFinishedResolution( 'core', selectorName, args );
const getResult = () => registry.select( 'core' )[ selectorName ]
.apply( null, args );

// trigger the selector (to trigger the resolver)
const result = getResult();
if ( hasFinished() ) {
return resolve( result );
}

const unsubscribe = registry.subscribe( () => {
if ( hasFinished() ) {
unsubscribe();
resolve( getResult() );
}
} );
} );
}
),
};

export default controls;
41 changes: 41 additions & 0 deletions packages/core-data/src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ export function users( state = { byId: {}, queries: {} }, action ) {
return state;
}

/**
* Reducer managing current user state.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
export function currentUser( state = {}, action ) {
switch ( action.type ) {
case 'RECEIVE_CURRENT_USER':
return action.currentUser;
}

return state;
}

/**
* Reducer managing taxonomies.
*
Expand Down Expand Up @@ -238,12 +255,36 @@ export function userPermissions( state = {}, action ) {
return state;
}

/**
* Reducer returning autosaves keyed by their parent's post id.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
export function autosaves( state = {}, action ) {
switch ( action.type ) {
case 'RECEIVE_AUTOSAVES':
const { postId, autosaves: autosavesData } = action;

return {
...state,
[ postId ]: autosavesData,
};
}

return state;
}

export default combineReducers( {
terms,
users,
currentUser,
taxonomies,
themeSupports,
entities,
embedPreviews,
userPermissions,
autosaves,
} );
Loading

0 comments on commit bb8deba

Please sign in to comment.