Skip to content

Commit

Permalink
DataViews: Boostrap Actions Extensibility API
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed May 28, 2024
1 parent 513f9ea commit 14db3d4
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/dataviews/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as DataViews } from './dataviews';
export { VIEW_LAYOUTS } from './layouts';
export { filterSortAndPaginate } from './filter-and-sort-data-view';
export type * from './types';
24 changes: 24 additions & 0 deletions packages/editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,18 @@ _Returns_

Undocumented declaration.

### registerEntityAction

Registers a new DataViews action.

This is an experimental API and is subject to change. it's only available in the Gutenberg plugin for now.

_Parameters_

- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _config_ `Action`: Action configuration.

### RichText

> **Deprecated** since 5.3, use `wp.blockEditor.RichText` instead.
Expand Down Expand Up @@ -1414,6 +1426,18 @@ Undocumented declaration.

Undocumented declaration.

### unregisterEntityAction

Unregisters a DataViews action.

This is an experimental API and is subject to change. it's only available in the Gutenberg plugin for now.

_Parameters_

- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _actionId_ `string`: Action ID.

### UnsavedChangesWarning

Warns the user if there are unsaved changes before leaving the editor. Compatible with Post Editor and Site Editor.
Expand Down
6 changes: 5 additions & 1 deletion packages/editor/src/components/post-actions/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -962,11 +962,13 @@ const resetTemplateAction = {
};

