diff --git a/package-lock.json b/package-lock.json index a461be9fbb16a..9ca357997a7f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22223,6 +22223,11 @@ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, + "node_modules/client-zip": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/client-zip/-/client-zip-2.4.4.tgz", + "integrity": "sha512-Ixk40BUI7VvNDxW7SCze20GbCuC+gjP4tGkXUpo6/W96bOf96HSed6cOQVeUOIe74SJAG/dIrBr7AtR4xBVnsA==" + }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -55245,6 +55250,7 @@ "@wordpress/wordcount": "file:../wordcount", "change-case": "^4.1.2", "classnames": "^2.3.1", + "client-zip": "^2.4.4", "colord": "^2.9.2", "deepmerge": "^4.3.0", "fast-deep-equal": "^3.1.3", @@ -70370,6 +70376,7 @@ "@wordpress/wordcount": "file:../wordcount", "change-case": "^4.1.2", "classnames": "^2.3.1", + "client-zip": "^2.4.4", "colord": "^2.9.2", "deepmerge": "^4.3.0", "fast-deep-equal": "^3.1.3", @@ -74222,6 +74229,11 @@ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, + "client-zip": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/client-zip/-/client-zip-2.4.4.tgz", + "integrity": "sha512-Ixk40BUI7VvNDxW7SCze20GbCuC+gjP4tGkXUpo6/W96bOf96HSed6cOQVeUOIe74SJAG/dIrBr7AtR4xBVnsA==" + }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index c4f31d385e5d2..f62faf0b8cd8f 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -69,6 +69,7 @@ "@wordpress/wordcount": "file:../wordcount", "change-case": "^4.1.2", "classnames": "^2.3.1", + "client-zip": "^2.4.4", "colord": "^2.9.2", "deepmerge": "^4.3.0", "fast-deep-equal": "^3.1.3", diff --git a/packages/edit-site/src/components/page-patterns/dataviews-pattern-actions.js b/packages/edit-site/src/components/page-patterns/dataviews-pattern-actions.js index 5a68f731c2afe..e908a49bb3608 100644 --- a/packages/edit-site/src/components/page-patterns/dataviews-pattern-actions.js +++ b/packages/edit-site/src/components/page-patterns/dataviews-pattern-actions.js @@ -2,6 +2,7 @@ * External dependencies */ import { paramCase as kebabCase } from 'change-case'; +import { downloadZip } from 'client-zip'; /** * WordPress dependencies @@ -41,21 +42,51 @@ const { useHistory } = unlock( routerPrivateApis ); const { CreatePatternModalContents, useDuplicatePatternProps } = unlock( patternsPrivateApis ); -export const exportJSONaction = { - id: 'export-pattern', - label: __( 'Export as JSON' ), - isEligible: ( item ) => item.type === PATTERN_TYPES.user, - callback: ( [ item ] ) => { - const json = { +function getJsonFromItem( item ) { + return JSON.stringify( + { __file: item.type, title: item.title || item.name, content: item.patternPost.content.raw, syncStatus: item.patternPost.wp_pattern_sync_status, - }; + }, + null, + 2 + ); +} + +export const exportJSONaction = { + id: 'export-pattern', + label: __( 'Export as JSON' ), + supportsBulk: true, + isEligible: ( item ) => item.type === PATTERN_TYPES.user, + callback: async ( items ) => { + if ( items.length === 1 ) { + return downloadBlob( + `${ kebabCase( items[ 0 ].title || items[ 0 ].name ) }.json`, + getJsonFromItem( items[ 0 ] ), + 'application/json' + ); + } + const nameCount = {}; + const filesToZip = items.map( ( item ) => { + const name = kebabCase( item.title || item.name ); + nameCount[ name ] = ( nameCount[ name ] || 0 ) + 1; + return { + name: `${ + name + + ( nameCount[ name ] > 1 + ? '-' + ( nameCount[ name ] - 1 ) + : '' ) + }.json`, + lastModified: new Date(), + input: getJsonFromItem( item ), + }; + } ); return downloadBlob( - `${ kebabCase( item.title || item.name ) }.json`, - JSON.stringify( json, null, 2 ), - 'application/json' + __( 'patterns-export' ) + '.zip', + await downloadZip( filesToZip ).blob(), + 'application/zip' ); }, };