index.js
145 lines
| 1 | /** |
| 2 | * WordPress dependencies |
| 3 | */ |
| 4 | import { __ } from '@wordpress/i18n'; |
| 5 | import { store as blockEditorStore } from '@wordpress/block-editor'; |
| 6 | import { useState, useEffect } from '@wordpress/element'; |
| 7 | import { registerBlockVariation } from '@wordpress/blocks'; |
| 8 | import { useSelect } from '@wordpress/data'; |
| 9 | |
| 10 | /** |
| 11 | * Internal dependencies |
| 12 | */ |
| 13 | import VariationForm from './block-variation-form'; |
| 14 | import { VariationIcon } from '../icons'; |
| 15 | import { SaveButton } from '../save-button'; |
| 16 | import { STORE_NAME } from '@vkblocks/utils/store/constants'; |
| 17 | |
| 18 | const DEFAULT_VARIATION = { |
| 19 | name: '', |
| 20 | title: '', |
| 21 | description: '', |
| 22 | category: '', |
| 23 | icon: '', |
| 24 | scope: [], |
| 25 | keywords: '', |
| 26 | }; |
| 27 | |
| 28 | export default function CreateVariation(props) { |
| 29 | const { blockName, clientId, setIsModalOpen, setHasUpdates } = props; |
| 30 | const [variation, setVariation] = useState(DEFAULT_VARIATION); |
| 31 | const [canSave, setCanSave] = useState(false); |
| 32 | |
| 33 | const [variationState, setVariationState] = useState(); |
| 34 | |
| 35 | const { optionObj } = useSelect((select) => { |
| 36 | const { getOptions } = select(STORE_NAME); |
| 37 | return { |
| 38 | optionObj: getOptions(), |
| 39 | }; |
| 40 | }, []); |
| 41 | const blockVariationLists = |
| 42 | optionObj?.vkBlocksOption?.block_variation_lists; |
| 43 | useEffect(() => { |
| 44 | setVariationState(blockVariationLists); |
| 45 | }, [blockVariationLists]); |
| 46 | |
| 47 | useEffect(() => { |
| 48 | if (JSON.stringify(variation) === JSON.stringify(DEFAULT_VARIATION)) { |
| 49 | setHasUpdates(false); |
| 50 | } else { |
| 51 | setHasUpdates(true); |
| 52 | } |
| 53 | }, [variation]); |
| 54 | |
| 55 | const { getBlocksByClientId } = useSelect( |
| 56 | (select) => select(blockEditorStore), |
| 57 | [] |
| 58 | ); |
| 59 | const blockObj = getBlocksByClientId(clientId)[0] ?? {}; |
| 60 | |
| 61 | const updateSettings = (newVariation) => { |
| 62 | variationState.push({ |
| 63 | block_name: blockName, |
| 64 | ...newVariation, |
| 65 | }); |
| 66 | setVariationState([...variationState]); |
| 67 | }; |
| 68 | |
| 69 | const saveAttributes = generateAttributes(blockObj.attributes, ['url']); |
| 70 | const saveInnerBlocks = generateInnerBlocks(blockObj.innerBlocks); |
| 71 | const saveButtonClick = () => { |
| 72 | const updateVariation = { |
| 73 | ...variation, |
| 74 | attributes: JSON.stringify(saveAttributes), |
| 75 | innerBlocks: JSON.stringify(saveInnerBlocks), |
| 76 | }; |
| 77 | updateSettings(updateVariation); |
| 78 | const blockVariation = { |
| 79 | ...updateVariation, |
| 80 | attributes: saveAttributes, |
| 81 | innerBlocks: saveInnerBlocks, |
| 82 | icon: variation.icon || VariationIcon, |
| 83 | block_name: undefined, |
| 84 | }; |
| 85 | registerBlockVariation(blockName, blockVariation); |
| 86 | |
| 87 | setIsModalOpen(false); |
| 88 | }; |
| 89 | return ( |
| 90 | <> |
| 91 | <VariationForm |
| 92 | variation={variation} |
| 93 | setVariation={setVariation} |
| 94 | blockName={blockName} |
| 95 | canSave={canSave} |
| 96 | setCanSave={setCanSave} |
| 97 | variationState={variationState} |
| 98 | setVariationState={setVariationState} |
| 99 | /> |
| 100 | <SaveButton |
| 101 | disabled={ |
| 102 | !canSave || !variation.title || variation.scope.length === 0 |
| 103 | } |
| 104 | onClick={saveButtonClick} |
| 105 | variationState={variationState} |
| 106 | setVariationState={setVariationState} |
| 107 | saveButtonChildren={__('Add', 'vk-blocks')} |
| 108 | /> |
| 109 | </> |
| 110 | ); |
| 111 | } |
| 112 | |
| 113 | function generateAttributes(attributes, excludeAttributes = []) { |
| 114 | const generatedAttributes = {}; |
| 115 | |
| 116 | for (const key in attributes) { |
| 117 | if ( |
| 118 | excludeAttributes.find((attribute) => { |
| 119 | return attribute === key; |
| 120 | }) === undefined |
| 121 | ) { |
| 122 | if ( |
| 123 | typeof attributes[key] === 'object' && |
| 124 | !Array.isArray(attributes[key]) |
| 125 | ) { |
| 126 | generatedAttributes[key] = generateAttributes(attributes[key]); |
| 127 | } else { |
| 128 | generatedAttributes[key] = attributes[key]; |
| 129 | } |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | return generatedAttributes; |
| 134 | } |
| 135 | |
| 136 | function generateInnerBlocks(propsInnerBlocks = []) { |
| 137 | return propsInnerBlocks.map( |
| 138 | ({ name, attributes = {}, innerBlocks = [] }) => [ |
| 139 | name, |
| 140 | attributes, |
| 141 | generateInnerBlocks(innerBlocks), |
| 142 | ] |
| 143 | ); |
| 144 | } |
| 145 |