Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ CoreData Entities ] add support for delete operations #21557

Merged
merged 32 commits into from
Jul 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
617e738
reset, delete nav menu items
draganescu Apr 13, 2020
fdceaa2
fixing a bad merge
draganescu May 15, 2020
1f8878b
no invalidateCache and refactored according to review
draganescu May 15, 2020
f4b6a83
revert change to getMergedItemIds
draganescu May 15, 2020
e062c55
refactor according to self review
draganescu May 18, 2020
aa147ac
deletes query items, adds tests for new entity methods
draganescu May 21, 2020
315c77b
refactored for properly deleteing entity ids from querries
draganescu May 22, 2020
d6bbb3f
updates tests
draganescu May 22, 2020
4ef424d
moved the REMOVE_ITEMS reducer to receive all query keys
draganescu May 22, 2020
24888af
removes the need to send query on delete
draganescu May 22, 2020
9744cf3
updates some comments
draganescu Jun 2, 2020
8f836b6
refactoring according to review
draganescu Jun 11, 2020
b657b19
do not clear cache on delete
draganescu Jun 11, 2020
c166e51
fixes test after reming superfluous actions from deleteEntityRecord
draganescu Jun 11, 2020
360cbaa
makes a proper POJO for removing items from queries and invalidates t…
draganescu Jun 24, 2020
f87a8a6
fix changelog and add deleteQueryParams to deleteRecord
draganescu Jun 26, 2020
c7606a0
fixes test
draganescu Jun 26, 2020
98ea4a8
Rename deleteQueryParams to query for consistency
draganescu Jun 29, 2020
d55f893
Use the new deleteEntityRecord to delete menus (#22428)
draganescu Jun 30, 2020
5abdf63
fixes query param's type for consistency
draganescu Jun 30, 2020
eeded0c
comment linting, removed useless catch logic for deleteEntityRecord, …
draganescu Jun 30, 2020
1995e69
try implement error handling for delete
draganescu Jul 2, 2020
b26e2e1
fixed the intentional typo and the unintentional one
draganescu Jul 2, 2020
be5b985
updates and fixes according to review
draganescu Jul 2, 2020
8586489
rename remove items' action id collection
draganescu Jul 9, 2020
ad3c7e7
makes notices unique in menu editor
draganescu Jul 9, 2020
3a6e36b
Update packages/core-data/src/queried-data/actions.js
draganescu Jul 9, 2020
28f5b11
fixes bugs introduced by renaming items to itemsIds in the remove ite…
draganescu Jul 10, 2020
a34ee64
lint
draganescu Jul 10, 2020
9a8d813
moves noticeId creation inside effect
draganescu Jul 16, 2020
59bb45c
updated according to review
draganescu Jul 24, 2020
8051532
lint
draganescu Jul 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions docs/designers-developers/developers/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,21 @@ _Returns_

- `?Array`: Records.

<a name="getLastEntityDeleteError" href="#getLastEntityDeleteError">#</a> **getLastEntityDeleteError**

Returns the specified entity record's last delete error.

_Parameters_

- _state_ `Object`: State tree.
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordId_ `number`: Record ID.

_Returns_

- `?Object`: The entity record's save error.

<a name="getLastEntitySaveError" href="#getLastEntitySaveError">#</a> **getLastEntitySaveError**

Returns the specified entity record's last save error.
Expand Down Expand Up @@ -407,6 +422,21 @@ _Returns_

- `boolean`: Whether the entity record is autosaving or not.

<a name="isDeletingEntityRecord" href="#isDeletingEntityRecord">#</a> **isDeletingEntityRecord**

Returns true if the specified entity record is deleting, and false otherwise.

_Parameters_

- _state_ `Object`: State tree.
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordId_ `number`: Record ID.

_Returns_

- `boolean`: Whether the entity record is deleting or not.

<a name="isPreviewEmbedFallback" href="#isPreviewEmbedFallback">#</a> **isPreviewEmbedFallback**

Determines if the returned preview is an oEmbed link fallback.
Expand Down Expand Up @@ -471,6 +501,17 @@ _Returns_

- `Object`: Action object.

<a name="deleteEntityRecord" href="#deleteEntityRecord">#</a> **deleteEntityRecord**

Action triggered to delete an entity record.

_Parameters_

- _kind_ `string`: Kind of the deleted entity.
- _name_ `string`: Name of the deleted entity.
- _recordId_ `string`: Record ID of the deleted entity.
- _query_ `?Object`: Special query parameters for the DELETE API call.

<a name="editEntityRecord" href="#editEntityRecord">#</a> **editEntityRecord**

Returns an action object that triggers an
Expand Down
6 changes: 6 additions & 0 deletions packages/core-data/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

### New Feature

- The `deleteEntityRecord` and `removeItems` actions have been added.
draganescu marked this conversation as resolved.
Show resolved Hide resolved
- The `isDeletingEntityRecord` and `getLastEntityDeleteError` selectors have been added.
- A `delete<entity.name>` helper is created for every registered entity.

## 2.3.0 (2019-05-21)

### New features
Expand Down
41 changes: 41 additions & 0 deletions packages/core-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ _Returns_

- `Object`: Action object.

<a name="deleteEntityRecord" href="#deleteEntityRecord">#</a> **deleteEntityRecord**

Action triggered to delete an entity record.

_Parameters_

- _kind_ `string`: Kind of the deleted entity.
- _name_ `string`: Name of the deleted entity.
- _recordId_ `string`: Record ID of the deleted entity.
- _query_ `?Object`: Special query parameters for the DELETE API call.

<a name="editEntityRecord" href="#editEntityRecord">#</a> **editEntityRecord**

Returns an action object that triggers an
Expand Down Expand Up @@ -440,6 +451,21 @@ _Returns_

- `?Array`: Records.

<a name="getLastEntityDeleteError" href="#getLastEntityDeleteError">#</a> **getLastEntityDeleteError**

Returns the specified entity record's last delete error.

_Parameters_

- _state_ `Object`: State tree.
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordId_ `number`: Record ID.

_Returns_

- `?Object`: The entity record's save error.

<a name="getLastEntitySaveError" href="#getLastEntitySaveError">#</a> **getLastEntitySaveError**

Returns the specified entity record's last save error.
Expand Down Expand Up @@ -633,6 +659,21 @@ _Returns_

- `boolean`: Whether the entity record is autosaving or not.

<a name="isDeletingEntityRecord" href="#isDeletingEntityRecord">#</a> **isDeletingEntityRecord**

Returns true if the specified entity record is deleting, and false otherwise.

_Parameters_

- _state_ `Object`: State tree.
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordId_ `number`: Record ID.

_Returns_

- `boolean`: Whether the entity record is deleting or not.

<a name="isPreviewEmbedFallback" href="#isPreviewEmbedFallback">#</a> **isPreviewEmbedFallback**

Determines if the returned preview is an oEmbed link fallback.
Expand Down
59 changes: 58 additions & 1 deletion packages/core-data/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
*/
import { castArray, get, isEqual, find } from 'lodash';

/**
* WordPress dependencies
*/
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
*/
import { receiveItems, receiveQueriedItems } from './queried-data';
import { receiveItems, removeItems, receiveQueriedItems } from './queried-data';
import { getKindEntities, DEFAULT_ENTITY_KEY } from './entities';
import { select, apiFetch } from './controls';

Expand Down Expand Up @@ -139,6 +144,58 @@ export function receiveEmbedPreview( url, preview ) {
};
}

