diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index c750c202e76fe..94e38d4ed30f0 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 { exportPatternAsJSONAction } from './export-pattern-action'; import { CreateTemplatePartModalContents } from '../create-template-part-modal'; import { getItemTitle } from '../../dataviews/actions/utils'; @@ -914,7 +913,6 @@ export function usePostActions( { postType, onActionPerformed, context } ) { duplicateTemplatePartAction, isPattern && userCanCreatePostType && duplicatePatternAction, supportsTitle && renamePostActionForPostType, - isPattern && exportPatternAsJSONAction, ! isTemplateOrTemplatePart && restorePostActionForPostType, ! isTemplateOrTemplatePart && ! isPattern && diff --git a/packages/editor/src/components/post-actions/export-pattern-action.native.js b/packages/editor/src/components/post-actions/export-pattern-action.native.js deleted file mode 100644 index b09f5a034a552..0000000000000 --- a/packages/editor/src/components/post-actions/export-pattern-action.native.js +++ /dev/null @@ -1,4 +0,0 @@ -// Client-zip is meant to be used in a browser and is therefore released as an ES6 module only, -// in order for the native build to succeed we are importing a null action and avoiding importing -// the non working in native context client-zip module. -export const exportPatternAsJSONAction = null; diff --git a/packages/editor/src/components/post-actions/export-pattern-action.js b/packages/editor/src/dataviews/actions/export-pattern.tsx similarity index 73% rename from packages/editor/src/components/post-actions/export-pattern-action.js rename to packages/editor/src/dataviews/actions/export-pattern.tsx index 959cfe1a4abc7..917b284ade1a2 100644 --- a/packages/editor/src/components/post-actions/export-pattern-action.js +++ b/packages/editor/src/dataviews/actions/export-pattern.tsx @@ -9,18 +9,15 @@ import { downloadZip } from 'client-zip'; */ import { downloadBlob } from '@wordpress/blob'; import { __ } from '@wordpress/i18n'; -import { privateApis as patternsPrivateApis } from '@wordpress/patterns'; +import type { Action } from '@wordpress/dataviews'; /** * Internal dependencies */ -import { unlock } from '../../lock-unlock'; -import { getItemTitle } from '../../dataviews/actions/utils'; +import type { Pattern } from '../types'; +import { getItemTitle } from './utils'; -// Patterns. -const { PATTERN_TYPES } = unlock( patternsPrivateApis ); - -function getJsonFromItem( item ) { +function getJsonFromItem( item: Pattern ) { return JSON.stringify( { __file: item.type, @@ -33,16 +30,10 @@ function getJsonFromItem( item ) { ); } -export const exportPatternAsJSONAction = { +const exportPattern: Action< Pattern > = { id: 'export-pattern', label: __( 'Export as JSON' ), supportsBulk: true, - isEligible: ( item ) => { - if ( ! item.type ) { - return false; - } - return item.type === PATTERN_TYPES.user; - }, callback: async ( items ) => { if ( items.length === 1 ) { return downloadBlob( @@ -53,7 +44,7 @@ export const exportPatternAsJSONAction = { 'application/json' ); } - const nameCount = {}; + const nameCount: Record< string, number > = {}; const filesToZip = items.map( ( item ) => { const name = kebabCase( getItemTitle( item ) || item.slug ); nameCount[ name ] = ( nameCount[ name ] || 0 ) + 1; @@ -75,3 +66,5 @@ export const exportPatternAsJSONAction = { ); }, }; + +export default exportPattern; diff --git a/packages/editor/src/dataviews/actions/index.ts b/packages/editor/src/dataviews/actions/index.ts index 7442c529f8571..730edf323578c 100644 --- a/packages/editor/src/dataviews/actions/index.ts +++ b/packages/editor/src/dataviews/actions/index.ts @@ -7,6 +7,7 @@ import { type StoreDescriptor, dispatch } from '@wordpress/data'; * Internal dependencies */ import deletePost from './delete-post'; +import exportPattern from './export-pattern'; import resetPost from './reset-post'; // @ts-ignore @@ -18,6 +19,7 @@ export default function registerDefaultActions() { dispatch( editorStore as StoreDescriptor ) ); + registerEntityAction( 'postType', 'wp_block', exportPattern ); registerEntityAction( 'postType', '*', resetPost ); registerEntityAction( 'postType', '*', deletePost ); } diff --git a/packages/editor/src/dataviews/store/reducer.ts b/packages/editor/src/dataviews/store/reducer.ts index e00af778ddf01..0e66fc0fcac72 100644 --- a/packages/editor/src/dataviews/store/reducer.ts +++ b/packages/editor/src/dataviews/store/reducer.ts @@ -19,8 +19,13 @@ function actions( state: ActionState = {}, action: ReduxAction ) { return { ...state, [ action.kind ]: { + ...state[ action.kind ], [ action.name ]: [ - ...( state[ action.kind ]?.[ action.name ] ?? [] ), + ...( + state[ action.kind ]?.[ action.name ] ?? [] + ).filter( + ( _action ) => _action.id !== action.config.id + ), action.config, ], }, @@ -28,9 +33,12 @@ function actions( state: ActionState = {}, action: ReduxAction ) { case 'UNREGISTER_ENTITY_ACTION': { return { ...state, - [ action.kind ]: ( - state[ action.kind ]?.[ action.name ] ?? [] - ).filter( ( _action ) => _action.id !== action.actionId ), + [ action.kind ]: { + ...state[ action.kind ], + [ action.name ]: ( + state[ action.kind ]?.[ action.name ] ?? [] + ).filter( ( _action ) => _action.id !== action.actionId ), + }, }; } } diff --git a/packages/editor/src/dataviews/types.ts b/packages/editor/src/dataviews/types.ts index 3d8906284a597..02ce996402578 100644 --- a/packages/editor/src/dataviews/types.ts +++ b/packages/editor/src/dataviews/types.ts @@ -20,7 +20,16 @@ export interface TemplateOrTemplatePart extends BasePost { id: string; } -export type Post = TemplateOrTemplatePart | BasePost; +export interface Pattern extends BasePost { + slug: string; + title: { raw: string }; + content: { + raw: string; + }; + wp_pattern_sync_status: string; +} + +export type Post = TemplateOrTemplatePart | Pattern | BasePost; // Will be unnecessary after typescript 5.0 upgrade. export type CoreDataError = { message?: string; code?: string };