diff --git a/CHANGELOG.md b/CHANGELOG.md index 9459f538..c60cf429 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,30 @@ 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). +#### [2.9.2](https://github.com/eea/volto-slate/compare/2.9.1...2.9.2) + +- Fix toolbar position in Link plugin [`#135`](https://github.com/eea/volto-slate/pull/135) +- I18n [`#119`](https://github.com/eea/volto-slate/pull/119) +- Update docker files [`#134`](https://github.com/eea/volto-slate/pull/134) +- Use BlockChooserButton component [`#133`](https://github.com/eea/volto-slate/pull/133) +- cy wait 1000 [`6cd4ec1`](https://github.com/eea/volto-slate/commit/6cd4ec188d652c3c43978fd1612560ad36aa7a89) +- Better fix [`46822c0`](https://github.com/eea/volto-slate/commit/46822c0cf5c8b9603d714b46ebb17cb4544bd807) +- Don't overoptimize calculate toolbar position [`bc28375`](https://github.com/eea/volto-slate/commit/bc283750c8f37855ace5e9e9b3ee2512996b1166) +- Remove production NODE_ENV flag from jenkins [`8c3cab3`](https://github.com/eea/volto-slate/commit/8c3cab3cfe895e6d71badea3a791df3c1aa86fe4) +- Merge develop [`03f842c`](https://github.com/eea/volto-slate/commit/03f842cddf65425077b0258536009ccedd64323e) +- Imrpove docker-compose.yml [`428b568`](https://github.com/eea/volto-slate/commit/428b568f4a762ad90ffdd5b9f0379271b88dc975) +- Fix tests [`008922d`](https://github.com/eea/volto-slate/commit/008922d57bfae3020123a8117e786c669e602fa8) +- Rename babel.config to make tests pass [`28d3c71`](https://github.com/eea/volto-slate/commit/28d3c719c88e46f59b715ef85aafedfc1e3283b1) +- Set NODE_ENV to production [`a7eb4ef`](https://github.com/eea/volto-slate/commit/a7eb4ef9e4d8cc01aaae6a0935b8df8a21abc0e5) +- Update snapshot [`b3beebf`](https://github.com/eea/volto-slate/commit/b3beebf7c7f0c7518c0cccc5bcb8f6db3fdb162a) +- Add i18n artifacts [`7d25290`](https://github.com/eea/volto-slate/commit/7d2529020afb72ba2a558085fbb5c6786153f15e) +- WIP on i18n [`d48e979`](https://github.com/eea/volto-slate/commit/d48e9791131cb2a4f1a32c5da3b90d69169bba45) + #### [2.9.1](https://github.com/eea/volto-slate/compare/2.9.0...2.9.1) +> 13 August 2021 + +- Release [`#132`](https://github.com/eea/volto-slate/pull/132) - add handle to unwrap note if empty string [`#129`](https://github.com/eea/volto-slate/pull/129) - Set CSS class according inline style menu selection paragraph style [`#111`](https://github.com/eea/volto-slate/pull/111) diff --git a/Jenkinsfile b/Jenkinsfile index 4c222513..be618b3e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -63,8 +63,8 @@ pipeline { ]) } finally { catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') { - junit testResults: 'xunit-reports/junit.xml', allowEmptyResults: true - } + junit testResults: 'xunit-reports/junit.xml', allowEmptyResults: true + } sh script: '''docker rm -v $BUILD_TAG-volto''', returnStatus: true } } @@ -91,7 +91,7 @@ pipeline { sh '''docker cp $BUILD_TAG-cypress:/opt/frontend/my-volto-project/src/addons/$GIT_NAME/cypress/videos cypress-reports/''' sh '''docker cp $BUILD_TAG-cypress:/opt/frontend/my-volto-project/src/addons/$GIT_NAME/cypress/reports cypress-results/''' coverage = sh script: '''docker cp $BUILD_TAG-cypress:/opt/frontend/my-volto-project/src/addons/$GIT_NAME/coverage cypress-coverage/''', returnStatus: true - if ( coverage == 0 ) { + if ( coverage == 0 ) { publishHTML (target : [allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, @@ -106,11 +106,11 @@ pipeline { finally { catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') { junit testResults: 'cypress-results/**/*.xml', allowEmptyResults: true - } + } sh script: "docker stop $BUILD_TAG-plone", returnStatus: true sh script: "docker rm -v $BUILD_TAG-plone", returnStatus: true sh script: "docker rm -v $BUILD_TAG-cypress", returnStatus: true - + } } } diff --git a/Makefile b/Makefile index 092c6aaa..cf45286a 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,11 @@ test: test-update: docker pull plone/volto-addon-ci docker run -it --rm -e GIT_NAME=volto-slate -e RAZZLE_JEST_CONFIG=jest-addon.config.js -v "$$(pwd):/opt/frontend/my-volto-project/src/addons/volto-slate" plone/volto-addon-ci yarn test --watchAll=false -u + +.PHONY: test-acceptance-server +test-acceptance-server: ## Run test acceptance server + docker run -i --rm --name=plone -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 + # # build-frontend: # yarn && RAZZLE_API_PATH=http://localhost:55001/plone yarn build diff --git a/babel.config.js-use-with-i18n b/babel.config.js-use-with-i18n new file mode 100644 index 00000000..a900a755 --- /dev/null +++ b/babel.config.js-use-with-i18n @@ -0,0 +1 @@ +module.exports = require('@plone/volto/babel'); diff --git a/cypress/integration/04-block-focus.js b/cypress/integration/04-block-focus.js index cbf13bec..4db4274c 100644 --- a/cypress/integration/04-block-focus.js +++ b/cypress/integration/04-block-focus.js @@ -34,11 +34,13 @@ describe('Block Tests', () => { 'Colorless green ideas sleep furiously.', ).setSelection('furiously'); - cy.wait(500); + cy.wait(1000); cy.get('.slate-inline-toolbar .button-wrapper a[title="Link"]').click(); cy.get('.sidebar-container a.item:nth-child(3)').click(); - cy.get('input[name="external_link-0-external"]').click().type('https://google.com{enter}'); + cy.get('input[name="external_link-0-external"]') + .click() + .type('https://google.com{enter}'); cy.get('.sidebar-container .form .header button:first-of-type').click(); cy.get('#toolbar-save').click(); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..33abd950 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,40 @@ +version: "3" +services: + + volto: + image: plone/volto-addon-ci + environment: + - GIT_NAME=volto-slate + - RAZZLE_JEST_CONFIG=jest-addon.config.js + volumes: + - .:/opt/frontend/my-volto-project/src/addons/volto-slate + # - ./project/package.json:/opt/frontend/my-volto-project/package.json + # - ./jest-addon.config.js:/opt/frontend/my-volto-project/jest-addon.config.js + command: cat + stdin_open: true + tty: true + working_dir: /opt/frontend/my-volto-project + + # user: root + # entrypoint: sh -c 'tail -f /dev/null' + + ci: + image: plone/volto-addon-ci + environment: + - GIT_NAME=volto-slate + - RAZZLE_JEST_CONFIG=jest-addon.config.js + - RAZZLE_API_PATH="http://plone:55001/plone" + - CYPRESS_BACKEND_HOST="plone" + - GIT_BRANCH=i18n + entrypoint: sh -c "tail -f /dev/null" + # command: cypress + # command: cat + # stdin_open: true + # tty: true + # working_dir: /opt/frontend/my-volto-project + +# project/node_modules/.bin/start-test ci:test-acceptance-server http-get://localhost:55001/plone 'docker run -i -e RAZZLE_API_PATH="http://plone:55001/plone" -e CYPRESS_BACKEND_HOST="plone" --name="cypress" -e DEPENDENCIES="" -e GI +# T_NAME=volto-slate plone/volto-addon-ci cypress' + +# docker run -it --rm -e GIT_NAME=volto-slate -e RAZZLE_JEST_CONFIG=jest-addon.config.js +# -v "$$(pwd):/opt/frontend/my-volto-project/src/addons/volto-slate" plone/volto-addon-ci yarn test --watchAll=false diff --git a/locales/volto.pot b/locales/volto.pot new file mode 100644 index 00000000..c526e5ff --- /dev/null +++ b/locales/volto.pot @@ -0,0 +1,175 @@ +msgid "" +msgstr "" +"Project-Id-Version: Plone\n" +"POT-Creation-Date: 2021-07-12T13:13:36.922Z\n" +"Last-Translator: Plone i18n \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" +"Language-Code: en\n" +"Language-Name: English\n" +"Preferred-Encodings: utf-8\n" +"Domain: volto\n" + +#: editor/plugins/SimpleLink/index +# defaultMessage: Add link +msgid "Add link" +msgstr "" + +#: editor/plugins/StyleMenu/StyleMenu +# defaultMessage: All Styles Applied +msgid "All Styles Applied" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserNav +# defaultMessage: Back +msgid "Back" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserNav +# defaultMessage: Browse +msgid "Browse" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Cell +msgid "Cell" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserBody +# defaultMessage: Choose Target +msgid "Choose Target" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserWidget +# defaultMessage: Delete +msgid "Delete" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Delete col +msgid "Delete col" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Delete row +msgid "Delete row" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Divide each row into separate cells +msgid "Divide each row into separate cells" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserWidget +# defaultMessage: Edit +msgid "Edit" +msgstr "" + +#: components/ElementEditor/messages +# defaultMessage: Edit element +msgid "Edit element" +msgstr "" + +#: editor/plugins/Link/index +#: editor/plugins/SimpleLink/index +# defaultMessage: Edit link +msgid "Edit link" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Fixed width table cells +msgid "Fixed width table cells" +msgstr "" + +#: editor/plugins/StyleMenu/StyleMenu +# defaultMessage: Font Style +msgid "Font Style" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Insert col after +msgid "Insert col after" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Insert col before +msgid "Insert col before" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Insert row after +msgid "Insert row after" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Insert row before +msgid "Insert row before" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Make the table compact +msgid "Make the table compact" +msgstr "" + +#: editor/plugins/StyleMenu/StyleMenu +# defaultMessage: No Style +msgid "No Style" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserWidget +# defaultMessage: No items selected +msgid "No items selected" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserWidget +# defaultMessage: Open object browser +msgid "Open object browser" +msgstr "" + +#: editor/plugins/StyleMenu/StyleMenu +# defaultMessage: Paragraph Style +msgid "Paragraph Style" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Reduce complexity +msgid "Reduce complexity" +msgstr "" + +#: components/ElementEditor/messages +# defaultMessage: Remove element +msgid "Remove element" +msgstr "" + +#: editor/plugins/Link/index +# defaultMessage: Remove link +msgid "Remove link" +msgstr "" + +#: widgets/BlocksBrowser/BlocksBrowserNav +# defaultMessage: Select +msgid "Select" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Stripe alternate rows with color +msgid "Stripe alternate rows with color" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Table +msgid "Table" +msgstr "" + +#: blocks/Table/Edit +# defaultMessage: Table color inverted +msgid "Table color inverted" +msgstr "" + +#: blocks/Text/TextBlockEdit +# defaultMessage: Type text… +msgid "Type text…" +msgstr "" diff --git a/package.json b/package.json index a25969bd..9f52e9f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "volto-slate", - "version": "2.9.1", + "version": "2.9.2", "description": "Slate.js integration with Volto", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team", @@ -60,6 +60,13 @@ "lint": "../../../node_modules/eslint/bin/eslint.js --max-warnings=0 'src/**/*.{js,jsx}'", "lint:fix": "../../../node_modules/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx}'", "cypress:run": "if [ -d ./project ]; then ./project/node_modules/cypress/bin/cypress run; else ../../../node_modules/cypress/bin/cypress run; fi", - "cypress:open": "if [ -d ./project ]; then ./project/node_modules/cypress/bin/cypress open; else ../../../node_modules/cypress/bin/cypress open; fi" + "cypress:open": "if [ -d ./project ]; then ./project/node_modules/cypress/bin/cypress open; else ../../../node_modules/cypress/bin/cypress open; fi", + "i18n": "rm -rf build/messages && NODE_ENV=production node src/i18n.js", + "cypress:start-frontend": "cd ../../../ && RAZZLE_API_PATH=http://localhost:55001/plone yarn start", + "ci:cypress:run": "make cypress", + "ci:cypress": "start-test ci:test-acceptance-server http-get://localhost:55001/plone ci:cypress:run", + "ci:test-acceptance-server": "make test-acceptance-server", + "cy:test:fixture:setup": "node cypress/support/reset-fixture.js", + "cy:test:fixture:teardown": "node cypress/support/reset-fixture.js teardown" } } diff --git a/src/blocks/Text/TextBlockEdit.jsx b/src/blocks/Text/TextBlockEdit.jsx index af62f2d3..08a8fb02 100644 --- a/src/blocks/Text/TextBlockEdit.jsx +++ b/src/blocks/Text/TextBlockEdit.jsx @@ -3,13 +3,12 @@ import { connect } from 'react-redux'; import { readAsDataURL } from 'promise-file-reader'; import Dropzone from 'react-dropzone'; -import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib'; -import { Button, Dimmer, Loader, Message, Segment } from 'semantic-ui-react'; +import { Dimmer, Loader, Message, Segment } from 'semantic-ui-react'; -import { Icon, BlockChooser, SidebarPortal } from '@plone/volto/components'; import InlineForm from '@plone/volto/components/manage/Form/InlineForm'; import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers'; import config from '@plone/volto/registry'; +import { SidebarPortal, BlockChooserButton } from '@plone/volto/components'; import { saveSlateBlockSelection } from 'volto-slate/actions'; import { SlateEditor } from 'volto-slate/editor'; @@ -25,7 +24,8 @@ import { handleKey, handleKeyDetached } from './keyboard'; import TextBlockSchema from './schema'; import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg'; -import addSVG from '@plone/volto/icons/circle-plus.svg'; + +import { defineMessages, useIntl } from 'react-intl'; import { useInView } from 'react-intersection-observer'; @@ -33,6 +33,13 @@ import './css/editor.css'; // TODO: refactor dropzone to separate component wrapper +const messages = defineMessages({ + text: { + id: 'Type text…', + defaultMessage: 'Type text…', + }, +}); + const DEBUG = false; export const DefaultTextBlockEditor = (props) => { @@ -63,7 +70,7 @@ export const DefaultTextBlockEditor = (props) => { const { textblockExtensions } = slate; const { value } = data; - const [addNewBlockOpened, setAddNewBlockOpened] = React.useState(); + // const [addNewBlockOpened, setAddNewBlockOpened] = React.useState(); const [showDropzone, setShowDropzone] = React.useState(false); const [uploading, setUploading] = React.useState(false); const [newImageId, setNewImageId] = React.useState(null); @@ -124,14 +131,6 @@ export const DefaultTextBlockEditor = (props) => { prevReq.current = loaded; }, [props, loaded, loading, prevLoaded, imageId, newImageId, index]); - // This event handler unregisters itself after its first call. - const handleClickOutside = React.useCallback((e) => { - const blockChooser = document.querySelector('.blocks-chooser'); - document.removeEventListener('mousedown', handleClickOutside, false); - if (doesNodeContainClick(blockChooser, e)) return; - setAddNewBlockOpened(false); - }, []); - const handleUpdate = React.useCallback( (editor) => { // defaultSelection is used for things such as "restoring" the selection @@ -159,7 +158,9 @@ export const DefaultTextBlockEditor = (props) => { instructions = formDescription; } - const placeholder = data.placeholder || formTitle || 'Enter some rich text…'; + const intl = useIntl(); + const placeholder = + data.placeholder || formTitle || intl.formatMessage(messages.text); const schema = TextBlockSchema(data); const disableNewBlocks = data?.disableNewBlocks || detached; @@ -227,36 +228,23 @@ export const DefaultTextBlockEditor = (props) => { ); }} - {selected && !disableNewBlocks && !data.plaintext && ( - - )} - {addNewBlockOpened && ( - { - onMutateBlock(...args); - setAddNewBlockOpened(false); - }} - blocksConfig={blocksConfig} + + {selected && !data.plaintext && !disableNewBlocks && ( + { onSelectBlock(onInsertBlock(id, value)); - setAddNewBlockOpened(false); }} - currentBlock={block} + onMutateBlock={onMutateBlock} allowedBlocks={allowedBlocks} + blocksConfig={blocksConfig} + size="24px" + className="block-add-button" + properties={properties} /> )} +
{instructions ? ( @@ -301,7 +289,9 @@ export const DetachedTextBlockEditor = (props) => { const { value } = data; const schema = TextBlockSchema(data); - const placeholder = data.placeholder || formTitle || 'Enter some rich text…'; + const intl = useIntl(); + const placeholder = + data.placeholder || formTitle || intl.formatMessage(messages.text); let instructions = data?.instructions?.data || data?.instructions; if (!instructions || instructions === '


') { instructions = formDescription; diff --git a/src/blocks/Text/TextBlockEdit.test.js b/src/blocks/Text/TextBlockEdit.test.js index 9b2abaca..d5cdba2c 100644 --- a/src/blocks/Text/TextBlockEdit.test.js +++ b/src/blocks/Text/TextBlockEdit.test.js @@ -8,8 +8,6 @@ import { mockAllIsIntersecting } from 'react-intersection-observer/test-utils'; const mockStore = configureStore(); -// ReactDOM.createPortal = (node) => node; - window.getSelection = () => null; global.__SERVER__ = true; // eslint-disable-line no-underscore-dangle @@ -40,6 +38,23 @@ beforeAll(() => { extensions: [], }, }; + config.blocks.blocksConfig.slate = { + id: 'slate', + title: 'Slate', + group: 'text', + edit: TextBlockEdit, + restricted: false, + mostUsed: false, + blockHasOwnFocusManagement: true, + sidebarTab: 1, + security: { + addPermission: [], + view: [], + }, + blockHasValue: (data) => { + return !!data.plaintext; + }, + }; }); describe('TextBlockEdit', () => { @@ -72,6 +87,8 @@ describe('TextBlockEdit', () => { properties={{}} setSlateBlockSelection={() => {}} data={{ + '@type': 'slate', + plaintext: '', value: [ { type: 'p', diff --git a/src/blocks/Text/__snapshots__/TextBlockEdit.test.js.snap b/src/blocks/Text/__snapshots__/TextBlockEdit.test.js.snap index b5463a99..65e756eb 100644 --- a/src/blocks/Text/__snapshots__/TextBlockEdit.test.js.snap +++ b/src/blocks/Text/__snapshots__/TextBlockEdit.test.js.snap @@ -35,7 +35,7 @@ exports[`TextBlockEdit renders w/o errors 1`] = ` data-slate-placeholder="true" style="position: absolute; pointer-events: none; width: 100%; max-width: 100%; display: block; opacity: 0.333; user-select: none; text-decoration: none;" > - Enter some rich text… + Type text…