Skip to content

Commit b234bee

Browse files
committed
add pages in design library
- also add prompt if there are existing blocks in the editor
1 parent 669a0ef commit b234bee

File tree

11 files changed

+384
-794
lines changed

11 files changed

+384
-794
lines changed

gulpfile.js

Lines changed: 1 addition & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -411,81 +411,6 @@ ${ blockDesignSystem });
411411
cb()
412412
} )
413413

414-
gulp.task( 'generate-design-library-default-placeholders-php', function( cb ) {
415-
const fs = require( 'fs' )
416-
417-
let defaultPlaceholders = 'array()'
418-
419-
const toAssocArray = ( key, value, cb, indent ) => {
420-
if ( typeof value === 'object' ) {
421-
const parsed = cb( value, indent + 1 )
422-
return `"${ key }" => ${ parsed }`
423-
}
424-
425-
return `"${ key }" => "${ value }"`
426-
}
427-
428-
const parsePlaceholders = ( obj, indent ) => {
429-
let content = ''
430-
const tab = '\t'.repeat( indent )
431-
432-
if ( typeof obj === 'object' ) {
433-
content += 'array(\n'
434-
435-
Object.entries( obj ).forEach( ( [ key, value ], index, bds ) => {
436-
content += tab + toAssocArray( key, value, parsePlaceholders, indent )
437-
438-
if ( index !== bds.length - 1 ) {
439-
content += ',\n'
440-
} else {
441-
content += '\n'
442-
}
443-
} )
444-
content += `\t`.repeat( indent - 1 ) + ')'
445-
}
446-
return content
447-
}
448-
449-
const jsonPath = path.resolve( __dirname, `src/components/design-library-list/default.json` )
450-
if ( fs.existsSync( jsonPath ) ) {
451-
const fileContent = fs.readFileSync( jsonPath, 'utf-8' )
452-
const raw = JSON.parse( fileContent )
453-
defaultPlaceholders = parsePlaceholders( raw, 4 )
454-
}
455-
456-
// Generate PHP variable string
457-
const script = `<?php
458-
// This is a generated file by gulp generate-design-library-default-placeholders-php
459-
// Use src/components/design-library-list/default.json if you want to edit this file.
460-
461-
// Exit if accessed directly.
462-
if ( ! defined( 'ABSPATH' ) ) {
463-
exit;
464-
}
465-
466-
if ( ! class_exists( 'Stackable_Design_Library_Placeholders' ) ) {
467-
class Stackable_Design_Library_Placeholders {
468-
469-
function __construct() {
470-
}
471-
472-
public static function get_default() {
473-
$default_placeholders = ${ defaultPlaceholders };
474-
475-
return $default_placeholders;
476-
}
477-
}
478-
479-
new Stackable_Design_Library_Placeholders();
480-
}
481-
?>
482-
`
483-
// Write PHP variable to file
484-
fs.writeFileSync( path.resolve( __dirname, 'src/design-library/default-placeholders.php' ), script )
485-
486-
cb()
487-
} )
488-
489414
gulp.task( 'generate-translations-js', gulp.series(
490415
// The collect function has an issue where it will not continue if the
491416
// folder will it writes to doesn't exist, create it to prevent an error.
@@ -778,7 +703,7 @@ gulp.task( 'style-deprecated', gulp.parallel(
778703
* END deprecated build styles, we still build these
779704
********************************************************************/
780705

781-
gulp.task( 'build-process', gulp.parallel( 'style', 'style-editor', 'welcome-styles', 'style-deprecated', 'generate-translations-js', 'generate-stk-block-typesphp', 'generate-design-library-default-placeholders-php' ) )
706+
gulp.task( 'build-process', gulp.parallel( 'style', 'style-editor', 'welcome-styles', 'style-deprecated', 'generate-translations-js', 'generate-stk-block-typesphp' ) )
782707

783708
gulp.task( 'build-block-design-system', gulp.parallel( 'generate-block-design-system-php', 'generate-block-design-system-scss' ) )
784709

@@ -815,11 +740,6 @@ const watchFuncs = ( basePath = '.' ) => {
815740
[ `${ basePath }/src/block/**/block.json` ],
816741
gulp.parallel( [ 'generate-stk-block-typesphp' ] )
817742
)
818-
819-
gulp.watch(
820-
[ `${ basePath }/src/components/design-library-list/default.json` ],
821-
gulp.parallel( [ 'generate-design-library-default-placeholders-php' ] )
822-
)
823743
}
824744

825745
gulp.task( 'watch', gulp.series( 'build-block-design-system', 'build-process', function watch( done ) {

plugin.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ function is_frontend() {
233233
require_once( plugin_dir_path( __FILE__ ) . 'src/kses.php' );
234234
require_once( plugin_dir_path( __FILE__ ) . 'src/dynamic-breakpoints.php' );
235235
require_once( plugin_dir_path( __FILE__ ) . 'src/design-library/init.php' );
236-
require_once( plugin_dir_path( __FILE__ ) . 'src/design-library/default-placeholders.php' );
237236
require_once( plugin_dir_path( __FILE__ ) . 'src/styles/block-design-system.php' );
238237
require_once( plugin_dir_path( __FILE__ ) . 'src/plugins/theme-block-style-inheritance/index.php' );
239238
require_once( plugin_dir_path( __FILE__ ) . 'src/global-settings.php' );

src/block/design-library/edit.js

Lines changed: 109 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,25 @@ const checkIfImageUrl = async value => {
8080
return value
8181
}
8282

83+
const DIALOG_OPTIONS = {
84+
CLOSE: 0,
85+
REMOVE_BLOCKS: 1,
86+
DISABLED_BLOCKS: 2,
87+
}
88+
8389
const Edit = props => {
8490
const {
8591
clientId,
8692
attributes,
8793
} = props
8894

8995
const [ isLibraryOpen, setIsLibraryOpen ] = useState( false )
90-
const [ isDialogOpen, setIsDialogOpen ] = useState( false )
96+
const [ isDialogOpen, setIsDialogOpen ] = useState( DIALOG_OPTIONS.CLOSE )
9197

9298
const designsRef = useRef( [] )
9399
const disabledBlocksRef = useRef( [] )
94100
const callbackRef = useRef( null )
101+
const blocksToRemoveRef = useRef( [] )
95102

96103
const blockProps = useBlockProps( {
97104
className: 'ugb-design-library-block',
@@ -240,14 +247,17 @@ const Edit = props => {
240247

241248
for ( const blockDesign of designs ) {
242249
const { designData, category } = blockDesign
243-
const {
244-
name, attributes, innerBlocks,
245-
} = designData
246-
if ( name && attributes ) {
247-
const block = await createBlockWithAttributes( category, name, applyFilters( 'stackable.design-library.attributes', attributes ), innerBlocks || [], substituteBlocks, parentClientId )
248-
blocks.push( block )
249-
} else {
250-
console.error( 'Design library selection failed: No block data found' ) // eslint-disable-line no-console
250+
251+
for ( const patterns of designData ) {
252+
const {
253+
name, attributes, innerBlocks,
254+
} = patterns
255+
if ( name && attributes ) {
256+
const block = await createBlockWithAttributes( category, name, applyFilters( 'stackable.design-library.attributes', attributes ), innerBlocks || [], substituteBlocks, parentClientId )
257+
blocks.push( block )
258+
} else {
259+
console.error( 'Design library selection failed: No block data found' ) // eslint-disable-line no-console
260+
}
251261
}
252262
}
253263

@@ -284,10 +294,18 @@ const Edit = props => {
284294
}
285295
}
286296

297+
const removeBlocks = () => {
298+
if ( blocksToRemoveRef.current.length ) {
299+
dispatch( 'core/block-editor' ).removeBlocks( blocksToRemoveRef.current )
300+
}
301+
}
302+
287303
const onClickSecondary = async () => {
304+
removeBlocks()
288305
await addDesigns( false )
289306
}
290307
const onClickPrimary = async () => {
308+
removeBlocks()
291309
await addDesigns( true )
292310
}
293311

@@ -324,7 +342,7 @@ const Edit = props => {
324342
onClose={ () => {
325343
setIsLibraryOpen( false )
326344
} }
327-
onSelect={ async ( _designs, callback ) => {
345+
onSelect={ async ( _designs, callback, type ) => {
328346
const designs = []
329347
let disabledBlocks = new Set()
330348

@@ -344,52 +362,100 @@ const Edit = props => {
344362
disabledBlocksRef.current = disabledBlocks
345363
callbackRef.current = callback
346364

365+
if ( type === 'pages' ) {
366+
const currentBlocks = select( 'core/block-editor' ).getBlockOrder().filter( id => id !== clientId )
367+
368+
if ( currentBlocks.length ) {
369+
blocksToRemoveRef.current = currentBlocks
370+
setIsDialogOpen( DIALOG_OPTIONS.REMOVE_BLOCKS )
371+
return
372+
}
373+
}
374+
347375
if ( disabledBlocks.size ) {
348-
setIsDialogOpen( true )
376+
setIsDialogOpen( DIALOG_OPTIONS.DISABLED_BLOCKS )
349377
return
350378
}
351379

352380
await addDesigns( false )
353381
} }
354382
/>
355383
}
356-
{ isDialogOpen &&
384+
{ isDialogOpen !== DIALOG_OPTIONS.CLOSE &&
357385
<Modal
358386
className="ugb-design-library__confirm-dialog"
359387
title={ __( 'Stackable Design Library', i18n ) }
360-
onRequestClose={ () => setIsDialogOpen( false ) }
388+
onRequestClose={ () => setIsDialogOpen( DIALOG_OPTIONS.CLOSE ) }
361389
>
362390
<VStack spacing={ 8 }>
363-
<div>
364-
<span>{ __( 'The designs you have selected contain the following disabled blocks:', i18n ) }</span>
365-
<ul>
366-
{ disabledBlocksRef.current && [ ...disabledBlocksRef.current ].map( ( block, i ) => <li key={ i }>{ block }</li> ) }
367-
</ul>
368-
<span> { __( 'These blocks can be enabled in the Stackable settings page. Do you want to keep the disabled blocks or substitute them with other Stackable or core blocks?', i18n ) }</span>
369-
</div>
370-
<Flex direction="column" align="flex-end">
371-
<Button
372-
__next40pxDefaultSize
373-
variant="primary"
374-
onClick={ () => onClickPrimary() }
375-
>
376-
{ __( 'Add patterns and substitute blocks', i18n ) }
377-
</Button>
378-
<Button
379-
__next40pxDefaultSize
380-
variant="secondary"
381-
onClick={ () => onClickSecondary() }
382-
>
383-
{ __( 'Add patterns only (no substitutes)', i18n ) }
384-
</Button>
385-
<Button
386-
__next40pxDefaultSize
387-
variant="tertiary"
388-
onClick={ () => onClickTertiary() }
389-
>
390-
{ __( 'Enable blocks in settings', i18n ) }
391-
</Button>
392-
</Flex>
391+
{ isDialogOpen === DIALOG_OPTIONS.REMOVE_BLOCKS && <>
392+
<div>
393+
<span>
394+
{ __( 'Adding this page design will replace all existing blocks in the editor. Are you sure you want to continue?', i18n ) }
395+
</span>
396+
</div>
397+
<Flex justify="flex-end">
398+
<Button
399+
__next40pxDefaultSize
400+
variant="secondary"
401+
onClick={ () => {
402+
blocksToRemoveRef.current = []
403+
setIsDialogOpen( DIALOG_OPTIONS.CLOSE )
404+
} }
405+
>
406+
{ __( 'Cancel', i18n ) }
407+
</Button>
408+
<Button
409+
__next40pxDefaultSize
410+
variant="primary"
411+
onClick={ () => {
412+
if ( disabledBlocksRef.current.size ) {
413+
// Close this dialog and reopen after a while to show the notice for disabled blocks
414+
// The existing blocks will be removed later
415+
setIsDialogOpen( DIALOG_OPTIONS.CLOSE )
416+
setTimeout( () => setIsDialogOpen( DIALOG_OPTIONS.DISABLED_BLOCKS ), 500 )
417+
} else {
418+
removeBlocks()
419+
addDesigns( false )
420+
}
421+
} }
422+
>
423+
{ __( 'Insert page design', i18n ) }
424+
</Button>
425+
</Flex>
426+
</> }
427+
{ isDialogOpen === DIALOG_OPTIONS.DISABLED_BLOCKS && <>
428+
<div>
429+
<span>{ __( 'The designs you have selected contain the following disabled blocks:', i18n ) }</span>
430+
<ul>
431+
{ disabledBlocksRef.current && [ ...disabledBlocksRef.current ].map( ( block, i ) => <li key={ i }>{ block }</li> ) }
432+
</ul>
433+
<span> { __( 'These blocks can be enabled in the Stackable settings page. Do you want to keep the disabled blocks or substitute them with other Stackable or core blocks?', i18n ) }</span>
434+
</div>
435+
<Flex direction="column" align="flex-end">
436+
<Button
437+
__next40pxDefaultSize
438+
variant="primary"
439+
onClick={ () => onClickPrimary() }
440+
>
441+
{ __( 'Add patterns and substitute blocks', i18n ) }
442+
</Button>
443+
<Button
444+
__next40pxDefaultSize
445+
variant="secondary"
446+
onClick={ () => onClickSecondary() }
447+
>
448+
{ __( 'Add patterns only (no substitutes)', i18n ) }
449+
</Button>
450+
<Button
451+
__next40pxDefaultSize
452+
variant="tertiary"
453+
onClick={ () => onClickTertiary() }
454+
>
455+
{ __( 'Enable blocks in settings', i18n ) }
456+
</Button>
457+
</Flex>
458+
</> }
393459
</VStack>
394460

395461
</Modal>

0 commit comments

Comments
 (0)