From f77863e21e8bb4c1419d30fb4d8ab12d0aa2072b Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 4 Jul 2024 12:01:58 +0200 Subject: [PATCH] DataViews: Register the reset template and template part action like any third-party action (#63017) Co-authored-by: youknowriad Co-authored-by: ntsekouras --- docs/reference-guides/data/data-core.md | 2 +- packages/core-data/README.md | 2 +- packages/core-data/src/actions.js | 8 +- .../src/components/post-actions/actions.js | 113 +------------- .../editor/src/dataviews/actions/index.ts | 3 + .../src/dataviews/actions/reset-post.tsx | 144 ++++++++++++++++++ packages/editor/src/dataviews/types.ts | 7 +- 7 files changed, 160 insertions(+), 119 deletions(-) create mode 100644 packages/editor/src/dataviews/actions/reset-post.tsx diff --git a/docs/reference-guides/data/data-core.md b/docs/reference-guides/data/data-core.md index 88db705f23f122..ba77f065584cfe 100644 --- a/docs/reference-guides/data/data-core.md +++ b/docs/reference-guides/data/data-core.md @@ -790,7 +790,7 @@ _Parameters_ - _kind_ `string`: Kind of the entity. - _name_ `string`: Name of the entity. - _recordId_ `Object`: ID of the record. -- _options_ `Object`: Saving options. +- _options_ `Object=`: Saving options. ### saveEntityRecord diff --git a/packages/core-data/README.md b/packages/core-data/README.md index 20ed0d4c660e2f..694f780dafb99d 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -299,7 +299,7 @@ _Parameters_ - _kind_ `string`: Kind of the entity. - _name_ `string`: Name of the entity. - _recordId_ `Object`: ID of the record. -- _options_ `Object`: Saving options. +- _options_ `Object=`: Saving options. ### saveEntityRecord diff --git a/packages/core-data/src/actions.js b/packages/core-data/src/actions.js index 36b0ba5f84c9d1..53ab935d868a37 100644 --- a/packages/core-data/src/actions.js +++ b/packages/core-data/src/actions.js @@ -773,10 +773,10 @@ export const __experimentalBatch = /** * Action triggered to save an entity record's edits. * - * @param {string} kind Kind of the entity. - * @param {string} name Name of the entity. - * @param {Object} recordId ID of the record. - * @param {Object} options Saving options. + * @param {string} kind Kind of the entity. + * @param {string} name Name of the entity. + * @param {Object} recordId ID of the record. + * @param {Object=} options Saving options. */ export const saveEditedEntityRecord = ( kind, name, recordId, options ) => diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index e38c64ddb3d7e6..cd1036faacdfd2 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -31,7 +31,6 @@ import { } from '../../store/constants'; import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -import isTemplateRevertable from '../../store/utils/is-template-revertable'; import { exportPatternAsJSONAction } from './export-pattern-action'; import { CreateTemplatePartModalContents } from '../create-template-part-modal'; @@ -804,114 +803,6 @@ const useDuplicatePostAction = ( postType ) => { ); }; -const resetTemplateAction = { - id: 'reset-template', - label: __( 'Reset' ), - isEligible: ( item ) => { - return isTemplateRevertable( item ); - }, - icon: backup, - supportsBulk: true, - hideModalHeader: true, - RenderModal: ( { items, closeModal, onActionPerformed } ) => { - const [ isBusy, setIsBusy ] = useState( false ); - const { revertTemplate } = unlock( useDispatch( editorStore ) ); - const { saveEditedEntityRecord } = useDispatch( coreStore ); - const { createSuccessNotice, createErrorNotice } = - useDispatch( noticesStore ); - const onConfirm = async () => { - try { - for ( const template of items ) { - await revertTemplate( template, { - allowUndo: false, - } ); - await saveEditedEntityRecord( - 'postType', - template.type, - template.id - ); - } - createSuccessNotice( - items.length > 1 - ? sprintf( - /* translators: The number of items. */ - __( '%s items reset.' ), - items.length - ) - : sprintf( - /* translators: The template/part's name. */ - __( '"%s" reset.' ), - decodeEntities( getItemTitle( items[ 0 ] ) ) - ), - { - type: 'snackbar', - id: 'revert-template-action', - } - ); - } catch ( error ) { - let fallbackErrorMessage; - if ( items[ 0 ].type === TEMPLATE_POST_TYPE ) { - fallbackErrorMessage = - items.length === 1 - ? __( - 'An error occurred while reverting the template.' - ) - : __( - 'An error occurred while reverting the templates.' - ); - } else { - fallbackErrorMessage = - items.length === 1 - ? __( - 'An error occurred while reverting the template part.' - ) - : __( - 'An error occurred while reverting the template parts.' - ); - } - const errorMessage = - error.message && error.code !== 'unknown_error' - ? error.message - : fallbackErrorMessage; - - createErrorNotice( errorMessage, { type: 'snackbar' } ); - } - }; - return ( - - - { __( 'Reset to default and clear all customizations?' ) } - - - - - - - ); - }, -}; - export const duplicatePatternAction = { id: 'duplicate-pattern', label: _x( 'Duplicate', 'action label' ), @@ -1037,9 +928,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { isPattern && userCanCreatePostType && duplicatePatternAction, supportsTitle && renamePostActionForPostType, isPattern && exportPatternAsJSONAction, - isTemplateOrTemplatePart - ? resetTemplateAction - : restorePostActionForPostType, + ! isTemplateOrTemplatePart && restorePostActionForPostType, ! isTemplateOrTemplatePart && ! isPattern && trashPostActionForPostType, diff --git a/packages/editor/src/dataviews/actions/index.ts b/packages/editor/src/dataviews/actions/index.ts index 87589d68262f3e..7442c529f85711 100644 --- a/packages/editor/src/dataviews/actions/index.ts +++ b/packages/editor/src/dataviews/actions/index.ts @@ -7,6 +7,8 @@ import { type StoreDescriptor, dispatch } from '@wordpress/data'; * Internal dependencies */ import deletePost from './delete-post'; +import resetPost from './reset-post'; + // @ts-ignore import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; @@ -16,5 +18,6 @@ export default function registerDefaultActions() { dispatch( editorStore as StoreDescriptor ) ); + registerEntityAction( 'postType', '*', resetPost ); registerEntityAction( 'postType', '*', deletePost ); } diff --git a/packages/editor/src/dataviews/actions/reset-post.tsx b/packages/editor/src/dataviews/actions/reset-post.tsx new file mode 100644 index 00000000000000..56440e6da33838 --- /dev/null +++ b/packages/editor/src/dataviews/actions/reset-post.tsx @@ -0,0 +1,144 @@ +/** + * WordPress dependencies + */ +import { backup } from '@wordpress/icons'; +import { useDispatch } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; +import { __, _n, sprintf, _x } from '@wordpress/i18n'; +import { store as noticesStore } from '@wordpress/notices'; +import { useState } from '@wordpress/element'; +import { + Button, + __experimentalText as Text, + __experimentalHStack as HStack, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import type { Action } from '@wordpress/dataviews'; +import type { StoreDescriptor } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { TEMPLATE_POST_TYPE, TEMPLATE_ORIGINS } from '../../store/constants'; +import { store as editorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; +import type { Post, CoreDataError } from '../types'; +import { isTemplateOrTemplatePart, getItemTitle } from './utils'; + +const resetPost: Action< Post > = { + id: 'reset-post', + label: __( 'Reset' ), + isEligible: ( item ) => { + return ( + isTemplateOrTemplatePart( item ) && + item?.source === TEMPLATE_ORIGINS.custom && + item?.has_theme_file + ); + }, + icon: backup, + supportsBulk: true, + hideModalHeader: true, + RenderModal: ( { items, closeModal, onActionPerformed } ) => { + const [ isBusy, setIsBusy ] = useState( false ); + const { revertTemplate } = unlock( + useDispatch( editorStore as StoreDescriptor ) + ); + const { saveEditedEntityRecord } = useDispatch( coreStore ); + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + const onConfirm = async () => { + try { + for ( const template of items ) { + await revertTemplate( template, { + allowUndo: false, + } ); + await saveEditedEntityRecord( + 'postType', + template.type, + template.id + ); + } + createSuccessNotice( + items.length > 1 + ? sprintf( + /* translators: The number of items. */ + __( '%s items reset.' ), + items.length + ) + : sprintf( + /* translators: The template/part's name. */ + __( '"%s" reset.' ), + getItemTitle( items[ 0 ] ) + ), + { + type: 'snackbar', + id: 'revert-template-action', + } + ); + } catch ( error ) { + let fallbackErrorMessage; + if ( items[ 0 ].type === TEMPLATE_POST_TYPE ) { + fallbackErrorMessage = + items.length === 1 + ? __( + 'An error occurred while reverting the template.' + ) + : __( + 'An error occurred while reverting the templates.' + ); + } else { + fallbackErrorMessage = + items.length === 1 + ? __( + 'An error occurred while reverting the template part.' + ) + : __( + 'An error occurred while reverting the template parts.' + ); + } + + const typedError = error as CoreDataError; + const errorMessage = + typedError.message && typedError.code !== 'unknown_error' + ? typedError.message + : fallbackErrorMessage; + + createErrorNotice( errorMessage, { type: 'snackbar' } ); + } + }; + return ( + + + { __( 'Reset to default and clear all customizations?' ) } + + + + + + + ); + }, +}; + +export default resetPost; diff --git a/packages/editor/src/dataviews/types.ts b/packages/editor/src/dataviews/types.ts index c1771801d8ee37..29f4358456324d 100644 --- a/packages/editor/src/dataviews/types.ts +++ b/packages/editor/src/dataviews/types.ts @@ -11,11 +11,16 @@ export interface BasePost { status?: PostStatus; title: string | { rendered: string }; type: string; + id: string | number; } export interface TemplateOrTemplatePart extends BasePost { - type: 'template' | 'template-part'; + type: 'wp_template' | 'wp_template_part'; source: string; has_theme_file: boolean; + id: string; } export type Post = TemplateOrTemplatePart | BasePost; + +// Will be unnecessary after typescript 5.0 upgrade. +export type CoreDataError = { message?: string; code?: string };