Skip to content

Commit

Permalink
Revisions: add new selectors to fetch entity revisions (#54046)
Browse files Browse the repository at this point in the history
* Fetching entity revisions using loaded name argument e.g., post:id:revisions

Revisions loaded into state tree under revisions[parent]

Invalidate revisions after saved entity

Revisions url params are contained in entity  config

Testing with global styles - modifying CPT to show in rest

Implementing thin API layer for Revisions over the getEntityRecords implementation

Duplicated the logic in the selectors for revisions functions

Added tests

* Revert edit context query param when fetching post types
Reverting timeout in performance tests.

* Tidying up reducer, allowing revisions for posts and pages only

* Adding types to the base entity records for revisions and global styles revisions.

* Removed unnecessary REST API change for global styles: it was to pull in the CPT in the /types response, which we don't need for core-data since it's a root entity.

* Remove duplicated queried-data reducer functions for revisions, and use them in the main reducer

Create dedicated resolvers for getRevision/s, thereby removing the split name parsing required (name:id:revisions)
Create dedicated action receivers for revisions
Rename from getEntityRevisions to getRevisions

Fully remove parseEntityName

Updated selector tests

Use queriedDataReducer shape for revisions. The queriedDataReducer doesn't need to know about the revisions action type.

Update doc comments

Updated CHANGELOG.md

* This commit:
- removes `hasRevisions` because it has no noticeable benefit, at least as far as I can see. I'm probably wrong.
- removes the default revisions query context for the API call (the default is 'view' anyway)
- fixes the revisions reducer
- Add _fields logic to resolvers and selectors

Adds basic reducer tests

* updated variable names: parentId > recordKey, key > revisionKey
removing lock-related code
deleting `recordKey` from action object before sending to queriedDataReducer
updating docs

* Removing revisions when items are removed.
  • Loading branch information
ramonjd authored Nov 20, 2023
1 parent 59c0356 commit 8eb63dd
Show file tree
Hide file tree
Showing 14 changed files with 947 additions and 5 deletions.
51 changes: 51 additions & 0 deletions docs/reference-guides/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,39 @@ _Returns_

- A value whose reference will change only when an edit occurs.

### getRevision

Returns a single, specific revision of a parent entity.

_Parameters_

- _state_ `State`: State tree
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordKey_ `EntityRecordKey`: The key of the entity record whose revisions you want to fetch.
- _revisionKey_ `EntityRecordKey`: The revision's key.
- _query_ `GetRecordsHttpQuery`: Optional query. If requesting specific fields, fields must always include the ID. For valid query parameters see revisions schema in [the REST API Handbook](https://developer.wordpress.org/rest-api/reference/). Then see the arguments available "Retrieve a [entity kind]".

_Returns_

- `RevisionRecord | Record< PropertyKey, never > | undefined`: Record.

### getRevisions

Returns an entity's revisions.

_Parameters_

- _state_ `State`: State tree
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordKey_ `EntityRecordKey`: The key of the entity record whose revisions you want to fetch.
- _query_ `GetRecordsHttpQuery`: Optional query. If requesting specific fields, fields must always include the ID. For valid query parameters see revisions schema in [the REST API Handbook](https://developer.wordpress.org/rest-api/reference/). Then see the arguments available "Retrieve a [Entity kind]".

_Returns_

- `RevisionRecord[] | null`: Record.

### getThemeSupports

Return theme supports data in the index.
Expand Down Expand Up @@ -704,6 +737,24 @@ _Returns_

- `Object`: Action object.

### receiveRevisions

Returns an action object used in signalling that revisions have been received.

_Parameters_

- _kind_ `string`: Kind of the received entity record revisions.
- _name_ `string`: Name of the received entity record revisions.
- _recordKey_ `number|string`: The key of the entity record whose revisions you want to fetch.
- _records_ `Array|Object`: Revisions received.
- _query_ `?Object`: Query Object.
- _invalidateCache_ `?boolean`: Should invalidate query caches.
- _meta_ `?Object`: Meta information about pagination.

_Returns_

- `Object`: Action object.

### receiveThemeSupports

> **Deprecated** since WP 5.9, this is not useful anymore, use the selector direclty.
Expand Down
1 change: 1 addition & 0 deletions packages/core-data/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
## Enhancements

- Add `getEntityRecordsTotalItems` and `getEntityRecordsTotalPages` selectors. [#55164](https://github.com/WordPress/gutenberg/pull/55164).
- Revisions: add new selectors, `getRevisions` and `getRevision`, to fetch entity revisions. [#54046](https://github.com/WordPress/gutenberg/pull/54046).

## 6.20.0 (2023-10-05)

Expand Down
55 changes: 53 additions & 2 deletions packages/core-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ The package provides general methods to interact with the entities (`getEntityRe

```js
// Get the record collection for the user entity.
wp.data.select( 'core' ).getEntityRecords( 'root' 'user' );
wp.data.select( 'core' ).getEntityRecords( 'root', 'user' );

// Get a single record for the user entity.
wp.data.select( 'core' ).getEntityRecord( 'root', 'user', recordId );
Expand All @@ -138,7 +138,7 @@ In addition to the general utilities (`getEntityRecords`, `getEntityRecord`, etc

```js
// Collection
wp.data.select( 'core' ).getEntityRecords( 'root' 'user' );
wp.data.select( 'core' ).getEntityRecords( 'root', 'user' );
wp.data.select( 'core' ).getUsers();

// Single record
Expand Down Expand Up @@ -248,6 +248,24 @@ _Returns_

- `Object`: Action object.

### receiveRevisions

Returns an action object used in signalling that revisions have been received.

_Parameters_

- _kind_ `string`: Kind of the received entity record revisions.
- _name_ `string`: Name of the received entity record revisions.
- _recordKey_ `number|string`: The key of the entity record whose revisions you want to fetch.
- _records_ `Array|Object`: Revisions received.
- _query_ `?Object`: Query Object.
- _invalidateCache_ `?boolean`: Should invalidate query caches.
- _meta_ `?Object`: Meta information about pagination.

_Returns_

- `Object`: Action object.

### receiveThemeSupports

> **Deprecated** since WP 5.9, this is not useful anymore, use the selector direclty.
Expand Down Expand Up @@ -727,6 +745,39 @@ _Returns_

- A value whose reference will change only when an edit occurs.

### getRevision

Returns a single, specific revision of a parent entity.

_Parameters_

- _state_ `State`: State tree
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordKey_ `EntityRecordKey`: The key of the entity record whose revisions you want to fetch.
- _revisionKey_ `EntityRecordKey`: The revision's key.
- _query_ `GetRecordsHttpQuery`: Optional query. If requesting specific fields, fields must always include the ID. For valid query parameters see revisions schema in [the REST API Handbook](https://developer.wordpress.org/rest-api/reference/). Then see the arguments available "Retrieve a [entity kind]".

_Returns_

- `RevisionRecord | Record< PropertyKey, never > | undefined`: Record.

### getRevisions

Returns an entity's revisions.

_Parameters_

- _state_ `State`: State tree
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordKey_ `EntityRecordKey`: The key of the entity record whose revisions you want to fetch.
- _query_ `GetRecordsHttpQuery`: Optional query. If requesting specific fields, fields must always include the ID. For valid query parameters see revisions schema in [the REST API Handbook](https://developer.wordpress.org/rest-api/reference/). Then see the arguments available "Retrieve a [Entity kind]".

_Returns_

- `RevisionRecord[] | null`: Record.

### getThemeSupports

Return theme supports data in the index.
Expand Down
33 changes: 33 additions & 0 deletions packages/core-data/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -924,3 +924,36 @@ export function receiveDefaultTemplateId( query, templateId ) {
templateId,
};
}

/**
* Returns an action object used in signalling that revisions have been received.
*
* @param {string} kind Kind of the received entity record revisions.
* @param {string} name Name of the received entity record revisions.
* @param {number|string} recordKey The key of the entity record whose revisions you want to fetch.
* @param {Array|Object} records Revisions received.
* @param {?Object} query Query Object.
* @param {?boolean} invalidateCache Should invalidate query caches.
* @param {?Object} meta Meta information about pagination.
* @return {Object} Action object.
*/
export function receiveRevisions(
kind,
name,
recordKey,
records,
query,
invalidateCache = false,
meta
) {
return {
type: 'RECEIVE_ITEM_REVISIONS',
items: Array.isArray( records ) ? records : [ records ],
recordKey,
meta,
query,
kind,
name,
invalidateCache,
};
}
21 changes: 21 additions & 0 deletions packages/core-data/src/entities.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export const DEFAULT_ENTITY_KEY = 'id';

const POST_RAW_ATTRIBUTES = [ 'title', 'excerpt', 'content' ];

// A hardcoded list of post types that support revisions.
// @TODO: Ideally this should be fetched from the `/types` REST API's view context.
const POST_TYPES_WITH_REVISIONS_SUPPORT = [ 'post', 'page' ];

export const rootEntitiesConfig = [
{
label: __( 'Base' ),
Expand Down Expand Up @@ -207,6 +211,12 @@ export const rootEntitiesConfig = [
baseURLParams: { context: 'edit' },
plural: 'globalStylesVariations', // Should be different than name.
getTitle: ( record ) => record?.title?.rendered || record?.title,
getRevisionsUrl: ( parentId ) =>
`/wp/v2/global-styles/${ parentId }/revisions`,
supports: {
revisions: true,
},
supportsPagination: true,
},
{
label: __( 'Themes' ),
Expand Down Expand Up @@ -295,6 +305,11 @@ async function loadPostTypeEntities() {
selection: true,
},
mergedEdits: { meta: true },
supports: {
revisions: POST_TYPES_WITH_REVISIONS_SUPPORT.includes(
postType?.slug
),
},
rawAttributes: POST_RAW_ATTRIBUTES,
getTitle: ( record ) =>
record?.title?.rendered ||
Expand Down Expand Up @@ -328,6 +343,12 @@ async function loadPostTypeEntities() {
syncObjectType: 'postType/' + postType.name,
getSyncObjectId: ( id ) => id,
supportsPagination: true,
getRevisionsUrl: ( parentId, revisionId ) =>
`/${ namespace }/${
postType.rest_base
}/${ parentId }/revisions${
revisionId ? '/' + revisionId : ''
}`,
};
} );
}
Expand Down
47 changes: 47 additions & 0 deletions packages/core-data/src/entity-types/global-styles-revision.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Internal dependencies
*/
import type { Context, ContextualField, OmitNevers } from './helpers';

import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records';

declare module './base-entity-records' {
export namespace BaseEntityRecords {
export interface GlobalStylesRevision< C extends Context > {
/**
* The ID for the author of the global styles revision.
*/
author: number;
/**
* The date the post global styles revision published, in the site's timezone.
*/
date: string | null;
/**
* The date the global styles revision was published, as GMT.
*/
date_gmt: ContextualField< string | null, 'view' | 'edit', C >;
/**
* Unique identifier for the revision.
*/
id: number;
/**
* The date the global styles revision was last modified, in the site's timezone.
*/
modified: ContextualField< string, 'view' | 'edit', C >;
/**
* The date the global styles revision was last modified, as GMT.
*/
modified_gmt: ContextualField< string, 'view' | 'edit', C >;
/**
* Identifier for the parent of the revision.
*/
parent: number;
styles: Record< string, Object >;
settings: Record< string, Object >;
}
}
}

export type GlobalStylesRevision< C extends Context = 'view' > = OmitNevers<
_BaseEntityRecords.GlobalStylesRevision< C >
>;
6 changes: 6 additions & 0 deletions packages/core-data/src/entity-types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import type { Context, Updatable } from './helpers';
import type { Attachment } from './attachment';
import type { Comment } from './comment';
import type { GlobalStylesRevision } from './global-styles-revision';
import type { MenuLocation } from './menu-location';
import type { NavMenu } from './nav-menu';
import type { NavMenuItem } from './nav-menu-item';
import type { Page } from './page';
import type { Plugin } from './plugin';
import type { Post } from './post';
import type { PostRevision } from './post-revision';
import type { Settings } from './settings';
import type { Sidebar } from './sidebar';
import type { Taxonomy } from './taxonomy';
Expand All @@ -27,12 +29,14 @@ export type {
Attachment,
Comment,
Context,
GlobalStylesRevision,
MenuLocation,
NavMenu,
NavMenuItem,
Page,
Plugin,
Post,
PostRevision,
Settings,
Sidebar,
Taxonomy,
Expand Down Expand Up @@ -82,12 +86,14 @@ export interface PerPackageEntityRecords< C extends Context > {
core:
| Attachment< C >
| Comment< C >
| GlobalStylesRevision< C >
| MenuLocation< C >
| NavMenu< C >
| NavMenuItem< C >
| Page< C >
| Plugin< C >
| Post< C >
| PostRevision< C >
| Settings< C >
| Sidebar< C >
| Taxonomy< C >
Expand Down
Loading

0 comments on commit 8eb63dd

Please sign in to comment.