diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ffab7d..db18b71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,19 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +### [6.2.0](https://github.com/eea/volto-group-block/compare/6.1.2...6.2.0) - 20 July 2023 + +#### :nail_care: Enhancements + +- refactor: char-count component refs #253801 [Nilesh - [`1a54719`](https://github.com/eea/volto-group-block/commit/1a54719af523663314190741417bb06142967f68)] + +#### :hammer_and_wrench: Others + +- Release 6.2.0 [Alin Voinea - [`e4e254d`](https://github.com/eea/volto-group-block/commit/e4e254da4c109ee1c8c8a9ce42821eeabfae06ef)] ### [6.1.2](https://github.com/eea/volto-group-block/compare/6.1.1...6.1.2) - 12 June 2023 #### :house: Internal changes -- chore: [JENKINS] Deprecate circularity website [valentinab25 - [`ad30e83`](https://github.com/eea/volto-group-block/commit/ad30e832bb869b67dc4e64ed99590b51cb80ab75)] #### :hammer_and_wrench: Others @@ -25,19 +33,12 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). #### :hammer_and_wrench: Others -- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`37ffae5`](https://github.com/eea/volto-group-block/commit/37ffae512967b36af22cbed208a3ec9e1ddc392b)] ## [6.0.0](https://github.com/eea/volto-group-block/compare/5.0.1...6.0.0) - 24 March 2023 #### :hammer_and_wrench: Others - (feat): Possibility to copy/cut/paste blocks within section group block - refs #157469 [dobri1408 - [`e9fc098`](https://github.com/eea/volto-group-block/commit/e9fc09825ba2ae258feb77864491d97d94c585b4)] -- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`db4b09a`](https://github.com/eea/volto-group-block/commit/db4b09a6c14a8b271dec0c766886ffbcc3fe205e)] -- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`b8c2bf4`](https://github.com/eea/volto-group-block/commit/b8c2bf471868bb0394b2dbbf75ccb7917a9ef0bf)] -- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`b343119`](https://github.com/eea/volto-group-block/commit/b3431196931fd568476fa8bf6fbc508e086229ae)] - test(Jenkins): Run tests and cypress with latest canary @plone/volto [Alin Voinea - [`2f42e7c`](https://github.com/eea/volto-group-block/commit/2f42e7c19a1da5a9c6a883cb4f101e8fa224ff94)] -- Add Sonarqube tag using cca-frontend addons list [EEA Jenkins - [`73afcc2`](https://github.com/eea/volto-group-block/commit/73afcc2f417797cedaa78cceefb007001d6c2406)] -- yarn 3 [Alin Voinea - [`3c00ccc`](https://github.com/eea/volto-group-block/commit/3c00ccc7110bbf12a4d268182313418fb46b1a5d)] -- Add Sonarqube tag using demo-kitkat-frontend addons list [EEA Jenkins - [`9b9662b`](https://github.com/eea/volto-group-block/commit/9b9662bda1da70ba0c3a7b4b05cebf130ed89e9e)] ### [5.0.1](https://github.com/eea/volto-group-block/compare/5.0.0...5.0.1) - 16 November 2022 #### :nail_care: Enhancements @@ -54,8 +55,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Prepare 5.0.0 release [Miu Razvan - [`88c0ddd`](https://github.com/eea/volto-group-block/commit/88c0ddd569aeda7ee34d1eadea6a087f4e7dc257)] - Update dependencies [Alin Voinea - [`c8405af`](https://github.com/eea/volto-group-block/commit/c8405afb830cdf62e7877bf30b619933519e1d71)] -- Add Sonarqube tag using marine-frontend addons list [EEA Jenkins - [`18e26c6`](https://github.com/eea/volto-group-block/commit/18e26c6939706d572ab8574e9b1826b9abc76314)] -- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`8ed6d21`](https://github.com/eea/volto-group-block/commit/8ed6d21d8489911cc4cb471e3f8823c35f4adc50)] ### [4.3.8](https://github.com/eea/volto-group-block/compare/4.3.7...4.3.8) - 26 August 2022 ### [4.3.7](https://github.com/eea/volto-group-block/compare/4.3.6...4.3.7) - 22 August 2022 @@ -68,9 +67,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). #### :hammer_and_wrench: Others -- Add Sonarqube tag using circularity-frontend addons list [EEA Jenkins - [`4e73f8b`](https://github.com/eea/volto-group-block/commit/4e73f8be3c73559557efadc410cb56abc055d82d)] -- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`3040335`](https://github.com/eea/volto-group-block/commit/3040335002c63b50208c95918413bc958150e7a9)] -- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`386f730`](https://github.com/eea/volto-group-block/commit/386f730ed65f73fe1468b9b77351c97fb70edcc5)] ### [4.3.5](https://github.com/eea/volto-group-block/compare/4.3.4...4.3.5) - 4 January 2022 ### [4.3.4](https://github.com/eea/volto-group-block/compare/4.3.3...4.3.4) - 3 January 2022 @@ -79,23 +75,15 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). #### :hammer_and_wrench: Others -- Add Sonarqube tag using freshwater-frontend addons list [EEA Jenkins - [`3e62d79`](https://github.com/eea/volto-group-block/commit/3e62d79a7ed37d10d623bc845d43e1144f8080f7)] ### [4.3.2](https://github.com/eea/volto-group-block/compare/4.3.1...4.3.2) - 10 December 2021 #### :hammer_and_wrench: Others - Refs #142010 - Optimize Volto-addons gitflow pipelines [valentinab25 - [`bc36cf5`](https://github.com/eea/volto-group-block/commit/bc36cf58c39e2b43c2fbf5189df6ddefc1260857)] -- Add Sonarqube tag using industry-frontend addons list [EEA Jenkins - [`8038e78`](https://github.com/eea/volto-group-block/commit/8038e783c1e8ddd71e21f72070fdfa8e7e098993)] -- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`daccdbc`](https://github.com/eea/volto-group-block/commit/daccdbc733e47be7d6536eb67f8f2eea038dc94b)] ### [4.3.1](https://github.com/eea/volto-group-block/compare/4.3.0...4.3.1) - 11 October 2021 #### :hammer_and_wrench: Others -- Add Sonarqube tag using bise-frontend addons list [EEA Jenkins - [`b0092e4`](https://github.com/eea/volto-group-block/commit/b0092e4f78a1a0184e22e32bb9806cd57417dfb2)] -- Add Sonarqube tag using sustainability-frontend addons list [EEA Jenkins - [`ff8889c`](https://github.com/eea/volto-group-block/commit/ff8889cb7b0761b1df43b201984ce40b14e1561b)] -- Add Sonarqube tag using climate-energy-frontend addons list [EEA Jenkins - [`0375c28`](https://github.com/eea/volto-group-block/commit/0375c28ed1ffe9186a4790b454795c0ca8039f72)] -- Add Sonarqube tag using ims-frontend addons list [EEA Jenkins - [`c392190`](https://github.com/eea/volto-group-block/commit/c392190f044f5d9397bd2fb8c3d6a357f84960d0)] -- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`9694501`](https://github.com/eea/volto-group-block/commit/9694501141e6780eba89464d36406e3c93629fd8)] ### [4.3.0](https://github.com/eea/volto-group-block/compare/4.2.3...4.3.0) - 24 June 2021 #### :hammer_and_wrench: Others @@ -211,7 +199,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Release 1.0.0 [Alin Voinea - [`b6ef873`](https://github.com/eea/volto-group-block/commit/b6ef873cb6f61e17db66fdd4de1d9d4902a66fc6)] - Update package meta info [Alin Voinea - [`143b7d4`](https://github.com/eea/volto-group-block/commit/143b7d44438d7afa5e346a9d21a85352df4e925f)] - Add Jenkinkins pipeline [Alin Voinea - [`866a4e1`](https://github.com/eea/volto-group-block/commit/866a4e14ea1eb8f5adb01222e576e5ab6dc73a70)] -- yarn prettier [Alin Voinea - [`e3fe0a3`](https://github.com/eea/volto-group-block/commit/e3fe0a36b89878769341b45198d6c9e2f2584d15)] ### [0.1.3](https://github.com/eea/volto-group-block/compare/0.1.2...0.1.3) - 9 November 2020 #### :hammer_and_wrench: Others @@ -251,5 +238,4 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Render meta block [Alin Voinea - [`0d44560`](https://github.com/eea/volto-group-block/commit/0d4456011ca56454068a54c610250b02df4ccb3b)] - Implement meta block allowedBlocks settings [Alin Voinea - [`f24feb1`](https://github.com/eea/volto-group-block/commit/f24feb1a1751f04841c21c7cd52a517fb02074ba)] - Edit meta block [Alin Voinea - [`236d291`](https://github.com/eea/volto-group-block/commit/236d29156fa835a7aa54eecdb4f120de0d64b271)] -- yarn bootstrap [Alin Voinea - [`e009dfb`](https://github.com/eea/volto-group-block/commit/e009dfb6b9b74d101a6722f0982a5359fc522b6b)] - Initial commit [Alin Voinea - [`6a7b0de`](https://github.com/eea/volto-group-block/commit/6a7b0deb8f873d1462fd6a9c61edfc1562b3aace)] diff --git a/package.json b/package.json index 6ad5b16..d02e61f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eeacms/volto-group-block", - "version": "6.1.2", + "version": "6.2.0", "description": "volto-group-block: Volto block to be used to group other blocks", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team", diff --git a/src/components/manage/Blocks/Group/CounterComponent.jsx b/src/components/manage/Blocks/Group/CounterComponent.jsx new file mode 100644 index 0000000..7279f6c --- /dev/null +++ b/src/components/manage/Blocks/Group/CounterComponent.jsx @@ -0,0 +1,84 @@ +import cx from 'classnames'; +import isString from 'lodash/isString'; +import isArray from 'lodash/isArray'; +import { Icon } from '@plone/volto/components'; +import config from '@plone/volto/registry'; +import { visitBlocks } from '@plone/volto/helpers/Blocks/Blocks'; +import { serializeNodesToText } from '@plone/volto-slate/editor/render'; +import delightedSVG from '@plone/volto/icons/delighted.svg'; +import dissatisfiedSVG from '@plone/volto/icons/dissatisfied.svg'; + +const CounterComponent = ({ data, setSidebarTab, setSelectedBlock }) => { + const { maxChars } = data; + let charCount = 0; + + const countCharsWithoutSpaces = (paragraph) => { + const regex = /[^\s\\]/g; + + return (paragraph.match(regex) || []).length; + }; + + const countCharsWithSpaces = (paragraph) => { + return paragraph?.length || 0; + }; + + const countTextInBlocks = (blocksObject) => { + const { countTextIn } = config.blocks?.blocksConfig?.group; + let groupCharCount = 0; + if (!maxChars) { + return groupCharCount; + } + if (!blocksObject) return groupCharCount; + + visitBlocks(blocksObject, ([id, data]) => { + let foundText; + if (data && countTextIn?.includes(data?.['@type'])) { + if (isString(data?.plaintext)) foundText = data?.plaintext; + else if (isArray(data?.value) && data?.value !== null) + foundText = serializeNodesToText(data?.value); + } else foundText = ''; + + groupCharCount += data?.ignoreSpaces + ? countCharsWithoutSpaces(foundText) + : countCharsWithSpaces(foundText); + }); + + return groupCharCount; + }; + + charCount = countTextInBlocks(data?.data); + + const counterClass = + charCount < Math.ceil(maxChars / 1.05) + ? 'info' + : charCount < maxChars + ? 'warning' + : 'danger'; + + return ( +