/**
* Action triggered to delete an entity record.
*
* @param {string} kind Kind of the deleted entity.
* @param {string} name Name of the deleted entity.
* @param {string} recordId Record ID of the deleted entity.
* @param {?Object} query Special query parameters for the DELETE API call.
*/
export function* deleteEntityRecord( kind, name, recordId, query ) {
const entities = yield getKindEntities( kind );
const entity = find( entities, { kind, name } );
let error;
let deletedRecord = false;
if ( ! entity ) {
return;
}

yield {
type: 'DELETE_ENTITY_RECORD_START',
kind,
name,
recordId,
};
draganescu marked this conversation as resolved.
Show resolved Hide resolved

try {
let path = `${ entity.baseURL }/${ recordId }`;

if ( query ) {
path = addQueryArgs( path, query );
}

deletedRecord = yield apiFetch( {
path,
method: 'DELETE',
} );

yield removeItems( kind, name, recordId, true );
draganescu marked this conversation as resolved.
Show resolved Hide resolved
} catch ( _error ) {
error = _error;
}

yield {
type: 'DELETE_ENTITY_RECORD_FINISH',
kind,
name,
recordId,
error,
};
draganescu marked this conversation as resolved.
Show resolved Hide resolved

return deletedRecord;
draganescu marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Returns an action object that triggers an
* edit to an entity record.
Expand Down
2 changes: 2 additions & 0 deletions packages/core-data/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const entityActions = defaultEntities.reduce( ( result, entity ) => {
const { kind, name } = entity;
result[ getMethodName( kind, name, 'save' ) ] = ( key ) =>
actions.saveEntityRecord( kind, name, key );
result[ getMethodName( kind, name, 'delete' ) ] = ( key, query ) =>
actions.deleteEntityRecord( kind, name, key, query );
return result;
}, {} );

Expand Down
20 changes: 20 additions & 0 deletions packages/core-data/src/queried-data/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ export function receiveItems( items ) {
};
}

