-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
DataViews: Bootstrap Actions Extensibility API #62052
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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'; |
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 ); | ||
} | ||
} |
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, | ||
}; | ||
} |
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 ] ?? []; | ||
ntsekouras marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
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, | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -402,4 +403,5 @@ export default combineReducers( { | |
listViewPanel, | ||
listViewToggleRef, | ||
publishSidebarActive, | ||
dataviews: dataviewsReducer, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is named like that because the plan is to have a separate package eventually? Because the actions are used beyond the Data Views, so I don't really get why name it like that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, I can rename, what would you suggest? I guess you can think of it as the package name. |
||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/tsconfig.json", | ||
"extends": "../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"rootDir": "src", | ||
"declarationDir": "build-types" | ||
}, | ||
"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/**/*.ts", "src/**/*.tsx" ] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is the bootstrap PR, but we should add validation, even if it's in a follow up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's one of the reasons I added the types, for us at least, everything is typed, so there's less need for validation but indeed, validation for third-parties would be great. I wonder if there's a runtime lib that can use typescript types to generate validation automatically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a todo list for this to the issue.