{ + setSelectedBlock(); + setSidebarTab(1); + }} + aria-hidden="true" + > + {maxChars - charCount < 0 ? ( + <> + {`${charCount - maxChars} characters over the limit`} + + + ) : ( + <> + {`${ + maxChars - charCount + } characters remaining out of ${maxChars}`} + + + )} +

+ ); +}; + +export default CounterComponent; diff --git a/src/components/manage/Blocks/Group/Edit.jsx b/src/components/manage/Blocks/Group/Edit.jsx index 36f9b60..3cbea44 100644 --- a/src/components/manage/Blocks/Group/Edit.jsx +++ b/src/components/manage/Blocks/Group/Edit.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useCallback } from 'react'; import { isEmpty, without } from 'lodash'; import config from '@plone/volto/registry'; import { @@ -12,14 +12,12 @@ import { emptyBlocksForm, getBlocksLayoutFieldname, } from '@plone/volto/helpers'; -import delightedSVG from '@plone/volto/icons/delighted.svg'; -import dissatisfiedSVG from '@plone/volto/icons/dissatisfied.svg'; import PropTypes from 'prop-types'; import { Button, Segment } from 'semantic-ui-react'; import EditBlockWrapper from './EditBlockWrapper'; import EditSchema from './EditSchema'; +import CounterComponent from './CounterComponent'; import helpSVG from '@plone/volto/icons/help.svg'; -import cx from 'classnames'; import './editor.less'; const Edit = (props) => { @@ -43,8 +41,6 @@ const Edit = (props) => { ); const blockState = {}; - let charCount = 0; - const handleKeyDown = ( e, index, @@ -71,47 +67,48 @@ const Edit = (props) => { } }; - const onSelectBlock = (id, isMultipleSelection, event, activeBlock) => { - let newMultiSelected = []; - let selected = id; + const onSelectBlock = useCallback( + (id, isMultipleSelection, event, activeBlock) => { + let newMultiSelected = []; + let selected = id; - if (isMultipleSelection) { - selected = null; - const blocksLayoutFieldname = getBlocksLayoutFieldname(data?.data); - const blocks_layout = data?.data[blocksLayoutFieldname].items; - if (event.shiftKey) { - const anchor = - multiSelected.length > 0 - ? blocks_layout.indexOf(multiSelected[0]) - : blocks_layout.indexOf(activeBlock); - const focus = blocks_layout.indexOf(id); - if (anchor === focus) { - newMultiSelected = [id]; - } else if (focus > anchor) { - newMultiSelected = [...blocks_layout.slice(anchor, focus + 1)]; - } else { - newMultiSelected = [...blocks_layout.slice(focus, anchor + 1)]; + if (isMultipleSelection) { + selected = null; + const blocksLayoutFieldname = getBlocksLayoutFieldname(data?.data); + const blocks_layout = data?.data[blocksLayoutFieldname].items; + if (event.shiftKey) { + const anchor = + multiSelected.length > 0 + ? blocks_layout.indexOf(multiSelected[0]) + : blocks_layout.indexOf(activeBlock); + const focus = blocks_layout.indexOf(id); + if (anchor === focus) { + newMultiSelected = [id]; + } else if (focus > anchor) { + newMultiSelected = [...blocks_layout.slice(anchor, focus + 1)]; + } else { + newMultiSelected = [...blocks_layout.slice(focus, anchor + 1)]; + } } - } - if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { - if (multiSelected.includes(id)) { - selected = null; - newMultiSelected = without(multiSelected, id); - } else { - newMultiSelected = [...(multiSelected || []), id]; + if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { + if (multiSelected.includes(id)) { + selected = null; + newMultiSelected = without(multiSelected, id); + } else { + newMultiSelected = [...(multiSelected || []), id]; + } } } - } - setSelectedBlock(selected); - setMultiSelected(newMultiSelected); - }; + setSelectedBlock(selected); + setMultiSelected(newMultiSelected); + }, + [data.data, multiSelected], + ); const changeBlockData = (newBlockData) => { let pastedBlocks = newBlockData.blocks_layout.items.filter((blockID) => { - if (data?.data?.blocks_layout.items.find((x) => x === blockID)) - return false; - return true; + return !data?.data?.blocks_layout.items.find((x) => x === blockID); }); const selectedIndex = data.data.blocks_layout.items.indexOf(selectedBlock) + 1; @@ -144,101 +141,6 @@ const Edit = (props) => { } }, [onChangeBlock, properties, selectedBlock, block, data, data_blocks]); - /** - * Count the number of characters that are anything except using Regex - * @param {string} paragraph - * @returns - */ - const countCharsWithoutSpaces = (paragraph) => { - const regex = /[^\s\\]/g; - - return (paragraph.match(regex) || []).length; - }; - - /** - * Count the number of characters - * @param {string} paragraph - * @returns - */ - const countCharsWithSpaces = (paragraph) => { - return paragraph?.length || 0; - }; - - /** - * Recursively look for any block that contains text or plaintext - * @param {Object} blocksObject - * @returns - */ - const countTextInBlocks = (blocksObject) => { - let groupCharCount = 0; - if (!props.data.maxChars) { - return groupCharCount; - } - - Object.keys(blocksObject).forEach((blockId) => { - const foundText = blocksObject[blockId]?.plaintext - ? blocksObject[blockId]?.plaintext - : blocksObject[blockId]?.text?.blocks[0]?.text - ? blocksObject[blockId].text.blocks[0].text - : blocksObject[blockId]?.data?.blocks - ? countTextInBlocks(blocksObject[blockId]?.data?.blocks) - : blocksObject[blockId]?.blocks - ? countTextInBlocks(blocksObject[blockId]?.blocks) - : ''; - const resultText = - typeof foundText === 'string' || foundText instanceof String - ? foundText - : ''; - - groupCharCount += props.data.ignoreSpaces - ? countCharsWithoutSpaces(resultText) - : countCharsWithSpaces(resultText); - }); - - return groupCharCount; - }; - - const showCharCounter = () => { - if (data_blocks) { - charCount = countTextInBlocks(data_blocks); - } - }; - showCharCounter(); - - const counterClass = - charCount < Math.ceil(props.data.maxChars / 1.05) - ? 'info' - : charCount < props.data.maxChars - ? 'warning' - : 'danger'; - - const counterComponent = props.data.maxChars ? ( -

{ - setSelectedBlock(); - props.setSidebarTab(1); - }} - aria-hidden="true" - > - {props.data.maxChars - charCount < 0 ? ( - <> - {`${ - charCount - props.data.maxChars - } characters over the limit`} - - - ) : ( - <> - {`${ - props.data.maxChars - charCount - } characters remaining out of ${props.data.maxChars}`} - - - )} -

- ) : null; - // Get editing instructions from block settings or props let instructions = data?.instructions?.data || data?.instructions; if (!instructions || instructions === '


') { @@ -355,7 +257,9 @@ const Edit = (props) => { )} - {counterComponent} + {props.data.maxChars && ( + + )} {instructions && ( diff --git a/src/index.js b/src/index.js index fc0bcf1..3857e97 100644 --- a/src/index.js +++ b/src/index.js @@ -59,6 +59,7 @@ const applyConfig = (config) => { }); return entries; }, + countTextIn: ['slate', 'description'], //id of the block whose text should be counted }; return config;