/**
* Returns an action object used in signalling that entity records have been
* deleted and they need to be removed from entities state.
*
* @param {string} kind Kind of the removed entities.
* @param {string} name Name of the removed entities.
* @param {Array|number} records Record IDs of the removed entities.
* @param {boolean} invalidateCache Controls whether we want to invalidate the cache.
* @return {Object} Action object.
*/
export function removeItems( kind, name, records, invalidateCache = false ) {
return {
type: 'REMOVE_ITEMS',
itemIds: castArray( records ),
kind,
name,
invalidateCache,
};
}

/**
* Returns an action object used in signalling that queried data has been
* received.
Expand Down
37 changes: 34 additions & 3 deletions packages/core-data/src/queried-data/reducer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
draganescu marked this conversation as resolved.
Show resolved Hide resolved
* External dependencies
*/
import { map, flowRight } from 'lodash';
import { map, flowRight, omit, forEach, filter } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -86,8 +86,10 @@ function items( state = {}, action ) {
return accumulator;
}, {} ),
};
case 'REMOVE_ITEMS':
const newState = omit( state, action.itemIds );
return newState;
}

return state;
}

Expand All @@ -100,7 +102,7 @@ function items( state = {}, action ) {
*
* @return {Object} Next state.
*/
const queries = flowRight( [
const receiveQueries = flowRight( [
// Limit to matching action type so we don't attempt to replace action on
// an unhandled action.
ifMatchingAction( ( action ) => 'query' in action ),
Expand Down Expand Up @@ -138,6 +140,35 @@ const queries = flowRight( [
);
} );

/**
* Reducer tracking queries state.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Next state.
*/
const queries = ( state = {}, action ) => {
switch ( action.type ) {
case 'RECEIVE_ITEMS':
return receiveQueries( state, action );
case 'REMOVE_ITEMS':
const newState = { ...state };
const removedItems = action.itemIds.reduce( ( result, itemId ) => {
result[ itemId ] = true;
return result;
}, {} );
forEach( newState, ( queryItems, key ) => {
newState[ key ] = filter( queryItems, ( queryId ) => {
return ! removedItems[ queryId ];
} );
} );
return newState;
default:
return state;
}
};

export default combineReducers( {
items,
queries,
Expand Down
17 changes: 17 additions & 0 deletions packages/core-data/src/queried-data/test/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Internal dependencies
*/
import { removeItems } from '../actions';

describe( 'removeItems', () => {
it( 'builds an action object', () => {
const postIds = [ 1, 2, 3 ];
expect( removeItems( 'postType', 'post', postIds ) ).toEqual( {
type: 'REMOVE_ITEMS',
itemIds: postIds,
kind: 'postType',
name: 'post',
invalidateCache: false,
} );
} );
} );
31 changes: 31 additions & 0 deletions packages/core-data/src/queried-data/test/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import deepFreeze from 'deep-freeze';
* Internal dependencies
*/
import reducer, { getMergedItemIds } from '../reducer';
import { removeItems } from '../actions';

describe( 'getMergedItemIds', () => {
it( 'should receive a page', () => {
Expand Down Expand Up @@ -113,4 +114,34 @@ describe( 'reducer', () => {
queries: {},
} );
} );

it( 'deletes an item', () => {
const kind = 'root';
const name = 'menu';
const original = deepFreeze( {
items: {
1: { id: 1, name: 'abc' },
2: { id: 2, name: 'def' },
3: { id: 3, name: 'ghi' },
4: { id: 4, name: 'klm' },
},
queries: {
'': [ 1, 2, 3, 4 ],
's=a': [ 1, 3 ],
},
} );
const state = reducer( original, removeItems( kind, name, 3 ) );

expect( state ).toEqual( {
items: {
1: { id: 1, name: 'abc' },
2: { id: 2, name: 'def' },
4: { id: 4, name: 'klm' },
},
queries: {
'': [ 1, 2, 4 ],
's=a': [ 1 ],
},
} );
} );
} );
Loading