diff --git a/.coverage.babel.config.js b/.coverage.babel.config.js index e8b54d3..37219fd 100644 --- a/.coverage.babel.config.js +++ b/.coverage.babel.config.js @@ -2,7 +2,7 @@ const defaultBabel = require('@plone/volto/babel'); function applyDefault(api) { const voltoBabel = defaultBabel(api); - voltoBabel.plugins.push('@babel/plugin-transform-modules-commonjs', 'transform-class-properties', 'istanbul'); + voltoBabel.plugins.push('istanbul'); return voltoBabel; } diff --git a/.gitignore b/.gitignore index cdcaf46..53b9801 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ .vscode/ .history .eslintrc.js +.nyc_output project +coverage logs *.log npm-debug.log* diff --git a/.i18n.babel.config.js b/.i18n.babel.config.js new file mode 100644 index 0000000..a900a75 --- /dev/null +++ b/.i18n.babel.config.js @@ -0,0 +1 @@ +module.exports = require('@plone/volto/babel'); diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c48924..ba3cc6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,60 +4,59 @@ 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). -#### [0.3.3](https://github.com/eea/volto-quote-block/compare/0.3.2...0.3.3) +### [1.0.0](https://github.com/eea/volto-quote-block/compare/0.3.3...1.0.0) - 28 October 2022 +#### :nail_care: Enhancements -#### [0.3.2](https://github.com/eea/volto-quote-block/compare/0.3.1...0.3.2) +- refactor(volto-slate): Upgrade to @plone/volto-slate - refs #153447 [Alin Voinea - [`a8745d3`](https://github.com/eea/volto-quote-block/commit/a8745d30aadf8bf23bab81d655ccff07beae3e76)] -> 30 June 2022 +#### :hammer_and_wrench: Others +- test(cypress): Remove cypress.json [Alin Voinea - [`467d978`](https://github.com/eea/volto-quote-block/commit/467d978dba7dc792bce569b95e10471971d91eca)] +- test(Jenkins): Update to volto-addon-ci:alpha [Alin Voinea - [`b8c17be`](https://github.com/eea/volto-quote-block/commit/b8c17be3b332423260d5a663ff649a4ec30d29a7)] +- test(lint): Fix eslint [Alin Voinea - [`13cccab`](https://github.com/eea/volto-quote-block/commit/13cccab93c79a428d0655c93c2eb58594df8dbc2)] +- Release 1.0.0 [Alin Voinea - [`4944731`](https://github.com/eea/volto-quote-block/commit/4944731b1c7b9b80620311909202bb75c894760c)] +- test(cypress): Cypress 10 / Razzle 4 [Alin Voinea - [`91262ed`](https://github.com/eea/volto-quote-block/commit/91262eddb7272d12686cdb71952c607846cecb5d)] +- Cleanup [Alin Voinea - [`9b70192`](https://github.com/eea/volto-quote-block/commit/9b7019284a8e2159248cfa6109c8c0f84c6273d8)] +### [0.3.3](https://github.com/eea/volto-quote-block/compare/0.3.2...0.3.3) - 1 August 2022 -#### [0.3.1](https://github.com/eea/volto-quote-block/compare/0.3.0...0.3.1) +### [0.3.2](https://github.com/eea/volto-quote-block/compare/0.3.1...0.3.2) - 30 June 2022 -> 9 June 2022 +### [0.3.1](https://github.com/eea/volto-quote-block/compare/0.3.0...0.3.1) - 9 June 2022 -- Fix SlateEditor + clean up [`#5`](https://github.com/eea/volto-quote-block/pull/5) +### [0.3.0](https://github.com/eea/volto-quote-block/compare/0.2.0...0.3.0) - 25 May 2022 -#### [0.3.0](https://github.com/eea/volto-quote-block/compare/0.2.0...0.3.0) +#### :hammer_and_wrench: Others -> 25 May 2022 +### [0.2.0](https://github.com/eea/volto-quote-block/compare/0.1.2...0.2.0) - 19 May 2022 -- refactor(quote): Rename SourceInfo to Extra component [`#4`](https://github.com/eea/volto-quote-block/pull/4) +#### :nail_care: Enhancements -#### [0.2.0](https://github.com/eea/volto-quote-block/compare/0.1.2...0.2.0) +- refactor(quote): Rename sourceInfo field to extra [Alin Voinea - [`51a9e32`](https://github.com/eea/volto-quote-block/commit/51a9e329e6d0a8b1caaadd42ccad1bd54e862210)] -> 19 May 2022 +#### :hammer_and_wrench: Others -- Update quote + add testimonial quote variation [`#3`](https://github.com/eea/volto-quote-block/pull/3) -- refactor(quote): Rename sourceInfo field to extra [`51a9e32`](https://github.com/eea/volto-quote-block/commit/51a9e329e6d0a8b1caaadd42ccad1bd54e862210) -- Upgrade footnotes registry to work with volto-slate-footnotes 5.x [`3261f27`](https://github.com/eea/volto-quote-block/commit/3261f27d8749a022171ecdf8c854da832c40a2b9) -- Move reversed option to layout fieldset [`f0a94ac`](https://github.com/eea/volto-quote-block/commit/f0a94ac92820adc661030b095dc91fe048791e26) -- Fix schema [`f27fc86`](https://github.com/eea/volto-quote-block/commit/f27fc86025a004adc700f4f8ba36a080626a94af) -- Add volto-slate back [`a518905`](https://github.com/eea/volto-quote-block/commit/a518905f5a7a98213db0fd99396334dd2dbacef2) -- Use attached image widget [`c6acaa0`](https://github.com/eea/volto-quote-block/commit/c6acaa08ab9d985c963debff78e4d989b90556ac) -- Add footnotes support [`c63729c`](https://github.com/eea/volto-quote-block/commit/c63729cafce78dfe98d875d70214b3d8fd6c1f11) -- Prettier fix [`e4dd69a`](https://github.com/eea/volto-quote-block/commit/e4dd69a3051da854435093dc30f8048a650798a2) -- Remove usememo [`b5880a5`](https://github.com/eea/volto-quote-block/commit/b5880a5a1cf5c9889ec4c211c60f51986fd6255d) +- Upgrade footnotes registry to work with volto-slate-footnotes 5.x [Alin Voinea - [`3261f27`](https://github.com/eea/volto-quote-block/commit/3261f27d8749a022171ecdf8c854da832c40a2b9)] +- Move reversed option to layout fieldset [Alin Voinea - [`f0a94ac`](https://github.com/eea/volto-quote-block/commit/f0a94ac92820adc661030b095dc91fe048791e26)] +- Fix schema [Miu Razvan - [`f27fc86`](https://github.com/eea/volto-quote-block/commit/f27fc86025a004adc700f4f8ba36a080626a94af)] +- Add volto-slate back [Miu Razvan - [`a518905`](https://github.com/eea/volto-quote-block/commit/a518905f5a7a98213db0fd99396334dd2dbacef2)] +- Use attached image widget [Miu Razvan - [`c6acaa0`](https://github.com/eea/volto-quote-block/commit/c6acaa08ab9d985c963debff78e4d989b90556ac)] +- Add footnotes support [Alin Voinea - [`c63729c`](https://github.com/eea/volto-quote-block/commit/c63729cafce78dfe98d875d70214b3d8fd6c1f11)] +- Prettier fix [Miu Razvan - [`e4dd69a`](https://github.com/eea/volto-quote-block/commit/e4dd69a3051da854435093dc30f8048a650798a2)] +- Remove usememo [Miu Razvan - [`b5880a5`](https://github.com/eea/volto-quote-block/commit/b5880a5a1cf5c9889ec4c211c60f51986fd6255d)] +### [0.1.2](https://github.com/eea/volto-quote-block/compare/0.1.1...0.1.2) - 17 May 2022 -#### [0.1.2](https://github.com/eea/volto-quote-block/compare/0.1.1...0.1.2) +### [0.1.1](https://github.com/eea/volto-quote-block/compare/0.1.0...0.1.1) - 28 April 2022 -> 17 May 2022 +#### :hammer_and_wrench: Others -- Disable Blockquote template for now and fix reversed pullquote [`#2`](https://github.com/eea/volto-quote-block/pull/2) +- Improvments [Miu Razvan - [`15b8aac`](https://github.com/eea/volto-quote-block/commit/15b8aac6b575af5b6b05d32cbfd32d8c603b2eb3)] +- Fix tests [Miu Razvan - [`f1faba6`](https://github.com/eea/volto-quote-block/commit/f1faba692370b519c690a831efe80f26d1e9a8cc)] +- Add slate add-on [Miu Razvan - [`57a1e1b`](https://github.com/eea/volto-quote-block/commit/57a1e1bd5d68ec08afb24d6a51346ad54fa891b3)] +- Lint fix [Miu Razvan - [`a1b29b0`](https://github.com/eea/volto-quote-block/commit/a1b29b0ceee5606ec14edd8d60e3196019b07506)] +- Remove uneeded code [Miu Razvan - [`ff26f0d`](https://github.com/eea/volto-quote-block/commit/ff26f0d60193f70e993522f5f3f1328ce3ce6e11)] +### 0.1.0 - 12 April 2022 -#### [0.1.1](https://github.com/eea/volto-quote-block/compare/0.1.0...0.1.1) +#### :hammer_and_wrench: Others -> 28 April 2022 - -- Add quote blocks and volto-slate quote plugin [`#1`](https://github.com/eea/volto-quote-block/pull/1) -- Improvments [`15b8aac`](https://github.com/eea/volto-quote-block/commit/15b8aac6b575af5b6b05d32cbfd32d8c603b2eb3) -- Fix tests [`f1faba6`](https://github.com/eea/volto-quote-block/commit/f1faba692370b519c690a831efe80f26d1e9a8cc) -- Add slate add-on [`57a1e1b`](https://github.com/eea/volto-quote-block/commit/57a1e1bd5d68ec08afb24d6a51346ad54fa891b3) -- Lint fix [`a1b29b0`](https://github.com/eea/volto-quote-block/commit/a1b29b0ceee5606ec14edd8d60e3196019b07506) -- Remove uneeded code [`ff26f0d`](https://github.com/eea/volto-quote-block/commit/ff26f0d60193f70e993522f5f3f1328ce3ce6e11) - -#### 0.1.0 - -> 12 April 2022 - -- Initial commit [`f748002`](https://github.com/eea/volto-quote-block/commit/f7480020346c8069fc825a439183b8f73445d62c) +- Initial commit [Miu Razvan - [`f748002`](https://github.com/eea/volto-quote-block/commit/f7480020346c8069fc825a439183b8f73445d62c)] diff --git a/Jenkinsfile b/Jenkinsfile index 6f587f2..3014314 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -4,7 +4,7 @@ pipeline { environment { GIT_NAME = "volto-quote-block" NAMESPACE = "@eeacms" - SONARQUBE_TAGS = "volto.eea.europa.eu,demo-www.eea.europa.eu" + SONARQUBE_TAGS = "volto.eea.europa.eu,demo-www.eea.europa.eu,prod-www.eea.europa.eu" DEPENDENCIES = "" VOLTO = "alpha" } @@ -41,19 +41,19 @@ pipeline { "ES lint": { node(label: 'docker') { - sh '''docker run -i --rm --name="$BUILD_TAG-eslint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci eslint''' + sh '''docker run -i --rm --name="$BUILD_TAG-eslint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha eslint''' } }, "Style lint": { node(label: 'docker') { - sh '''docker run -i --rm --name="$BUILD_TAG-stylelint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci stylelint''' + sh '''docker run -i --rm --name="$BUILD_TAG-stylelint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha stylelint''' } }, "Prettier": { node(label: 'docker') { - sh '''docker run -i --rm --name="$BUILD_TAG-prettier" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci prettier''' + sh '''docker run -i --rm --name="$BUILD_TAG-prettier" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha prettier''' } } ) @@ -77,8 +77,8 @@ pipeline { node(label: 'docker') { script { try { - sh '''docker pull plone/volto-addon-ci''' - sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci''' + sh '''docker pull plone/volto-addon-ci:alpha''' + sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha''' sh '''rm -rf xunit-reports''' sh '''mkdir -p xunit-reports''' sh '''docker cp $BUILD_TAG-volto:/opt/frontend/my-volto-project/coverage xunit-reports/''' @@ -126,7 +126,7 @@ pipeline { script { try { sh '''docker pull eeacms/plone-backend; docker run --rm -d --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="eea.kitkat:testing" eeacms/plone-backend''' - sh '''docker pull plone/volto-addon-ci; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=development -e VOLTO="$VOLTO" plone/volto-addon-ci cypress''' + sh '''docker pull plone/volto-addon-ci:alpha; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha cypress''' } finally { try { sh '''rm -rf cypress-reports cypress-results cypress-coverage''' diff --git a/Makefile b/Makefile index bfdb33d..6bd245b 100644 --- a/Makefile +++ b/Makefile @@ -47,5 +47,51 @@ test-update: .PHONY: 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 :)" -)" -.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)" + +ifeq ($(wildcard ./project),) + NODE_MODULES = "../../../node_modules" +else + NODE_MODULES = "./project/node_modules" +endif + +.PHONY: stylelint +stylelint: + $(NODE_MODULES)/stylelint/bin/stylelint.js --allow-empty-input 'src/**/*.{css,less}' + +.PHONY: stylelint-overrides +stylelint-overrides: + $(NODE_MODULES)/.bin/stylelint --syntax less --allow-empty-input 'theme/**/*.overrides' 'src/**/*.overrides' + +.PHONY: stylelint-fix +stylelint-fix: + $(NODE_MODULES)/stylelint/bin/stylelint.js --allow-empty-input 'src/**/*.{css,less}' --fix + $(NODE_MODULES)/.bin/stylelint --syntax less --allow-empty-input 'theme/**/*.overrides' 'src/**/*.overrides' --fix + +.PHONY: prettier +prettier: + $(NODE_MODULES)/.bin/prettier --single-quote --check 'src/**/*.{js,jsx,json,css,less,md}' + +.PHONY: prettier-fix +prettier-fix: + $(NODE_MODULES)/.bin/prettier --single-quote --write 'src/**/*.{js,jsx,json,css,less,md}' + +.PHONY: lint +lint: + $(NODE_MODULES)/eslint/bin/eslint.js --max-warnings=0 'src/**/*.{js,jsx}' + +.PHONY: lint-fix +lint-fix: + $(NODE_MODULES)/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx}' + +.PHONY: i18n +i18n: + rm -rf build/messages + NODE_ENV=development $(NODE_MODULES)/.bin/i18n --addon + +.PHONY: cypress-run +cypress-run: + NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run + +.PHONY: cypress-open +cypress-open: + NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress open diff --git a/babel.config.js b/babel.config.js index 2f4e1e8..51bd52b 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,6 +1,6 @@ module.exports = function (api) { api.cache(true); - const presets = ['razzle/babel']; + const presets = ['razzle']; const plugins = [ [ 'react-intl', // React Intl extractor, required for the whole i18n infrastructure to work diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 0000000..30be8ac --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,26 @@ +const { defineConfig } = require('cypress'); + +module.exports = defineConfig({ + viewportWidth: 1280, + defaultCommandTimeout: 8888, + chromeWebSecurity: false, + reporter: 'junit', + video: true, + retries: { + runMode: 8, + openMode: 0, + }, + reporterOptions: { + mochaFile: 'cypress/reports/cypress-[hash].xml', + jenkinsMode: true, + toConsole: true, + }, + e2e: { + setupNodeEvents(on, config) { + // e2e testing node events setup code + require('@cypress/code-coverage/task')(on, config); + return config; + }, + baseUrl: 'http://localhost:3000', + }, +}); diff --git a/cypress.json b/cypress.json deleted file mode 100644 index 736dedd..0000000 --- a/cypress.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "baseUrl": "http://localhost:3000", - "viewportWidth": 1280, - "defaultCommandTimeout": 8888, - "chromeWebSecurity": false, - "reporter": "junit", - "video": true, - "retries": { - "runMode": 8, - "openMode": 0 - }, - "reporterOptions": { - "mochaFile": "cypress/reports/cypress-[hash].xml", - "jenkinsMode": true, - "toConsole": true - } -} diff --git a/cypress/integration/block-basics.js b/cypress/e2e/01-block-basics.cy.js similarity index 67% rename from cypress/integration/block-basics.js rename to cypress/e2e/01-block-basics.cy.js index 2b90366..089c7b3 100644 --- a/cypress/integration/block-basics.js +++ b/cypress/e2e/01-block-basics.cy.js @@ -1,18 +1,17 @@ -import { setupBeforeEach, tearDownAfterEach } from '../support'; +import { slateBeforeEach, slateAfterEach } from '../support/e2e'; describe('Blocks Tests', () => { - beforeEach(setupBeforeEach); - afterEach(tearDownAfterEach); + beforeEach(slateBeforeEach); + afterEach(slateAfterEach); it('Add Block: Empty', () => { // Change page title - cy.get('[contenteditable=true]').first().clear(); - - cy.get('[contenteditable=true]').first().type('My Add-on Page'); + cy.clearSlateTitle(); + cy.getSlateTitle().type('My Add-on Page'); cy.get('.documentFirstHeading').contains('My Add-on Page'); - cy.get('[contenteditable=true]').first().type('{enter}'); + cy.getSlate().click(); // Add block cy.get('.ui.basic.icon.button.block-add-button').first().click(); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 27a31a5..0000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,26 +0,0 @@ -/// -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config - /* coverage-start - require('@cypress/code-coverage/task')(on, config) - on('file:preprocessor', require('@cypress/code-coverage/use-babelrc')) - return config - coverage-end */ -}; diff --git a/cypress/support/commands.js b/cypress/support/commands.js index ac48461..f030097 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -1,5 +1,8 @@ /* eslint no-console: ["error", { allow: ["log"] }] */ +const SLATE_SELECTOR = '.content-area .slate-editor [contenteditable=true]'; +const SLATE_TITLE_SELECTOR = '.block.inner.title [contenteditable="true"]'; + // --- AUTOLOGIN ------------------------------------------------------------- Cypress.Commands.add('autologin', () => { let api_url, user, password; @@ -68,8 +71,7 @@ Cypress.Commands.add( id: contentId, title: contentTitle, image: { - data: - 'iVBORw0KGgoAAAANSUhEUgAAANcAAAA4CAMAAABZsZ3QAAAAM1BMVEX29fK42OU+oMvn7u9drtIPisHI4OhstdWZyt4fkcXX5+sAg74umMhNp86p0eJ7vNiKw9v/UV4wAAAAAXRSTlMAQObYZgAABBxJREFUeF7tmuty4yAMhZG4X2zn/Z92J5tsBJwWXG/i3XR6frW2Y/SBLIRAfaQUDNt8E5tLUt9BycfcKfq3R6Mlfyimtx4rzp+K3dtibXkor99zsEqLYZltblTecciogoh+TXfY1Ve4dn07rCDGG9dHSEEOg/GmXl0U1XDxTKxNK5De7BxsyyBr6gGm2/vPxKJ8F6f7BXKfRMp1xIWK9A+5ks25alSb353dWnDJN1k35EL5f8dVGifTf/4tjUuuFq7u4srmXC60yAmldLXIWbg65RKU87lcGxJCFqUPv0IacW0PmSivOZFLE908inPToMmii/roG+MRV/O8FU88i8tFsxV3a06MFUw0Qu7RmAtdV5/HVVaOVMTWNOWSwMljLhzhcB6XIS7OK5V6AvRDNN7t5VJWQs1J40UmalbK56usBG/CuCHSYuc+rkUGeMCViNRARPrzW52N3oQLe6WifNliSuuGaH3czbVNudI9s7ZLUCLHVwWlyES522o1t14uvmbblmVTKqFjaZYJFSTPP4dLL1kU1z7p0lzdbRulmEWLxoQX+z9ce7A8GqEEucllLxePuZwdJl1Lezu0hoswvTPt61DrFcRuujV/2cmlxaGBC7Aw6cpovGANwRiSdOAWJ5AGy4gLL64dl0QhUEAuEUNws+XxV+OKGPdw/hESGYF9XEGaFC7sNLMSXWJjHsnanYi87VK428N2uxpOjOFANcagLM5l+7mSycM8KknZpKLcGi6jmzWGr/vLurZ/0g4u9AZuAoeb5r1ceQhyiTPY1E4wUR6u/F3H2ojSpXMMriBPT9cezTto8Cx+MsglHL4fv1Rxrb1LVw9yvyQpJ3AhFnLZfuRLH2QsOG3FGGD20X/th/u5bFAt16Bt308KjF+MNOXgl/SquIEySX3GhaZvc67KZbDxcCDORz2N8yCWPaY5lyQZO7lQ29fnZbt3Xu6qoge4+DjXl/MocySPOp9rlvdyznahRyHEYd77v3LhugOXDv4J65QXfl803BDAdaWBEDhfVx7nKofjoVCgxnUAqw/UAUDPn788BDvQuG4TDtdtUPvzjSlXAB8DvaDOhhrmhwbywylXAm8CvaouikJTL93gs3y7Yy4VYbIxOHrcMizPqWOjqO9l3Uz52kibQy4xxOgqhJvD+w5rvokOcAlGvNCfeqCv1ste1stzLm0f71Iq3ZfTrPfuE5nhPtF+LvQE2lffQC7pYtQy3tdzdrKvd5TLVVzDetScS3nEKmmwDyt1Cev1kX3YfbvzNK4fzrlw+cB6vm+uiUgf2zdXI62241LawCb7Pi5FXFPF8KpzDoF/Sw2lg+GrHNbno1mhPu+VCF/vfMnw06PnUl6j48dVHD3jHNHPua+fc3o/5yp/zsGi0vYtzi3Pz5mHd4T6BWMIlewacd63AAAAAElFTkSuQmCC', + data: 'iVBORw0KGgoAAAANSUhEUgAAANcAAAA4CAMAAABZsZ3QAAAAM1BMVEX29fK42OU+oMvn7u9drtIPisHI4OhstdWZyt4fkcXX5+sAg74umMhNp86p0eJ7vNiKw9v/UV4wAAAAAXRSTlMAQObYZgAABBxJREFUeF7tmuty4yAMhZG4X2zn/Z92J5tsBJwWXG/i3XR6frW2Y/SBLIRAfaQUDNt8E5tLUt9BycfcKfq3R6Mlfyimtx4rzp+K3dtibXkor99zsEqLYZltblTecciogoh+TXfY1Ve4dn07rCDGG9dHSEEOg/GmXl0U1XDxTKxNK5De7BxsyyBr6gGm2/vPxKJ8F6f7BXKfRMp1xIWK9A+5ks25alSb353dWnDJN1k35EL5f8dVGifTf/4tjUuuFq7u4srmXC60yAmldLXIWbg65RKU87lcGxJCFqUPv0IacW0PmSivOZFLE908inPToMmii/roG+MRV/O8FU88i8tFsxV3a06MFUw0Qu7RmAtdV5/HVVaOVMTWNOWSwMljLhzhcB6XIS7OK5V6AvRDNN7t5VJWQs1J40UmalbK56usBG/CuCHSYuc+rkUGeMCViNRARPrzW52N3oQLe6WifNliSuuGaH3czbVNudI9s7ZLUCLHVwWlyES522o1t14uvmbblmVTKqFjaZYJFSTPP4dLL1kU1z7p0lzdbRulmEWLxoQX+z9ce7A8GqEEucllLxePuZwdJl1Lezu0hoswvTPt61DrFcRuujV/2cmlxaGBC7Aw6cpovGANwRiSdOAWJ5AGy4gLL64dl0QhUEAuEUNws+XxV+OKGPdw/hESGYF9XEGaFC7sNLMSXWJjHsnanYi87VK428N2uxpOjOFANcagLM5l+7mSycM8KknZpKLcGi6jmzWGr/vLurZ/0g4u9AZuAoeb5r1ceQhyiTPY1E4wUR6u/F3H2ojSpXMMriBPT9cezTto8Cx+MsglHL4fv1Rxrb1LVw9yvyQpJ3AhFnLZfuRLH2QsOG3FGGD20X/th/u5bFAt16Bt308KjF+MNOXgl/SquIEySX3GhaZvc67KZbDxcCDORz2N8yCWPaY5lyQZO7lQ29fnZbt3Xu6qoge4+DjXl/MocySPOp9rlvdyznahRyHEYd77v3LhugOXDv4J65QXfl803BDAdaWBEDhfVx7nKofjoVCgxnUAqw/UAUDPn788BDvQuG4TDtdtUPvzjSlXAB8DvaDOhhrmhwbywylXAm8CvaouikJTL93gs3y7Yy4VYbIxOHrcMizPqWOjqO9l3Uz52kibQy4xxOgqhJvD+w5rvokOcAlGvNCfeqCv1ste1stzLm0f71Iq3ZfTrPfuE5nhPtF+LvQE2lffQC7pYtQy3tdzdrKvd5TLVVzDetScS3nEKmmwDyt1Cev1kX3YfbvzNK4fzrlw+cB6vm+uiUgf2zdXI62241LawCb7Pi5FXFPF8KpzDoF/Sw2lg+GrHNbno1mhPu+VCF/vfMnw06PnUl6j48dVHD3jHNHPua+fc3o/5yp/zsGi0vYtzi3Pz5mHd4T6BWMIlewacd63AAAAAElFTkSuQmCC', encoding: 'base64', filename: 'image.png', 'content-type': 'image/png', @@ -92,7 +94,7 @@ Cypress.Commands.add( title: contentTitle, blocks: { 'd3f1c443-583f-4e8e-a682-3bf25752a300': { '@type': 'title' }, - '7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': 'text' }, + '7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': 'slate' }, }, blocks_layout: { items: [ @@ -122,9 +124,103 @@ Cypress.Commands.add( }) .then(() => console.log(`${contentType} created`)); } - }, + } ); +// --- Add DX Content-Type ---------------------------------------------------------- +Cypress.Commands.add('addContentType', (name) => { + let api_url, auth; + api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone'; + auth = { + user: 'admin', + pass: 'admin', + }; + return cy + .request({ + method: 'POST', + url: `${api_url}/@controlpanels/dexterity-types/${name}`, + headers: { + Accept: 'application/json', + }, + auth: auth, + body: { + title: name, + }, + }) + .then(() => console.log(`${name} content-type added.`)); +}); + +// --- Remove DX behavior ---------------------------------------------------------- +Cypress.Commands.add('removeContentType', (name) => { + let api_url, auth; + api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone'; + auth = { + user: 'admin', + pass: 'admin', + }; + return cy + .request({ + method: 'DELETE', + url: `${api_url}/@controlpanels/dexterity-types/${name}`, + headers: { + Accept: 'application/json', + }, + auth: auth, + body: {}, + }) + .then(() => console.log(`${name} content-type removed.`)); +}); + +// --- Add DX field ---------------------------------------------------------- +Cypress.Commands.add('addSlateJSONField', (type, name) => { + let api_url, auth; + api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone'; + auth = { + user: 'admin', + pass: 'admin', + }; + return cy + .request({ + method: 'POST', + url: `${api_url}/@types/${type}`, + headers: { + Accept: 'application/json', + }, + auth: auth, + body: { + id: name, + title: name, + description: 'Slate JSON Field', + factory: 'SlateJSONField', + required: false, + }, + }) + .then(() => console.log(`${name} SlateJSONField field added to ${type}`)); +}); + +// --- Remove DX field ---------------------------------------------------------- +Cypress.Commands.add('removeSlateJSONField', (type, name) => { + let api_url, auth; + api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone'; + auth = { + user: 'admin', + pass: 'admin', + }; + return cy + .request({ + method: 'DELETE', + url: `${api_url}/@types/${type}/${name}`, + headers: { + Accept: 'application/json', + }, + auth: auth, + body: {}, + }) + .then(() => + console.log(`${name} SlateJSONField field removed from ${type}`) + ); +}); + // --- REMOVE CONTENT -------------------------------------------------------- Cypress.Commands.add('removeContent', (path) => { let api_url, auth; @@ -146,6 +242,41 @@ Cypress.Commands.add('removeContent', (path) => { .then(() => console.log(`${path} removed`)); }); +Cypress.Commands.add('typeInSlate', { prevSubject: true }, (subject, text) => { + return ( + cy + .wrap(subject) + .then((subject) => { + subject[0].dispatchEvent( + new InputEvent('beforeinput', { + inputType: 'insertText', + data: text, + }) + ); + return subject; + }) + // TODO: do this only for Electron-based browser which does not understand instantaneously + // that the user inserted some text in the block + .wait(1000) + ); +}); + +Cypress.Commands.add('lineBreakInSlate', { prevSubject: true }, (subject) => { + return ( + cy + .wrap(subject) + .then((subject) => { + subject[0].dispatchEvent( + new InputEvent('beforeinput', { inputType: 'insertLineBreak' }) + ); + return subject; + }) + // TODO: do this only for Electron-based browser which does not understand instantaneously + // that the block was split + .wait(1000) + ); +}); + // --- SET WORKFLOW ---------------------------------------------------------- Cypress.Commands.add( 'setWorkflow', @@ -184,7 +315,7 @@ Cypress.Commands.add( include_children: include_children, }, }); - }, + } ); // --- waitForResourceToLoad ---------------------------------------------------------- @@ -244,9 +375,86 @@ Cypress.Commands.add( setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset); } }); - }, + } ); +Cypress.Commands.add('getSlate', (createNewSlate = false) => { + let slate; + if (createNewSlate) { + cy.get('.block.inner').last().type('{moveToEnd}{enter}'); + } + cy.getIfExists( + SLATE_SELECTOR, + () => { + slate = cy.get(SLATE_SELECTOR).last(); + }, + () => { + slate = cy.get(SLATE_SELECTOR, { timeout: 10000 }).last(); + } + ); + return slate; +}); + +Cypress.Commands.add('clearSlate', (selector) => { + return cy + .get(selector) + .focus() + .click() + .wait(1000) + .type('{selectAll}') + .wait(1000) + .type('{backspace}'); +}); + +Cypress.Commands.add('getSlateTitle', () => { + return cy.get(SLATE_TITLE_SELECTOR, { + timeout: 10000, + }); +}); + +Cypress.Commands.add('clearSlateTitle', () => { + return cy.clearSlate(SLATE_TITLE_SELECTOR); +}); + +Cypress.Commands.add('setSlateSelection', (subject, query, endQuery) => { + cy.get('.slate-editor.selected [contenteditable=true]') + .focus() + .click() + .setSelection(subject, query, endQuery) + .wait(1000); // this wait is needed for the selection change to be detected after +}); + +Cypress.Commands.add('getSlateEditorAndType', (type) => { + cy.getSlate().focus().click().type(type); +}); + +Cypress.Commands.add('setSlateCursor', (subject, query, endQuery) => { + cy.get('.slate-editor.selected [contenteditable=true]') + .focus() + .click() + .setCursor(subject, query, endQuery) + .wait(1000); +}); + +Cypress.Commands.add('clickSlateButton', (button) => { + cy.get(`.slate-inline-toolbar .button-wrapper a[title="${button}"]`, { + timeout: 10000, + }).click({ force: true }); //force click is needed to ensure the button in visible in view. +}); + +Cypress.Commands.add('toolbarSave', () => { + cy.wait(1000); + + // Save + cy.get('#toolbar-save').click(); + cy.waitForResourceToLoad('@navigation'); + cy.waitForResourceToLoad('@breadcrumbs'); + cy.waitForResourceToLoad('@actions'); + cy.waitForResourceToLoad('@types'); + cy.waitForResourceToLoad('my-page'); + cy.url().should('eq', Cypress.config().baseUrl + '/cypress/my-page'); +}); + // Low level command reused by `setCursorBefore` and `setCursorAfter`, equal to `setCursorAfter` Cypress.Commands.add( 'setCursor', @@ -262,7 +470,7 @@ Cypress.Commands.add( }); // Depending on what you're testing, you may need to chain a `.click()` here to ensure // further commands are picked up by whatever you're testing (this was required for Slate, for example). - }, + } ); Cypress.Commands.add( @@ -270,7 +478,7 @@ Cypress.Commands.add( { prevSubject: true }, (subject, query) => { cy.wrap(subject).setCursor(query, true); - }, + } ); Cypress.Commands.add( @@ -278,7 +486,7 @@ Cypress.Commands.add( { prevSubject: true }, (subject, query) => { cy.wrap(subject).setCursor(query); - }, + } ); // Helper functions @@ -313,3 +521,16 @@ Cypress.Commands.add('store', () => { Cypress.Commands.add('settings', (key, value) => { return cy.window().its('settings'); }); + +Cypress.Commands.add( + 'getIfExists', + (selector, successAction = () => {}, failAction = () => {}) => { + cy.get('body').then((body) => { + if (body.find(selector).length > 0 && successAction) { + successAction(); + } else if (failAction) { + failAction(); + } + }); + } +); diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js new file mode 100644 index 0000000..f696418 --- /dev/null +++ b/cypress/support/e2e.js @@ -0,0 +1,125 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands'; +// Alternatively you can use CommonJS syntax: +// require('./commands') + +//Generate code-coverage +import '@cypress/code-coverage/support'; + +export const slateBeforeEach = (contentType = 'Document') => { + cy.autologin(); + cy.createContent({ + contentType: 'Document', + contentId: 'cypress', + contentTitle: 'Cypress', + }); + cy.createContent({ + contentType: contentType, + contentId: 'my-page', + contentTitle: 'My Page', + path: 'cypress', + }); + cy.visit('/cypress/my-page'); + cy.waitForResourceToLoad('@navigation'); + cy.waitForResourceToLoad('@breadcrumbs'); + cy.waitForResourceToLoad('@actions'); + cy.waitForResourceToLoad('@types'); + cy.waitForResourceToLoad('my-page'); + cy.navigate('/cypress/my-page/edit'); +}; + +export const slateAfterEach = () => { + cy.autologin(); + cy.removeContent('cypress'); +}; + +export const slateJsonBeforeEach = (contentType = 'slate') => { + cy.autologin(); + cy.addContentType(contentType); + cy.addSlateJSONField(contentType, 'slate'); + slateBeforeEach(contentType); +}; + +export const slateJsonAfterEach = (contentType = 'slate') => { + cy.autologin(); + cy.removeContentType(contentType); + slateAfterEach(); +}; + +export const getSelectedSlateEditor = () => { + return cy.get('.slate-editor.selected [contenteditable=true]').click(); +}; + +export const createSlateBlock = () => { + cy.get('.ui.basic.icon.button.block-add-button').first().click(); + cy.get('.blocks-chooser .title').contains('Text').click(); + cy.get('.ui.basic.icon.button.slate').contains('Text').click(); + return getSelectedSlateEditor(); +}; + +export const getSlateBlockValue = (sb) => { + return sb.invoke('attr', 'data-slate-value').then((str) => { + return typeof str === 'undefined' ? [] : JSON.parse(str); + }); +}; + +export const createSlateBlockWithList = ({ + numbered, + firstItemText, + secondItemText, +}) => { + let s1 = createSlateBlock(); + + s1.typeInSlate(firstItemText + secondItemText); + + // select all contents of slate block + // - this opens hovering toolbar + cy.contains(firstItemText + secondItemText).then((el) => { + selectSlateNodeOfWord(el); + }); + + // TODO: do not hardcode these selectors: + if (numbered) { + // this is the numbered list option in the hovering toolbar + cy.get('.slate-inline-toolbar > :nth-child(9)').click(); + } else { + // this is the bulleted list option in the hovering toolbar + cy.get('.slate-inline-toolbar > :nth-child(10)').click(); + } + + // move the text cursor + const sse = getSelectedSlateEditor(); + sse.type('{leftarrow}'); + for (let i = 0; i < firstItemText.length; ++i) { + sse.type('{rightarrow}'); + } + + // simulate pressing Enter + getSelectedSlateEditor().lineBreakInSlate(); + + return s1; +}; + +export const selectSlateNodeOfWord = (el) => { + return cy.window().then((win) => { + var event = new CustomEvent('Test_SelectWord', { + detail: el[0], + }); + win.document.dispatchEvent(event); + }); +}; diff --git a/cypress/support/index.js b/cypress/support/index.js deleted file mode 100644 index 32395ab..0000000 --- a/cypress/support/index.js +++ /dev/null @@ -1,53 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands'; - -// Alternatively you can use CommonJS syntax: -// require('./commands') - -/* coverage-start -//Generate code-coverage -import '@cypress/code-coverage/support'; -coverage-end */ - -export const setupBeforeEach = () => { - cy.autologin(); - cy.createContent({ - contentType: 'Document', - contentId: 'cypress', - contentTitle: 'Cypress', - }); - cy.createContent({ - contentType: 'Document', - contentId: 'my-page', - contentTitle: 'My Page', - path: 'cypress', - }); - cy.visit('/cypress/my-page'); - cy.waitForResourceToLoad('@navigation'); - cy.waitForResourceToLoad('@breadcrumbs'); - cy.waitForResourceToLoad('@actions'); - cy.waitForResourceToLoad('@types'); - cy.waitForResourceToLoad('my-page'); - cy.navigate('/cypress/my-page/edit'); - cy.get(`.block.title h1`); -}; - -export const tearDownAfterEach = () => { - cy.autologin(); - cy.removeContent('cypress'); -}; diff --git a/jest-addon.config.js b/jest-addon.config.js index 7c15499..da38318 100644 --- a/jest-addon.config.js +++ b/jest-addon.config.js @@ -9,18 +9,18 @@ module.exports = { '@plone/volto/babel': '/node_modules/@plone/volto/babel', '@plone/volto/(.*)$': '/node_modules/@plone/volto/src/$1', '@package/(.*)$': '/src/$1', + '@root/(.*)$': '/src/$1', '@plone/volto-quanta/(.*)$': '/src/addons/volto-quanta/src/$1', '@eeacms/(.*?)/(.*)$': '/src/addons/$1/src/$2', - 'volto-slate/(.*)$': '/src/addons/volto-slate/src/$1', + '@plone/volto-slate': + '/node_modules/@plone/volto/packages/volto-slate/src', '~/(.*)$': '/src/$1', 'load-volto-addons': '/node_modules/@plone/volto/jest-addons-loader.js', + '\\.(css|less|scss|sass)$': 'identity-obj-proxy', }, transform: { '^.+\\.js(x)?$': 'babel-jest', - '^.+\\.css$': 'jest-css-modules', - '^.+\\.less$': 'jest-css-modules', - '^.+\\.scss$': 'jest-css-modules', '^.+\\.(png)$': 'jest-file', '^.+\\.(jpg)$': 'jest-file', '^.+\\.(svg)$': './node_modules/@plone/volto/jest-svgsystem-transform.js', diff --git a/package.json b/package.json index ffd69fe..8879151 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eeacms/volto-quote-block", - "version": "0.3.3", + "version": "1.0.0", "description": "@eeacms/volto-quote-block: Volto add-on", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team", @@ -17,33 +17,34 @@ "url": "git@github.com:eea/volto-quote-block.git" }, "addons": [ - "@eeacms/volto-object-widget", - "volto-slate" + "@eeacms/volto-object-widget" ], "dependencies": { - "@plone/scripts": "*", - "volto-slate": "*", "@eeacms/volto-object-widget": "*" }, "devDependencies": { - "@cypress/code-coverage": "^3.9.5", - "babel-plugin-transform-class-properties": "^6.24.1" + "@plone/scripts": "*", + "@cypress/code-coverage": "^3.10.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "md5": "^2.3.0" }, "scripts": { "release": "release-it", + "release-major-beta": "release-it major --preRelease=beta", + "release-beta": "release-it --preRelease=beta", "bootstrap": "npm install -g ejs; npm link ejs; node bootstrap", "test": "make test", "test:fix": "make test-update", "pre-commit": "yarn stylelint:fix && yarn prettier:fix && yarn lint:fix", - "stylelint": "../../../node_modules/.bin/stylelint 'theme/**/*.{css,less}' 'src/**/*.{css,less}'", - "stylelint:overrides": "../../../node_modules/.bin/stylelint --allow-empty-input 'theme/**/*.overrides' 'src/**/*.overrides'", - "stylelint:fix": "yarn stylelint --fix && yarn stylelint:overrides --fix", - "prettier": "if [ -d ./project ]; then ./project/node_modules/.bin/prettier --single-quote --check 'src/**/*.{js,jsx,json,css,less,md}'; else ../../../node_modules/.bin/prettier --single-quote --check 'src/**/*.{js,jsx,json,css,less,md}'; fi", - "prettier:fix": "if [ -d ./project ]; then ./project/node_modules/.bin/prettier --single-quote --write 'src/**/*.{js,jsx,json,css,less,md}'; else ../../../node_modules/.bin/prettier --single-quote --write 'src/**/*.{js,jsx,json,css,less,md}'; fi", - "lint": "if [ -d ./project ]; then ./project/node_modules/eslint/bin/eslint.js --max-warnings=0 'src/**/*.{js,jsx}'; else ../../../node_modules/eslint/bin/eslint.js --max-warnings=0 'src/**/*.{js,jsx}'; fi", - "lint:fix": "if [ -d ./project ]; then ./project/node_modules/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx}'; else ../../../node_modules/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx}'; fi", - "i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon", - "cypress:run": "if [ -d ./project ]; then NODE_ENV=development ./project/node_modules/cypress/bin/cypress run; else NODE_ENV=development ../../../node_modules/cypress/bin/cypress run; fi", - "cypress:open": "if [ -d ./project ]; then NODE_ENV=development ./project/node_modules/cypress/bin/cypress open; else NODE_ENV=development ../../../node_modules/cypress/bin/cypress open; fi" + "stylelint": "make stylelint", + "stylelint:overrides": "make stylelint-overrides", + "stylelint:fix": "make stylelint-fix", + "prettier": "make prettier", + "prettier:fix": "make prettier-fix", + "lint": "make lint", + "lint:fix": "make lint-fix", + "i18n": "make i18n", + "cypress:run": "make cypress-run", + "cypress:open": "make cypress-open" } } diff --git a/src/Blocks/Quote/variations/DefaultQuote.jsx b/src/Blocks/Quote/variations/DefaultQuote.jsx index a8f829e..95c5893 100644 --- a/src/Blocks/Quote/variations/DefaultQuote.jsx +++ b/src/Blocks/Quote/variations/DefaultQuote.jsx @@ -3,9 +3,12 @@ import cx from 'classnames'; import { connect } from 'react-redux'; import { Icon, Message } from 'semantic-ui-react'; import config from '@plone/volto/registry'; -import SlateEditor from 'volto-slate/editor/SlateEditor'; -import { handleKey } from 'volto-slate/blocks/Text/keyboard'; -import { uploadContent, saveSlateBlockSelection } from 'volto-slate/actions'; +import SlateEditor from '@plone/volto-slate/editor/SlateEditor'; +import { handleKey } from '@plone/volto-slate/blocks/Text/keyboard'; +import { + uploadContent, + saveSlateBlockSelection, +} from '@plone/volto-slate/actions'; import { createSlateParagraph, isFloated, diff --git a/src/Blocks/Quote/variations/TestimonialQuote.jsx b/src/Blocks/Quote/variations/TestimonialQuote.jsx index 2c5d616..865214c 100644 --- a/src/Blocks/Quote/variations/TestimonialQuote.jsx +++ b/src/Blocks/Quote/variations/TestimonialQuote.jsx @@ -3,9 +3,12 @@ import { connect } from 'react-redux'; import { Grid, Card, Image } from 'semantic-ui-react'; import config from '@plone/volto/registry'; import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers'; -import SlateEditor from 'volto-slate/editor/SlateEditor'; -import { handleKey } from 'volto-slate/blocks/Text/keyboard'; -import { uploadContent, saveSlateBlockSelection } from 'volto-slate/actions'; +import SlateEditor from '@plone/volto-slate/editor/SlateEditor'; +import { handleKey } from '@plone/volto-slate/blocks/Text/keyboard'; +import { + uploadContent, + saveSlateBlockSelection, +} from '@plone/volto-slate/actions'; import { createSlateParagraph, serializeText, diff --git a/src/helpers.js b/src/helpers.js index 5b5de1c..7f29942 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,6 +1,6 @@ import { isArray } from 'lodash'; import config from '@plone/volto/registry'; -import { serializeNodes } from 'volto-slate/editor/render'; +import { serializeNodes } from '@plone/volto-slate/editor/render'; export const createSlateParagraph = (text) => { return isArray(text) ? text : config.settings.slate.defaultValue();