diff --git a/packages/volto-slate/news/6529.bugfix b/packages/volto-slate/news/6529.bugfix new file mode 100644 index 0000000000..75d42324e0 --- /dev/null +++ b/packages/volto-slate/news/6529.bugfix @@ -0,0 +1 @@ +Pass `intl` object to `initialValue` function. @wesleybl diff --git a/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx b/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx index 385cc84a65..b0c7b8bbe0 100644 --- a/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +++ b/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx @@ -142,10 +142,10 @@ export const DefaultTextBlockEditor = (props) => { const url = flattenToAppURL(imageId); setNewImageId(imageId); - createImageBlock(url, index, props); + createImageBlock(url, index, props, intl); } prevReq.current = loaded; - }, [props, loaded, loading, prevLoaded, imageId, newImageId, index]); + }, [props, loaded, loading, prevLoaded, imageId, newImageId, index, intl]); const handleUpdate = React.useCallback( (editor) => { diff --git a/packages/volto-slate/src/blocks/Text/extensions/breakList.js b/packages/volto-slate/src/blocks/Text/extensions/breakList.js index 515b8c4c67..a3249a1117 100644 --- a/packages/volto-slate/src/blocks/Text/extensions/breakList.js +++ b/packages/volto-slate/src/blocks/Text/extensions/breakList.js @@ -11,6 +11,7 @@ import { createEmptyParagraph } from '@plone/volto-slate/utils/blocks'; * Handles `Enter` key on empty and non-empty list items. * * @param {Editor} editor The editor which should be modified by this extension + * @param {Object} intl intl object. * with a new version of the `insertBreak` method of the Slate editor. * * @description If the selection does not exist or is expanded, handle with the @@ -20,7 +21,7 @@ import { createEmptyParagraph } from '@plone/volto-slate/utils/blocks'; * text cursor and then split the editor in two fragments, and convert them to * separate Slate Text blocks, based on the selection. */ -export const breakList = (editor) => { +export const breakList = (editor, intl) => { const { insertBreak } = editor; editor.insertBreak = () => { @@ -84,7 +85,7 @@ export const breakList = (editor) => { }); Transforms.select(editor, Editor.end(editor, [])); } else { - createAndSelectNewBlockAfter(editor, [createEmptyParagraph()]); + createAndSelectNewBlockAfter(editor, [createEmptyParagraph()], intl); Transforms.removeNodes(editor, { at: ref.current }); } return true; @@ -96,7 +97,7 @@ export const breakList = (editor) => { if (detached) { Editor.insertNode(editor, createEmptyParagraph()); } else { - createAndSelectNewBlockAfter(editor, [createEmptyParagraph()]); + createAndSelectNewBlockAfter(editor, [createEmptyParagraph()], intl); } return true; } @@ -104,7 +105,7 @@ export const breakList = (editor) => { if (!detached) { const [top, bottom] = splitEditorInTwoFragments(editor, ref.current); setEditorContent(editor, top); - createAndSelectNewBlockAfter(editor, bottom); + createAndSelectNewBlockAfter(editor, bottom, intl); } return true; }; diff --git a/packages/volto-slate/src/blocks/Text/extensions/insertBreak.js b/packages/volto-slate/src/blocks/Text/extensions/insertBreak.js index 91846daf3e..2836bba490 100644 --- a/packages/volto-slate/src/blocks/Text/extensions/insertBreak.js +++ b/packages/volto-slate/src/blocks/Text/extensions/insertBreak.js @@ -8,6 +8,7 @@ import { rangeIsInSplittableNode } from '@plone/volto-slate/utils/internals'; /** * @param {Editor} editor The Slate editor object to extend. + * @param {Object} intl intl object. * @description If the selection exists and touches with one of its edges a * closest-to-root `Text` node (`Path` with length `2`) * @@ -18,7 +19,7 @@ import { rangeIsInSplittableNode } from '@plone/volto-slate/utils/internals'; * and if the selection does not exist or does not touch with one of its edges a * closest-to-root `Text` node, call the default behavior. */ -export const withSplitBlocksOnBreak = (editor) => { +export const withSplitBlocksOnBreak = (editor, intl) => { const { insertBreak } = editor; editor.insertBreak = () => { @@ -40,7 +41,7 @@ export const withSplitBlocksOnBreak = (editor) => { ReactDOM.unstable_batchedUpdates(() => { const [top, bottom] = splitEditorInTwoFragments(editor); // ReactEditor.blur(editor); - createAndSelectNewBlockAfter(editor, bottom); + createAndSelectNewBlockAfter(editor, bottom, intl); setEditorContent(editor, top); }); } diff --git a/packages/volto-slate/src/blocks/Text/keyboard/joinBlocks.js b/packages/volto-slate/src/blocks/Text/keyboard/joinBlocks.js index 8c166f8c0f..d00097f8e0 100644 --- a/packages/volto-slate/src/blocks/Text/keyboard/joinBlocks.js +++ b/packages/volto-slate/src/blocks/Text/keyboard/joinBlocks.js @@ -26,7 +26,7 @@ import { * @param {Editor} editor * @param {KeyboardEvent} event */ -export function joinWithPreviousBlock({ editor, event }) { +export function joinWithPreviousBlock({ editor, event }, intl) { if (!isCursorAtBlockStart(editor)) return; const blockProps = editor.getBlockProps(); @@ -60,7 +60,7 @@ export function joinWithPreviousBlock({ editor, event }) { const text = Editor.string(editor, []); if (!text) { const cursor = getBlockEndAsRange(otherBlock); - const newFormData = deleteBlock(properties, block); + const newFormData = deleteBlock(properties, block, intl); ReactDOM.unstable_batchedUpdates(() => { saveSlateBlockSelection(otherBlockId, cursor); @@ -89,7 +89,7 @@ export function joinWithPreviousBlock({ editor, event }) { value: combined, plaintext: serializeNodesToText(combined || []), }); - const newFormData = deleteBlock(formData, block); + const newFormData = deleteBlock(formData, block, intl); ReactDOM.unstable_batchedUpdates(() => { saveSlateBlockSelection(otherBlockId, cursor); @@ -107,7 +107,7 @@ export function joinWithPreviousBlock({ editor, event }) { * @param {Editor} editor * @param {KeyboardEvent} event */ -export function joinWithNextBlock({ editor, event }) { +export function joinWithNextBlock({ editor, event }, intl) { if (!isCursorAtBlockEnd(editor)) return; const blockProps = editor.getBlockProps(); @@ -146,7 +146,7 @@ export function joinWithNextBlock({ editor, event }) { value: combined, plaintext: serializeNodesToText(combined || []), }); - const newFormData = deleteBlock(formData, block); + const newFormData = deleteBlock(formData, block, intl); ReactDOM.unstable_batchedUpdates(() => { // saveSlateBlockSelection(otherBlockId, cursor); diff --git a/packages/volto-slate/src/utils/volto-blocks.js b/packages/volto-slate/src/utils/volto-blocks.js index e01a40cc68..f4bba8b8de 100644 --- a/packages/volto-slate/src/utils/volto-blocks.js +++ b/packages/volto-slate/src/utils/volto-blocks.js @@ -118,7 +118,7 @@ export function syncCreateSlateBlock(value) { return [id, block]; } -export function createImageBlock(url, index, props) { +export function createImageBlock(url, index, props, intl) { const { properties, onChangeField, onSelectBlock } = props; const blocksFieldname = getBlocksFieldname(properties); const blocksLayoutFieldname = getBlocksLayoutFieldname(properties); @@ -128,7 +128,7 @@ export function createImageBlock(url, index, props) { let id, newFormData; if (currBlockHasValue) { - [id, newFormData] = addBlock(properties, 'image', index + 1); + [id, newFormData] = addBlock(properties, 'image', index + 1, {}, intl); newFormData = changeBlock(newFormData, id, { '@type': 'image', url }); } else { [id, newFormData] = insertBlock(properties, currBlockId, { @@ -144,12 +144,18 @@ export function createImageBlock(url, index, props) { }); } -export const createAndSelectNewBlockAfter = (editor, blockValue) => { +export const createAndSelectNewBlockAfter = (editor, blockValue, intl) => { const blockProps = editor.getBlockProps(); const { onSelectBlock, properties, index, onChangeField } = blockProps; - const [blockId, formData] = addBlock(properties, 'slate', index + 1); + const [blockId, formData] = addBlock( + properties, + 'slate', + index + 1, + {}, + intl, + ); const options = { '@type': 'slate', diff --git a/packages/volto/news/6529.bugfix b/packages/volto/news/6529.bugfix new file mode 100644 index 0000000000..c9e1029a3f --- /dev/null +++ b/packages/volto/news/6529.bugfix @@ -0,0 +1,2 @@ +Pass `intl` object to `initialValue` function. @wesleybl + diff --git a/packages/volto/src/components/manage/Blocks/Block/BlocksForm.jsx b/packages/volto/src/components/manage/Blocks/Block/BlocksForm.jsx index a8fd1e7c05..cba2390706 100644 --- a/packages/volto/src/components/manage/Blocks/Block/BlocksForm.jsx +++ b/packages/volto/src/components/manage/Blocks/Block/BlocksForm.jsx @@ -138,7 +138,7 @@ const BlocksForm = (props) => { }; const onMutateBlock = (id, value) => { - const newFormData = mutateBlock(properties, id, value); + const newFormData = mutateBlock(properties, id, value, {}, intl); onChangeFormData(newFormData); }; @@ -149,6 +149,8 @@ const BlocksForm = (props) => { value, current, config.experimental.addBlockButton.enabled ? 1 : 0, + {}, + intl, ); const blocksFieldname = getBlocksFieldname(newFormData); @@ -166,7 +168,7 @@ const BlocksForm = (props) => { const onAddBlock = (type, index) => { if (editable) { - const [id, newFormData] = addBlock(properties, type, index); + const [id, newFormData] = addBlock(properties, type, index, {}, intl); const blocksFieldname = getBlocksFieldname(newFormData); const blockData = newFormData[blocksFieldname][id]; newFormData[blocksFieldname][id] = applyBlockDefaults({ @@ -188,7 +190,7 @@ const BlocksForm = (props) => { const onDeleteBlock = (id, selectPrev) => { const previous = previousBlockId(properties, id); - const newFormData = deleteBlock(properties, id); + const newFormData = deleteBlock(properties, id, intl); onChangeFormData(newFormData); onSelectBlock(selectPrev ? previous : null); @@ -260,7 +262,7 @@ const BlocksForm = (props) => { for (const [n, v] of blockList) { if (!v) { - const newFormData = deleteBlock(properties, n); + const newFormData = deleteBlock(properties, n, intl); onChangeFormData(newFormData); } } diff --git a/packages/volto/src/components/manage/Blocks/Block/EditBlockWrapper.jsx b/packages/volto/src/components/manage/Blocks/Block/EditBlockWrapper.jsx index 3ef354708b..31351f8439 100644 --- a/packages/volto/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +++ b/packages/volto/src/components/manage/Blocks/Block/EditBlockWrapper.jsx @@ -135,6 +135,7 @@ const EditBlockWrapper = (props) => { [id]: value || null, }, }, + intl, }); const newValue = newFormData[blocksFieldname][id]; onChangeBlock(id, newValue); diff --git a/packages/volto/src/helpers/Blocks/Blocks.js b/packages/volto/src/helpers/Blocks/Blocks.js index d5559828e5..bff936b4ca 100644 --- a/packages/volto/src/helpers/Blocks/Blocks.js +++ b/packages/volto/src/helpers/Blocks/Blocks.js @@ -120,9 +120,10 @@ export function moveBlock(formData, source, destination) { * @function deleteBlock * @param {Object} formData Form data * @param {string} blockId Block uid + * @param {Object} intl intl object. * @return {Object} New form data */ -export function deleteBlock(formData, blockId) { +export function deleteBlock(formData, blockId, intl) { const blocksFieldname = getBlocksFieldname(formData); const blocksLayoutFieldname = getBlocksLayoutFieldname(formData); @@ -135,7 +136,13 @@ export function deleteBlock(formData, blockId) { }; if (newFormData[blocksLayoutFieldname].items.length === 0) { - newFormData = addBlock(newFormData, config.settings.defaultBlockType, 0); + newFormData = addBlock( + newFormData, + config.settings.defaultBlockType, + 0, + {}, + intl, + ); } return newFormData; @@ -147,9 +154,11 @@ export function deleteBlock(formData, blockId) { * @param {Object} formData Form data * @param {string} type Block type * @param {number} index Destination index + * @param {Object} blocksConfig Blocks configuration. + * @param {Object} intl intl object. * @return {Array} New block id, New form data */ -export function addBlock(formData, type, index, blocksConfig) { +export function addBlock(formData, type, index, blocksConfig, intl) { const { settings } = config; const id = uuid(); const idTrailingBlock = uuid(); @@ -192,6 +201,7 @@ export function addBlock(formData, type, index, blocksConfig) { }, selected: id, }, + intl, }), ]; } @@ -208,6 +218,7 @@ export const applyBlockInitialValue = ({ value, blocksConfig, formData, + intl, }) => { const type = value['@type']; blocksConfig = blocksConfig || config.blocks.blocksConfig; @@ -217,6 +228,7 @@ export const applyBlockInitialValue = ({ id, value, formData, + intl, }); const blocksFieldname = getBlocksFieldname(formData); formData[blocksFieldname][id] = value; @@ -231,9 +243,11 @@ export const applyBlockInitialValue = ({ * @param {Object} formData Form data * @param {string} id Block uid to mutate * @param {number} value Block's new value + * @param {Object} blocksConfig Blocks configuration. + * @param {Object} intl intl object. * @return {Object} New form data */ -export function mutateBlock(formData, id, value, blocksConfig) { +export function mutateBlock(formData, id, value, blocksConfig, intl) { const { settings } = config; const blocksFieldname = getBlocksFieldname(formData); const blocksLayoutFieldname = getBlocksLayoutFieldname(formData); @@ -260,6 +274,7 @@ export function mutateBlock(formData, id, value, blocksConfig) { [id]: value || null, }, }, + intl, }); if (!blockHasValue(block)) { return newFormData; @@ -288,6 +303,7 @@ export function mutateBlock(formData, id, value, blocksConfig) { ], }, }, + intl, }); return newFormData; } @@ -298,6 +314,10 @@ export function mutateBlock(formData, id, value, blocksConfig) { * @param {Object} formData Form data * @param {string} id Insert new block before the block with this id * @param {number} value New block's value + * @param {Object} current Current block + * @param {number} offset offset position + * @param {Object} blocksConfig Blocks configuration. + * @param {Object} intl intl object. * @return {Array} New block id, New form data */ export function insertBlock( @@ -307,6 +327,7 @@ export function insertBlock( current = {}, offset = 0, blocksConfig, + intl, ) { const blocksFieldname = getBlocksFieldname(formData); const blocksLayoutFieldname = getBlocksLayoutFieldname(formData); @@ -340,6 +361,7 @@ export function insertBlock( ], }, }, + intl, }); return [newBlockId, newFormData]; diff --git a/packages/volto/src/helpers/Blocks/Blocks.test.js b/packages/volto/src/helpers/Blocks/Blocks.test.js index 659b3c9b50..2887d8d0a3 100644 --- a/packages/volto/src/helpers/Blocks/Blocks.test.js +++ b/packages/volto/src/helpers/Blocks/Blocks.test.js @@ -568,6 +568,52 @@ describe('Blocks', () => { marker: true, }); }); + + it('initialValue with intl', () => { + // Mock intl with formatMessage function + const intl = { + formatMessage: jest.fn(({ id }) => id), + }; + + const messages = { + intl: { + id: 'intl', + defaultMessage: 'intl', + }, + }; + + config.blocks.blocksConfig.text.initialValue = ({ + id, + value, + formData, + intl, + }) => { + return { + ...formData.blocks[id], + intl: intl.formatMessage(messages.intl), + }; + }; + const [newId, form] = addBlock( + { + blocks: { a: { value: 1 }, b: { value: 2 } }, + blocks_layout: { items: ['a', 'b'] }, + }, + 'text', + 1, + config.blocks.blocksConfig, + intl, + ); + + delete config.blocks.blocksConfig.text.initialValue; + + expect(form.blocks[newId]).toStrictEqual({ + '@type': 'text', + booleanField: false, + description: 'Default description', + title: 'Default title', + intl: 'intl', + }); + }); }); describe('moveBlock', () => { diff --git a/packages/volto/types/helpers/Blocks/Blocks.d.ts b/packages/volto/types/helpers/Blocks/Blocks.d.ts index 42c7973f94..f21c5fd7bd 100644 --- a/packages/volto/types/helpers/Blocks/Blocks.d.ts +++ b/packages/volto/types/helpers/Blocks/Blocks.d.ts @@ -40,36 +40,43 @@ export function moveBlock(formData: any, source: number, destination: number): a * @function deleteBlock * @param {Object} formData Form data * @param {string} blockId Block uid + * @param {Object} intl intl object. * @return {Object} New form data */ -export function deleteBlock(formData: any, blockId: string): any; +export function deleteBlock(formData: any, blockId: string, intl: Object): any; /** * Adds a block to the blocks form * @function addBlock * @param {Object} formData Form data * @param {string} type Block type * @param {number} index Destination index + * @param {Object} blocksConfig Blocks configuration. + * @param {Object} intl intl object. * @return {Array} New block id, New form data */ -export function addBlock(formData: any, type: string, index: number, blocksConfig: any): any[]; +export function addBlock(formData: any, type: string, index: number, blocksConfig: any, intl: Object): any[]; /** * Mutate block, changes the block @type * @function mutateBlock * @param {Object} formData Form data * @param {string} id Block uid to mutate * @param {number} value Block's new value + * @param {Object} blocksConfig Blocks configuration. + * @param {Object} intl intl object. * @return {Object} New form data */ -export function mutateBlock(formData: any, id: string, value: number, blocksConfig: any): any; +export function mutateBlock(formData: any, id: string, value: number, blocksConfig: any, intl: Object): any; /** * Insert new block before another block * @function insertBlock * @param {Object} formData Form data * @param {string} id Insert new block before the block with this id * @param {number} value New block's value + * @param {Object} blocksConfig Blocks configuration. + * @param {Object} intl intl object. * @return {Array} New block id, New form data */ -export function insertBlock(formData: any, id: string, value: number, current: {}, offset: number, blocksConfig: any): any[]; +export function insertBlock(formData: any, id: string, value: number, current: {}, offset: number, blocksConfig: any, intl: Object): any[]; /** * Change block * @function changeBlock @@ -167,11 +174,12 @@ export function findBlocks(blocks: {}, types: any, result?: any[]): any[]; */ export function moveBlockEnhanced(formData: any, { source, destination }: number): any; export function getBlocks(properties: any): any[]; -export function applyBlockInitialValue({ id, value, blocksConfig, formData, }: { +export function applyBlockInitialValue({ id, value, blocksConfig, formData, intl}: { id: any; value: any; blocksConfig: any; formData: any; + intl: Object; }): any; export function styleToClassName(key: any, value: any, prefix?: string): any; export function buildStyleClassNamesFromData(obj?: {}, prefix?: string): any;