From b3ded11648ff7cc6daed38bea60cf7d779a600a9 Mon Sep 17 00:00:00 2001 From: dana-cfc4 Date: Thu, 15 Jun 2023 13:11:24 +0300 Subject: [PATCH 01/11] Fix issues identified by Sonarqube --- .../manage/Blocks/Accordion/Edit.jsx | 27 ++++++------------- .../manage/Blocks/Accordion/View.jsx | 3 +-- .../manage/Blocks/Accordion/util.js | 2 +- .../manage/Widgets/PanelsWidget.jsx | 3 +-- 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/components/manage/Blocks/Accordion/Edit.jsx b/src/components/manage/Blocks/Accordion/Edit.jsx index ce17d6e..a2f5047 100644 --- a/src/components/manage/Blocks/Accordion/Edit.jsx +++ b/src/components/manage/Blocks/Accordion/Edit.jsx @@ -3,24 +3,23 @@ import { Icon, SidebarPortal, BlocksToolbar, + BlockDataForm, } from '@plone/volto/components'; import { emptyBlocksForm, getBlocksLayoutFieldname, + withBlockExtensions, } from '@plone/volto/helpers'; import helpSVG from '@plone/volto/icons/help.svg'; -import { isEmpty, without } from 'lodash'; +import { isEmpty, without, cloneDeep } from 'lodash'; import React, { useState } from 'react'; import { Button, Segment } from 'semantic-ui-react'; -import { withBlockExtensions } from '@plone/volto/helpers'; -import { BlockDataForm } from '@plone/volto/components'; import { useIntl } from 'react-intl'; import AccordionEdit from './AccordionEdit'; import EditBlockWrapper from './EditBlockWrapper'; import './editor.less'; import { AccordionBlockSchema } from './Schema'; import { emptyAccordion, getPanels } from './util'; -import { cloneDeep } from 'lodash'; import config from '@plone/volto/registry'; const Edit = (props) => { @@ -88,15 +87,9 @@ const Edit = (props) => { }; const searchElementInMultiSelection = (uid, blockprops) => { - if ( - multiSelected.find((el) => { - if (el === blockprops.block) return true; - return false; - }) - ) - return true; - return false; + return !!multiSelected.find((el) => el === blockprops.block); }; + const applySchemaEnhancer = (originalSchema) => { let schema, schemaEnhancer; const formData = data; @@ -222,13 +215,9 @@ const Edit = (props) => { let pastedBlocks = Object.entries(newBlockData.blocks).filter((block) => { let key = block[0]; - if ( - data?.data?.blocks[currentUid].blocks_layout.items.find( - (x) => x === key, - ) - ) - return false; - return true; + return !data?.data?.blocks[currentUid].blocks_layout.items.find( + (x) => x === key, + ); }); let blockLayout = pastedBlocks.map((el) => el[0]); diff --git a/src/components/manage/Blocks/Accordion/View.jsx b/src/components/manage/Blocks/Accordion/View.jsx index 6866a7c..a638f29 100644 --- a/src/components/manage/Blocks/Accordion/View.jsx +++ b/src/components/manage/Blocks/Accordion/View.jsx @@ -1,12 +1,11 @@ import React from 'react'; -import { RenderBlocks } from '@plone/volto/components'; import { getPanels, accordionBlockHasValue } from './util'; import { Accordion, Icon } from 'semantic-ui-react'; import { withBlockExtensions } from '@plone/volto/helpers'; import { useLocation } from 'react-router-dom'; import cx from 'classnames'; -import { Icon as VoltoIcon } from '@plone/volto/components'; +import { Icon as VoltoIcon, RenderBlocks } from '@plone/volto/components'; import AnimateHeight from 'react-animate-height'; import config from '@plone/volto/registry'; import './editor.less'; diff --git a/src/components/manage/Blocks/Accordion/util.js b/src/components/manage/Blocks/Accordion/util.js index ae24496..8e1e2f8 100644 --- a/src/components/manage/Blocks/Accordion/util.js +++ b/src/components/manage/Blocks/Accordion/util.js @@ -1,11 +1,11 @@ import { v4 as uuid } from 'uuid'; -import { emptyBlocksForm } from '@plone/volto/helpers'; import { map } from 'lodash'; import { getBlocksFieldname, getBlocksLayoutFieldname, blockHasValue, + emptyBlocksForm, } from '@plone/volto/helpers'; export const emptyAccordion = (count) => { diff --git a/src/components/manage/Widgets/PanelsWidget.jsx b/src/components/manage/Widgets/PanelsWidget.jsx index d7ffd6b..3d47cd7 100644 --- a/src/components/manage/Widgets/PanelsWidget.jsx +++ b/src/components/manage/Widgets/PanelsWidget.jsx @@ -4,8 +4,7 @@ import { omit, without } from 'lodash'; import move from 'lodash-move'; import { useIntl, defineMessages } from 'react-intl'; import { Button } from 'semantic-ui-react'; -import { Icon, FormFieldWrapper } from '@plone/volto/components'; -import { DragDropList } from '@plone/volto/components'; +import { Icon, FormFieldWrapper, DragDropList } from '@plone/volto/components'; import { emptyBlocksForm } from '@plone/volto/helpers'; import addSVG from '@plone/volto/icons/add.svg'; From 4b780ec32e6aedce6a61cb25876f7c96a6f471a7 Mon Sep 17 00:00:00 2001 From: ana-oprea <80201759+ana-oprea@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:57:50 +0300 Subject: [PATCH 02/11] test: add unit tests View and AccordionEdit - refs #253277 --- .../Blocks/Accordion/AccordionEdit.test.jsx | 46 +++++++++- .../manage/Blocks/Accordion/View.test.jsx | 85 +++++++++++++++++-- .../__snapshots__/View.test.jsx.snap | 51 ++--------- 3 files changed, 129 insertions(+), 53 deletions(-) diff --git a/src/components/manage/Blocks/Accordion/AccordionEdit.test.jsx b/src/components/manage/Blocks/Accordion/AccordionEdit.test.jsx index 91aa2e2..2f74569 100644 --- a/src/components/manage/Blocks/Accordion/AccordionEdit.test.jsx +++ b/src/components/manage/Blocks/Accordion/AccordionEdit.test.jsx @@ -2,8 +2,8 @@ import { render, fireEvent } from '@testing-library/react'; import React from 'react'; import AccordionEdit from './AccordionEdit'; import renderer from 'react-test-renderer'; -import '@testing-library/jest-dom/extend-expect'; import config from '@plone/volto/registry'; +import '@testing-library/jest-dom/extend-expect'; config.blocks.blocksConfig.accordion = { ...config.blocks.blocksConfig.accordion, @@ -118,4 +118,48 @@ describe('AccordionEdit', () => { panel, ]); }); + + it('should open accordion content when title is clicked', () => { + config.blocks.blocksConfig.accordion = { + ...config.blocks.blocksConfig.accordion, + semanticIcon: undefined, + }; + const { container, getByText } = render( + +

Accordion Content

+
, + ); + const accordionTitle = container.querySelector('.accordion-title'); + fireEvent.click(accordionTitle); + + const contentElement = getByText('Accordion Content'); + expect(contentElement).toBeInTheDocument(); + }); + + it('should open accordion content when title is clicked', () => { + const { container, getByText } = render( + +

Accordion Content

+
, + ); + const accordionTitle = container.querySelector('.accordion-title'); + fireEvent.click(accordionTitle); + + const contentElement = getByText('Accordion Content'); + expect(contentElement).toBeInTheDocument(); + }); }); diff --git a/src/components/manage/Blocks/Accordion/View.test.jsx b/src/components/manage/Blocks/Accordion/View.test.jsx index 69c153e..1c2c63c 100644 --- a/src/components/manage/Blocks/Accordion/View.test.jsx +++ b/src/components/manage/Blocks/Accordion/View.test.jsx @@ -1,11 +1,12 @@ import React from 'react'; import View from './View'; import renderer from 'react-test-renderer'; -import { render } from '@testing-library/react'; +import { render, fireEvent } from '@testing-library/react'; import configureStore from 'redux-mock-store'; import { Provider } from 'react-intl-redux'; import { MemoryRouter } from 'react-router-dom'; import config from '@plone/volto/registry'; +import * as utils from './util'; import '@testing-library/jest-dom/extend-expect'; config.blocks.blocksConfig.accordion = { @@ -41,11 +42,8 @@ jest.mock('@plone/volto/components', () => ({ })); jest.mock('./util', () => ({ - getPanels: () => [ - ['id1', { title: 'Panel 1' }], - ['id2', { title: 'Panel 2' }], - ], - accordionBlockHasValue: () => true, + getPanels: () => [['id1', { title: 'Panel 1' }]], + accordionBlockHasValue: jest.fn(), })); const mockData = { @@ -69,6 +67,20 @@ const mockData1 = { describe('View Component', () => { it('renders without crashing', () => { + utils.accordionBlockHasValue.mockReturnValue(true); + const component = renderer.create( + + + + + , + ); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); + + it('renders null', () => { + utils.accordionBlockHasValue.mockReturnValue(false); const component = renderer.create( @@ -81,6 +93,7 @@ describe('View Component', () => { }); it('renders with panels', () => { + utils.accordionBlockHasValue.mockReturnValue(true); const { rerender, getByText } = render( @@ -89,7 +102,6 @@ describe('View Component', () => { , ); expect(getByText('Panel 1')).toBeInTheDocument(); - expect(getByText('Panel 2')).toBeInTheDocument(); rerender( @@ -99,4 +111,63 @@ describe('View Component', () => { , ); }); + + it('should open accordion content when title is clicked', () => { + utils.accordionBlockHasValue.mockReturnValue(true); + config.blocks.blocksConfig.accordion = { + ...config.blocks.blocksConfig.accordion, + semanticIcon: 'someIcon', + }; + const { container, getByText } = render( + + + + + , + ); + const accordionTitle = container.querySelector('.accordion-title'); + fireEvent.click(accordionTitle); + + const contentElement = getByText('RenderBlocks'); + expect(contentElement).toBeInTheDocument(); + }); + + it('should open accordion content when title is clicked', () => { + utils.accordionBlockHasValue.mockReturnValue(true); + const { container, getByText } = render( + + + +

Accordion Content

+
+
+
, + ); + const accordionTitle = container.querySelector('.accordion-title'); + fireEvent.click(accordionTitle); + + const contentElement = getByText('RenderBlocks'); + expect(contentElement).toBeInTheDocument(); + }); + + it('should open accordion content when Enter key is pressed', () => { + config.blocks.blocksConfig.accordion = { + ...config.blocks.blocksConfig.accordion, + semanticIcon: 'someIcon', + }; + + const { container, getByText } = render( + + + + + , + ); + + const accordionTitle = container.querySelector('.accordion-title'); + fireEvent.keyDown(accordionTitle, { keyCode: 13 }); + + const contentElement = getByText('RenderBlocks'); + expect(contentElement).toBeInTheDocument(); + }); }); diff --git a/src/components/manage/Blocks/Accordion/__snapshots__/View.test.jsx.snap b/src/components/manage/Blocks/Accordion/__snapshots__/View.test.jsx.snap index edc2b15..c2dff9b 100644 --- a/src/components/manage/Blocks/Accordion/__snapshots__/View.test.jsx.snap +++ b/src/components/manage/Blocks/Accordion/__snapshots__/View.test.jsx.snap @@ -1,5 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`View Component renders null 1`] = ` +
+`; + exports[`View Component renders without crashing 1`] = `
-
-

-
- Icon -
- - Panel 2 - -

-
-
-
-
- RenderBlocks -
-
-
-
-
`; From 527165fa59e2e04041524f6c8631b619171f6ade Mon Sep 17 00:00:00 2001 From: Alin Voinea Date: Mon, 26 Jun 2023 17:20:44 +0300 Subject: [PATCH 03/11] chore: Cleanup console warnings about styled and fluid --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index f39a8fd..761574a 100644 --- a/src/index.js +++ b/src/index.js @@ -59,8 +59,8 @@ const applyConfig = (config) => { schemaEnhancer: AccordionStylingSchema, // See https://react.semantic-ui.com/modules/accordion/ options: { - styled: 'styled', - fluid: 'fluid', + styled: true, + fluid: true, }, defaults: {}, security: { From 3c9b757f72a9f4ccc3f46458d8488e250acac437 Mon Sep 17 00:00:00 2001 From: Alin Voinea Date: Wed, 28 Jun 2023 09:40:35 +0300 Subject: [PATCH 04/11] test: Add cypress for accordion in DX Layout - refs #254894 --- DEVELOP.md | 105 +++++++++++--- Dockerfile | 14 ++ Makefile | 132 +++++++++++------- README.md | 36 ++--- .../02-dexterity-controlpanel-layout.cy.js | 119 ++++++++++++++++ cypress/support/e2e.js | 16 +++ docker-compose.yml | 27 ++++ 7 files changed, 353 insertions(+), 96 deletions(-) create mode 100644 Dockerfile create mode 100644 cypress/e2e/02-dexterity-controlpanel-layout.cy.js create mode 100644 docker-compose.yml diff --git a/DEVELOP.md b/DEVELOP.md index 78764e9..b77a8d3 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -2,50 +2,119 @@ ## Develop +### With Docker + +1. Make sure you have `docker` and `docker compose` installed and running on your machine: + + ```Bash + git clone https://github.com/eea/volto-accordion-block.git + cd volto-accordion-block + git checkout -b bugfix-123456 develop + make + make start + ``` + +1. Wait for `Volto started at 0.0.0.0:3000` meesage + +1. Go to http://localhost:3000 + +1. Happy hacking! + + ```Bash + cd src/addons/volto-accordion-block/ + ``` + +### Or add volto-accordion-block to your Volto project + Before starting make sure your development environment is properly set. See [Volto Developer Documentation](https://docs.voltocms.com/getting-started/install/) 1. Make sure you have installed `yo`, `@plone/generator-volto` and `mrs-developer` - npm install -g yo @plone/generator-volto mrs-developer + ```Bash + npm install -g yo @plone/generator-volto mrs-developer + ``` 1. Create new volto app - yo @plone/volto my-volto-project --addon @eeacms/volto-accordion-block --skip-install - cd my-volto-project + ```Bash + yo @plone/volto my-volto-project --addon @eeacms/volto-accordion-block --skip-install + cd my-volto-project + ``` 1. Add the following to `mrs.developer.json`: - { - "volto-accordion-block": { - "url": "https://github.com/eea/volto-accordion-block.git", - "package": "@eeacms/volto-accordion-block", - "branch": "develop", - "path": "src" - } + ```JSON + { + "volto-accordion-block": { + "url": "https://github.com/eea/volto-accordion-block.git", + "package": "@eeacms/volto-accordion-block", + "branch": "develop", + "path": "src" } + } + ``` 1. Install - yarn develop - yarn + ```Bash + make develop + yarn + ``` 1. Start backend - docker pull plone - docker run -d --name plone -p 8080:8080 -e SITE=Plone -e PROFILES="profile-plone.restapi:blocks" plone + ```Bash + docker compose up backend + ``` ...wait for backend to setup and start - `Ready to handle requests`: - docker logs -f plone - ...you can also check http://localhost:8080/Plone 1. Start frontend - yarn start + ```BASH + yarn start + ``` 1. Go to http://localhost:3000 1. Happy hacking! - cd src/addons/volto-accordion-block/ + ```BASH + cd src/addons/volto-accordion-block/ + ``` + +## Cypress + +To run cypress locally, first make sure you don't have any Volto/Plone running on ports `8080` and `3000`. + +You don't have to be in a `clean-volto-project`, you can be in any Volto Frontend +project where you added `volto-accordion-block` to `mrs.developer.json` + +Go to: + + ```BASH + cd src/addons/volto-accordion-block/ + ``` + +Start: + + ```Bash + make + make start + ``` + +This will build and start with Docker a clean `Plone backend` and `Volto Frontend` with `volto-accordion-block` block installed. + +Open Cypress Interface: + + ```Bash + make cypress-open + ``` + +Or run it: + + ```Bash + make cypress-run + ``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bd8e10d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# syntax=docker/dockerfile:1 +ARG VOLTO_VERSION +FROM plone/frontend-builder:${VOLTO_VERSION} + +ARG ADDON_NAME +ARG ADDON_PATH + +COPY --chown=node:node ./ /app/src/addons/${ADDON_PATH}/ + +RUN /setupAddon +RUN yarn install + +ENTRYPOINT ["yarn"] +CMD ["start"] diff --git a/Makefile b/Makefile index cc237ff..6c18722 100644 --- a/Makefile +++ b/Makefile @@ -1,54 +1,90 @@ -SHELL=/bin/bash +############################################################################## +# Run: +# make +# make start +# +# Go to: +# +# http://localhost:3000 +# +# Cypress: +# +# make cypress-open +# +############################################################################## +# SETUP MAKE +# +## Defensive settings for make: https://tech.davis-hansson.com/p/make/ +SHELL:=bash +.ONESHELL: +# for Makefile debugging purposes add -x to the .SHELLFLAGS +.SHELLFLAGS:=-eu -o pipefail -O inherit_errexit -c +.SILENT: +.DELETE_ON_ERROR: +MAKEFLAGS+=--warn-undefined-variables +MAKEFLAGS+=--no-builtin-rules + +# Colors +# OK=Green, warn=yellow, error=red +ifeq ($(TERM),) +# no colors if not in terminal + MARK_COLOR= + OK_COLOR= + WARN_COLOR= + ERROR_COLOR= + NO_COLOR= +else + MARK_COLOR=`tput setaf 6` + OK_COLOR=`tput setaf 2` + WARN_COLOR=`tput setaf 3` + ERROR_COLOR=`tput setaf 1` + NO_COLOR=`tput sgr0` +endif +############################################################################## +# SETTINGS AND VARIABLE DIR=$(shell basename $$(pwd)) -ADDON ?= "@eeacms/volto-accordion-block" - -# We like colors -# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects -RED=`tput setaf 1` -GREEN=`tput setaf 2` -RESET=`tput sgr0` -YELLOW=`tput setaf 3` +NODE_MODULES?="../../../node_modules" +PLONE_VERSION?=6 +VOLTO_VERSION?=16 +ADDON_PATH="${DIR}" +ADDON_NAME="@eeacms/${ADDON_PATH}" +DOCKER_COMPOSE=PLONE_VERSION=${PLONE_VERSION} VOLTO_VERSION=${VOLTO_VERSION} ADDON_NAME=${ADDON_NAME} ADDON_PATH=${ADDON_PATH} docker compose + +# Top-level targets +.PHONY: all +all: clean install + +.PHONY: clean +clean: ## Cleanup development environment + ${DOCKER_COMPOSE} down --volumes --remove-orphans + +.PHONY: install +install: ## Build and install development environment + echo "Running: ${DOCKER_COMPOSE} build" + ${DOCKER_COMPOSE} pull + ${DOCKER_COMPOSE} build + +.PHONY: start +start: ## Start development environment + echo "Running: ${DOCKER_COMPOSE} up" + ${DOCKER_COMPOSE} up -ifeq ($(wildcard ./project),) - NODE_MODULES = "../../../node_modules" -else - NODE_MODULES = "./project/node_modules" -endif +.PHONY: cypress-open +cypress-open: ## Open cypress integration tests + NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress open -project: - npm install -g yo - npm install -g @plone/generator-volto - npm install -g mrs-developer - yo @plone/volto project --addon ${ADDON} --workspace "src/addons/${DIR}" --no-interactive - ln -sf $$(pwd) project/src/addons/ - cp .project.eslintrc.js .eslintrc.js - cd project && yarn - @echo "-------------------" - @echo "$(GREEN)Volto project is ready!$(RESET)" - @echo "$(RED)Now run: cd project && yarn start$(RESET)" - -all: project - -.PHONY: start-test-backend -start-test-backend: ## Start Test Plone Backend - @echo "$(GREEN)==> Start Test Plone Backend$(RESET)" - docker run -i --rm -e ZSERVER_HOST=0.0.0.0 -e ZSERVER_PORT=55001 -p 55001:55001 -e SITE=plone -e APPLY_PROFILES=plone.app.contenttypes:plone-content,plone.restapi:default,kitconcept.volto:default-homepage -e CONFIGURE_PACKAGES=plone.app.contenttypes,plone.restapi,kitconcept.volto,kitconcept.volto.cors -e ADDONS='plone.app.robotframework plone.app.contenttypes plone.restapi kitconcept.volto' plone ./bin/robot-server plone.app.robotframework.testing.PLONE_ROBOT_TESTING - -.PHONY: start-backend-docker -start-backend-docker: ## Starts a Docker-based backend - @echo "$(GREEN)==> Start Docker-based Plone Backend$(RESET)" - docker run -it --rm --name=plone -p 8080:8080 -e SITE=Plone -e ADDONS="kitconcept.volto" -e ZCML="kitconcept.volto.cors" plone +.PHONY: cypress-run +cypress-run: ## Run cypress integration tests + NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run .PHONY: test test: ## Run jest tests - docker pull plone/volto-addon-ci:alpha - docker run -it --rm -e NAMESPACE="@eeacms" -e GIT_NAME="${DIR}" -e RAZZLE_JEST_CONFIG=jest-addon.config.js -v "$$(pwd):/opt/frontend/my-volto-project/src/addons/${DIR}" -e CI="true" plone/volto-addon-ci:alpha + ${DOCKER_COMPOSE} run -e CI=1 frontend test .PHONY: test-update test-update: ## Update jest tests snapshots - docker pull plone/volto-addon-ci:alpha - docker run -it --rm -e NAMESPACE="@eeacms" -e GIT_NAME="${DIR}" -e RAZZLE_JEST_CONFIG=jest-addon.config.js -v "$$(pwd):/opt/frontend/my-volto-project/src/addons/${DIR}" -e CI="true" plone/volto-addon-ci:alpha yarn test src/addons/${DIR}/src --watchAll=false -u + ${DOCKER_COMPOSE} run -e CI=1 frontend test -u .PHONY: stylelint stylelint: ## Stylelint @@ -81,17 +117,9 @@ lint-fix: ## Fix ES Lint .PHONY: i18n i18n: ## i18n - rm -rf build/messages - NODE_ENV=development $(NODE_MODULES)/.bin/i18n --addon - -.PHONY: cypress-run -cypress-run: ## Run cypress integration tests - NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run - -.PHONY: cypress-open -cypress-open: ## Open cypress integration tests - NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress open + ${DOCKER_COMPOSE} run frontend i18n .PHONY: help -help: ## Show this help. +help: ## Show this help. @echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)" + head -n 14 Makefile diff --git a/README.md b/README.md index 64838e4..827b5bd 100644 --- a/README.md +++ b/README.md @@ -20,41 +20,25 @@ ![Volto Block Accordion](https://github.com/eea/volto-accordion-block/raw/docs/docs/volto-accordion-block.gif) -## Upgrade - -### Upgrading to 6.x - -This version requires: `@plone/volto >= 16.0.0.alpha.46` (schemaEnhancer / addStyling). - ## Getting started ### Try volto-accordion-block with Docker -1. Get the latest Docker images + git clone https://github.com/eea/volto-accordion-block.git + cd volto-accordion-block + make + make start - ``` - docker pull plone - docker pull plone/volto - ``` - -1. Start Plone backend - - ``` - docker run -d --name plone -p 8080:8080 -e SITE=Plone -e PROFILES="profile-plone.restapi:blocks" plone - ``` - -1. Start Volto frontend - - ``` - docker run -it --rm -p 3000:3000 --link plone -e ADDONS="@eeacms/volto-accordion-block" plone/volto - ``` - -1. Go to http://localhost:3000 +Go to http://localhost:3000 ### Add volto-accordion-block to your Volto project 1. Make sure you have a [Plone backend](https://plone.org/download) up-and-running at http://localhost:8080/Plone + ```Bash + docker compose up backend + ``` + 1. Start Volto frontend - If you already have a volto project, just update `package.json`: @@ -65,7 +49,7 @@ This version requires: `@plone/volto >= 16.0.0.alpha.46` (schemaEnhancer / addSt ], "dependencies": { - "@eeacms/volto-accordion-block": "^3.0.0" + "@eeacms/volto-accordion-block": "*" } ``` diff --git a/cypress/e2e/02-dexterity-controlpanel-layout.cy.js b/cypress/e2e/02-dexterity-controlpanel-layout.cy.js new file mode 100644 index 0000000..ac97d27 --- /dev/null +++ b/cypress/e2e/02-dexterity-controlpanel-layout.cy.js @@ -0,0 +1,119 @@ +import { slateLayoutBeforeEach, slateLayoutAfterEach } from '../support/e2e'; + +describe('ControlPanel: Dexterity Content-Types Layout', () => { + beforeEach(slateLayoutBeforeEach); + afterEach(slateLayoutAfterEach); + + it('Edit Blocks Layout for Book', () => { + cy.visit('/controlpanel/dexterity-types'); + cy.waitForResourceToLoad('@navigation'); + cy.waitForResourceToLoad('@breadcrumbs'); + cy.waitForResourceToLoad('@actions'); + cy.waitForResourceToLoad('@types'); + + cy.get('a[href="/controlpanel/dexterity-types/book"]').should( + 'have.text', + 'book', + ); + + cy.visit('/controlpanel/dexterity-types/book/layout'); + cy.get('#page-controlpanel-layout').contains( + 'Can not edit Layout for book', + ); + cy.get('#page-controlpanel-layout button').click(); + + // Wait a bit for draftjs to load, without this the title block + // custom placeholder is missing and cypress gives a timeout error + cy.wait(1000); + cy.get('input[id="field-placeholder"]').type('Book title'); + cy.get('label[for="field-required"]').click(); + cy.get('label[for="field-fixed"]').click(); + + cy.getSlate().click(); + + cy.get('.ui.basic.icon.button.block-add-button:visible').click(); + cy.get('.blocks-chooser .title').contains('Common').click(); + cy.get('.content.active.common .button.accordion') + .contains('Accordion') + .click(); + + cy.get('#field-allowedBlocks.react-select-container').click().type("Image{enter}"); + cy.get('#field-allowedBlocks.react-select-container').click().type("Text{enter}"); + + // By default all should be collapsed (no active class on first) + cy.get('.accordion:nth-child(2)').should('not.have.class', 'active'); + + cy.get('.accordion:nth-child(2) > .title input') + .click() + .type('Chapter 1') + .should('have.value', 'Chapter 1'); + + cy.get('.accordion:nth-child(2) .content .slate-editor [contenteditable=true]') + .last().focus().click().type('Once upon a time...{enter}'); + + cy.get('.accordion:nth-child(2) .content .slate-editor [contenteditable=true]') + .last().focus().click().type('/'); + cy.wait(500); + cy.get('.power-user-menu a.item').should('have.length', 1); + + cy.get('.accordion:nth-child(3) > .title input') + .click() + .type('Chapter 2') + .should('have.value', 'Chapter 2'); + + cy.get('#toolbar-save').click(); + + cy.visit('/cypress'); + cy.waitForResourceToLoad('@navigation'); + cy.waitForResourceToLoad('@breadcrumbs'); + cy.waitForResourceToLoad('@actions'); + cy.waitForResourceToLoad('@types'); + + cy.get('button[class="add"]').click(); + cy.get('#toolbar-add-book').click(); + cy.get('.block.title').contains('Book title'); + + // Change book title + cy.clearSlateTitle(); + cy.getSlateTitle().type('My First Book'); + cy.get('.documentFirstHeading').contains('My First Book'); + + cy.get('.accordion:nth-child(3) > .title > .icon').click(); + cy.wait(500); + cy.get('.accordion:nth-child(3) .content .slate-editor [contenteditable=true]') + .last().focus().click().type('The quick brown fox jumps over the lazy dog{enter}') + + cy.get('.accordion:nth-child(3) .content .slate-editor [contenteditable=true]') + .last().focus().click().type('/'); + cy.wait(500); + cy.get('.power-user-menu a.item').should('have.length', 1); + cy.get('.accordion:nth-child(3) .content .slate-editor [contenteditable=true]') + .last().focus().click().type('Image{enter}'); + cy.get('.accordion:nth-child(3) .content .block.image input[type="text"]') + .click().type('https://eea.github.io/volto-eea-design-system/img/eea_icon.png{enter}'); + + cy.get('.accordion:nth-child(4) > .title input') + .click() + .type('Chapter 3') + .should('have.value', 'Chapter 3'); + + cy.get('.accordion-block legend').click(); + cy.get('[id="field-title_size"] .react-select__value-container') + .click() + .type('h2{enter}'); + + cy.get('#toolbar-save').click(); + cy.get('.documentFirstHeading').contains('My First Book'); + cy.get('.accordion:nth-child(1) > h2.title').contains('Chapter 1'); + cy.get('.accordion:nth-child(2) > h2.title').contains('Chapter 2'); + cy.get('.accordion:nth-child(3) > h2.title').contains('Chapter 3'); + + cy.get('.accordion:nth-child(1) > h2.title').click(); + cy.get('.accordion:nth-child(1) .content').contains('Once upon a time...'); + + cy.get('.accordion:nth-child(2) > h2.title').click(); + cy.get('.accordion:nth-child(2) .content').contains('The quick brown fox jumps over the lazy dog'); + cy.get('.accordion:nth-child(2) .content img') + .should('have.attr', 'src', 'https://eea.github.io/volto-eea-design-system/img/eea_icon.png'); + }); +}); diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index f696418..90fe032 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -61,6 +61,22 @@ export const slateJsonAfterEach = (contentType = 'slate') => { slateAfterEach(); }; +export const slateLayoutBeforeEach = (contentType = 'book') => { + cy.autologin(); + cy.addContentType(contentType); + cy.createContent({ + contentType: 'Document', + contentId: 'cypress', + contentTitle: 'Cypress', + }); +}; + +export const slateLayoutAfterEach = (contentType = 'book') => { + cy.autologin(); + cy.removeContentType(contentType); + cy.removeContent('cypress'); +}; + export const getSelectedSlateEditor = () => { return cy.get('.slate-editor.selected [contenteditable=true]').click(); }; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..aa5b551 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3" +services: + backend: + image: plone/plone-backend:${PLONE_VERSION:-6} + ports: + - "8080:8080" + environment: + SITE: "Plone" + + frontend: + build: + context: ./ + dockerfile: ./Dockerfile + args: + ADDON_NAME: "${ADDON_NAME}" + ADDON_PATH: "${ADDON_PATH}" + VOLTO_VERSION: ${VOLTO_VERSION:-16} + ports: + - "3000:3000" + - "3001:3001" + depends_on: + - backend + volumes: + - ./:/app/src/addons/${ADDON_PATH} + environment: + RAZZLE_INTERNAL_API_PATH: "http://backend:8080/Plone" + RAZZLE_DEV_PROXY_API_PATH: "http://backend:8080/Plone" From 38bc517ae34914656345c397467891802ffeba7c Mon Sep 17 00:00:00 2001 From: Alin Voinea Date: Wed, 28 Jun 2023 12:53:12 +0300 Subject: [PATCH 05/11] fix: Fix i18n make command and eslint - refs #254894 --- Makefile | 3 ++- babel.config.js-use-when-running-i18n | 1 - src/components/index.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 babel.config.js-use-when-running-i18n diff --git a/Makefile b/Makefile index 6c18722..13481d3 100644 --- a/Makefile +++ b/Makefile @@ -117,7 +117,8 @@ lint-fix: ## Fix ES Lint .PHONY: i18n i18n: ## i18n - ${DOCKER_COMPOSE} run frontend i18n + rm -rf build/messages + NODE_ENV=development $(NODE_MODULES)/.bin/i18n --addon .PHONY: help help: ## Show this help. diff --git a/babel.config.js-use-when-running-i18n b/babel.config.js-use-when-running-i18n deleted file mode 100644 index a900a75..0000000 --- a/babel.config.js-use-when-running-i18n +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@plone/volto/babel'); diff --git a/src/components/index.js b/src/components/index.js index b8e3843..4bd9c13 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -1,5 +1,5 @@ -export AccordionLayoutSchema from '@eeacms/volto-accordion-block/components/manage/Blocks/Accordion/LayoutSchema'; +export { default as AccordionLayoutSchema } from '@eeacms/volto-accordion-block/components/manage/Blocks/Accordion/LayoutSchema'; export { AccordionStylingSchema } from '@eeacms/volto-accordion-block/components/manage/Blocks/Accordion/Schema'; -export AccordionBlockEdit from '@eeacms/volto-accordion-block/components/manage/Blocks/Accordion/Edit'; -export AccordionBlockView from '@eeacms/volto-accordion-block/components/manage/Blocks/Accordion/View'; -export PanelsWidget from '@eeacms/volto-accordion-block/components/manage/Widgets/PanelsWidget'; +export { default as AccordionBlockEdit } from '@eeacms/volto-accordion-block/components/manage/Blocks/Accordion/Edit'; +export { default as AccordionBlockView } from '@eeacms/volto-accordion-block/components/manage/Blocks/Accordion/View'; +export { default as PanelsWidget } from '@eeacms/volto-accordion-block/components/manage/Widgets/PanelsWidget'; From ecb74144f67b71a265e84628adb46aabc49c9416 Mon Sep 17 00:00:00 2001 From: Alin Voinea Date: Wed, 28 Jun 2023 12:53:31 +0300 Subject: [PATCH 06/11] i18n: Add Romanian --- locales/pt_BR/volto.po | 5 +- locales/ro/LC_MESSAGES/volto.po | 102 ++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 locales/ro/LC_MESSAGES/volto.po diff --git a/locales/pt_BR/volto.po b/locales/pt_BR/volto.po index 267b403..9545578 100644 --- a/locales/pt_BR/volto.po +++ b/locales/pt_BR/volto.po @@ -1,13 +1,16 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" +"Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-09-27T08:42:53.695Z\n" +"PO-Revision-Date: \n" "Last-Translator: Plone i18n \n" +"Language: \n" "Language-Team: Plone i18n \n" -"MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" "Language-Code: en\n" "Language-Name: English\n" "Preferred-Encodings: utf-8\n" diff --git a/locales/ro/LC_MESSAGES/volto.po b/locales/ro/LC_MESSAGES/volto.po new file mode 100644 index 0000000..efb707c --- /dev/null +++ b/locales/ro/LC_MESSAGES/volto.po @@ -0,0 +1,102 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language: \n" +"Language-Team: \n" +"Content-Type: \n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Accordion +msgid "Accordion" +msgstr "Acordeon" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Accordion Title size +msgid "Accordion Title size" +msgstr "Mărimea titlului acordeonului" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Accordion theme +msgid "Accordion theme" +msgstr "Tema acordeonului" + +#: components/manage/Widgets/PanelsWidget +# defaultMessage: Add +msgid "Add" +msgstr "Adaugă" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Allow multiple panels open at a time +msgid "Allow multiple panels open at a time" +msgstr "Permite deschiderea mai multor panouri simultan" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Collapsed by default +msgid "Collapsed by default" +msgstr "Închis implicit" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Friendly name +msgid "Friendly name" +msgstr "Nume" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Non exclusive +msgid "Non exclusive" +msgstr "Non exclusiv" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Options +msgid "Options" +msgstr "Opțiuni" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Primary +msgid "Primary" +msgstr "Primară" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Secondary +msgid "Secondary" +msgstr "Secundară" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Tertiary +msgid "Tertiary" +msgstr "Terțiară" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Theme +msgid "Theme" +msgstr "Tema" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Title +msgid "Title" +msgstr "Titlu" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Title Icon on the right +msgid "Title Icon on the right" +msgstr "Pictograma în dreapta titlului" + +#: components/manage/Blocks/Accordion/Schema +# defaultMessage: Title size +msgid "Title size" +msgstr "Mărime titlu" + +#: components/manage/Blocks/Accordion/EditBlockWrapper +# defaultMessage: Unknown Block {block} +msgid "Unknown Block" +msgstr "Block necunoscut" + +#: components/manage/Blocks/Accordion/EditBlockWrapper +# defaultMessage: delete +msgid "delete" +msgstr "Șterge" From fc615e9802ae57e481159b738520f6d783953a0c Mon Sep 17 00:00:00 2001 From: Alin Voinea Date: Wed, 28 Jun 2023 13:15:31 +0300 Subject: [PATCH 07/11] chore: Cleanup unused .i18n.babel.config.js --- .i18n.babel.config.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .i18n.babel.config.js diff --git a/.i18n.babel.config.js b/.i18n.babel.config.js deleted file mode 100644 index a900a75..0000000 --- a/.i18n.babel.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@plone/volto/babel'); From bdf3e97fac92c130f43c03e610e530f41dd5bc17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Fern=C3=A1ndez=20de=20Alba?= Date: Wed, 28 Jun 2023 15:31:18 +0200 Subject: [PATCH 08/11] feat: Add support for custom `blocksConfig`. Fix add new block to accordion button. --- .../02-dexterity-controlpanel-layout.cy.js | 3 + .../manage/Blocks/Accordion/Edit.jsx | 19 +++- .../Blocks/Accordion/EditBlockWrapper.jsx | 80 +++-------------- .../Blocks/Accordion/NewBlockAddButton.jsx | 87 +++++++++++++++++++ .../manage/Blocks/Accordion/editor.less | 19 ++++ 5 files changed, 138 insertions(+), 70 deletions(-) create mode 100644 src/components/manage/Blocks/Accordion/NewBlockAddButton.jsx diff --git a/cypress/e2e/02-dexterity-controlpanel-layout.cy.js b/cypress/e2e/02-dexterity-controlpanel-layout.cy.js index ac97d27..934f556 100644 --- a/cypress/e2e/02-dexterity-controlpanel-layout.cy.js +++ b/cypress/e2e/02-dexterity-controlpanel-layout.cy.js @@ -48,6 +48,9 @@ describe('ControlPanel: Dexterity Content-Types Layout', () => { .type('Chapter 1') .should('have.value', 'Chapter 1'); + cy.get('.accordion:nth-child(2) > .title > .icon').click(); + cy.wait(500); + cy.get('.accordion:nth-child(2) .content .slate-editor [contenteditable=true]') .last().focus().click().type('Once upon a time...{enter}'); diff --git a/src/components/manage/Blocks/Accordion/Edit.jsx b/src/components/manage/Blocks/Accordion/Edit.jsx index a2f5047..d9b98dc 100644 --- a/src/components/manage/Blocks/Accordion/Edit.jsx +++ b/src/components/manage/Blocks/Accordion/Edit.jsx @@ -11,7 +11,7 @@ import { withBlockExtensions, } from '@plone/volto/helpers'; import helpSVG from '@plone/volto/icons/help.svg'; -import { isEmpty, without, cloneDeep } from 'lodash'; +import { isEmpty, without, cloneDeep, pickBy } from 'lodash'; import React, { useState } from 'react'; import { Button, Segment } from 'semantic-ui-react'; import { useIntl } from 'react-intl'; @@ -35,6 +35,7 @@ const Edit = (props) => { manage, formDescription, } = props; + const intl = useIntl(); const properties = isEmpty(data?.data?.blocks) ? emptyAccordion(3) @@ -249,6 +250,16 @@ const Edit = (props) => { }); }; + const blockConfig = config.blocks.blocksConfig.accordion; + const blocksConfig = blockConfig.blocksConfig || props.blocksConfig; + // The accordion is able to get the allowedBlocks info from the custom DX layout + // Fallback to the blockConfig one + const allowedBlocks = data.allowedBlocks || blockConfig.allowedBlocks; + + const allowedBlocksConfig = allowedBlocks + ? pickBy(blocksConfig, (value, key) => allowedBlocks.includes(key)) + : blocksConfig; + return (
{ title={data.placeholder} description={instructions} manage={manage} - allowedBlocks={data.allowedBlocks} + blocksConfig={allowedBlocksConfig} metadata={metadata} properties={isEmpty(panel) ? emptyBlocksForm() : panel} selectedBlock={selected ? selectedBlock[uid] : null} @@ -357,7 +368,7 @@ const Edit = (props) => { {selected ? ( { setMultiSelected(blockIds); @@ -395,6 +406,8 @@ const Edit = (props) => { }} formData={data} block={block} + blocksConfig={blocksConfig} + onChangeBlock={onChangeBlock} /> )} diff --git a/src/components/manage/Blocks/Accordion/EditBlockWrapper.jsx b/src/components/manage/Blocks/Accordion/EditBlockWrapper.jsx index 19429aa..db32b82 100644 --- a/src/components/manage/Blocks/Accordion/EditBlockWrapper.jsx +++ b/src/components/manage/Blocks/Accordion/EditBlockWrapper.jsx @@ -1,16 +1,15 @@ import React from 'react'; -import { Icon, BlockChooser } from '@plone/volto/components'; +import { Icon } from '@plone/volto/components'; import { blockHasValue } from '@plone/volto/helpers'; import config from '@plone/volto/registry'; import { Button } from 'semantic-ui-react'; import includes from 'lodash/includes'; import isBoolean from 'lodash/isBoolean'; import { defineMessages, injectIntl } from 'react-intl'; -import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib'; import cx from 'classnames'; +import NewBlockAddButton from './NewBlockAddButton'; import dragSVG from '@plone/volto/icons/drag.svg'; -import addSVG from '@plone/volto/icons/circle-plus.svg'; import trashSVG from '@plone/volto/icons/delete.svg'; const messages = defineMessages({ @@ -25,38 +24,6 @@ const messages = defineMessages({ }); class EditBlockWrapper extends React.Component { - constructor(props) { - super(props); - this.state = { - addNewBlockOpened: false, - }; - } - - componentDidMount() { - document.addEventListener('mousedown', this.handleClickOutside, false); - } - - componentWillUnmount() { - document.removeEventListener('mousedown', this.handleClickOutside); - } - - handleClickOutside = (e) => { - if ( - this.blockNode.current && - doesNodeContainClick(this.blockNode.current, e) - ) - return; - - if (this.state.addNewBlockOpened) { - this.setState({ - addNewBlockOpened: false, - }); - return true; - } - }; - - blockNode = React.createRef(); - render() { const { intl, @@ -68,14 +35,14 @@ class EditBlockWrapper extends React.Component { } = this.props; const { - allowedBlocks, block, data, onDeleteBlock, onInsertBlock, - onMutateBlock, onSelectBlock, selected, + index, + blocksConfig, } = blockProps; const type = data['@type']; const { disableNewBlocks } = data; @@ -86,11 +53,8 @@ class EditBlockWrapper extends React.Component { ? data.required : includes(config.blocks.requiredBlocks, type); - const allowedBlocksFromConfig = - blockProps.blocksConfig.accordion?.allowedBlocks; - return ( -
+
{!disableNewBlocks && !blockHasValue(data) && ( - + /> )} + {!required && ( )} - {this.state.addNewBlockOpened && ( - { - onMutateBlock(id, value); - this.setState({ addNewBlockOpened: false }); - }} - onInsertBlock={(id, value) => { - onSelectBlock(onInsertBlock(id, value)); - this.setState({ addNewBlockOpened: false }); - }} - currentBlock={block} - allowedBlocks={allowedBlocks || allowedBlocksFromConfig} - /> - )} )}
diff --git a/src/components/manage/Blocks/Accordion/NewBlockAddButton.jsx b/src/components/manage/Blocks/Accordion/NewBlockAddButton.jsx new file mode 100644 index 0000000..49c656c --- /dev/null +++ b/src/components/manage/Blocks/Accordion/NewBlockAddButton.jsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { Button, Ref } from 'semantic-ui-react'; +import { BlockChooser, Icon } from '@plone/volto/components'; +import { usePopper } from 'react-popper'; +import { Portal } from 'react-portal'; +import addSVG from '@plone/volto/icons/add.svg'; + +const OpenedBlocksChooser = (props) => { + const { blocksConfig, block, onInsertBlock } = props; + + const ref = React.useRef(null); + + function handleClickOutside(event) { + if (ref.current && !ref.current.contains(event.target)) { + props.setOpenMenu(false); + } + } + + React.useEffect(() => { + document.body.addEventListener('mousedown', handleClickOutside); + return () => { + document.body.removeEventListener('mousedown', handleClickOutside); + }; + }); + + return ( + + ); +}; + +const NewBlockAddButton = (props) => { + const { index } = props; + const [isOpenMenu, setOpenMenu] = React.useState(false); + + const [referenceElement, setReferenceElement] = React.useState(null); + const [popperElement, setPopperElement] = React.useState(null); + const { styles, attributes } = usePopper(referenceElement, popperElement, { + placement: 'left', + modifiers: [ + { + name: 'offset', + options: { + offset: [0, 0], + }, + }, + { + name: 'flip', + }, + ], + }); + + return ( + <> + + + + +
+ {isOpenMenu ? ( + + ) : null} +
+
+ + ); +}; + +export default NewBlockAddButton; diff --git a/src/components/manage/Blocks/Accordion/editor.less b/src/components/manage/Blocks/Accordion/editor.less index 3d005df..1b7f74a 100644 --- a/src/components/manage/Blocks/Accordion/editor.less +++ b/src/components/manage/Blocks/Accordion/editor.less @@ -15,6 +15,10 @@ margin-bottom: 1rem; } + [class^='block-editor-'] { + margin-bottom: 2rem; + } + .block-add-button { display: none !important; } @@ -24,6 +28,13 @@ border-style: dashed; } + .add-block-button { + svg.circled { + padding: 0; + border: 1px solid currentColor; + } + } + fieldset { border: none; @@ -181,3 +192,11 @@ opacity: 1 !important; } } + +.accordion-chooser { + z-index: 100; + + .blocks-chooser { + position: static; + } +} From 5e0ef4e45c7168314c7b287ece1152fa878a6f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Fern=C3=A1ndez=20de=20Alba?= Date: Wed, 28 Jun 2023 17:25:34 +0200 Subject: [PATCH 09/11] feat: Add headline field to the block field. --- .../manage/Blocks/Accordion/Edit.jsx | 280 +++++++++--------- .../manage/Blocks/Accordion/Schema.js | 10 +- .../manage/Blocks/Accordion/View.jsx | 1 + 3 files changed, 154 insertions(+), 137 deletions(-) diff --git a/src/components/manage/Blocks/Accordion/Edit.jsx b/src/components/manage/Blocks/Accordion/Edit.jsx index d9b98dc..a050d8a 100644 --- a/src/components/manage/Blocks/Accordion/Edit.jsx +++ b/src/components/manage/Blocks/Accordion/Edit.jsx @@ -261,157 +261,165 @@ const Edit = (props) => { : blocksConfig; return ( -
- { - setSelectedBlock({}); - props.setSidebarTab(1); - }} - aria-hidden="true" - > - {data.title || 'Accordion'} - - {panels.map(([uid, panel], index) => ( - setSelectedBlock({})} - data={data} - index={index} + <> + {data.headline &&

{data.headline}

} +
+ { + setSelectedBlock({}); + props.setSidebarTab(1); + }} + aria-hidden="true" > - { - const isMultipleSelection = e - ? e.shiftKey || e.ctrlKey || e.metaKey - : false; - onSelectBlock(uid, id, isMultipleSelection, e, selectedBlock); - }} - onChangeFormData={(newFormData) => { - onChangeBlock(block, { - ...data, - data: { - ...panelData, - blocks: { - ...panelData.blocks, - [uid]: newFormData, - }, - }, - }); - }} - onChangeField={(id, value) => { - if (['blocks', 'blocks_layout'].indexOf(id) > -1) { - blockState[id] = value; + {data.title || 'Accordion'} + + {panels.map(([uid, panel], index) => ( + setSelectedBlock({})} + data={data} + index={index} + > + { + const isMultipleSelection = e + ? e.shiftKey || e.ctrlKey || e.metaKey + : false; + onSelectBlock(uid, id, isMultipleSelection, e, selectedBlock); + }} + onChangeFormData={(newFormData) => { onChangeBlock(block, { ...data, data: { ...panelData, blocks: { ...panelData.blocks, - [uid]: { - ...panelData.blocks?.[uid], - ...blockState, - }, + [uid]: newFormData, }, }, }); - } else { - onChangeField(id, value); - } - }} - pathname={pathname} - > - {({ draginfo }, editBlock, blockProps) => { - return ( - - {instructions && ( - <> - - - )} - - } - > - {editBlock} - - ); + }} + onChangeField={(id, value) => { + if (['blocks', 'blocks_layout'].indexOf(id) > -1) { + blockState[id] = value; + onChangeBlock(block, { + ...data, + data: { + ...panelData, + blocks: { + ...panelData.blocks, + [uid]: { + ...panelData.blocks?.[uid], + ...blockState, + }, + }, + }, + }); + } else { + onChangeField(id, value); + } + }} + pathname={pathname} + > + {({ draginfo }, editBlock, blockProps) => { + return ( + + {instructions && ( + <> + + + )} + + } + > + {editBlock} + + ); + }} + + + ))} + {selected ? ( + { + setMultiSelected(blockIds); }} - - - ))} - {selected ? ( - { - setMultiSelected(blockIds); - }} - onSelectBlock={(id, l, e) => { - const isMultipleSelection = e - ? e.shiftKey || e.ctrlKey || e.metaKey - : false; + onSelectBlock={(id, l, e) => { + const isMultipleSelection = e + ? e.shiftKey || e.ctrlKey || e.metaKey + : false; - onSelectBlock(id, isMultipleSelection, e, selectedBlock); - }} - onChangeBlocks={(newBlockData) => { - changeBlockData(newBlockData); - }} - /> - ) : ( - '' - )} - - - {instructions && ( - -
- - )} - {!data?.readOnlySettings && ( - { - onChangeBlock(block, { - ...data, - [id]: value, - }); + onSelectBlock(id, isMultipleSelection, e, selectedBlock); + }} + onChangeBlocks={(newBlockData) => { + changeBlockData(newBlockData); }} - formData={data} - block={block} - blocksConfig={blocksConfig} - onChangeBlock={onChangeBlock} /> + ) : ( + '' )} - -
+ + + {instructions && ( + +
+ + )} + {!data?.readOnlySettings && ( + { + onChangeBlock(block, { + ...data, + [id]: value, + }); + }} + formData={data} + block={block} + blocksConfig={blocksConfig} + onChangeBlock={onChangeBlock} + /> + )} + +
+ ); }; diff --git a/src/components/manage/Blocks/Accordion/Schema.js b/src/components/manage/Blocks/Accordion/Schema.js index 5f7d257..661258b 100644 --- a/src/components/manage/Blocks/Accordion/Schema.js +++ b/src/components/manage/Blocks/Accordion/Schema.js @@ -63,6 +63,10 @@ const messages = defineMessages({ id: 'Tertiary', defaultMessage: 'Tertiary', }, + headline: { + id: 'Headline', + defaultMessage: 'Headline', + }, }); export const AccordionSchema = { @@ -94,6 +98,7 @@ export const AccordionBlockSchema = ({ intl }) => ({ id: 'options', title: intl.formatMessage(messages.Options), fields: [ + 'headline', 'title', 'title_size', 'right_arrows', @@ -103,6 +108,9 @@ export const AccordionBlockSchema = ({ intl }) => ({ }, ], properties: { + headline: { + title: intl.formatMessage(messages.headline), + }, title: { title: intl.formatMessage(messages.Title), description: intl.formatMessage(messages.friendly_name), @@ -143,7 +151,7 @@ export const AccordionBlockSchema = ({ intl }) => ({ default: true, }, }, - required: ['title'], + required: [], }); export const AccordionStylingSchema = (props) => { diff --git a/src/components/manage/Blocks/Accordion/View.jsx b/src/components/manage/Blocks/Accordion/View.jsx index a638f29..c2a9f55 100644 --- a/src/components/manage/Blocks/Accordion/View.jsx +++ b/src/components/manage/Blocks/Accordion/View.jsx @@ -47,6 +47,7 @@ const View = (props) => { return (
+ {data.headline &&

{data.headline}

} {panels.map(([id, panel], index) => { return accordionBlockHasValue(panel) ? ( Date: Wed, 28 Jun 2023 19:46:51 +0300 Subject: [PATCH 10/11] Release 9.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 15f05fe..bbd8984 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eeacms/volto-accordion-block", - "version": "8.1.0", + "version": "9.0.0", "description": "volto-accordion-block: Volto accordion block", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team", From 720eb0ddab62e39c2972373846581d177c0d2087 Mon Sep 17 00:00:00 2001 From: EEA Jenkins <@users.noreply.github.com> Date: Wed, 28 Jun 2023 16:59:06 +0000 Subject: [PATCH 11/11] Automated release 9.0.0 --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e9039b..1b5698c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ 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). +### [9.0.0](https://github.com/eea/volto-accordion-block/compare/8.1.0...9.0.0) - 28 June 2023 + +#### :rocket: New Features + +- feat: Add headline field to the block field. [Víctor Fernández de Alba - [`5e0ef4e`](https://github.com/eea/volto-accordion-block/commit/5e0ef4e45c7168314c7b287ece1152fa878a6f82)] +- feat: Add support for custom `blocksConfig`. Fix add new block to accordion button. [Víctor Fernández de Alba - [`bdf3e97`](https://github.com/eea/volto-accordion-block/commit/bdf3e97fac92c130f43c03e610e530f41dd5bc17)] + +#### :bug: Bug Fixes + +- fix: Fix i18n make command and eslint - refs #254894 [Alin Voinea - [`38bc517`](https://github.com/eea/volto-accordion-block/commit/38bc517ae34914656345c397467891802ffeba7c)] + +#### :house: Internal changes + +- chore: Cleanup unused .i18n.babel.config.js [Alin Voinea - [`fc615e9`](https://github.com/eea/volto-accordion-block/commit/fc615e9802ae57e481159b738520f6d783953a0c)] +- chore: Cleanup console warnings about styled and fluid [Alin Voinea - [`527165f`](https://github.com/eea/volto-accordion-block/commit/527165fa59e2e04041524f6c8631b619171f6ade)] + +#### :hammer_and_wrench: Others + +- Release 9.0.0 [Alin Voinea - [`1a3a11c`](https://github.com/eea/volto-accordion-block/commit/1a3a11c98b6aa8ad875f49a0da588ce2f0da2d25)] +- i18n: Add Romanian [Alin Voinea - [`ecb7414`](https://github.com/eea/volto-accordion-block/commit/ecb74144f67b71a265e84628adb46aabc49c9416)] +- test: Add cypress for accordion in DX Layout - refs #254894 [Alin Voinea - [`3c9b757`](https://github.com/eea/volto-accordion-block/commit/3c9b757f72a9f4ccc3f46458d8488e250acac437)] +- test: add unit tests View and AccordionEdit - refs #253277 [ana-oprea - [`4b780ec`](https://github.com/eea/volto-accordion-block/commit/4b780ec32e6aedce6a61cb25876f7c96a6f471a7)] ### [8.1.0](https://github.com/eea/volto-accordion-block/compare/8.0.0...8.1.0) - 12 June 2023 #### :rocket: New Features