import {__, _x, sprintf} from '@wordpress/i18n' import { store as blockEditorStore, // @ts-expect-error } from '@wordpress/block-editor' import { useSelect, useDispatch, } from '@wordpress/data' import { store as noticesStore, } from '@wordpress/notices' import type { tBlock, tBlockAttributes, } from '@ska/shared' import { flattenInnerBlocks, resolveVariation, resolveVariationSlug, useVariationOptionsEdit, type BlockVariationSlug, type createVariation, type Variation, type VariationOptions, type VariationSlug, } from '.' export const useVariations = () => { const [select] = useVariationOptionsEdit() return select.getOption('variations') as VariationOptions['variations'] } export const useVariationSlugs = () => { return Object.keys(useVariations()) } export const useVariationSlug = (slug: BlockVariationSlug) => { const variations = useVariations() if(!slug) { return undefined } if(Object(variations).hasOwnProperty(slug)) { return slug as VariationSlug } return resolveVariationSlug(slug, variations) } export const useVariation = (slug: BlockVariationSlug) => { const variations = useVariations() if(!slug) { return undefined } if(Object(variations).hasOwnProperty(slug)) { return variations[slug] } const resolvedVariation = resolveVariation(slug, variations) if(resolvedVariation.ref === '404') { return undefined } return resolvedVariation } export const useApplyVariation = (clientId: string, variationToApply?: Variation): () => void => { const block: tBlock = useSelect(select => select(blockEditorStore).getBlock(clientId), [clientId]) const { updateBlockAttributes, } = useDispatch(blockEditorStore) const { createSuccessNotice, createErrorNotice, } = useDispatch(noticesStore) return () => { if(!block) { createErrorNotice(__('Invalid block', 'ska-blocks'), {type: 'snackbar'}) return } if(!variationToApply) { createErrorNotice(__('Invalid variation', 'ska-blocks'), {type: 'snackbar'}) return } const { title = '', variation: variationJson = '{}', } = variationToApply try { const variation = JSON.parse(variationJson) as ReturnType const { attributes: variationAttributes = {}, innerBlocks = [], } = variation const flatVariationInnerBlocks = flattenInnerBlocks(innerBlocks) const flatBlockInnerBlocks = flattenInnerBlocks(block.innerBlocks || []) if(flatVariationInnerBlocks.length !== flatBlockInnerBlocks.length) { createErrorNotice(__('Block structure does not match variation', 'ska-blocks'), {type: 'snackbar'}) return } const clientIds: string[] = [] const attributes: Record = {} clientIds.push(block.clientId) attributes[block.clientId] = variationAttributes flatVariationInnerBlocks.forEach(({attributes: variationAttributes = {}}, index) => { const { clientId, } = flatBlockInnerBlocks[index] clientIds.push(clientId) attributes[clientId] = variationAttributes }) updateBlockAttributes(clientIds, attributes, true) createSuccessNotice(sprintf(__('Re-applied variation "%s"', 'ska-blocks'), title), {type: 'snackbar'}) } catch(e) { createErrorNotice(__('Invalid variation', 'ska-blocks'), {type: 'snackbar'}) } } }