export function usePostActions( postType, onActionPerformed ) {
const { postTypeObject } = useSelect(
const { defaultActions, postTypeObject } = useSelect(
( select ) => {
const { getPostType } = select( coreStore );
const { getEntityActions } = unlock( select( editorStore ) );
return {
postTypeObject: getPostType( postType ),
defaultActions: getEntityActions( 'postType', postType ),
};
},
[ postType ]
Expand Down Expand Up @@ -1001,6 +1003,7 @@ export function usePostActions( postType, onActionPerformed ) {
? deletePostAction
: trashPostAction,
! isTemplateOrTemplatePart && permanentlyDeletePostAction,
...defaultActions,
].filter( Boolean );

if ( onActionPerformed ) {
Expand Down Expand Up @@ -1046,6 +1049,7 @@ export function usePostActions( postType, onActionPerformed ) {

return actions;
}, [
defaultActions,
isTemplateOrTemplatePart,
isPattern,
postTypeObject?.viewable,
Expand Down
55 changes: 55 additions & 0 deletions packages/editor/src/dataviews/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* WordPress dependencies
*/
import { dispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
import { unlock } from '../lock-unlock';
import { store as editorStore } from '../store';

/**
* @typedef {import('@wordpress/dataviews').Action} Action
*/

/**
* Registers a new DataViews action.
*
* This is an experimental API and is subject to change.
* it's only available in the Gutenberg plugin for now.
*
* @param {string} kind Entity kind.
* @param {string} name Entity name.
* @param {Action} config Action configuration.
*/

export function registerEntityAction( kind, name, config ) {
const { registerEntityAction: _registerEntityAction } = unlock(
dispatch( editorStore )
);

if ( globalThis.IS_GUTENBERG_PLUGIN ) {
_registerEntityAction( kind, name, config );
}
}

/**
* Unregisters a DataViews action.
*
* This is an experimental API and is subject to change.
* it's only available in the Gutenberg plugin for now.
*
* @param {string} kind Entity kind.
* @param {string} name Entity name.
* @param {string} actionId Action ID.
*/
export function unregisterEntityAction( kind, name, actionId ) {
const { unregisterEntityAction: _unregisterEntityAction } = unlock(
dispatch( editorStore )
);

if ( globalThis.IS_GUTENBERG_PLUGIN ) {
_unregisterEntityAction( kind, name, actionId );
}
}
30 changes: 30 additions & 0 deletions packages/editor/src/dataviews/store/private-actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* WordPress dependencies
*/
import type { Action, AnyItem } from '@wordpress/dataviews';

export function registerEntityAction< Item extends AnyItem >(
kind: string,
name: string,
config: Action< Item >
) {
return {
type: 'REGISTER_ENTITY_ACTION' as const,
kind,
name,
config,
};
}

export function unregisterEntityAction(
kind: string,
name: string,
actionId: string
) {
return {
type: 'UNREGISTER_ENTITY_ACTION' as const,
kind,
name,
actionId,
};
}
8 changes: 8 additions & 0 deletions packages/editor/src/dataviews/store/private-selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Internal dependencies
*/
import type { State } from './reducer';

export function getEntityActions( state: State, kind: string, name: string ) {
return state.actions[ kind ]?.[ name ] ?? [];
}
44 changes: 44 additions & 0 deletions packages/editor/src/dataviews/store/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* WordPress dependencies
*/
import { combineReducers } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import type { Action } from '@wordpress/dataviews';

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

export type ActionState = Record< string, Record< string, Action< any >[] > >;
export type State = {
actions: ActionState;
};

function actions( state: ActionState = {}, action: ReduxAction ) {
switch ( action.type ) {
case 'REGISTER_ENTITY_ACTION':
return {
...state,
[ action.kind ]: {
[ action.name ]: [
...( state[ action.kind ]?.[ action.name ] ?? [] ),
action.config,
],
},
};
case 'UNREGISTER_ENTITY_ACTION': {
return {
...state,
[ action.kind ]: (
state[ action.kind ]?.[ action.name ] ?? []
).filter( ( _action ) => _action.id !== action.actionId ),
};
}
}

return state;
}

export default combineReducers( {
actions,
} );
1 change: 1 addition & 0 deletions packages/editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export { storeConfig, store } from './store';
export * from './components';
export * from './utils';
export * from './private-apis';
export * from './dataviews/api';

/*
* Backward compatibility
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { decodeEntities } from '@wordpress/html-entities';
* Internal dependencies
*/
import isTemplateRevertable from './utils/is-template-revertable';
export * from '../dataviews/store/private-actions';

/**
* Returns an action object used to set which template is currently being used/edited.
Expand Down
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 @@ -21,6 +21,7 @@ import {
} from './selectors';
import { TEMPLATE_PART_POST_TYPE } from './constants';
import { getFilteredTemplatePartBlocks } from './utils/get-filtered-template-parts';
import { getEntityActions as _getEntityActions } from '../dataviews/store/private-selectors';

const EMPTY_INSERTION_POINT = {
rootClientId: undefined,
Expand Down Expand Up @@ -135,3 +136,7 @@ export const getCurrentTemplateTemplateParts = createRegistrySelector(
return getFilteredTemplatePartBlocks( blocks, templateParts );
}
);

export function getEntityActions( state, ...args ) {
return _getEntityActions( state.dataviews, ...args );
}
2 changes: 2 additions & 0 deletions packages/editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { combineReducers } from '@wordpress/data';
* Internal dependencies
*/
import { EDITOR_SETTINGS_DEFAULTS } from './defaults';
import dataviewsReducer from '../dataviews/store/reducer';

/**
* Returns a post attribute value, flattening nested rendered content using its
Expand Down Expand Up @@ -402,4 +403,5 @@ export default combineReducers( {
listViewPanel,
listViewToggleRef,
publishSidebarActive,
dataviews: dataviewsReducer,
} );
37 changes: 37 additions & 0 deletions packages/editor/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"declarationDir": "build-types",
"checkJs": false,
},
"references": [
{ "path": "../a11y" },
{ "path": "../api-fetch" },
{ "path": "../blob" },
{ "path": "../block-editor" },
{ "path": "../components" },
{ "path": "../compose" },
{ "path": "../core-data" },
{ "path": "../data" },
{ "path": "../dataviews" },
{ "path": "../date" },
{ "path": "../deprecated" },
{ "path": "../dom" },
{ "path": "../element" },
{ "path": "../hooks" },
{ "path": "../html-entities" },
{ "path": "../i18n" },
{ "path": "../icons" },
{ "path": "../keycodes" },
{ "path": "../notices" },
{ "path": "../plugins" },
{ "path": "../private-apis" },
{ "path": "../rich-text" },
{ "path": "../url" },
{ "path": "../warning" },
{ "path": "../wordcount" }
],
"include": [ "src" ]
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
{ "path": "packages/dom" },
{ "path": "packages/dom-ready" },
{ "path": "packages/e2e-test-utils-playwright" },
{ "path": "packages/editor" },
{ "path": "packages/element" },
{ "path": "packages/escape-html" },
{ "path": "packages/eslint-plugin" },
Expand Down

0 comments on commit 14db3d4

Please sign in to comment.