Skip to content

Commit

Permalink
Implement store: reducer, actions, selectors
Browse files Browse the repository at this point in the history
  • Loading branch information
oandregal committed Nov 20, 2024
1 parent c38610a commit 3012632
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
68 changes: 67 additions & 1 deletion packages/editor/src/dataviews/store/private-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { store as coreStore } from '@wordpress/core-data';
import type { Action } from '@wordpress/dataviews';
import type { Action, Field } from '@wordpress/dataviews';
import { doAction } from '@wordpress/hooks';

/**
Expand All @@ -24,6 +24,15 @@ import {
renamePost,
resetPost,
deletePost,
featuredImageField,
dateField,
parentField,
passwordField,
commentStatusField,
slugField,
statusField,
authorField,
titleField,
} from '@wordpress/fields';
import duplicateTemplatePart from '../actions/duplicate-template-part';

Expand Down Expand Up @@ -53,6 +62,32 @@ export function unregisterEntityAction(
};
}

export function registerEntityField< Item >(
kind: string,
name: string,
config: Field< Item >
) {
return {
type: 'REGISTER_ENTITY_FIELD' as const,
kind,
name,
config,
};
}

export function unregisterEntityField(
kind: string,
name: string,
fieldId: string
) {
return {
type: 'UNREGISTER_ENTITY_FIELD' as const,
kind,
name,
fieldId,
};
}

export function setIsReady( kind: string, name: string ) {
return {
type: 'SET_IS_READY' as const,
Expand Down Expand Up @@ -139,3 +174,34 @@ export const registerPostTypeActions =

doAction( 'core.registerPostTypeActions', postType );
};

export const registerPostTypeFields =
( postType: string ) =>
async ( { registry }: { registry: any } ) => {
// TODO: do not register fields if there were already registered.
// Consider the existing isReady state.

const fields = [
featuredImageField,
titleField,
authorField,
statusField,
dateField,
slugField,
parentField,
commentStatusField,
passwordField,
];

registry.batch( () => {
fields.forEach( ( field ) => {
unlock( registry.dispatch( editorStore ) ).registerEntityField(
'postType',
postType,
field
);
} );
} );

doAction( 'core.registerPostTypeFields', postType );
};
4 changes: 4 additions & 0 deletions packages/editor/src/dataviews/store/private-selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export function getEntityActions( state: State, kind: string, name: string ) {
return state.actions[ kind ]?.[ name ] ?? EMPTY_ARRAY;
}

export function getEntityFields( state: State, kind: string, name: string ) {
return state.fields[ kind ]?.[ name ] ?? EMPTY_ARRAY;
}

export function isEntityReady( state: State, kind: string, name: string ) {
return state.isReady[ kind ]?.[ name ];
}
39 changes: 38 additions & 1 deletion packages/editor/src/dataviews/store/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
* WordPress dependencies
*/
import { combineReducers } from '@wordpress/data';
import type { Action } from '@wordpress/dataviews';
import type { Action, Field } from '@wordpress/dataviews';

type ReduxAction =
| ReturnType< typeof import('./private-actions').registerEntityAction >
| ReturnType< typeof import('./private-actions').unregisterEntityAction >
| ReturnType< typeof import('./private-actions').registerEntityField >
| ReturnType< typeof import('./private-actions').unregisterEntityField >
| ReturnType< typeof import('./private-actions').setIsReady >;

export type ActionState = Record< string, Record< string, Action< any >[] > >;
export type FieldsState = Record< string, Record< string, Field< any >[] > >;
export type ReadyState = Record< string, Record< string, boolean > >;
export type State = {
actions: ActionState;
fields: FieldsState;
isReady: ReadyState;
};

Expand Down Expand Up @@ -64,7 +68,40 @@ function actions( state: ActionState = {}, action: ReduxAction ) {
return state;
}

function fields( state: FieldsState = {}, action: ReduxAction ) {
switch ( action.type ) {
case 'REGISTER_ENTITY_FIELD':
return {
...state,
[ action.kind ]: {
...state[ action.kind ],
[ action.name ]: [
...(
state[ action.kind ]?.[ action.name ] ?? []
).filter(
( _field ) => _field.id !== action.config.id
),
action.config,
],
},
};
case 'UNREGISTER_ENTITY_FIELD':
return {
...state,
[ action.kind ]: {
...state[ action.kind ],
[ action.name ]: (
state[ action.kind ]?.[ action.name ] ?? []
).filter( ( _field ) => _field.id !== action.fieldId ),
},
};
}

return state;
}

export default combineReducers( {
actions,
fields,
isReady,
} );
5 changes: 5 additions & 0 deletions packages/editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from './selectors';
import {
getEntityActions as _getEntityActions,
getEntityFields as _getEntityFields,
isEntityReady as _isEntityReady,
} from '../dataviews/store/private-selectors';

Expand Down Expand Up @@ -171,6 +172,10 @@ export function isEntityReady( state, ...args ) {
return _isEntityReady( state.dataviews, ...args );
}

export function getEntityFields( state, ...args ) {
return _getEntityFields( state.dataviews, ...args );
}

/**
* Similar to getBlocksByName in @wordpress/block-editor, but only returns the top-most
* blocks that aren't descendants of the query block.
Expand Down

0 comments on commit 3012632

Please sign in to comment.