Skip to content

Commit

Permalink
Update last inserted block state to track multiple blocks (#46885)
Browse files Browse the repository at this point in the history
* Include replace in tracking last “inserted” block

* Update reducer tests

* Make selector experimental

* Refactor state to return array of inserted blocks

* rename selector

* Deprecates existing function

* Adds selector to return multiple blocks

* Add tests for new selector

* Fix usage to utilise new selector

* fix selector name

* Remove selector

As per @youknowriad advice in #46885 (comment)

Co-authored-by: Ben Dwyer <[email protected]>
  • Loading branch information
getdave and Ben Dwyer authored Jan 5, 2023
1 parent 339aa2c commit 7e7e78c
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 24 deletions.
6 changes: 3 additions & 3 deletions docs/reference-guides/data/data-core-block-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,17 +556,17 @@ _Properties_
- _isDisabled_ `boolean`: Whether or not the user should be prevented from inserting this item.
- _frecency_ `number`: Heuristic that combines frequency and recency.

### getLastInsertedBlockClientId
### getLastInsertedBlocksClientIds

Gets the client id of the last inserted block.
Gets the client ids of the last inserted blocks.

_Parameters_

- _state_ `Object`: Global application state.

_Returns_

- `string|undefined`: Client Id of the last inserted block.
- `Array|undefined`: Client Ids of the last inserted block(s).

### getLastMultiSelectedBlockClientId

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ const ListViewBlockContents = forwardRef(
const {
hasBlockMovingClientId,
getSelectedBlockClientId,
getLastInsertedBlockClientId,
getLastInsertedBlocksClientIds,
} = select( blockEditorStore );
return {
blockMovingClientId: hasBlockMovingClientId(),
selectedBlockInBlockEditor: getSelectedBlockClientId(),
lastInsertedBlockClientId: getLastInsertedBlockClientId(),
lastInsertedBlockClientId:
getLastInsertedBlocksClientIds()[ 0 ],
};
},
[ clientId ]
Expand Down
9 changes: 7 additions & 2 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1829,14 +1829,19 @@ export function highlightedBlock( state, action ) {
export function lastBlockInserted( state = {}, action ) {
switch ( action.type ) {
case 'INSERT_BLOCKS':
case 'REPLACE_BLOCKS':
case 'REPLACE_INNER_BLOCKS':
if ( ! action.blocks.length ) {
return state;
}

const clientId = action.blocks[ 0 ].clientId;
const clientIds = action.blocks.map( ( block ) => {
return block.clientId;
} );

const source = action.meta?.source;

return { clientId, source };
return { clientIds, source };
case 'RESET_BLOCKS':
return {};
}
Expand Down
10 changes: 5 additions & 5 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2647,19 +2647,19 @@ export const __experimentalGetActiveBlockIdByBlockNames = createSelector(
export function wasBlockJustInserted( state, clientId, source ) {
const { lastBlockInserted } = state;
return (
lastBlockInserted.clientId === clientId &&
lastBlockInserted.clientIds?.includes( clientId ) &&
lastBlockInserted.source === source
);
}

/**
* Gets the client id of the last inserted block.
* Gets the client ids of the last inserted blocks.
*
* @param {Object} state Global application state.
* @return {string|undefined} Client Id of the last inserted block.
* @return {Array|undefined} Client Ids of the last inserted block(s).
*/
export function getLastInsertedBlockClientId( state ) {
return state?.lastBlockInserted?.clientId;
export function getLastInsertedBlocksClientIds( state ) {
return state?.lastBlockInserted?.clientIds;
}

/**
Expand Down
48 changes: 45 additions & 3 deletions packages/block-editor/src/store/test/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3255,7 +3255,7 @@ describe( 'state', () => {
} );

describe( 'lastBlockInserted', () => {
it( 'should return client id if last block inserted is called with action INSERT_BLOCKS', () => {
it( 'should contain client id if last block inserted is called with action INSERT_BLOCKS', () => {
const expectedClientId = '62bfef6e-d5e9-43ba-b7f9-c77cf354141f';

const action = {
Expand All @@ -3272,7 +3272,7 @@ describe( 'state', () => {

const state = lastBlockInserted( {}, action );

expect( state.clientId ).toBe( expectedClientId );
expect( state.clientIds ).toContain( expectedClientId );
} );

it( 'should return inserter_menu source if last block inserted is called with action INSERT_BLOCKS', () => {
Expand All @@ -3297,7 +3297,7 @@ describe( 'state', () => {

it( 'should return state if last block inserted is called with action INSERT_BLOCKS and block list is empty', () => {
const expectedState = {
clientId: '9db792c6-a25a-495d-adbd-97d56a4c4189',
clientIds: [ '9db792c6-a25a-495d-adbd-97d56a4c4189' ],
};

const action = {
Expand All @@ -3313,6 +3313,48 @@ describe( 'state', () => {
expect( state ).toEqual( expectedState );
} );

it( 'should return client ids of blocks when called with REPLACE_BLOCKS', () => {
const clientIdOne = '62bfef6e-d5e9-43ba-b7f9-c77cf354141f';
const clientIdTwo = '9db792c6-a25a-495d-adbd-97d56a4c4189';

const action = {
blocks: [
{
clientId: clientIdOne,
},
{
clientId: clientIdTwo,
},
],
type: 'REPLACE_BLOCKS',
};

const state = lastBlockInserted( {}, action );

expect( state.clientIds ).toEqual( [ clientIdOne, clientIdTwo ] );
} );

it( 'should return client ids of all blocks when inner blocks are replaced with REPLACE_INNER_BLOCKS', () => {
const clientIdOne = '62bfef6e-d5e9-43ba-b7f9-c77cf354141f';
const clientIdTwo = '9db792c6-a25a-495d-adbd-97d56a4c4189';

const action = {
blocks: [
{
clientId: clientIdOne,
},
{
clientId: clientIdTwo,
},
],
type: 'REPLACE_INNER_BLOCKS',
};

const state = lastBlockInserted( {}, action );

expect( state.clientIds ).toEqual( [ clientIdOne, clientIdTwo ] );
} );

it( 'should return empty state if last block inserted is called with action RESET_BLOCKS', () => {
const expectedState = {};

Expand Down
21 changes: 12 additions & 9 deletions packages/block-editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const {
__experimentalGetPatternTransformItems,
wasBlockJustInserted,
__experimentalGetGlobalBlocksByName,
getLastInsertedBlockClientId,
getLastInsertedBlocksClientIds,
} = selectors;

describe( 'selectors', () => {
Expand Down Expand Up @@ -4457,7 +4457,7 @@ describe( 'selectors', () => {

const state = {
lastBlockInserted: {
clientId: expectedClientId,
clientIds: [ expectedClientId ],
source,
},
};
Expand All @@ -4474,7 +4474,7 @@ describe( 'selectors', () => {

const state = {
lastBlockInserted: {
clientId: unexpectedClientId,
clientIds: [ unexpectedClientId ],
source,
},
};
Expand All @@ -4490,7 +4490,7 @@ describe( 'selectors', () => {

const state = {
lastBlockInserted: {
clientId,
clientIds: [ clientId ],
},
};

Expand Down Expand Up @@ -4667,22 +4667,25 @@ describe( '__unstableGetClientIdsTree', () => {
} );
} );

describe( 'getLastInsertedBlockClientId', () => {
describe( 'getLastInsertedBlocksClientIds', () => {
it( 'should return undefined if no blocks have been inserted', () => {
const state = {
lastBlockInserted: {},
};

expect( getLastInsertedBlockClientId( state ) ).toEqual( undefined );
expect( getLastInsertedBlocksClientIds( state ) ).toEqual( undefined );
} );

it( 'should return clientId if blocks have been inserted', () => {
it( 'should return clientIds if blocks have been inserted', () => {
const state = {
lastBlockInserted: {
clientId: '123456',
clientIds: [ '123456', '78910' ],
},
};

expect( getLastInsertedBlockClientId( state ) ).toEqual( '123456' );
expect( getLastInsertedBlocksClientIds( state ) ).toEqual( [
'123456',
'78910',
] );
} );
} );

0 comments on commit 7e7e78c

Please sign in to comment.