diff --git a/CHANGELOG.md b/CHANGELOG.md index ed90e70754..8b7aed4fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,78 @@ +## 17.0.0-alpha.14 (2023-06-23) + +### Feature + +- Added slug-based linked headings in `volto-slate`. @tiberiuichim, @nileshgulia1 [#4287](https://github.com/plone/volto/issues/4287) +- Refactored Anontools components. @Tishasoumya-02 [#4845](https://github.com/plone/volto/issues/4845) + +### Bugfix + +- Update to version 6.0.5 of Plone backend. @davisagli [#4897](https://github.com/plone/volto/issues/4897) + + +## 17.0.0-alpha.13 (2023-06-15) + +### Feature + +- Add and enforce a new config setting, `maxFileUploadSize`. @davisagli [#4868](https://github.com/plone/volto/issues/4868) + +### Bugfix + +- Fix and improve the `addStyling` helper @sneridagh [#4880](https://github.com/plone/volto/issues/4880) + + +## 17.0.0-alpha.12 (2023-06-14) + +### Feature + +- Allow to deselect color in ColorPickerWidget. @ksuess [#4838](https://github.com/plone/volto/issues/4838) +- Configurable Container component from registry for some key route views. @sneridagh [#4871](https://github.com/plone/volto/issues/4871) + +### Bugfix + +- Fix regression in horizontal scroll in contents view, add it back @sneridagh [#4872](https://github.com/plone/volto/issues/4872) + + +## 17.0.0-alpha.11 (2023-06-09) + +### Bugfix + +- Added current page parameter to route in listing and search block pagination - Fix: #3868 @bipoza [#4159](https://github.com/plone/volto/issues/4159) + + +## 17.0.0-alpha.10 (2023-06-09) + +### Feature + +- Search Block: Add support for advanced facets that are only displayed on demand. + [pbauer, razvanMiu, claudiaifrim] [#4783](https://github.com/plone/volto/issues/4783) +- Display PAS validation errors. [tschorr] [#4801](https://github.com/plone/volto/issues/4801) +- Added a CSS identifier to the Slate style menu options. @razvanMiu [#4846](https://github.com/plone/volto/issues/4846) +- Use a Container from the registry in the Form component and fallback to the Semantic UI one. @sneridagh [#4849](https://github.com/plone/volto/issues/4849) +- Update Brazilian Portuguese translations @ericof [#4853](https://github.com/plone/volto/issues/4853) + +### Bugfix + +- Convert header class to function. @gomez [#4767](https://github.com/plone/volto/issues/4767) +- Do not break validation on required number field with value 0 @cekk [#4841](https://github.com/plone/volto/issues/4841) + + +## 17.0.0-alpha.9 (2023-06-01) + +### Bugfix + +- Fix special characters in request urls @pnicolli @mamico @luca-bellenghi @cekk [#4825](https://github.com/plone/volto/issues/4825) +- Fix block is undefined in StyleWrapper helper when building classnames @sneridagh [#4827](https://github.com/plone/volto/issues/4827) +- Fix navigation sections in 404 pages @sneridagh [#4836](https://github.com/plone/volto/issues/4836) + +### Documentation + +- Fix glossary warning due to lack of empty line before a term. @stevepiercy [#4820](https://github.com/plone/volto/issues/4820) + + ## 17.0.0-alpha.8 (2023-05-24) ### Feature @@ -225,6 +297,44 @@ - Use a universal static path for both documentation and volto repos. @stevepiercy [#4376](https://github.com/plone/volto/issues/4376) +## 16.21.1 (2023-06-23) + +### Bugfix + +- Added current page parameter to route in listing and search block pagination - Fix: #3868 @bipoza [#4159](https://github.com/plone/volto/issues/4159) + + +## 16.21.0 (2023-06-16) + +### Feature + +- Display PAS validation errors. [tschorr] [#4801](https://github.com/plone/volto/issues/4801) +- Allow to deselect color in ColorPickerWidget. @ksuess [#4838](https://github.com/plone/volto/issues/4838) +- Added a CSS identifier to the Slate style menu options. @razvanMiu [#4846](https://github.com/plone/volto/issues/4846) +- Use a Container from the registry in the Form component and fallback to the Semantic UI one. @sneridagh [#4849](https://github.com/plone/volto/issues/4849) +- Add and enforce a new config setting, `maxFileUploadSize`. @davisagli [#4868](https://github.com/plone/volto/issues/4868) +- Configurable Container component from registry for some key route views. @sneridagh [#4871](https://github.com/plone/volto/issues/4871) + +### Bugfix + +- Do not break validation on required number field with value 0 @cekk [#4841](https://github.com/plone/volto/issues/4841) +- Fix regression in horizontal scroll in contents view, add it back @sneridagh [#4872](https://github.com/plone/volto/issues/4872) +- Fix and improve the `addStyling` helper @sneridagh [#4880](https://github.com/plone/volto/issues/4880) + + +## 16.20.8 (2023-06-01) + +### Bugfix + +- Fix special characters in request urls @pnicolli @mamico @luca-bellenghi @cekk [#4826](https://github.com/plone/volto/issues/4826) +- Fix block is undefined in StyleWrapper helper when building classnames @sneridagh [#4827](https://github.com/plone/volto/issues/4827) +- Fix navigation sections in 404 pages @sneridagh [#4836](https://github.com/plone/volto/issues/4836) + +### Documentation + +- Fix glossary warning due to lack of empty line before a term. @stevepiercy [#4820](https://github.com/plone/volto/issues/4820) + + ## 16.20.7 (2023-05-24) ### Bugfix @@ -1196,6 +1306,7 @@ See https://6.docs.plone.org/volto/upgrade-guide/index.html for more information - Add support for loading core add-ons from the `packages` folder defined in Volto's `package.json` @sneridagh - Implement the Upgrade Control Panel @ericof - Allow addons to customize modules from the project root, via the `@root` namespace and folder @tiberiuichim +- Updated Spanish translation @macagua ### Bugfix diff --git a/Makefile b/Makefile index 17d412f4aa..a094073869 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ MAKEFLAGS+=--no-builtin-rules # Project settings INSTANCE_PORT=8080 -DOCKER_IMAGE=plone/server-dev:6.0.4 -DOCKER_IMAGE_ACCEPTANCE=plone/server-acceptance:6.0.4 +DOCKER_IMAGE=plone/server-dev:6.0.5 +DOCKER_IMAGE_ACCEPTANCE=plone/server-acceptance:6.0.5 KGS= NODEBIN = ./node_modules/.bin SCRIPTSPACKAGE = ./packages/scripts diff --git a/README.md b/README.md index 7c32093b7f..c86d75746b 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ cd myvoltoproject You can bootstrap a ready Docker Plone container with all the dependencies and ready for Volto use. We recommend to use the Plone docker builds based in `pip` [plone/plone-backend](https://github.com/plone/plone-backend) image: ```shell -docker run -it --rm --name=plone -p 8080:8080 -e SITE=Plone -e PROFILES="plone.volto:default-homepage" plone/plone-backend:6.0.1 +docker run -it --rm --name=plone -p 8080:8080 -e SITE=Plone -e PROFILES="plone.volto:default-homepage" plone/plone-backend:6.0.5 ``` or as an alternative if you have experience with Plone and you have all the @@ -266,7 +266,7 @@ yarn Either using a Docker command: ```shell -docker run -it --rm --name=plone -p 8080:8080 -e SITE=Plone -e PROFILES="plone.volto:default-homepage" plone/plone-backend:6.0.1 +docker run -it --rm --name=plone -p 8080:8080 -e SITE=Plone -e PROFILES="plone.volto:default-homepage" plone/plone-backend:6.0.5 ``` or using the convenience makefile command: diff --git a/api/buildout.cfg b/api/buildout.cfg index ead796cfcb..f3d12ae947 100644 --- a/api/buildout.cfg +++ b/api/buildout.cfg @@ -1,7 +1,7 @@ [buildout] index = https://pypi.org/simple/ extends = - http://dist.plone.org/release/6.0.4/versions.cfg + http://dist.plone.org/release/6.0.5/versions.cfg version-constraints.cfg versions.cfg parts = instance plonesite site-packages test robot-server diff --git a/cypress/support/commands.js b/cypress/support/commands.js index cd2e6f23d4..70bd7683a8 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -849,3 +849,23 @@ Cypress.Commands.add('getTableSlate', (header = false) => { ); return slate; }); + +Cypress.Commands.add('configureListingWith', (contentType) => { + cy.get('.sidebar-container .tabs-wrapper .menu .item') + .contains('Block') + .click(); + cy.get('.querystring-widget .fields').contains('Add criteria').click(); + cy.get( + '.querystring-widget .fields:first-of-type .field:first-of-type .react-select__menu .react-select__option', + ) + .contains('Type') + .click(); + + //insert Page + cy.get('.querystring-widget .fields:first-of-type > .field').click(); + cy.get( + '.querystring-widget .fields:first-of-type > .field .react-select__menu .react-select__option', + ) + .contains(contentType) + .click(); +}); diff --git a/cypress/tests/core/blocks/block-anchors.js b/cypress/tests/core/blocks/block-anchors.js new file mode 100644 index 0000000000..1166b0ce26 --- /dev/null +++ b/cypress/tests/core/blocks/block-anchors.js @@ -0,0 +1,71 @@ +import { slateBeforeEach } from '../../../support/volto-slate'; + +describe('Block Tests: Anchors', () => { + beforeEach(slateBeforeEach); + + it('Add Block: Links', () => { + // Change page title + cy.clearSlateTitle(); + cy.getSlateTitle().type('Slate Heading Anchors'); + cy.getSlate().click(); + + // Add TOC block + cy.get('.ui.basic.icon.button.block-add-button').first().click(); + cy.get(".blocks-chooser .ui.form .field.searchbox input[type='text']").type( + 'table of contents', + ); + cy.get('.button.toc').click(); + + // Save page + cy.get('#toolbar-save').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/my-page'); + cy.get('h1.documentFirstHeading') + .trigger('mouseover', { eventConstructor: 'MouseEvent' }) + .children() + .should('have.length', 1); + }); + + it('Add Block: add content to TOC', () => { + // Change page title + cy.clearSlateTitle(); + cy.getSlateTitle().type('Slate Heading Anchors'); + cy.getSlate().click(); + + // Add TOC block + cy.get('.ui.basic.icon.button.block-add-button').first().click(); + cy.get(".blocks-chooser .ui.form .field.searchbox input[type='text']").type( + 'table of contents', + ); + cy.get('.button.toc').click(); + + // Add headings + cy.get('.ui.drag.block.inner.slate').click().type('Title 1').click(); + cy.get('.ui.drag.block.inner.slate span span span').setSelection('Title 1'); + cy.get('.slate-inline-toolbar .button-wrapper a[title="Title"]').click({ + force: true, + }); + cy.get('.ui.drag.block.inner.slate').click().type('{enter}'); + + cy.get('.ui.drag.block.inner.slate').eq(1).click().type('Title 2').click(); + cy.get('.ui.drag.block.inner.slate span span span') + .eq(1) + .setSelection('Title 2'); + cy.get('.slate-inline-toolbar .button-wrapper a[title="Title"]').click({ + force: true, + }); + cy.get('.ui.drag.block.inner.slate').eq(1).click().type('{enter}'); + + // Save page + cy.get('#toolbar-save').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/my-page'); + + // Check if the page contains the TOC and scrolls to each entry on click + cy.contains('Slate Heading Anchors'); + cy.get('h2[id="title-1"]').contains('Title 1'); + cy.get('h2[id="title-2"]').contains('Title 2'); + cy.get('a[href="#title-1"]').click(); + cy.get('h2[id="title-1"]').scrollIntoView().should('be.visible'); + cy.get('a[href="#title-2"]').click(); + cy.get('h2[id="title-2"]').scrollIntoView().should('be.visible'); + }); +}); diff --git a/cypress/tests/core/blocks/blocks-listing.js b/cypress/tests/core/blocks/blocks-listing.js index bea65dac47..288909dc79 100644 --- a/cypress/tests/core/blocks/blocks-listing.js +++ b/cypress/tests/core/blocks/blocks-listing.js @@ -21,6 +21,42 @@ describe('Listing Block Tests', () => { cy.waitForResourceToLoad(''); }); + it('Add Listing block with no results', () => { + cy.intercept('PATCH', '/**/my-page').as('save'); + cy.intercept('GET', '/**/my-page').as('content'); + cy.intercept('GET', '/**/@types/Document').as('schema'); + + cy.createContent({ + contentType: 'Document', + contentId: 'my-page-test', + contentTitle: 'My Page Test', + path: 'my-page', + }); + + cy.navigate('/my-page'); + cy.wait('@content'); + + cy.navigate('/my-page/edit'); + cy.wait('@schema'); + + cy.clearSlateTitle().type('My title'); + + //add listing block + cy.addNewBlock('listing'); + + cy.configureListingWith('News Item'); + + //save + cy.get('#toolbar-save').click(); + cy.wait('@save'); + cy.wait('@content'); + + //test after save + cy.get('#page-document .block.listing.default .emptyListing').contains( + 'No results found.', + ); + }); + it('Add Listing block', () => { cy.intercept('PATCH', '/**/my-page').as('save'); cy.intercept('GET', '/**/my-page').as('content'); @@ -841,6 +877,354 @@ describe('Listing Block Tests', () => { cy.get('.listing-item h4').first().contains('My Folder 3'); }); + it('Navigates in listing block pagination and url clears on logo click', () => { + cy.intercept('PATCH', '/**/my-page').as('save'); + cy.intercept('GET', '/**/my-page').as('content'); + cy.intercept('GET', '/**/@types/Document').as('schema'); + + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder', + contentTitle: 'My Folder', + path: 'my-page', + }); + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder2', + contentTitle: 'My Folder 2', + path: 'my-page', + }); + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder3', + contentTitle: 'My Folder 3', + path: 'my-page', + }); + + cy.navigate('/my-page'); + cy.wait('@content'); + + cy.navigate('/my-page/edit'); + cy.wait('@schema'); + + cy.clearSlateTitle().type('Listing block - navigate to second page'); + + //add listing block + cy.addNewBlock('listing'); + + //verify before save + cy.get(`.block.listing .listing-body:first-of-type`).contains('My Folder'); + + cy.get('.sidebar-container .tabs-wrapper .menu .item') + .contains('Block') + .click(); + cy.get('.querystring-widget .fields').contains('Add criteria').click(); + cy.get( + '.querystring-widget .fields:first-of-type .field:first-of-type .react-select__menu .react-select__option', + ) + .contains('Type') + .click(); + + //insert Page + cy.get('.querystring-widget .fields:first-of-type > .field').click(); + cy.get( + '.querystring-widget .fields:first-of-type > .field .react-select__menu .react-select__option', + ) + .contains('Page') + .click(); + + cy.get('#field-limit-3-querystring').click().type('2'); + + cy.get('#field-limit-3-querystring').click().clear().type('0'); + cy.get('#field-b_size-4-querystring').click().type('2'); + cy.get('.ui.pagination.menu a[value="2"]').first().click(); + cy.get('#toolbar-save').click(); + cy.wait('@save'); + cy.wait('@content'); + //test second pagination click + cy.get('.ui.pagination.menu a[value="2"]').first().click({ force: true }); + cy.url().should('include', '?page=2'); + //on logo click go to home page and remove ?page=2 from path + cy.get('.logo').first().click(); + cy.url().should('not.include', '?page=2'); + }); + + // reload url when ?page=2 + it('Reload path when listing page = 2', () => { + cy.intercept('PATCH', '/**/my-page').as('save'); + cy.intercept('GET', '/**/my-page').as('content'); + cy.intercept('GET', '/**/@types/Document').as('schema'); + + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder', + contentTitle: 'My Folder', + path: 'my-page', + }); + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder2', + contentTitle: 'My Folder 2', + path: 'my-page', + }); + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder3', + contentTitle: 'My Folder 3', + path: 'my-page', + }); + + cy.navigate('/my-page'); + cy.wait('@content'); + + cy.navigate('/my-page/edit'); + cy.wait('@schema'); + + cy.clearSlateTitle().type( + 'Listing block - navigate to second page and reload path', + ); + + //add listing block + cy.addNewBlock('listing'); + + //verify before save + cy.get(`.block.listing .listing-body:first-of-type`).contains('My Folder'); + + cy.get('.sidebar-container .tabs-wrapper .menu .item') + .contains('Block') + .click(); + cy.get('.querystring-widget .fields').contains('Add criteria').click(); + cy.get( + '.querystring-widget .fields:first-of-type .field:first-of-type .react-select__menu .react-select__option', + ) + .contains('Type') + .click(); + + //insert Page + cy.get('.querystring-widget .fields:first-of-type > .field').click(); + cy.get( + '.querystring-widget .fields:first-of-type > .field .react-select__menu .react-select__option', + ) + .contains('Page') + .click(); + + cy.get('#field-limit-3-querystring').click().type('2'); + + //save + cy.get('#toolbar-save').click(); + cy.wait('@save'); + cy.wait('@content'); + + //test after save + cy.get('#page-document .listing-item:first-of-type a').should( + 'have.attr', + 'href', + '/my-page/my-folder', + ); + cy.get('.listing-item').should(($els) => { + expect($els).to.have.length(2); + }); + + cy.navigate('/my-page/edit'); + cy.wait('@schema'); + + cy.get('.block-editor-listing').click(); + cy.get('.sidebar-container .tabs-wrapper .menu .item') + .contains('Block') + .click(); + + cy.get('#field-limit-3-querystring').click().clear().type('0'); + cy.get('#field-b_size-4-querystring').click().type('2'); + cy.get('.ui.pagination.menu a[value="2"]').first().click(); + + cy.get('.listing-item h4').first().contains('My Folder 3'); + cy.get('#toolbar-save').click(); + cy.wait('@save'); + cy.wait('@content'); + //test second pagination click + cy.get('.ui.pagination.menu a[value="2"]').first().click(); + + //test f5 + cy.reload(); + cy.url().should('include', '?page=2'); + }); + + // different page in two listings on the same page + it('Navigate to different pages on two different listings', () => { + cy.intercept('PATCH', '/**/my-page').as('save'); + cy.intercept('GET', '/**/my-page').as('content'); + cy.intercept('GET', '/**/@types/Document').as('schema'); + + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder', + contentTitle: 'My Folder', + path: 'my-page', + }); + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder2', + contentTitle: 'My Folder 2', + path: 'my-page', + }); + cy.createContent({ + contentType: 'Document', + contentId: 'my-folder3', + contentTitle: 'My Folder 3', + path: 'my-page', + }); + + cy.navigate('/my-page'); + cy.wait('@content'); + + cy.navigate('/my-page/edit'); + cy.wait('@schema'); + + cy.clearSlateTitle().type( + 'Listing block - navigate to different pages on two different listings', + ); + + //add listing block + cy.addNewBlock('listing'); + + //verify before save + cy.get(`.block.listing .listing-body:first-of-type`).contains('My Folder'); + + cy.get('.sidebar-container .tabs-wrapper .menu .item') + .contains('Block') + .click(); + cy.get('.querystring-widget .fields').contains('Add criteria').click(); + cy.get( + '.querystring-widget .fields:first-of-type .field:first-of-type .react-select__menu .react-select__option', + ) + .contains('Type') + .click(); + + //insert Page + cy.get('.querystring-widget .fields:first-of-type > .field').click(); + cy.get( + '.querystring-widget .fields:first-of-type > .field .react-select__menu .react-select__option', + ) + .contains('Page') + .click(); + + cy.get('#field-limit-3-querystring').click().type('0'); + cy.get('#field-b_size-4-querystring').click().type('2'); + + cy.addNewBlock('listing'); + + //verify before save + cy.get(`.block.listing .listing-body:first-of-type`).contains('My Folder'); + + cy.get('.sidebar-container .tabs-wrapper .menu .item') + .contains('Block') + .click(); + cy.get('.querystring-widget .fields').contains('Add criteria').click(); + cy.get( + '.querystring-widget .fields:first-of-type .field:first-of-type .react-select__menu .react-select__option', + ) + .contains('Type') + .click(); + + //insert Page + cy.get('.querystring-widget .fields:first-of-type > .field').click(); + cy.get( + '.querystring-widget .fields:first-of-type > .field .react-select__menu .react-select__option', + ) + .contains('Page') + .click(); + + cy.get('#field-limit-3-querystring').click().type('0'); + cy.get('#field-b_size-4-querystring').click().type('1'); + cy.get('#toolbar-save').click(); + cy.wait('@save'); + cy.wait('@content'); + + // const listing1 = cy.get('.ui.pagination.menu').first(); + // cy.log('listing1', listing1); + //test second pagination click + cy.get('.ui.pagination.menu a[value="2"]').first().click(); + //test f5 + cy.reload(); + cy.url().should('include', '=2'); + // const listing2 = cy.get('.ui.pagination.menu').last(); + //test third pagination click on second listing + cy.get('.ui.pagination.menu a[value="3"]').first().click(); + //test f5 + cy.reload(); + cy.url().should('include', '=2'); + cy.url().should('include', '=3'); + //on logo click go to home page and remove ?page=2 from path + cy.get('.logo').first().click(); + cy.url().should('not.include', '=2'); + cy.url().should('not.include', '=3'); + //test back button + cy.navigate('/my-page'); + cy.wait('@content'); + cy.get('.ui.pagination.menu a[value="2"]').first().click({ force: true }); + cy.get('.ui.pagination.menu a[value="3"]').first().click({ force: true }); + cy.go(-1); + cy.url().should('not.include', '=3'); + cy.go(-1); + cy.url().should('not.include', '=2'); + cy.url().should('not.include', '=3'); + }); + + it('Add Listing block with no results, navigate to home, add a News Item, go to the listing', () => { + cy.intercept('PATCH', '/**/my-page').as('save'); + cy.intercept('GET', '/**/my-page').as('content'); + cy.intercept('GET', '/**/@types/Document').as('schema'); + + cy.createContent({ + contentType: 'Document', + contentId: 'my-page-test', + contentTitle: 'My Page Test', + path: 'my-page', + }); + + cy.navigate('/my-page'); + cy.wait('@content'); + + cy.navigate('/my-page/edit'); + cy.wait('@schema'); + + cy.clearSlateTitle().type('My title'); + + //add listing block + cy.addNewBlock('listing'); + + cy.configureListingWith('News Item'); + + //save + cy.get('#toolbar-save').click(); + cy.wait('@save'); + cy.wait('@content'); + + //test after save + cy.get('#page-document .block.listing.default .emptyListing').contains( + 'No results found.', + ); + + cy.get('.logo').first().click(); + + cy.createContent({ + contentType: 'News Item', + contentId: 'my-news-item-test', + contentTitle: 'My News Item', + path: 'my-page', + }); + cy.navigate('/my-page'); + + cy.get('#page-document .listing-body:first-of-type').contains( + 'My News Item', + ); + cy.get('#page-document .listing-item:first-of-type a').should( + 'have.attr', + 'href', + '/my-page/my-news-item-test', + ); + }); + // it('Listing block - Test Criteria: Location Navigation', () => { // /*not implemented because Navigation ui is not yet developed in Listing Block sidebar*/ // }); diff --git a/cypress/tests/core/guillotina/blocks-text.js b/cypress/tests/core/guillotina/blocks-text.js index 8ca7b815b8..334c3b3c32 100644 --- a/cypress/tests/core/guillotina/blocks-text.js +++ b/cypress/tests/core/guillotina/blocks-text.js @@ -53,7 +53,7 @@ describe('Text Block Tests', () => { // then the page view should contain a link cy.contains('Colorless green ideas sleep furiously.'); - cy.get('#page-document a') + cy.get('#page-document p a') .should('have.attr', 'href') .and('include', 'https://google.com'); }); @@ -81,7 +81,7 @@ describe('Text Block Tests', () => { // then the page view should contain a mailto link cy.contains('Colorless green ideas sleep furiously.'); - cy.get('#page-document a') + cy.get('#page-document p a') .should('have.attr', 'href') .and('include', 'mailto:hello@example.com'); }); diff --git a/cypress/tests/core/volto-slate/05-block-slate-format-basics.js b/cypress/tests/core/volto-slate/05-block-slate-format-basics.js index 413d43a21b..3d32b822e4 100644 --- a/cypress/tests/core/volto-slate/05-block-slate-format-basics.js +++ b/cypress/tests/core/volto-slate/05-block-slate-format-basics.js @@ -135,7 +135,7 @@ describe('Block Tests: Basic text format', () => { cy.toolbarSave(); // then the page view should contain our changes - cy.get('[id="page-document"] h2').children().should('have.length', 0); + cy.get('[id="page-document"] h2').children().should('have.length', 1); cy.get('[id="page-document"] h2').contains('Colorless'); }); @@ -177,7 +177,7 @@ describe('Block Tests: Basic text format', () => { cy.toolbarSave(); // then the page view should contain our changes - cy.get('[id="page-document"] h3').children().should('have.length', 0); + cy.get('[id="page-document"] h3').children().should('have.length', 1); cy.get('[id="page-document"] h3').contains('Colorless'); }); diff --git a/cypress/tests/guillotina/blocks-text.js b/cypress/tests/guillotina/blocks-text.js index 8ca7b815b8..334c3b3c32 100644 --- a/cypress/tests/guillotina/blocks-text.js +++ b/cypress/tests/guillotina/blocks-text.js @@ -53,7 +53,7 @@ describe('Text Block Tests', () => { // then the page view should contain a link cy.contains('Colorless green ideas sleep furiously.'); - cy.get('#page-document a') + cy.get('#page-document p a') .should('have.attr', 'href') .and('include', 'https://google.com'); }); @@ -81,7 +81,7 @@ describe('Text Block Tests', () => { // then the page view should contain a mailto link cy.contains('Colorless green ideas sleep furiously.'); - cy.get('#page-document a') + cy.get('#page-document p a') .should('have.attr', 'href') .and('include', 'mailto:hello@example.com'); }); diff --git a/docker-compose.yml b/docker-compose.yml index 82a49830b7..ba7948726a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.3' services: backend: - image: plone/plone-backend:6.0.1 + image: plone/plone-backend:6.0.5 # Plone 5.2 series can be used too # image: plone/plone-backend:5.2.10 ports: diff --git a/docs/source/configuration/settings-reference.md b/docs/source/configuration/settings-reference.md index 65d3d3cca1..c201810b22 100644 --- a/docs/source/configuration/settings-reference.md +++ b/docs/source/configuration/settings-reference.md @@ -83,6 +83,10 @@ maxResponseSize You can edit this limit in the `settings` object setting a new value in bytes (for example, to set 500 mb you need to write 5000000000). +maxFileUploadSize + The maximum allowed size of file uploads (in bytes). + Default: `null` (no limit enforced by Volto). + initialReducersBlacklist The initial state passed from server to browser needs to be minimal in order to optimize the resultant html generated. This state gets stored in `window.__data` and received in client. @@ -226,7 +230,6 @@ workflowMapping It's meant to be extended with your own workflows/transitions. It is recommended to assign the same color to the transition as the destination state, so the user can have the visual hint to which state are they transitioning to. - styleClassNameConverters An object with functions used by the style wrapper helpers to convert style data to actual class names. You can customize the generated classname by @@ -374,6 +377,7 @@ additionalToolbarComponents }} ``` + blockSettingsTabFieldsetsInitialStateOpen A Boolean, `true` by default. The fieldsets in the blocks settings tab start by default as non-collapsed (opened), you can decide to have them collapsed (closed) by default setting this to `false`. diff --git a/docs/source/configuration/volto-slate/configuration-settings.md b/docs/source/configuration/volto-slate/configuration-settings.md index a6da06c3b2..97276b804f 100644 --- a/docs/source/configuration/volto-slate/configuration-settings.md +++ b/docs/source/configuration/volto-slate/configuration-settings.md @@ -239,6 +239,19 @@ They are not persisted in the final value, so they are useful, for example, to h slate.runtimeDecorators = [([node, path], ranges) => ranges]; ``` +(editor-configuration-slate-useLinkedHeadings-label)= + +## `slate.useLinkedHeadings` + +The setting `slate.useLinkedHeadings` controls whether `volto-slate` creates anchors for headings, such as `h1` and `h2`, in the editor. + +The default setting is `true`. + +You can opt out of this feature by setting its value to `false`. + +```js +slate.useLinkedHeadings = false +``` (editor-configuration-blocks-initialBlocksFocus-label)= diff --git a/docs/source/user-manual/blocks.md b/docs/source/user-manual/blocks.md index 9e4c744d4d..7c8e42b3d5 100644 --- a/docs/source/user-manual/blocks.md +++ b/docs/source/user-manual/blocks.md @@ -408,6 +408,9 @@ Hide facet? : Toggle to show or hide the facet. Hidden facets will still filter the results if proper parameters are passed in URLs +Advanced facet? +: Select to set the facet as advanced. + Advanced facets are initially hidden and displayed on demand. #### Controls diff --git a/locales/ca/LC_MESSAGES/volto.po b/locales/ca/LC_MESSAGES/volto.po index a02dd0dc4c..db73f21323 100644 --- a/locales/ca/LC_MESSAGES/volto.po +++ b/locales/ca/LC_MESSAGES/volto.po @@ -277,6 +277,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1262,9 +1272,9 @@ msgstr "" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Introduïu la vostra nova contrasenya. Mínim 5 caràcters." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Introduïu la vostra nova contrasenya. Mínim 8 caràcters." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1582,6 +1592,11 @@ msgstr "Amaga les respostes" msgid "Hide facet?" msgstr "Amagar la faceta?" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1878,11 +1893,21 @@ msgstr "Imatge Principal" msgid "Left" msgstr "A l'esquerra" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Enllaç" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2087,6 +2112,11 @@ msgstr "Mensual" msgid "More" msgstr "Més" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3096,6 +3126,11 @@ msgstr "Mostrar tots" msgid "Show Replies" msgstr "Mostra les respostes" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4273,6 +4308,11 @@ msgstr "quan" msgid "event_where" msgstr "On?" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/de/LC_MESSAGES/volto.po b/locales/de/LC_MESSAGES/volto.po index 16f7066fe3..4d37f47225 100644 --- a/locales/de/LC_MESSAGES/volto.po +++ b/locales/de/LC_MESSAGES/volto.po @@ -274,6 +274,16 @@ msgstr "Erweiterung erfolgreich deaktiviert" msgid "Addon upgraded succesfuly" msgstr "Erweiterung erfolgreich aktualisiert" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1259,9 +1269,9 @@ msgstr "Geben Sie Ihre E-Mail zur Verifikation ein." #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Geben Sie ihr neues Passwort ein. Mindestens 5 Zeichen." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Geben Sie ihr neues Passwort ein. Mindestens 8 Zeichen." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1579,6 +1589,11 @@ msgstr "Antworten ausblenden" msgid "Hide facet?" msgstr "Facette verstecken" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1875,11 +1890,21 @@ msgstr "Lead-Bild" msgid "Left" msgstr "Links" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Link" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2084,6 +2109,11 @@ msgstr "Monatlich" msgid "More" msgstr "Mehr" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3093,6 +3123,11 @@ msgstr "Alle anzeigen" msgid "Show Replies" msgstr "Antworten anzeigen" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4270,10 +4305,15 @@ msgstr "Datum" msgid "event_where" msgstr "Ort" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "Dateien, die größer sind als {limit}, dürfen nicht hochgeladen werden." + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" -msgstr "TODO Translation. IntIds neu generieren und Relationen neu katalogisieren" +msgstr "IntIds neu generieren und Relationen neu katalogisieren" #: components/manage/Blocks/Teaser/schema # defaultMessage: Head title diff --git a/locales/en/LC_MESSAGES/volto.po b/locales/en/LC_MESSAGES/volto.po index a24059b653..7783ecbea7 100644 --- a/locales/en/LC_MESSAGES/volto.po +++ b/locales/en/LC_MESSAGES/volto.po @@ -268,6 +268,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1253,8 +1263,8 @@ msgstr "" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." msgstr "" #: components/theme/PasswordReset/PasswordReset @@ -1573,6 +1583,11 @@ msgstr "" msgid "Hide facet?" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1869,11 +1884,21 @@ msgstr "" msgid "Left" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2078,6 +2103,11 @@ msgstr "" msgid "More" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3087,6 +3117,11 @@ msgstr "" msgid "Show Replies" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4264,6 +4299,11 @@ msgstr "" msgid "event_where" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/es/LC_MESSAGES/volto.po b/locales/es/LC_MESSAGES/volto.po index 46d8d38ef5..e532261061 100644 --- a/locales/es/LC_MESSAGES/volto.po +++ b/locales/es/LC_MESSAGES/volto.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Plone\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-03 03:20-0400\n" -"PO-Revision-Date: 2022-12-02 11:45+0100\n" +"PO-Revision-Date: 2023-06-20 14:02-0400\n" "Last-Translator: Leonardo J. Caballero G. \n" "Language: es\n" "Language-Team: ES \n" @@ -15,7 +15,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" -"X-Generator: Poedit 2.3\n" +"X-Generator: Poedit 3.3.1\n" "Language-Code: es\n" "Language-Name: Español\n" "Preferred-Encodings: utf-8\n" @@ -279,6 +279,16 @@ msgstr "Complemento desinstalado con éxito" msgid "Addon upgraded succesfuly" msgstr "Complemento actualizado con éxito" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "¿Faceta avanzada?" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "Las facetas avanzadas se ocultan inicialmente y se muestran cuando se solicitan" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -469,7 +479,7 @@ msgstr "Barra de ruta" #: components/manage/Controlpanels/Relations/BrokenRelations # defaultMessage: Broken relations msgid "Broken relations" -msgstr "" +msgstr "Relaciones rotas" #: components/manage/Blocks/HeroImageLeft/Edit #: components/manage/Contents/ContentsUploadModal @@ -792,7 +802,7 @@ msgstr "Información del copyright o otros derechos en este elemento." #: helpers/MessageLabels/MessageLabels # defaultMessage: Create or delete relations to target msgid "Create or delete relations to target" -msgstr "" +msgstr "Crear o eliminar relaciones con el destino" #: components/manage/Toolbar/More # defaultMessage: Create working copy @@ -1264,9 +1274,9 @@ msgstr "Introduzca su correo electrónico para verificar." #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Introduzca su nueva contraseña. Mínimo 5 caracteres." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Introduzca su nueva contraseña. Mínimo 8 caracteres." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1416,7 +1426,7 @@ msgstr "Nombre del archivo" #: helpers/MessageLabels/MessageLabels # defaultMessage: Filter msgid "Filter" -msgstr "" +msgstr "Filtrar" #: components/manage/Controlpanels/Rules/Rules # defaultMessage: Filter Rules: @@ -1446,7 +1456,7 @@ msgstr "Primero" #: helpers/MessageLabels/MessageLabels # defaultMessage: Fix relations msgid "Fix relations" -msgstr "" +msgstr "Corregir relaciones" #: components/manage/Blocks/Table/Edit # defaultMessage: Fixed width columns @@ -1584,6 +1594,11 @@ msgstr "Ocultar respuestas" msgid "Hide facet?" msgstr "¿Ocultar la faceta?" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "Ocultar filtros" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1655,7 +1670,7 @@ msgstr "Galería de imágenes" #: components/manage/Blocks/Teaser/schema # defaultMessage: Image override msgid "Image override" -msgstr "" +msgstr "Reemplazar imagen" #: components/manage/Blocks/Image/schema # defaultMessage: Image size @@ -1718,7 +1733,7 @@ msgstr "Insertar fila antes" #: helpers/MessageLabels/MessageLabels # defaultMessage: Inspect relations msgid "Inspect relations" -msgstr "" +msgstr "Inspeccionar relaciones" #: components/manage/Controlpanels/AddonsControlpanel # defaultMessage: Install @@ -1764,7 +1779,7 @@ msgstr "Intervalo anual" #: components/theme/View/RenderBlocks # defaultMessage: Invalid block - Will be removed on saving msgid "Invalid Block" -msgstr "Bloque no válido" +msgstr "Bloque no válido: se eliminará al guardar" #: components/manage/Widgets/QuerystringWidget # defaultMessage: Item batch size @@ -1880,11 +1895,21 @@ msgstr "Imagen principal" msgid "Left" msgstr "Izquierda" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "Menos filtros" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Enlace" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2010,7 +2035,7 @@ msgstr "¿Añadidos de forma manual o automática?" #: helpers/MessageLabels/MessageLabels # defaultMessage: Many relations found. Please search. msgid "Many relations found. Please search." -msgstr "" +msgstr "Muchas relaciones encontradas. Por favor, busque." #: components/manage/Blocks/Maps/MapsSidebar #: components/manage/Blocks/Maps/schema @@ -2089,6 +2114,11 @@ msgstr "Mensualmente" msgid "More" msgstr "Más" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "Más filtros" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -2206,7 +2236,7 @@ msgstr "No se han encontrado complementos" #: components/manage/Controlpanels/Relations/RelationsMatrix # defaultMessage: No broken relations found. msgid "No broken relations found." -msgstr "" +msgstr "No se encontraron relaciones rotas." #: components/theme/RequestTimeout/RequestTimeout # defaultMessage: There is no connection to the server, due to a timeout o no network connection. @@ -2264,7 +2294,7 @@ msgstr "No hay opciones" #: helpers/MessageLabels/MessageLabels # defaultMessage: No relation found msgid "No relation found" -msgstr "" +msgstr "No se encontró relación" #: components/manage/BlockChooser/BlockChooser #: components/theme/Search/Search @@ -2449,7 +2479,7 @@ msgstr "Las personas responsables de la creación del contenido de este elemento #: components/manage/Blocks/Teaser/DefaultBody # defaultMessage: Please choose an existing content as source for this element msgid "Please choose an existing content as source for this element" -msgstr "" +msgstr "Elija un contenido existente como origen para este elemento" #: components/manage/Controlpanels/Controlpanels # defaultMessage: Please continue with the upgrade. @@ -2489,7 +2519,7 @@ msgstr "Actualice plone.restapi a la versión 8.24.0 o superior." #: components/manage/Controlpanels/Relations/Relations # defaultMessage: Please upgrade to plone.restapi >= 8.35.3. msgid "Please upgrade to plone.restapi >= 8.35.3." -msgstr "" +msgstr "Por favor, actualice a plone.restapi >= 8.35.3." #: components/theme/Footer/Footer # defaultMessage: Plone Foundation @@ -2588,7 +2618,7 @@ msgstr "Leer Más..." #: components/manage/Controlpanels/Relations/RelationsListing # defaultMessage: Read only for this type of relation. msgid "Read only for this type of relation." -msgstr "" +msgstr "Solo lectura para este tipo de relación." #: components/manage/Contents/Contents # defaultMessage: Rearrange items by… @@ -2636,24 +2666,24 @@ msgstr "Formulario de registro" #: helpers/MessageLabels/MessageLabels # defaultMessage: Relation msgid "Relation name" -msgstr "" +msgstr "Relación" #: components/manage/Controlpanels/Controlpanels #: components/manage/Controlpanels/Relations/Relations #: helpers/MessageLabels/MessageLabels # defaultMessage: Relations msgid "Relations" -msgstr "" +msgstr "Relaciones" #: components/manage/Controlpanels/Relations/RelationsListing # defaultMessage: Relations are editable with plone.api >= 2.0.3. msgid "Relations are editable with plone.api >= 2.0.3." -msgstr "" +msgstr "Las relaciones son editables con plone.api >= 2.0.3." #: helpers/MessageLabels/MessageLabels # defaultMessage: Relations updated msgid "Relations updated" -msgstr "" +msgstr "Relaciones actualizadas" #: components/theme/Search/Search # defaultMessage: Relevance @@ -2757,7 +2787,7 @@ msgstr "Limpiar el título del término" #: components/manage/Blocks/Teaser/Data # defaultMessage: Reset the block msgid "Reset the block" -msgstr "" +msgstr "Restablecer el bloque" #: components/manage/Widgets/QuerystringWidget # defaultMessage: Results limit @@ -2866,7 +2896,7 @@ msgstr "Guardado" #: components/manage/Contents/ContentsItem # defaultMessage: Scheduled msgid "Scheduled" -msgstr "" +msgstr "Programado" #: components/manage/Controlpanels/ContentTypesActions # defaultMessage: Schema @@ -2944,12 +2974,12 @@ msgstr "Resultados de búsqueda para {term}" #: helpers/MessageLabels/MessageLabels # defaultMessage: Search sources by title or path msgid "Search sources by title or path" -msgstr "" +msgstr "Buscar orígenes por título o ruta" #: helpers/MessageLabels/MessageLabels # defaultMessage: Search targets by title or path msgid "Search targets by title or path" -msgstr "" +msgstr "Buscar destinos por título o ruta" #: helpers/MessageLabels/MessageLabels # defaultMessage: Search users… @@ -2992,7 +3022,7 @@ msgstr "Seleccionar columnas a mostrar" #: helpers/MessageLabels/MessageLabels # defaultMessage: Select relation msgid "Select relation" -msgstr "" +msgstr "Seleccionar relación" #: components/manage/Contents/ContentsWorkflowModal # defaultMessage: Select the transition to be used for modifying the items state. @@ -3002,7 +3032,7 @@ msgstr "Seleccione la transición a ser efectuada al cambiar el estado del conte #: helpers/MessageLabels/MessageLabels # defaultMessage: Selected msgid "Selected" -msgstr "" +msgstr "Seleccionado" #: components/manage/Widgets/RecurrenceWidget/Occurences # defaultMessage: Selected dates @@ -3098,6 +3128,11 @@ msgstr "Mostrar todos" msgid "Show Replies" msgstr "Mostrar respuestas" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "Mostrar filtros" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -3111,12 +3146,12 @@ msgstr "Mostrar elemento" #: components/manage/Controlpanels/Relations/RelationsMatrix # defaultMessage: Show potential sources. Not only objects that are source of some relation. msgid "Show potential sources. Not only objects that are source of some relation." -msgstr "" +msgstr "Mostrar orígenes potenciales. No solo objetos que son orígenes de alguna relación." #: components/manage/Controlpanels/Relations/RelationsMatrix # defaultMessage: Show potential targets. Not only objects that are target of some relation. msgid "Show potential targets. Not only objects that are target of some relation." -msgstr "" +msgstr "Mostrar destinos potenciales. No solo objetos que son destino de alguna relación." #: components/manage/Blocks/Search/schema # defaultMessage: Show search button? @@ -3188,7 +3223,7 @@ msgstr "Pequeño" #: components/manage/Controlpanels/Relations/Relations # defaultMessage: Some relations are broken. Please fix. msgid "Some relations are broken. Please fix." -msgstr "" +msgstr "Algunas relaciones están rotas. Por favor, arréglelas." #: error # defaultMessage: Sorry, something went wrong with your request @@ -3401,7 +3436,7 @@ msgstr "El camino de destino debe comenzar con /." #: components/manage/Blocks/Teaser/schema # defaultMessage: Teaser msgid "Teaser" -msgstr "" +msgstr "Destacado" #: components/manage/Widgets/SchemaWidget # defaultMessage: Text @@ -3597,7 +3632,7 @@ msgstr "Comentarios totales" #: components/manage/Contents/Contents # defaultMessage: Total items to be deleted: msgid "Total items to be deleted:" -msgstr "" +msgstr "Total de elementos a eliminar:" #: components/manage/Controlpanels/DatabaseInformation # defaultMessage: Total number of objects in each cache @@ -4122,7 +4157,7 @@ msgstr "Ha sido salido del sitio." #: components/manage/Controlpanels/Relations/Relations # defaultMessage: You have not the required permission for this control panel. msgid "You have not the required permission for this control panel." -msgstr "" +msgstr "No tiene el permiso requerido para este panel de control." #: components/theme/PasswordReset/RequestPasswordReset # defaultMessage: Your email is required for reset your password. @@ -4275,15 +4310,20 @@ msgstr "Cuándo" msgid "event_where" msgstr "Dónde" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "Este sitio web no acepta archivos de más de {limit}" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" -msgstr "" +msgstr "vaciar intIds y reconstruir relaciones" #: components/manage/Blocks/Teaser/schema # defaultMessage: Head title msgid "head_title" -msgstr "" +msgstr "Encabezado" #: components/theme/PasswordReset/RequestPasswordReset # defaultMessage: Password reset confirmation sent @@ -4384,7 +4424,7 @@ msgstr "Más usado" #: components/manage/Controlpanels/Relations/RelationsListing # defaultMessage: Found {sources} sources and {targets} targets. Narrow down to {max}! msgid "narrowDownRelations" -msgstr "" +msgstr "Se encontraron {sources} orígenes y {targets} destinos. ¡Reduzca a {max}!" #: components/manage/Blocks/Search/components/DateRangeFacetFilterListEntry #: components/manage/Blocks/Search/components/ToggleFacetFilterListEntry @@ -4442,7 +4482,7 @@ msgstr "Seleccione..." #: helpers/MessageLabels/MessageLabels # defaultMessage: rebuild relations msgid "rebuild relations" -msgstr "" +msgstr "reconstruir relaciones" #: components/theme/Search/Search # defaultMessage: results @@ -4647,7 +4687,7 @@ msgstr "Ordenar" #: helpers/MessageLabels/MessageLabels # defaultMessage: sources path msgid "sources path" -msgstr "" +msgstr "ruta de origen" #: config/Blocks # defaultMessage: Table @@ -4657,7 +4697,7 @@ msgstr "Tabla" #: helpers/MessageLabels/MessageLabels # defaultMessage: target path msgid "target path" -msgstr "" +msgstr "ruta de destino" #: config/Blocks # defaultMessage: Text diff --git a/locales/eu/LC_MESSAGES/volto.po b/locales/eu/LC_MESSAGES/volto.po index 931b0ccfcc..85aa21e868 100644 --- a/locales/eu/LC_MESSAGES/volto.po +++ b/locales/eu/LC_MESSAGES/volto.po @@ -275,6 +275,16 @@ msgstr "Produktu gehigarria ondo kendu da" msgid "Addon upgraded succesfuly" msgstr "Produktu gehigarria ondo eguneratu da" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1260,9 +1270,9 @@ msgstr "Idatzi zure eposta helbidea egiaztatu dezagun." #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Idatzi zure pasahitz berria. Gutxienez 5 karaktere." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Idatzi zure pasahitz berria. Gutxienez 8 karaktere." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1580,6 +1590,11 @@ msgstr "Ezkutatu erantzunak" msgid "Hide facet?" msgstr "Fazeta ezkutatu?" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1876,11 +1891,21 @@ msgstr "Irudia" msgid "Left" msgstr "Ezkerrean" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Esteka" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2085,6 +2110,11 @@ msgstr "Hilero" msgid "More" msgstr "Gehiago" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3094,6 +3124,11 @@ msgstr "Erakutsi guztiak" msgid "Show Replies" msgstr "Erakutsi erantzunak" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4271,6 +4306,11 @@ msgstr "Noiz" msgid "event_where" msgstr "Non" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/fi/LC_MESSAGES/volto.po b/locales/fi/LC_MESSAGES/volto.po index 814af6ebdd..e3d3b2cc3f 100644 --- a/locales/fi/LC_MESSAGES/volto.po +++ b/locales/fi/LC_MESSAGES/volto.po @@ -279,6 +279,16 @@ msgstr "Laajennos poistettu onnistuneesti" msgid "Addon upgraded succesfuly" msgstr "Laajennos päivitetty onnistuneesti" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1264,9 +1274,9 @@ msgstr "Syötä sähköpostiosoitteesi vahvistusta varten." #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Syötä uusi salasanasi, jossa on vähintään viisi (5) merkkiä." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Syötä uusi salasanasi, jossa on vähintään viisi (8) merkkiä." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1584,6 +1594,11 @@ msgstr "Piilota vastaukset" msgid "Hide facet?" msgstr "Piilota fasetti?" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1880,11 +1895,21 @@ msgstr "Nostokuva" msgid "Left" msgstr "Vasemmalla" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Linkki" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2089,6 +2114,11 @@ msgstr "Kuukausittain" msgid "More" msgstr "Lisää" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3098,6 +3128,11 @@ msgstr "Näytä kaikki" msgid "Show Replies" msgstr "Näytä vastaukset" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4275,6 +4310,11 @@ msgstr "Milloin" msgid "event_where" msgstr "Missä" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/fr/LC_MESSAGES/volto.po b/locales/fr/LC_MESSAGES/volto.po index d437f15166..8862a6e1ac 100644 --- a/locales/fr/LC_MESSAGES/volto.po +++ b/locales/fr/LC_MESSAGES/volto.po @@ -285,6 +285,16 @@ msgstr "Module désinstallé avec succès" msgid "Addon upgraded succesfuly" msgstr "Module mis à jour avec succès" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1270,9 +1280,9 @@ msgstr "Saisissez votre email pour vérification." #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Saisissez votre nouveau mot de passe. Minimum 5 caractères." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Saisissez votre nouveau mot de passe. Minimum 8 caractères." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1590,6 +1600,11 @@ msgstr "Masquer les réponses" msgid "Hide facet?" msgstr "Masquer la facette ?" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1886,11 +1901,21 @@ msgstr "Image de garde" msgid "Left" msgstr "Gauche" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Lien" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2095,6 +2120,11 @@ msgstr "Mensuel" msgid "More" msgstr "Plus" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3104,6 +3134,11 @@ msgstr "Afficher tous" msgid "Show Replies" msgstr "Afficher les réponses" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4281,6 +4316,11 @@ msgstr "Quand" msgid "event_where" msgstr "Où" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/it/LC_MESSAGES/volto.po b/locales/it/LC_MESSAGES/volto.po index aafcf9dda1..c081ae1612 100644 --- a/locales/it/LC_MESSAGES/volto.po +++ b/locales/it/LC_MESSAGES/volto.po @@ -268,6 +268,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1253,9 +1263,9 @@ msgstr "Inserisci la tua email per la verifica." #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Inserisci la tua nuova password. Minimo 5 caratteri." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Inserisci la tua nuova password. Minimo 8 caratteri." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1573,6 +1583,11 @@ msgstr "Nascondi risposte" msgid "Hide facet?" msgstr "Nascondi il filtro" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1869,11 +1884,21 @@ msgstr "Immagine di testata" msgid "Left" msgstr "Sinistra" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Link" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2078,6 +2103,11 @@ msgstr "Mensile" msgid "More" msgstr "Altro" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3087,6 +3117,11 @@ msgstr "Mostra tutti" msgid "Show Replies" msgstr "Mostra risposte" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4264,6 +4299,11 @@ msgstr "Quando" msgid "event_where" msgstr "Dove" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/ja/LC_MESSAGES/volto.po b/locales/ja/LC_MESSAGES/volto.po index 0ecb23ffe3..81b4228ce9 100644 --- a/locales/ja/LC_MESSAGES/volto.po +++ b/locales/ja/LC_MESSAGES/volto.po @@ -276,6 +276,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1261,9 +1271,9 @@ msgstr "" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "新しいパスワードを入力。(5文字以上)" +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "新しいパスワードを入力。(8文字以上)" #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1581,6 +1591,11 @@ msgstr "" msgid "Hide facet?" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1877,11 +1892,21 @@ msgstr "リード画像" msgid "Left" msgstr "左" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "リンク" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2086,6 +2111,11 @@ msgstr "毎月" msgid "More" msgstr "もっと見る" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3095,6 +3125,11 @@ msgstr "すべて表示" msgid "Show Replies" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4272,6 +4307,11 @@ msgstr "日時" msgid "event_where" msgstr "場所" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/nl/LC_MESSAGES/volto.po b/locales/nl/LC_MESSAGES/volto.po index 0c6aacd343..24d58061a5 100644 --- a/locales/nl/LC_MESSAGES/volto.po +++ b/locales/nl/LC_MESSAGES/volto.po @@ -287,6 +287,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1272,9 +1282,9 @@ msgstr "" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Geef een nieuw wachtwoord op. Minimaal 5 karakters." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Geef een nieuw wachtwoord op. Minimaal 8 karakters." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1592,6 +1602,11 @@ msgstr "" msgid "Hide facet?" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1888,11 +1903,21 @@ msgstr "" msgid "Left" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2097,6 +2122,11 @@ msgstr "" msgid "More" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3106,6 +3136,11 @@ msgstr "" msgid "Show Replies" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4283,6 +4318,11 @@ msgstr "" msgid "event_where" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/pt/LC_MESSAGES/volto.po b/locales/pt/LC_MESSAGES/volto.po index ca756af8c7..b5ecc4dd7d 100644 --- a/locales/pt/LC_MESSAGES/volto.po +++ b/locales/pt/LC_MESSAGES/volto.po @@ -276,6 +276,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1261,9 +1271,9 @@ msgstr "" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Escreva uma senha nova. Mínimo de 5 caracteres." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Escreva uma senha nova. Mínimo de 8 caracteres." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1581,6 +1591,11 @@ msgstr "" msgid "Hide facet?" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1877,11 +1892,21 @@ msgstr "" msgid "Left" msgstr "Esquerda" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2086,6 +2111,11 @@ msgstr "" msgid "More" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3095,6 +3125,11 @@ msgstr "" msgid "Show Replies" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4272,6 +4307,11 @@ msgstr "" msgid "event_where" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/pt_BR/LC_MESSAGES/volto.po b/locales/pt_BR/LC_MESSAGES/volto.po index e2fdf9d27a..19cfd33d8d 100644 --- a/locales/pt_BR/LC_MESSAGES/volto.po +++ b/locales/pt_BR/LC_MESSAGES/volto.po @@ -278,6 +278,16 @@ msgstr "Complemento desinstalado com sucesso" msgid "Addon upgraded succesfuly" msgstr "Complemento atualizado com sucesso" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "Facetas avançadas?" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "Facetas avançadas ficam ocultas inicialmente e exibidas sob demanda" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -468,7 +478,7 @@ msgstr "Navegação estrutural" #: components/manage/Controlpanels/Relations/BrokenRelations # defaultMessage: Broken relations msgid "Broken relations" -msgstr "" +msgstr "Relacionamentos rompidos" #: components/manage/Blocks/HeroImageLeft/Edit #: components/manage/Contents/ContentsUploadModal @@ -791,7 +801,7 @@ msgstr "Declaração de copyright ou outras informações de direitos sobre este #: helpers/MessageLabels/MessageLabels # defaultMessage: Create or delete relations to target msgid "Create or delete relations to target" -msgstr "" +msgstr "Crie ou remova relacionamentos para o destino" #: components/manage/Toolbar/More # defaultMessage: Create working copy @@ -1263,9 +1273,9 @@ msgstr "Informe seu e-mail para verificação." #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Digite sua nova senha. Mínimo de 5 caracteres." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Digite sua nova senha. Mínimo de 8 caracteres." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1415,7 +1425,7 @@ msgstr "Nome do arquivo" #: helpers/MessageLabels/MessageLabels # defaultMessage: Filter msgid "Filter" -msgstr "" +msgstr "Filtrar" #: components/manage/Controlpanels/Rules/Rules # defaultMessage: Filter Rules: @@ -1445,7 +1455,7 @@ msgstr "Primeiro" #: helpers/MessageLabels/MessageLabels # defaultMessage: Fix relations msgid "Fix relations" -msgstr "" +msgstr "Consertar relacionamentos" #: components/manage/Blocks/Table/Edit # defaultMessage: Fixed width columns @@ -1583,6 +1593,11 @@ msgstr "Ocultar respostas" msgid "Hide facet?" msgstr "Ocultar faceta?" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "Ocultar filtros" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1654,7 +1669,7 @@ msgstr "Galeria de imagem" #: components/manage/Blocks/Teaser/schema # defaultMessage: Image override msgid "Image override" -msgstr "" +msgstr "Substituir imagem" #: components/manage/Blocks/Image/schema # defaultMessage: Image size @@ -1717,7 +1732,7 @@ msgstr "Inserir linha antes" #: helpers/MessageLabels/MessageLabels # defaultMessage: Inspect relations msgid "Inspect relations" -msgstr "" +msgstr "Inspecionar relacionamentos" #: components/manage/Controlpanels/AddonsControlpanel # defaultMessage: Install @@ -1879,11 +1894,21 @@ msgstr "Imagem principal" msgid "Left" msgstr "Esquerda" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "Menos filtros" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Link" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2009,7 +2034,7 @@ msgstr "Adicionado manual ou automaticamente?" #: helpers/MessageLabels/MessageLabels # defaultMessage: Many relations found. Please search. msgid "Many relations found. Please search." -msgstr "" +msgstr "Muitos relacionamentos foram encontrados. Por favor realize uma busca" #: components/manage/Blocks/Maps/MapsSidebar #: components/manage/Blocks/Maps/schema @@ -2040,7 +2065,7 @@ msgstr "Médio" #: helpers/MessageLabels/MessageLabels # defaultMessage: Membership updated msgid "Membership updated" -msgstr "" +msgstr "Participação atualizada" #: components/theme/ContactForm/ContactForm # defaultMessage: Message @@ -2088,6 +2113,11 @@ msgstr "Mensalmente" msgid "More" msgstr "Mais" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "Mais filtros" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -2205,7 +2235,7 @@ msgstr "Nenhum complemento encontrado" #: components/manage/Controlpanels/Relations/RelationsMatrix # defaultMessage: No broken relations found. msgid "No broken relations found." -msgstr "" +msgstr "Nenhum relacionamento rompido foi encontrado" #: components/theme/RequestTimeout/RequestTimeout # defaultMessage: There is no connection to the server, due to a timeout o no network connection. @@ -2230,7 +2260,7 @@ msgstr "Nenhuma imagem definida no campo de imagem" #: components/manage/Blocks/Listing/GalleryNoResultsComponent # defaultMessage: No images found. msgid "No images found." -msgstr "" +msgstr "Nenhuma imagem foi encontrada" #: components/manage/Blocks/Listing/ListingBody # defaultMessage: No items found in this container. @@ -2263,7 +2293,7 @@ msgstr "Sem opções" #: helpers/MessageLabels/MessageLabels # defaultMessage: No relation found msgid "No relation found" -msgstr "" +msgstr "Nenhum relacionamento foi encontrado" #: components/manage/BlockChooser/BlockChooser #: components/theme/Search/Search @@ -2448,7 +2478,7 @@ msgstr "Pessoas responsáveis pela criação do conteúdo deste item. Por favor, #: components/manage/Blocks/Teaser/DefaultBody # defaultMessage: Please choose an existing content as source for this element msgid "Please choose an existing content as source for this element" -msgstr "" +msgstr "Por favor selecione um conteúdo existente como fonte para este elemento" #: components/manage/Controlpanels/Controlpanels # defaultMessage: Please continue with the upgrade. @@ -2488,7 +2518,7 @@ msgstr "Por favor, atualize para plone.restapi >= 8.24.0." #: components/manage/Controlpanels/Relations/Relations # defaultMessage: Please upgrade to plone.restapi >= 8.35.3. msgid "Please upgrade to plone.restapi >= 8.35.3." -msgstr "" +msgstr "Por favor atualize a plone.restapi para versão 8.35.3 ou superior." #: components/theme/Footer/Footer # defaultMessage: Plone Foundation @@ -2587,12 +2617,12 @@ msgstr "Leia Mais…" #: components/manage/Controlpanels/Relations/RelationsListing # defaultMessage: Read only for this type of relation. msgid "Read only for this type of relation." -msgstr "" +msgstr "Apenas leitura para este tipo de relacionamento." #: components/manage/Contents/Contents # defaultMessage: Rearrange items by… msgid "Rearrange items by…" -msgstr "Reorganize itens por…" +msgstr "Reorganizar itens por…" #: components/manage/Widgets/RecurrenceWidget/EndField # defaultMessage: Ends @@ -2635,24 +2665,24 @@ msgstr "Formulário de cadastro" #: helpers/MessageLabels/MessageLabels # defaultMessage: Relation msgid "Relation name" -msgstr "" +msgstr "Nome do relacionamento" #: components/manage/Controlpanels/Controlpanels #: components/manage/Controlpanels/Relations/Relations #: helpers/MessageLabels/MessageLabels # defaultMessage: Relations msgid "Relations" -msgstr "" +msgstr "Relacionamentos" #: components/manage/Controlpanels/Relations/RelationsListing # defaultMessage: Relations are editable with plone.api >= 2.0.3. msgid "Relations are editable with plone.api >= 2.0.3." -msgstr "" +msgstr "Relacionamentos são editáveis com uso da plone.api versão 2.0.3 ou superior." #: helpers/MessageLabels/MessageLabels # defaultMessage: Relations updated msgid "Relations updated" -msgstr "" +msgstr "Relacionamentos atualizados" #: components/theme/Search/Search # defaultMessage: Relevance @@ -2756,7 +2786,7 @@ msgstr "Redefinir o título do termo" #: components/manage/Blocks/Teaser/Data # defaultMessage: Reset the block msgid "Reset the block" -msgstr "" +msgstr "Redefinir o bloco" #: components/manage/Widgets/QuerystringWidget # defaultMessage: Results limit @@ -2865,7 +2895,7 @@ msgstr "Salvo" #: components/manage/Contents/ContentsItem # defaultMessage: Scheduled msgid "Scheduled" -msgstr "" +msgstr "Agendado" #: components/manage/Controlpanels/ContentTypesActions # defaultMessage: Schema @@ -2943,12 +2973,12 @@ msgstr "Resultados da pesquisa para {term}" #: helpers/MessageLabels/MessageLabels # defaultMessage: Search sources by title or path msgid "Search sources by title or path" -msgstr "" +msgstr "Pesquise fontes por título ou caminho" #: helpers/MessageLabels/MessageLabels # defaultMessage: Search targets by title or path msgid "Search targets by title or path" -msgstr "" +msgstr "Pesquise destinos por título ou caminho" #: helpers/MessageLabels/MessageLabels # defaultMessage: Search users… @@ -2991,7 +3021,7 @@ msgstr "Selecione colunas para mostrar" #: helpers/MessageLabels/MessageLabels # defaultMessage: Select relation msgid "Select relation" -msgstr "" +msgstr "Selecione um relacionamento" #: components/manage/Contents/ContentsWorkflowModal # defaultMessage: Select the transition to be used for modifying the items state. @@ -3001,7 +3031,7 @@ msgstr "Selecione a transição a ser usada para modificar o estado dos itens." #: helpers/MessageLabels/MessageLabels # defaultMessage: Selected msgid "Selected" -msgstr "" +msgstr "Selecionado" #: components/manage/Widgets/RecurrenceWidget/Occurences # defaultMessage: Selected dates @@ -3097,6 +3127,11 @@ msgstr "Mostrar tudo" msgid "Show Replies" msgstr "Mostrar respostas" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "Exibir filtros" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -3110,12 +3145,12 @@ msgstr "Mostrar item" #: components/manage/Controlpanels/Relations/RelationsMatrix # defaultMessage: Show potential sources. Not only objects that are source of some relation. msgid "Show potential sources. Not only objects that are source of some relation." -msgstr "" +msgstr "Exibir potenciais fontes. Não apenas os objetos que já são fonte de algum relacionamento." #: components/manage/Controlpanels/Relations/RelationsMatrix # defaultMessage: Show potential targets. Not only objects that are target of some relation. msgid "Show potential targets. Not only objects that are target of some relation." -msgstr "" +msgstr "Exibir potenciais destinos. Não apenas os objetos que já são destino de algum relacionamento." #: components/manage/Blocks/Search/schema # defaultMessage: Show search button? @@ -3187,7 +3222,7 @@ msgstr "Pequeno" #: components/manage/Controlpanels/Relations/Relations # defaultMessage: Some relations are broken. Please fix. msgid "Some relations are broken. Please fix." -msgstr "" +msgstr "Alguns relacionamentos estão rompidos. Por favor corrija-os." #: error # defaultMessage: Sorry, something went wrong with your request @@ -3400,7 +3435,7 @@ msgstr "O caminho da URL de destino deve começar com uma barra." #: components/manage/Blocks/Teaser/schema # defaultMessage: Teaser msgid "Teaser" -msgstr "" +msgstr "Destaque" #: components/manage/Widgets/SchemaWidget # defaultMessage: Text @@ -3596,7 +3631,7 @@ msgstr "Total de comentários" #: components/manage/Contents/Contents # defaultMessage: Total items to be deleted: msgid "Total items to be deleted:" -msgstr "" +msgstr "Total de itens a serem removidos:" #: components/manage/Controlpanels/DatabaseInformation # defaultMessage: Total number of objects in each cache @@ -4121,7 +4156,7 @@ msgstr "Você foi desconectado do site." #: components/manage/Controlpanels/Relations/Relations # defaultMessage: You have not the required permission for this control panel. msgid "You have not the required permission for this control panel." -msgstr "" +msgstr "Você não possui a permissão necessária para acessar esse painel de controle." #: components/theme/PasswordReset/RequestPasswordReset # defaultMessage: Your email is required for reset your password. @@ -4274,15 +4309,20 @@ msgstr "Quando" msgid "event_where" msgstr "Onde" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" -msgstr "" +msgstr "descarrega os intIds e recontrua os relacionamentos" #: components/manage/Blocks/Teaser/schema # defaultMessage: Head title msgid "head_title" -msgstr "" +msgstr "Título principal" #: components/theme/PasswordReset/RequestPasswordReset # defaultMessage: Password reset confirmation sent @@ -4383,7 +4423,7 @@ msgstr "Mais usados" #: components/manage/Controlpanels/Relations/RelationsListing # defaultMessage: Found {sources} sources and {targets} targets. Narrow down to {max}! msgid "narrowDownRelations" -msgstr "" +msgstr "Encontradas {sources} fontes e {targets} destinos. Por favor, reduza ao máximo de {max}!" #: components/manage/Blocks/Search/components/DateRangeFacetFilterListEntry #: components/manage/Blocks/Search/components/ToggleFacetFilterListEntry @@ -4441,7 +4481,7 @@ msgstr "Selecionar" #: helpers/MessageLabels/MessageLabels # defaultMessage: rebuild relations msgid "rebuild relations" -msgstr "" +msgstr "reconstruir relacionamentos" #: components/theme/Search/Search # defaultMessage: results @@ -4646,7 +4686,7 @@ msgstr "ordenar" #: helpers/MessageLabels/MessageLabels # defaultMessage: sources path msgid "sources path" -msgstr "" +msgstr "caminho da fonte" #: config/Blocks # defaultMessage: Table @@ -4656,7 +4696,7 @@ msgstr "Tabela" #: helpers/MessageLabels/MessageLabels # defaultMessage: target path msgid "target path" -msgstr "" +msgstr "caminho do destino" #: config/Blocks # defaultMessage: Text diff --git a/locales/ro/LC_MESSAGES/volto.po b/locales/ro/LC_MESSAGES/volto.po index 970e3a748c..e3e7c2ae0c 100644 --- a/locales/ro/LC_MESSAGES/volto.po +++ b/locales/ro/LC_MESSAGES/volto.po @@ -268,6 +268,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1253,9 +1263,9 @@ msgstr "" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "Introduceți noua parolă. Minim 5 caractere." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "Introduceți noua parolă. Minim 8 caractere." #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1573,6 +1583,11 @@ msgstr "Ascunde răspunsurile" msgid "Hide facet?" msgstr "Ascundeți fațeta?" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1869,11 +1884,21 @@ msgstr "Imaginea de start" msgid "Left" msgstr "Stânga" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "Legătură" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2078,6 +2103,11 @@ msgstr "Lunar" msgid "More" msgstr "Mai mult" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3087,6 +3117,11 @@ msgstr "Afișează tot" msgid "Show Replies" msgstr "Afișați răspunsurile" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4264,6 +4299,11 @@ msgstr "Data" msgid "event_where" msgstr "Locație" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/volto.pot b/locales/volto.pot index 08666abef4..4ef602b388 100644 --- a/locales/volto.pot +++ b/locales/volto.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2023-05-23T08:20:31.464Z\n" +"POT-Creation-Date: 2023-06-13T20:41:58.672Z\n" "Last-Translator: Plone i18n \n" "Language-Team: Plone i18n \n" "MIME-Version: 1.0\n" @@ -270,6 +270,16 @@ msgstr "" msgid "Addon upgraded succesfuly" msgstr "" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1255,8 +1265,8 @@ msgstr "" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." msgstr "" #: components/theme/PasswordReset/PasswordReset @@ -1575,6 +1585,11 @@ msgstr "" msgid "Hide facet?" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1871,11 +1886,21 @@ msgstr "" msgid "Left" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2080,6 +2105,11 @@ msgstr "" msgid "More" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3089,6 +3119,11 @@ msgstr "" msgid "Show Replies" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4266,6 +4301,11 @@ msgstr "" msgid "event_where" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/locales/zh_CN/LC_MESSAGES/volto.po b/locales/zh_CN/LC_MESSAGES/volto.po index 7f1887725d..0355a55f65 100644 --- a/locales/zh_CN/LC_MESSAGES/volto.po +++ b/locales/zh_CN/LC_MESSAGES/volto.po @@ -274,6 +274,16 @@ msgstr "附件卸载成功" msgid "Addon upgraded succesfuly" msgstr "附件升级成功" +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facet? +msgid "Advanced facet?" +msgstr "" + +#: components/manage/Blocks/Search/schema +# defaultMessage: Advanced facets are initially hidden and displayed on demand +msgid "Advanced facets are initially hidden and displayed on demand" +msgstr "" + #: config/Views # defaultMessage: Album view msgid "Album view" @@ -1259,9 +1269,9 @@ msgstr "输入你的邮箱进行验证" #: components/manage/Preferences/ChangePassword #: components/theme/PasswordReset/PasswordReset -# defaultMessage: Enter your new password. Minimum 5 characters. -msgid "Enter your new password. Minimum 5 characters." -msgstr "输入你的新密码。最少5个字符" +# defaultMessage: Enter your new password. Minimum 8 characters. +msgid "Enter your new password. Minimum 8 characters." +msgstr "" #: components/theme/PasswordReset/PasswordReset # defaultMessage: Enter your username for verification. @@ -1579,6 +1589,11 @@ msgstr "隐藏回复" msgid "Hide facet?" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Hide filters +msgid "Hide filters" +msgstr "" + #: components/manage/History/History #: components/manage/Toolbar/More # defaultMessage: History @@ -1875,11 +1890,21 @@ msgstr "首图" msgid "Left" msgstr "" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Less filters +msgid "Less filters" +msgstr "" + #: components/manage/Toolbar/Toolbar # defaultMessage: Link msgid "Link" msgstr "链接" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: Link copied to clipboard +msgid "Link copied to clipboard" +msgstr "" + #: components/manage/Blocks/HeroImageLeft/schema #: components/manage/Blocks/Listing/schema # defaultMessage: Link more @@ -2084,6 +2109,11 @@ msgstr "每月" msgid "More" msgstr "更多" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: More filters +msgid "More filters" +msgstr "" + #: components/manage/Controlpanels/UpgradeControlPanel # defaultMessage: More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide. msgid "More information about the upgrade procedure can be found in the documentation section of plone.org in the Upgrade Guide." @@ -3093,6 +3123,11 @@ msgstr "显示全部" msgid "Show Replies" msgstr "显示回复" +#: components/manage/Blocks/Search/components/Facets +# defaultMessage: Show filters +msgid "Show filters" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: Show groups of users below msgid "Show groups of users below" @@ -4270,6 +4305,11 @@ msgstr "" msgid "event_where" msgstr "" +#: helpers/MessageLabels/MessageLabels +# defaultMessage: This website does not accept files larger than {limit} +msgid "fileTooLarge" +msgstr "" + #: helpers/MessageLabels/MessageLabels # defaultMessage: flush intIds and rebuild relations msgid "flush intIds and rebuild relations" diff --git a/news/4917.bugfix b/news/4917.bugfix new file mode 100644 index 0000000000..938e6722b5 --- /dev/null +++ b/news/4917.bugfix @@ -0,0 +1 @@ +Remove anonymous function calls. Remove default exports from. @sneridagh diff --git a/package.json b/package.json index c1c9c86bc5..912d4e392f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ } ], "license": "MIT", - "version": "17.0.0-alpha.8", + "version": "17.0.0-alpha.14", "repository": { "type": "git", "url": "git@github.com:plone/volto.git" @@ -288,6 +288,7 @@ "eslint-plugin-react-hooks": "4.6.0", "express": "4.17.3", "filesize": "6", + "github-slugger": "1.4.0", "glob": "7.1.6", "history": "4.10.1", "hoist-non-react-statics": "3.3.2", diff --git a/packages/generator-volto/generators/addon/templates/Makefile b/packages/generator-volto/generators/addon/templates/Makefile index 59c4f32e52..be8d5fb29c 100644 --- a/packages/generator-volto/generators/addon/templates/Makefile +++ b/packages/generator-volto/generators/addon/templates/Makefile @@ -11,15 +11,15 @@ MAKEFLAGS+=--warn-undefined-variables MAKEFLAGS+=--no-builtin-rules # Project settings -# Update the versions depending on your project requirements | Last Updated 2022-12-23 -DOCKER_IMAGE=plone/server-dev:6.0.2 -DOCKER_IMAGE_ACCEPTANCE=plone/server-acceptance:6.0.2 +# Update the versions depending on your project requirements | Last Updated 2023-06-17 +DOCKER_IMAGE=plone/server-dev:6.0.5 +DOCKER_IMAGE_ACCEPTANCE=plone/server-acceptance:6.0.5 KGS= NODEBIN = ./node_modules/.bin # Plone 5 legacy DOCKER_IMAGE5=plone/plone-backend:5.2.10 -KGS5=plone.restapi==8.35.1 plone.volto==4.0.7 plone.rest==3.0.0 +KGS5=plone.restapi==8.37.0 plone.volto==4.0.8 plone.rest==3.0.0 TESTING_ADDONS=plone.app.robotframework==2.0.0 plone.app.testing==7.0.0 DIR=$(shell basename $$(pwd)) diff --git a/packages/volto-slate/package.json b/packages/volto-slate/package.json index 4b159c1895..7d599abd35 100644 --- a/packages/volto-slate/package.json +++ b/packages/volto-slate/package.json @@ -1,6 +1,6 @@ { "name": "@plone/volto-slate", - "version": "17.0.0-alpha.8", + "version": "17.0.0-alpha.14", "description": "Slate.js integration with Volto", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team", diff --git a/packages/volto-slate/src/actions/index.js b/packages/volto-slate/src/actions/index.js index b73121ac23..7cbe33490e 100644 --- a/packages/volto-slate/src/actions/index.js +++ b/packages/volto-slate/src/actions/index.js @@ -1,3 +1,3 @@ -export saveSlateBlockSelection from './selection'; +export { default as saveSlateBlockSelection } from './selection'; export * from './content'; export * from './plugins'; diff --git a/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx b/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx index bdd3f42926..4bdcf09756 100644 --- a/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +++ b/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx @@ -6,7 +6,11 @@ import { defineMessages, useIntl } from 'react-intl'; import { useInView } from 'react-intersection-observer'; import { Dimmer, Loader, Message, Segment } from 'semantic-ui-react'; -import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers'; +import { + flattenToAppURL, + getBaseUrl, + validateFileUploadSize, +} from '@plone/volto/helpers'; import config from '@plone/volto/registry'; import { BlockDataForm, @@ -71,6 +75,7 @@ export const DefaultTextBlockEditor = (props) => { const { slate } = config.settings; const { textblockExtensions } = slate; const { value } = data; + const intl = useIntl(); // const [addNewBlockOpened, setAddNewBlockOpened] = React.useState(); const [showDropzone, setShowDropzone] = React.useState(false); @@ -106,6 +111,7 @@ export const DefaultTextBlockEditor = (props) => { files.forEach((file) => { const [mime] = file.type.split('/'); if (mime !== 'image') return; + if (!validateFileUploadSize(file, intl.formatMessage)) return; readAsDataURL(file).then((data) => { const fields = data.match(/^data:(.*);(.*),(.*)$/); @@ -127,7 +133,7 @@ export const DefaultTextBlockEditor = (props) => { }); setShowDropzone(false); }, - [pathname, uploadContent, block], + [pathname, uploadContent, block, intl.formatMessage], ); const { loaded, loading } = uploadRequest; @@ -178,7 +184,6 @@ export const DefaultTextBlockEditor = (props) => { instructions = formDescription; } - const intl = useIntl(); const placeholder = data.placeholder || formTitle || intl.formatMessage(messages.text); const schema = TextBlockSchema(data); diff --git a/packages/volto-slate/src/blocks/Text/TextBlockView.jsx b/packages/volto-slate/src/blocks/Text/TextBlockView.jsx index 5e8accb82c..7f9f623fbd 100644 --- a/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +++ b/packages/volto-slate/src/blocks/Text/TextBlockView.jsx @@ -1,26 +1,30 @@ -import { serializeNodes } from '@plone/volto-slate/editor/render'; +import { + serializeNodes, + serializeNodesToText, +} from '@plone/volto-slate/editor/render'; import config from '@plone/volto/registry'; +import { isEqual } from 'lodash'; +import Slugger from 'github-slugger'; const TextBlockView = (props) => { const { id, data, styling = {} } = props; const { value, override_toc } = data; const metadata = props.metadata || props.properties; - return serializeNodes( - value, - (node, path) => { - const res = { ...styling }; - if (node.type) { - if ( - config.settings.slate.topLevelTargetElements.includes(node.type) || - override_toc - ) { - res.id = id; - } + const { topLevelTargetElements } = config.settings.slate; + + const getAttributes = (node, path) => { + const res = { ...styling }; + if (node.type && isEqual(path, [0])) { + if (topLevelTargetElements.includes(node.type) || override_toc) { + const text = serializeNodesToText(node?.children || []); + const slug = Slugger.slug(text); + res.id = slug || id; } - return res; - }, - { metadata: metadata }, - ); + } + return res; + }; + + return serializeNodes(value, getAttributes, { metadata: metadata }); }; export default TextBlockView; diff --git a/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js b/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js index 3dab777f0e..f4f8eaf08d 100644 --- a/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js +++ b/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js @@ -1,7 +1,7 @@ import isUrl from 'is-url'; import imageExtensions from 'image-extensions'; import { blockTagDeserializer } from '@plone/volto-slate/editor/deserialize'; -import { getBaseUrl } from '@plone/volto/helpers'; +import { getBaseUrl, validateFileUploadSize } from '@plone/volto/helpers'; import { v4 as uuid } from 'uuid'; import { Transforms } from 'slate'; @@ -66,7 +66,9 @@ export const withDeserializers = (editor) => { ...editor.dataTransferHandlers, files: (files) => { const unprocessed = []; + const { intl } = editor.getBlockProps(); for (const file of files) { + if (!validateFileUploadSize(file, intl.formatMessage)) return; const reader = new FileReader(); const [mime] = file.type.split('/'); if (mime === 'image') { diff --git a/packages/volto-slate/src/blocks/Text/index.js b/packages/volto-slate/src/blocks/Text/index.js index 8082b45296..c6ee9893de 100644 --- a/packages/volto-slate/src/blocks/Text/index.js +++ b/packages/volto-slate/src/blocks/Text/index.js @@ -35,7 +35,7 @@ import textSVG from '@plone/volto/icons/subtext.svg'; export { TextBlockView, TextBlockEdit, TextBlockSchema }; -export default (config) => { +export default function applyConfig(config) { config.settings.slate = { // TODO: should we inverse order? First here gets executed last textblockExtensions: [ @@ -165,4 +165,4 @@ export default (config) => { restricted: true, }; return config; -}; +} diff --git a/packages/volto-slate/src/editor/config.jsx b/packages/volto-slate/src/editor/config.jsx index d97bb021d7..cdacc04daa 100644 --- a/packages/volto-slate/src/editor/config.jsx +++ b/packages/volto-slate/src/editor/config.jsx @@ -43,6 +43,7 @@ import { bTagDeserializer, codeTagDeserializer, } from './deserialize'; +import { renderLinkElement } from './render'; // Registry of available buttons export const buttons = { @@ -234,10 +235,10 @@ export const defaultBlockType = 'p'; export const elements = { default: ({ attributes, children }) =>

{children}

, - h1: ({ attributes, children }) =>

{children}

, - h2: ({ attributes, children }) =>

{children}

, - h3: ({ attributes, children }) =>

{children}

, - h4: ({ attributes, children }) =>

{children}

, + h1: renderLinkElement('h1'), + h2: renderLinkElement('h2'), + h3: renderLinkElement('h3'), + h4: renderLinkElement('h4'), li: ({ attributes, children }) =>
  • {children}
  • , ol: ({ attributes, children }) =>
      {children}
    , diff --git a/packages/volto-slate/src/editor/index.js b/packages/volto-slate/src/editor/index.js index c092f1927d..0200279e01 100644 --- a/packages/volto-slate/src/editor/index.js +++ b/packages/volto-slate/src/editor/index.js @@ -1,9 +1,9 @@ import * as slateConfig from './config'; import installDefaultPlugins from './plugins'; -export SlateEditor from './SlateEditor'; -export EditorReference from './EditorReference'; +export { default as SlateEditor } from './SlateEditor'; +export { default as EditorReference } from './EditorReference'; -export default (config) => { +export default function applyConfig(config) { config.settings.slate = { ...slateConfig, // showExpandedToolbar: false, @@ -11,4 +11,4 @@ export default (config) => { }; config = installDefaultPlugins(config); return config; -}; +} diff --git a/packages/volto-slate/src/editor/less/slate.less b/packages/volto-slate/src/editor/less/slate.less new file mode 100644 index 0000000000..954ee09ab2 --- /dev/null +++ b/packages/volto-slate/src/editor/less/slate.less @@ -0,0 +1,28 @@ +h1, +h2, +h3, +h4 { + &:hover { + a.anchor { + svg { + opacity: 1; + transform: rotate(15deg); + } + } + } + + a.anchor { + position: absolute; + display: inline-block; + margin-left: 5px; + vertical-align: middle; + + svg { + width: 1.6ch; + fill: #42526e; + opacity: 0; + transform: rotate(15deg) translate(-8px, 2px); + transition: opacity 0.2s ease 0s, transform 0.2s ease 0s; + } + } +} diff --git a/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx b/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx index af37a9f5f0..2771759873 100644 --- a/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +++ b/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx @@ -28,13 +28,13 @@ const StyleMenuButton = ({ icon, active, ...props }) => ( ); -const MenuOpts = ({ editor, toSelect, option, ...rest }) => { +const MenuOpts = ({ editor, toSelect, option, type }) => { const isActive = toSelect.includes(option); return ( { @@ -118,7 +118,12 @@ const StylingsButton = (props) => { content={intl.formatMessage(messages.inlineStyle)} /> {inlineOpts.map((option, index) => ( - + ))} )} @@ -129,7 +134,12 @@ const StylingsButton = (props) => { content={intl.formatMessage(messages.paragraphStyle)} /> {blockOpts.map((option, index) => ( - + ))} )} diff --git a/packages/volto-slate/src/editor/render.jsx b/packages/volto-slate/src/editor/render.jsx index bfc34cb66e..45ab42ca75 100644 --- a/packages/volto-slate/src/editor/render.jsx +++ b/packages/volto-slate/src/editor/render.jsx @@ -1,9 +1,18 @@ import React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; +import { useLocation } from 'react-router-dom'; +import { toast } from 'react-toastify'; +import { useIntl } from 'react-intl'; import { Node, Text } from 'slate'; import cx from 'classnames'; -import { isEmpty, isEqual, omit } from 'lodash'; +import { isEmpty, omit } from 'lodash'; +import { UniversalLink, Toast } from '@plone/volto/components'; +import { messages, addAppURL } from '@plone/volto/helpers'; +import useClipboard from '@plone/volto/hooks/clipboard/useClipboard'; import config from '@plone/volto/registry'; +import linkSVG from '@plone/volto/icons/link.svg'; + +import './less/slate.less'; const OMITTED = ['editor', 'path']; @@ -106,13 +115,7 @@ export const serializeNodes = (nodes, getAttributes, extras = {}) => { mode="view" key={path} data-slate-data={node.data ? serializeData(node) : null} - attributes={ - isEqual(path, [0]) - ? getAttributes - ? getAttributes(node, path) - : null - : null - } + attributes={getAttributes ? getAttributes(node, path) : null} extras={extras} > {_serializeNodes(Array.from(Node.children(editor, path)))} @@ -153,3 +156,60 @@ export const serializeNodesToText = (nodes) => { export const serializeNodesToHtml = (nodes) => renderToStaticMarkup(serializeNodes(nodes)); + +export const renderLinkElement = (tagName) => { + function LinkElement({ + attributes, + children, + mode = 'edit', + className = null, + }) { + const { slate = {} } = config.settings; + const Tag = tagName; + const slug = attributes.id || ''; + const location = useLocation(); + const appPathname = addAppURL(location.pathname); + // eslint-disable-next-line no-unused-vars + const [copied, copy, setCopied] = useClipboard( + appPathname.concat(`#${slug}`), + ); + const intl = useIntl(); + + return slate.useLinkedHeadings === false ? ( + + {children} + + ) : ( + + {children} + {mode === 'view' && slug && ( + + )} + + ); + } + LinkElement.displayName = `${tagName}LinkElement`; + return LinkElement; +}; diff --git a/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx b/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx index d140070779..6f8e494bfb 100644 --- a/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +++ b/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx @@ -3,11 +3,11 @@ import Toolbar from './Toolbar'; // A toolbar that conditionally renders itself based on the presense of // children -export default ({ editor, plugins, show }) => { +export default function SlateContextToolbar({ editor, plugins, show }) { if (!show) { return null; } const components = plugins.map((plug) => plug(editor)).filter((c) => !!c); return components.length ? {components} : ''; -}; +} diff --git a/packages/volto-slate/src/editor/ui/index.js b/packages/volto-slate/src/editor/ui/index.js index 089e0012c3..422bc6ac2c 100644 --- a/packages/volto-slate/src/editor/ui/index.js +++ b/packages/volto-slate/src/editor/ui/index.js @@ -1,15 +1,15 @@ -export BasicToolbar from './BasicToolbar'; -export BlockButton from './BlockButton'; -export ClearFormattingButton from './ClearFormattingButton'; -export ExpandedToolbar from './ExpandedToolbar'; -export Expando from './Expando'; -export MarkButton from './MarkButton'; -export Menu from './Menu'; -export Separator from './Separator'; -export SlateContextToolbar from './SlateContextToolbar'; -export SlateToolbar from './SlateToolbar'; -export Toolbar from './Toolbar'; -export ToolbarButton from './ToolbarButton'; -export MarkElementButton from './MarkElementButton'; -export PositionedToolbar from './PositionedToolbar'; -export InlineToolbar from './InlineToolbar'; +export { default as BasicToolbar } from './BasicToolbar'; +export { default as BlockButton } from './BlockButton'; +export { default as ClearFormattingButton } from './ClearFormattingButton'; +export { default as ExpandedToolbar } from './ExpandedToolbar'; +export { default as Expando } from './Expando'; +export { default as MarkButton } from './MarkButton'; +export { default as Menu } from './Menu'; +export { default as Separator } from './Separator'; +export { default as SlateContextToolbar } from './SlateContextToolbar'; +export { default as SlateToolbar } from './SlateToolbar'; +export { default as Toolbar } from './Toolbar'; +export { default as ToolbarButton } from './ToolbarButton'; +export { default as MarkElementButton } from './MarkElementButton'; +export { default as PositionedToolbar } from './PositionedToolbar'; +export { default as InlineToolbar } from './InlineToolbar'; diff --git a/packages/volto-slate/src/index.js b/packages/volto-slate/src/index.js index ffcb29c775..a9ba83c2f5 100644 --- a/packages/volto-slate/src/index.js +++ b/packages/volto-slate/src/index.js @@ -8,7 +8,7 @@ import RichTextWidgetView from './widgets/RichTextWidgetView'; import HtmlSlateWidget from './widgets/HtmlSlateWidget'; import ObjectByTypeWidget from './widgets/ObjectByTypeWidget'; -export default (config) => { +export default function applyConfig(config) { config = [installSlate, installTextBlock, installTableBlock].reduce( (acc, apply) => apply(acc), config, @@ -58,4 +58,4 @@ export default (config) => { } return config; -}; +} diff --git a/src/components/manage/Blocks/HeroImageLeft/Edit.jsx b/src/components/manage/Blocks/HeroImageLeft/Edit.jsx index a93014fd28..422769a376 100644 --- a/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +++ b/src/components/manage/Blocks/HeroImageLeft/Edit.jsx @@ -14,7 +14,11 @@ import { defineMessages, injectIntl } from 'react-intl'; import cx from 'classnames'; import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; -import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers'; +import { + flattenToAppURL, + getBaseUrl, + validateFileUploadSize, +} from '@plone/volto/helpers'; import { createContent } from '@plone/volto/actions'; import { Icon, SidebarPortal, LinkMore } from '@plone/volto/components'; @@ -275,6 +279,7 @@ class EditComponent extends Component { */ onUploadImage({ target }) { const file = target.files[0]; + if (!validateFileUploadSize(file, this.props.intl.formatMessage)) return; this.setState({ uploading: true, }); diff --git a/src/components/manage/Blocks/Image/Edit.jsx b/src/components/manage/Blocks/Image/Edit.jsx index 63087dabf2..2e7548f19b 100644 --- a/src/components/manage/Blocks/Image/Edit.jsx +++ b/src/components/manage/Blocks/Image/Edit.jsx @@ -21,6 +21,7 @@ import { flattenToAppURL, getBaseUrl, isInternalURL, + validateFileUploadSize, } from '@plone/volto/helpers'; import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg'; @@ -125,6 +126,7 @@ class Edit extends Component { onUploadImage = (e) => { e.stopPropagation(); const file = e.target.files[0]; + if (!validateFileUploadSize(file, this.props.intl.formatMessage)) return; this.setState({ uploading: true, }); @@ -178,23 +180,25 @@ class Edit extends Component { * @param {array} files File objects * @returns {undefined} */ - onDrop = (file) => { - this.setState({ - uploading: true, - }); + onDrop = (files) => { + if (!validateFileUploadSize(files[0], this.props.intl.formatMessage)) { + this.setState({ dragging: false }); + return; + } + this.setState({ uploading: true }); - readAsDataURL(file[0]).then((data) => { + readAsDataURL(files[0]).then((data) => { const fields = data.match(/^data:(.*);(.*),(.*)$/); this.props.createContent( getBaseUrl(this.props.pathname), { '@type': 'Image', - title: file[0].name, + title: files[0].name, image: { data: fields[3], encoding: fields[2], 'content-type': fields[1], - filename: file[0].name, + filename: files[0].name, }, }, this.props.block, diff --git a/src/components/manage/Blocks/Listing/ListingBody.jsx b/src/components/manage/Blocks/Listing/ListingBody.jsx index 0d8e54003f..227b473c8f 100644 --- a/src/components/manage/Blocks/Listing/ListingBody.jsx +++ b/src/components/manage/Blocks/Listing/ListingBody.jsx @@ -1,14 +1,35 @@ -import React, { createRef } from 'react'; +import React, { createRef, useMemo } from 'react'; import { FormattedMessage, injectIntl } from 'react-intl'; import cx from 'classnames'; import { Pagination, Dimmer, Loader } from 'semantic-ui-react'; +import Slugger from 'github-slugger'; import { Icon } from '@plone/volto/components'; +import { renderLinkElement } from '@plone/volto-slate/editor/render'; import config from '@plone/volto/registry'; import withQuerystringResults from './withQuerystringResults'; import paginationLeftSVG from '@plone/volto/icons/left-key.svg'; import paginationRightSVG from '@plone/volto/icons/right-key.svg'; +const Headline = ({ headlineTag, id, data = {}, listingItems, isEditMode }) => { + let attr = { id }; + const slug = Slugger.slug(data.headline); + attr.id = slug || id; + const LinkedHeadline = useMemo(() => renderLinkElement(headlineTag), [ + headlineTag, + ]); + return ( + 0, + })} + /> + ); +}; + const ListingBody = withQuerystringResults((props) => { const { data = {}, @@ -22,6 +43,7 @@ const ListingBody = withQuerystringResults((props) => { nextBatch, isFolderContentsListing, hasLoaded, + id, } = props; let ListingBodyTemplate; @@ -50,13 +72,13 @@ const ListingBody = withQuerystringResults((props) => { return ( <> {data.headline && ( - 0, - })} - > - {data.headline} - + )} {listingItems?.length > 0 ? (
    diff --git a/src/components/manage/Blocks/Listing/ListingBody.test.jsx b/src/components/manage/Blocks/Listing/ListingBody.test.jsx index d52c7df814..8a5c359972 100644 --- a/src/components/manage/Blocks/Listing/ListingBody.test.jsx +++ b/src/components/manage/Blocks/Listing/ListingBody.test.jsx @@ -36,6 +36,26 @@ test('renders a ListingBody component', () => { content: { data: { is_folderish: true, + blocks: { + '839ee00b-013b-4f4a-9b10-8867938fdac3': { + '@type': 'listing', + block: '839ee00b-013b-4f4a-9b10-8867938fdac3', + headlineTag: 'h2', + query: [], + querystring: { + b_size: '2', + query: [ + { + i: 'path', + o: 'plone.app.querystring.operation.string.absolutePath', + v: '/', + }, + ], + sort_order: 'ascending', + }, + variation: 'default', + }, + }, }, }, intl: { diff --git a/src/components/manage/Blocks/Listing/__snapshots__/ListingBody.test.jsx.snap b/src/components/manage/Blocks/Listing/__snapshots__/ListingBody.test.jsx.snap index e81db3c83f..5fa1511b42 100644 --- a/src/components/manage/Blocks/Listing/__snapshots__/ListingBody.test.jsx.snap +++ b/src/components/manage/Blocks/Listing/__snapshots__/ListingBody.test.jsx.snap @@ -5,7 +5,7 @@ exports[`renders a ListingBody component 1`] = ` className="emptyListing" >
    state.querystringsearch.subrequests, ); @@ -50,7 +52,7 @@ export default function withQuerystringResults(WrappedComponent) { const folderItems = content?.is_folderish ? content.items : []; const hasQuery = querystring?.query?.length > 0; - const hasLoaded = hasQuery ? !querystringResults?.[id]?.loading : true; + const hasLoaded = hasQuery ? querystringResults?.[id]?.loaded : true; const listingItems = querystring?.query?.length > 0 && querystringResults?.[id] @@ -109,6 +111,8 @@ export default function withQuerystringResults(WrappedComponent) { } else { dispatch(getContent(initialPath, null, null, currentPage)); } + adaptedQueryRef.current = adaptedQuery; + currentPageRef.current = currentPage; }, [ id, isImageGallery, diff --git a/src/components/manage/Blocks/Search/components/Facets.jsx b/src/components/manage/Blocks/Search/components/Facets.jsx index 0adc1009d0..ea016334e7 100644 --- a/src/components/manage/Blocks/Search/components/Facets.jsx +++ b/src/components/manage/Blocks/Search/components/Facets.jsx @@ -1,7 +1,16 @@ -import React from 'react'; +import React, { useState, useMemo } from 'react'; +import { Button, Grid } from 'semantic-ui-react'; import { resolveExtension } from '@plone/volto/helpers/Extensions/withBlockExtensions'; import config from '@plone/volto/registry'; import { hasNonValueOperation, hasDateOperation } from '../utils'; +import { defineMessages, useIntl } from 'react-intl'; + +const messages = defineMessages({ + moreFilters: { id: 'More filters', defaultMessage: 'More filters' }, + lessFilters: { id: 'Less filters', defaultMessage: 'Less filters' }, + showFilters: { id: 'Show filters', defaultMessage: 'Show filters' }, + hideFilters: { id: 'Hide filters', defaultMessage: 'Hide filters' }, +}); const showFacet = (index) => { const { values } = index; @@ -14,6 +23,7 @@ const showFacet = (index) => { }; const Facets = (props) => { + const [hidden, setHidden] = useState(true); const { querystring, data = {}, @@ -24,11 +34,29 @@ const Facets = (props) => { } = props; const { search } = config.blocks.blocksConfig; + const advancedFilters = useMemo(() => { + let count = 0; + for (let facetSettings of data.facets || []) { + if (facetSettings.advanced) { + count++; + } + } + + if (count === data.facets?.length) { + return 2; + } + if (count) { + return 1; + } + return 0; + }, [data.facets]); + const FacetWrapper = facetWrapper; const query_to_values = Object.assign( {}, ...(data?.query?.query?.map(({ i, v }) => ({ [i]: v })) || []), ); + const intl = useIntl(); return ( <> @@ -36,6 +64,7 @@ const Facets = (props) => { ?.filter((facetSettings) => !facetSettings.hidden) .map((facetSettings) => { const field = facetSettings?.field?.value; + const isAdvanced = facetSettings?.advanced; const index = querystring.indexes[field] || {}; const { values = {} } = index; @@ -58,6 +87,7 @@ const Facets = (props) => { const isMulti = facetSettings.multiple; const selectedValue = facets[facetSettings?.field?.value]; + const visible = (isAdvanced && !hidden) || !isAdvanced; // TODO :handle changing the type of facet (multi/nonmulti) @@ -74,7 +104,11 @@ const Facets = (props) => { } = search.extensions.facetWidgets; return FacetWrapper && (isEditMode || showFacet(index)) ? ( - + { '' ); })} + {advancedFilters > 0 && ( + + + + )} ); }; diff --git a/src/components/manage/Blocks/Search/hocs/withSearch.jsx b/src/components/manage/Blocks/Search/hocs/withSearch.jsx index 332d6feb4f..b810cc282f 100644 --- a/src/components/manage/Blocks/Search/hocs/withSearch.jsx +++ b/src/components/manage/Blocks/Search/hocs/withSearch.jsx @@ -148,12 +148,16 @@ const getSearchFields = (searchData) => { }; /** - * A HOC that will mirror the search block state to a hash location + * A hook that will mirror the search block state to a hash location */ const useHashState = () => { const location = useLocation(); const history = useHistory(); + /** + * Required to maintain parameter compatibility. + With this we will maintain support for receiving hash (#) and search (?) type parameters. + */ const oldState = React.useMemo(() => { return { ...qs.parse(location.search), @@ -169,7 +173,7 @@ const useHashState = () => { const setSearchData = React.useCallback( (searchData) => { - const newParams = qs.parse(location.hash); + const newParams = qs.parse(location.search); let changed = false; @@ -186,11 +190,11 @@ const useHashState = () => { if (changed) { history.push({ - hash: qs.stringify(newParams), + search: qs.stringify(newParams), }); } }, - [history, oldState, location.hash], + [history, oldState, location.search], ); return [current, setSearchData]; diff --git a/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx b/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx index 626f721de2..950a688628 100644 --- a/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +++ b/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx @@ -11,6 +11,7 @@ import { Grid, Segment } from 'semantic-ui-react'; import { Button } from 'semantic-ui-react'; import { flushSync } from 'react-dom'; import { defineMessages, useIntl } from 'react-intl'; +import cx from 'classnames'; const messages = defineMessages({ searchButtonText: { @@ -19,11 +20,22 @@ const messages = defineMessages({ }, }); -const FacetWrapper = ({ children }) => ( - - {children} - -); +const FacetWrapper = ({ children, facetSettings = {}, visible }) => { + const { advanced, field = {} } = facetSettings; + + return ( + + {children} + + ); +}; const LeftColumnFacets = (props) => { const { diff --git a/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx b/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx index 091449bf1e..fc378b610f 100644 --- a/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +++ b/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx @@ -11,6 +11,7 @@ import { Grid, Segment } from 'semantic-ui-react'; import { Button } from 'semantic-ui-react'; import { flushSync } from 'react-dom'; import { defineMessages, useIntl } from 'react-intl'; +import cx from 'classnames'; const messages = defineMessages({ searchButtonText: { @@ -19,11 +20,22 @@ const messages = defineMessages({ }, }); -const FacetWrapper = ({ children }) => ( - - {children} - -); +const FacetWrapper = ({ children, facetSettings = {}, visible }) => { + const { advanced, field = {} } = facetSettings; + + return ( + + {children} + + ); +}; const RightColumnFacets = (props) => { const { diff --git a/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx b/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx index 21469e625e..5518382f7f 100644 --- a/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +++ b/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx @@ -11,6 +11,7 @@ import { SortOn, ViewSwitcher, } from '../components'; +import cx from 'classnames'; const messages = defineMessages({ searchButtonText: { @@ -19,11 +20,24 @@ const messages = defineMessages({ }, }); -const FacetWrapper = ({ children }) => ( - - {children} - -); +const FacetWrapper = ({ children, facetSettings = {}, visible }) => { + const { advanced, field = {} } = facetSettings; + + return ( + + {children} + + ); +}; const TopSideFacets = (props) => { const { @@ -117,6 +131,7 @@ const TopSideFacets = (props) => { )}
    + {data.facets?.length > 0 && (
    {data.facetsTitle &&

    {data.facetsTitle}

    } @@ -136,6 +151,7 @@ const TopSideFacets = (props) => {
    )} +
    diff --git a/src/components/manage/Toast/Toast.jsx b/src/components/manage/Toast/Toast.jsx index bd3421519e..96f4355656 100644 --- a/src/components/manage/Toast/Toast.jsx +++ b/src/components/manage/Toast/Toast.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Icon } from '@plone/volto/components'; +import Icon from '@plone/volto/components/theme/Icon/Icon'; import successSVG from '@plone/volto/icons/ready.svg'; import infoSVG from '@plone/volto/icons/info.svg'; diff --git a/src/components/manage/Widgets/ColorPickerWidget.jsx b/src/components/manage/Widgets/ColorPickerWidget.jsx index 929c0095e7..97c88c99be 100644 --- a/src/components/manage/Widgets/ColorPickerWidget.jsx +++ b/src/components/manage/Widgets/ColorPickerWidget.jsx @@ -51,7 +51,12 @@ const ColorPickerWidget = (props) => { onClick={(e) => { e.preventDefault(); e.stopPropagation(); - onChange(id, color.name); + onChange( + id, + value === color.name + ? props.missing_value + : color.name, + ); }} active={value === color.name} circular diff --git a/src/components/manage/Widgets/FileWidget.jsx b/src/components/manage/Widgets/FileWidget.jsx index 046437c33e..34db736933 100644 --- a/src/components/manage/Widgets/FileWidget.jsx +++ b/src/components/manage/Widgets/FileWidget.jsx @@ -11,7 +11,7 @@ import { injectIntl } from 'react-intl'; import deleteSVG from '@plone/volto/icons/delete.svg'; import { Icon, FormFieldWrapper } from '@plone/volto/components'; import loadable from '@loadable/component'; -import { flattenToAppURL } from '@plone/volto/helpers'; +import { flattenToAppURL, validateFileUploadSize } from '@plone/volto/helpers'; import { defineMessages, useIntl } from 'react-intl'; const imageMimetypes = [ @@ -95,6 +95,7 @@ const FileWidget = (props) => { */ const onDrop = (files) => { const file = files[0]; + if (!validateFileUploadSize(file, intl.formatMessage)) return; readAsDataURL(file).then((data) => { const fields = data.match(/^data:(.*);(.*),(.*)$/); onChange(id, { diff --git a/src/components/theme/Anontools/Anontools.jsx b/src/components/theme/Anontools/Anontools.jsx index 2b9e9fb5b6..ccff3638b0 100644 --- a/src/components/theme/Anontools/Anontools.jsx +++ b/src/components/theme/Anontools/Anontools.jsx @@ -1,83 +1,56 @@ -/** - * Anontools component. - * @module components/theme/Anontools/Anontools - */ - -import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; import { Menu } from 'semantic-ui-react'; import { FormattedMessage } from 'react-intl'; +import { flattenToAppURL } from '@plone/volto/helpers'; +import { useToken } from '@plone/volto/hooks/userSession/useToken'; +import { useContent } from '@plone/volto/hooks/content/useContent'; import config from '@plone/volto/registry'; -/** - * Anontools container class. - */ -export class Anontools extends Component { - /** - * Property types. - * @property {Object} propTypes Property types. - * @static - */ - static propTypes = { - token: PropTypes.string, - content: PropTypes.shape({ - '@id': PropTypes.string, - }), - }; - - /** - * Default properties. - * @property {Object} defaultProps Default properties. - * @static - */ - static defaultProps = { - token: null, - content: { - '@id': null, - }, - }; +const Anontools = () => { + const token = useToken(); + const { data: content } = useContent(); - /** - * Render method. - * @method render - * @returns {string} Markup for the component. - */ - render() { - const { settings } = config; - return ( - !this.props.token && ( - + const { settings } = config; + return ( + !token && ( + + + + + + + {settings.showSelfRegistration && ( - - + + - {settings.showSelfRegistration && ( - - - - - - )} - - ) - ); - } -} + )} + + ) + ); +}; + +export default Anontools; + +Anontools.propTypes = { + token: PropTypes.string, + content: PropTypes.shape({ + '@id': PropTypes.string, + }), +}; -export default connect((state) => ({ - token: state.userSession.token, - content: state.content.data, -}))(Anontools); +Anontools.defaultProps = { + token: null, + content: { + '@id': null, + }, +}; diff --git a/src/components/theme/Anontools/Anontools.test.jsx b/src/components/theme/Anontools/Anontools.test.jsx index 628e214925..28f54f9544 100644 --- a/src/components/theme/Anontools/Anontools.test.jsx +++ b/src/components/theme/Anontools/Anontools.test.jsx @@ -12,7 +12,14 @@ describe('Anontools', () => { it('renders an anontools component when no token is specified', () => { const store = mockStore({ userSession: { token: null }, - content: { data: { '@id': 'myid' } }, + content: { + data: { '@id': 'myid' }, + get: { + loading: false, + loaded: true, + error: null, + }, + }, intl: { locale: 'en', messages: {}, @@ -32,7 +39,14 @@ describe('Anontools', () => { it('should not render an anontools component when a token is specified', () => { const store = mockStore({ userSession: { token: '1234' }, - content: { data: {} }, + content: { + data: {}, + get: { + loading: false, + loaded: true, + error: null, + }, + }, intl: { locale: 'en', messages: {}, diff --git a/src/components/theme/Header/Header.jsx b/src/components/theme/Header/Header.jsx index 491f92d2ca..2cda868be9 100644 --- a/src/components/theme/Header/Header.jsx +++ b/src/components/theme/Header/Header.jsx @@ -1,12 +1,6 @@ -/** - * Header component. - * @module components/theme/Header/Header - */ - -import React, { Component } from 'react'; import { Container, Segment } from 'semantic-ui-react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; +import { useToken } from '@plone/volto/hooks/userSession/useToken'; import { Anontools, @@ -16,65 +10,45 @@ import { SearchWidget, } from '@plone/volto/components'; -/** - * Header component class. - * @class Header - * @extends Component - */ -class Header extends Component { - /** - * Property types. - * @property {Object} propTypes Property types. - * @static - */ - static propTypes = { - token: PropTypes.string, - pathname: PropTypes.string.isRequired, - }; - - /** - * Default properties. - * @property {Object} defaultProps Default properties. - * @static - */ - static defaultProps = { - token: null, - }; +const Header = ({ pathname }) => { + const token = useToken(); - /** - * Render method. - * @method render - * @returns {string} Markup for the component. - */ - render() { - return ( - - -
    -
    -
    - -
    - + return ( + + +
    +
    +
    +
    -
    - - {!this.props.token && ( -
    - -
    - )} -
    - + +
    +
    + + {!token && ( +
    +
    + )} +
    +
    - - - ); - } -} +
    + + + ); +}; + +export default Header; + +Header.propTypes = { + token: PropTypes.string, + pathname: PropTypes.string.isRequired, + content: PropTypes.objectOf(PropTypes.any), +}; -export default connect((state) => ({ - token: state.userSession.token, -}))(Header); +Header.defaultProps = { + token: null, + content: null, +}; diff --git a/src/components/theme/Header/Header.md b/src/components/theme/Header/Header.md deleted file mode 100644 index b097be635d..0000000000 --- a/src/components/theme/Header/Header.md +++ /dev/null @@ -1,27 +0,0 @@ -Header example: - -```jsx static -
    -``` - -Output: - -```jsx noeditor -const { Provider } = require('react-intl-redux'); -const configureStore = require('redux-mock-store').default; -const store = configureStore()({ - userSession: { - login: {}, - }, - intl: { - locale: 'en', - messages: {}, - }, -}); - -
    - -
    - -
    ; -``` diff --git a/src/components/theme/Header/Header.test.jsx b/src/components/theme/Header/Header.test.jsx index 8002a8cbba..4144f673bc 100644 --- a/src/components/theme/Header/Header.test.jsx +++ b/src/components/theme/Header/Header.test.jsx @@ -39,4 +39,22 @@ describe('Header', () => { const json = component.toJSON(); expect(json).toMatchSnapshot(); }); + + it('renders a header component - auth', () => { + const store = mockStore({ + userSession: { token: '1234567890' }, + intl: { + locale: 'en', + messages: {}, + }, + }); + + const component = renderer.create( + +
    + , + ); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); }); diff --git a/src/components/theme/Header/__snapshots__/Header.test.jsx.snap b/src/components/theme/Header/__snapshots__/Header.test.jsx.snap index 5cd7084418..43c47d0a58 100644 --- a/src/components/theme/Header/__snapshots__/Header.test.jsx.snap +++ b/src/components/theme/Header/__snapshots__/Header.test.jsx.snap @@ -1,5 +1,49 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Header renders a header component - auth 1`] = ` +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +`; + exports[`Header renders a header component 1`] = `
    ( - -

    - -

    -

    - -

    -

    - - - - ), - }} - /> -

    -

    - -

    -
    -); +const NotFound = () => { + const dispatch = useDispatch(); + const lang = useSelector((state) => state.intl.locale); + + useEffect(() => { + dispatch( + getNavigation( + config.settings.isMultilingual ? `/${toBackendLang(lang)}` : '/', + config.settings.navDepth, + ), + ); + }, [dispatch, lang]); + + return ( + + +

    + +

    +

    + +

    +

    + + + + ), + }} + /> +

    +

    + +

    +
    + ); +}; export default withServerErrorCode(404)(NotFound); diff --git a/src/components/theme/PasswordReset/PasswordReset.jsx b/src/components/theme/PasswordReset/PasswordReset.jsx index f676b2d3d0..e4513b9a6f 100644 --- a/src/components/theme/PasswordReset/PasswordReset.jsx +++ b/src/components/theme/PasswordReset/PasswordReset.jsx @@ -50,8 +50,8 @@ const messages = defineMessages({ defaultMessage: 'New password', }, passwordDescription: { - id: 'Enter your new password. Minimum 5 characters.', - defaultMessage: 'Enter your new password. Minimum 5 characters.', + id: 'Enter your new password. Minimum 8 characters.', + defaultMessage: 'Enter your new password. Minimum 8 characters.', }, passwordRepeatTitle: { id: 'Confirm password', @@ -227,6 +227,9 @@ class PasswordReset extends Component { ); } if (this.props.token) { + const errmsg = this.props.error + ? this.props.error.response.body.error + : null; return (
    - hasBlocksData(content) ? ( -
    +const NewsItemView = ({ content }) => { + const Container = + config.getComponent({ name: 'Container' }).component || SemanticContainer; + + return hasBlocksData(content) ? ( + -
    + ) : ( {content.title && ( @@ -57,6 +61,7 @@ const NewsItemView = ({ content }) => )} ); +}; /** * Property types. diff --git a/src/components/theme/View/RenderBlocks.jsx b/src/components/theme/View/RenderBlocks.jsx index 86de669b25..440dd53df0 100644 --- a/src/components/theme/View/RenderBlocks.jsx +++ b/src/components/theme/View/RenderBlocks.jsx @@ -44,7 +44,13 @@ const RenderBlocks = (props) => { }); return Block ? ( - + { - schema.fieldsets.push({ - id: 'styling', - title: intl.formatMessage(messages.styling), - fields: ['styles'], - }); + if (isEmpty(find(schema.fieldsets, { id: 'styling' }))) { + schema.fieldsets.push({ + id: 'styling', + title: intl.formatMessage(messages.styling), + fields: ['styles'], + }); + + schema.properties.styles = { + widget: 'object', + title: intl.formatMessage(messages.styling), + schema: cloneDeepSchema(EMPTY_STYLES_SCHEMA), + }; + } - schema.properties.styles = { - widget: 'object', - title: intl.formatMessage(messages.styling), - schema: EMPTY_STYLES_SCHEMA, - }; return schema; }; diff --git a/src/helpers/Extensions/withBlockSchemaEnhancer.test.js b/src/helpers/Extensions/withBlockSchemaEnhancer.test.js index e02a533d16..d5e29f4105 100644 --- a/src/helpers/Extensions/withBlockSchemaEnhancer.test.js +++ b/src/helpers/Extensions/withBlockSchemaEnhancer.test.js @@ -2,6 +2,7 @@ import { addExtensionFieldToSchema, applySchemaEnhancer, composeSchema, + addStyling, } from './withBlockSchemaEnhancer'; import config from '@plone/volto/registry'; @@ -246,3 +247,147 @@ describe('composeSchema', () => { expect(res).toStrictEqual([6, 9]); }); }); + +describe('addStyling', () => { + it('returns an enhanced schema with the styling wrapper object on it', () => { + const intl = { formatMessage: () => 'Styling' }; + + const schema = { + fieldsets: [ + { + id: 'default', + title: 'Default', + fields: [], + }, + ], + properties: {}, + required: [], + }; + + const result = addStyling({ schema, intl }); + + expect(result).toStrictEqual({ + fieldsets: [ + { id: 'default', title: 'Default', fields: [] }, + { id: 'styling', title: 'Styling', fields: ['styles'] }, + ], + properties: { + styles: { + widget: 'object', + title: 'Styling', + schema: { + fieldsets: [ + { + fields: [], + id: 'default', + title: 'Default', + }, + ], + properties: {}, + required: [], + }, + }, + }, + required: [], + }); + }); + + it('multiple schema enhancers', () => { + const intl = { formatMessage: () => 'Styling' }; + + const schema1 = { + fieldsets: [ + { + id: 'default', + title: 'Default', + fields: [], + }, + ], + properties: {}, + required: [], + }; + + const schema2 = { + fieldsets: [ + { + id: 'default', + title: 'Default', + fields: [], + }, + ], + properties: {}, + required: [], + }; + + const result = addStyling({ schema: schema1, intl }); + + // We add some fields to the styling schema + result.properties.styles.schema.properties.align = { + widget: 'align', + title: 'align', + actions: ['left', 'right', 'center'], + default: 'left', + }; + + result.properties.styles.schema.fieldsets[0].fields = ['align']; + + const result2 = addStyling({ schema: schema2, intl }); + + expect(result).toStrictEqual({ + fieldsets: [ + { id: 'default', title: 'Default', fields: [] }, + { id: 'styling', title: 'Styling', fields: ['styles'] }, + ], + properties: { + styles: { + widget: 'object', + title: 'Styling', + schema: { + fieldsets: [ + { + fields: ['align'], + id: 'default', + title: 'Default', + }, + ], + properties: { + align: { + widget: 'align', + title: 'align', + actions: ['left', 'right', 'center'], + default: 'left', + }, + }, + required: [], + }, + }, + }, + required: [], + }); + + expect(result2).toStrictEqual({ + fieldsets: [ + { id: 'default', title: 'Default', fields: [] }, + { id: 'styling', title: 'Styling', fields: ['styles'] }, + ], + properties: { + styles: { + widget: 'object', + title: 'Styling', + schema: { + fieldsets: [ + { + fields: [], + id: 'default', + title: 'Default', + }, + ], + properties: {}, + required: [], + }, + }, + }, + required: [], + }); + }); +}); diff --git a/src/helpers/FormValidation/FormValidation.js b/src/helpers/FormValidation/FormValidation.js index 0c5fd28eac..52941afa75 100644 --- a/src/helpers/FormValidation/FormValidation.js +++ b/src/helpers/FormValidation/FormValidation.js @@ -1,5 +1,8 @@ import { map, uniq, keys, intersection, isEmpty } from 'lodash'; import { messages } from '../MessageLabels/MessageLabels'; +import config from '@plone/volto/registry'; +import { toast } from 'react-toastify'; +import Toast from '@plone/volto/components/manage/Toast/Toast'; /** * Will return the intl message if invalid @@ -203,7 +206,7 @@ const validateRequiredFields = ( const type = schema.properties[requiredField]?.type; const widget = schema.properties[requiredField]?.widget; - let isEmpty = !formData[requiredField]; + let isEmpty = !formData[requiredField] && formData[requiredField] !== 0; if (!isEmpty) { if (type === 'array') { isEmpty = formData[requiredField] @@ -369,3 +372,29 @@ class FormValidation { } export default FormValidation; + +/** + * Check if a file upload is within the maximum size limit. + * @param {File} file + * @param {Function} intlFunc + * @returns {Boolean} + */ +export const validateFileUploadSize = (file, intlFunc) => { + const isValid = + !config.settings.maxFileUploadSize || + file.size <= config.settings.maxFileUploadSize; + if (!isValid) { + toast.error( + , + ); + } + return isValid; +}; diff --git a/src/helpers/FormValidation/FormValidation.test.js b/src/helpers/FormValidation/FormValidation.test.js index df25ac0038..9f97c6849a 100644 --- a/src/helpers/FormValidation/FormValidation.test.js +++ b/src/helpers/FormValidation/FormValidation.test.js @@ -66,6 +66,38 @@ describe('FormValidation', () => { }); }); + it('do not treat 0 as missing required value', () => { + let newSchema = { + ...schema, + properties: { + ...schema.properties, + age: { + title: 'age', + type: 'integer', + widget: 'number', + description: '', + }, + }, + required: ['age'], + }; + expect( + FormValidation.validateFieldsPerFieldset({ + schema: newSchema, + formData: { username: 'test username', age: null }, + formatMessage, + }), + ).toEqual({ + age: [messages.required.defaultMessage], + }); + expect( + FormValidation.validateFieldsPerFieldset({ + schema: newSchema, + formData: { username: 'test username', age: 0 }, + formatMessage, + }), + ).toEqual({}); + }); + it('validates incorrect email', () => { expect( FormValidation.validateFieldsPerFieldset({ diff --git a/src/helpers/MessageLabels/MessageLabels.js b/src/helpers/MessageLabels/MessageLabels.js index 69c8d3cfe9..2e1c4f6b90 100644 --- a/src/helpers/MessageLabels/MessageLabels.js +++ b/src/helpers/MessageLabels/MessageLabels.js @@ -260,6 +260,10 @@ export const messages = defineMessages({ id: 'Show groups of users below', defaultMessage: 'Show groups of users below', }, + urlClipboardCopy: { + id: 'Link copied to clipboard', + defaultMessage: 'Link copied to clipboard', + }, inspectRelations: { id: 'Inspect relations', defaultMessage: 'Inspect relations', @@ -332,4 +336,8 @@ export const messages = defineMessages({ id: 'Filter', defaultMessage: 'Filter', }, + fileTooLarge: { + id: 'fileTooLarge', + defaultMessage: 'This website does not accept files larger than {limit}', + }, }); diff --git a/src/helpers/ScrollToTop/ScrollToTop.jsx b/src/helpers/ScrollToTop/ScrollToTop.jsx index 6d4a87bcc7..8122fbea63 100644 --- a/src/helpers/ScrollToTop/ScrollToTop.jsx +++ b/src/helpers/ScrollToTop/ScrollToTop.jsx @@ -28,15 +28,17 @@ class ScrollToTop extends React.Component { * @memberof ScrollToTop */ componentDidUpdate(prevProps) { + const { location } = this.props; const noInitialBlocksFocus = // Do not scroll on /edit config.blocks?.initialBlocksFocus === null ? this.props.location?.pathname.slice(-5) !== '/edit' : true; + + const isHash = location?.hash || location?.pathname.hash; if ( - !this.props.location?.hash && - !this.props.location?.pathname.hash && + !isHash && noInitialBlocksFocus && - this.props.location?.pathname !== prevProps.location?.pathname + location?.pathname !== prevProps.location?.pathname ) { window.scrollTo(0, 0); } diff --git a/src/helpers/Utils/usePagination.js b/src/helpers/Utils/usePagination.js index acb12d2ac5..083ec48682 100644 --- a/src/helpers/Utils/usePagination.js +++ b/src/helpers/Utils/usePagination.js @@ -1,25 +1,83 @@ -import React from 'react'; -import { isEqual } from 'lodash'; -import { usePrevious } from './usePrevious'; -import useDeepCompareEffect from 'use-deep-compare-effect'; +import React, { useRef, useEffect } from 'react'; +import { useHistory, useLocation } from 'react-router-dom'; +import qs from 'query-string'; +import { useSelector } from 'react-redux'; +import { slugify } from '@plone/volto/helpers/Utils/Utils'; + +/** + * @function useCreatePageQueryStringKey + * @description A hook that creates a key with an id if there are multiple blocks with pagination. + * @returns {string} Example: page || page_012345678 + */ +const useCreatePageQueryStringKey = (id) => { + const blockTypesWithPagination = ['search', 'listing']; + const blocks = useSelector((state) => state?.content?.data?.blocks) || []; + const blocksLayout = + useSelector((state) => state?.content?.data?.blocks_layout?.items) || []; + const displayedBlocks = blocksLayout?.map((item) => blocks[item]); + const hasMultiplePaginations = + displayedBlocks.filter((item) => + blockTypesWithPagination.includes(item['@type']), + ).length > 1 || false; + + return hasMultiplePaginations ? slugify(`page-${id}`) : 'page'; +}; + +const useGetBlockType = (id) => { + const blocks = useSelector((state) => state?.content?.data?.blocks) || []; + const block = blocks[id]; + return block ? block?.['@type'] : null; +}; /** * A pagination helper that tracks the query and resets pagination in case the * query changes. */ -export const usePagination = (query, defaultPage = 1) => { - const previousQuery = usePrevious(query); - const [currentPage, setCurrentPage] = React.useState(defaultPage); +export const usePagination = (id = null, defaultPage = 1) => { + const location = useLocation(); + const history = useHistory(); + const pageQueryStringKey = useCreatePageQueryStringKey(id); + const block_type = useGetBlockType(id); + const pageQueryParam = + qs.parse(location.search)[pageQueryStringKey] || defaultPage; + const [currentPage, setCurrentPageState] = React.useState( + parseInt(pageQueryParam), + ); + const setCurrentPage = (page) => { + setCurrentPageState(page); + const newParams = { + ...qs.parse(location.search), + [pageQueryStringKey]: page, + }; + history.push({ search: qs.stringify(newParams) }); + }; - useDeepCompareEffect(() => { - setCurrentPage(defaultPage); - }, [query, previousQuery, defaultPage]); + const queryRef = useRef(qs.parse(location.search)?.query); + useEffect(() => { + if ( + queryRef.current !== qs.parse(location.search)?.query && + block_type === 'search' + ) { + setCurrentPageState(defaultPage); + const newParams = { + ...qs.parse(location.search), + [pageQueryStringKey]: defaultPage, + }; + delete newParams[pageQueryStringKey]; + history.replace({ search: qs.stringify(newParams) }); + queryRef.current = qs.parse(location.search)?.query; + } else { + setCurrentPageState( + parseInt( + qs.parse(location.search)?.[pageQueryStringKey] || defaultPage, + ), + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [location.search, block_type]); return { - currentPage: - previousQuery && !isEqual(previousQuery, query) - ? defaultPage - : currentPage, + currentPage, setCurrentPage, }; }; diff --git a/src/helpers/Utils/usePagination.test.js b/src/helpers/Utils/usePagination.test.js new file mode 100644 index 0000000000..26924d78a0 --- /dev/null +++ b/src/helpers/Utils/usePagination.test.js @@ -0,0 +1,115 @@ +import { renderHook } from '@testing-library/react-hooks'; +import { usePagination } from './usePagination'; +import * as redux from 'react-redux'; +import routeData from 'react-router'; +import { slugify } from '@plone/volto/helpers/Utils/Utils'; + +const searchBlockId = '545b33de-92cf-4747-969d-68851837b317'; +const searchBlockId2 = '454b33de-92cf-4747-969d-68851837b713'; +const searchBlock = { + '@type': 'search', + query: { + b_size: '4', + query: [ + { + i: 'path', + o: 'plone.app.querystring.operation.string.relativePath', + v: '', + }, + ], + sort_order: 'ascending', + }, + showSearchInput: true, + showTotalResults: true, +}; +let state = { + content: { + data: { + blocks: { + [searchBlockId]: searchBlock, + }, + blocks_layout: { + items: [searchBlockId], + }, + }, + }, +}; + +let mockUseLocationValue = { + pathname: '/testroute', + search: '', +}; + +const setUp = (searchParam, numberOfSearches) => { + mockUseLocationValue.search = searchParam; + if (numberOfSearches > 1) { + state.content.data.blocks[searchBlockId2] = searchBlock; + state.content.data.blocks_layout.items.push(searchBlockId2); + } + return renderHook(({ id, defaultPage }) => usePagination(id, defaultPage), { + initialProps: { + id: searchBlockId, + defaultPage: 1, + }, + }); +}; + +describe(`Tests for usePagination, for the block ${searchBlockId}`, () => { + const useLocation = jest.spyOn(routeData, 'useLocation'); + const useHistory = jest.spyOn(routeData, 'useHistory'); + const useSelector = jest.spyOn(redux, 'useSelector'); + beforeEach(() => { + useLocation.mockReturnValue(mockUseLocationValue); + useHistory.mockReturnValue({ replace: jest.fn() }); + useSelector.mockImplementation((cb) => cb(state)); + }); + + it('1 paginated block with id and defaultPage 1 - shoud be 1', () => { + const { result } = setUp(); + expect(result.current.currentPage).toBe(1); + }); + + it('1 paginated block without params - shoud be 1', () => { + const { result } = setUp(); + expect(result.current.currentPage).toBe(1); + }); + + const param1 = '?page=2'; + it(`1 paginated block with params: ${param1} - shoud be 2`, () => { + const { result } = setUp(param1); + expect(result.current.currentPage).toBe(2); + }); + + const param2 = `?${slugify(`page-${searchBlockId}`)}=2`; + it(`2 paginated blocks with current block in the params: ${param2} - shoud be 2`, () => { + const { result } = setUp(param2, 2); + expect(result.current.currentPage).toBe(2); + }); + + const param3 = `?${slugify(`page-${searchBlockId2}`)}=2`; + it(`2 paginated blocks with the other block in the params: ${param3} - shoud be 1`, () => { + const { result } = setUp(param3, 2); + expect(result.current.currentPage).toBe(1); + }); + + const param4 = `?${slugify(`page-${searchBlockId}`)}=2&${slugify( + `page-${searchBlockId2}`, + )}=1`; + it(`2 paginated blocks with both blocks in the params, current 2: ${param4} - shoud be 2`, () => { + const { result } = setUp(param4, 2); + expect(result.current.currentPage).toBe(2); + }); + + const param5 = `?${slugify(`page-${searchBlockId}`)}=1&${slugify( + `page-${searchBlockId2}`, + )}=2`; + it(`2 paginated blocks with both blocks in the params, current 1: ${param5} - shoud be 1`, () => { + const { result } = setUp(param5, 2); + expect(result.current.currentPage).toBe(1); + }); + + it(`2 paginated blocks with wrong page param: ${param1} - shoud be 1`, () => { + const { result } = setUp(param1, 2); + expect(result.current.currentPage).toBe(1); + }); +}); diff --git a/src/helpers/index.js b/src/helpers/index.js index e9b1c035eb..46b6fe6472 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -72,6 +72,7 @@ export { export { default as langmap } from './LanguageMap/LanguageMap'; export { default as Helmet } from './Helmet/Helmet'; export { default as FormValidation } from './FormValidation/FormValidation'; +export { validateFileUploadSize } from './FormValidation/FormValidation'; export { difference, getColor, diff --git a/src/hooks/clipboard/useClipboard.js b/src/hooks/clipboard/useClipboard.js new file mode 100644 index 0000000000..eaabbf7a15 --- /dev/null +++ b/src/hooks/clipboard/useClipboard.js @@ -0,0 +1,26 @@ +import { useState, useRef, useEffect, useCallback } from 'react'; + +export default function useClipboard(clipboardText = '') { + const stringToCopy = useRef(clipboardText); + const [copied, setCopied] = useState(false); + + //synchronous: window.clipboardData.setData(options.format || "text", text); + const copyToClipboard = async (text) => { + if ('clipboard' in navigator) { + return await navigator.clipboard.writeText(text); + } else { + return document.execCommand('copy', true, text); + } + }; + + const copyAction = useCallback(() => { + const copiedString = copyToClipboard(stringToCopy.current); + setCopied(copiedString); + }, [stringToCopy]); + + useEffect(() => { + stringToCopy.current = clipboardText; + }, [clipboardText]); + + return [copied, copyAction, setCopied]; +} diff --git a/src/hooks/content/useContent.js b/src/hooks/content/useContent.js new file mode 100644 index 0000000000..3001c1d7a4 --- /dev/null +++ b/src/hooks/content/useContent.js @@ -0,0 +1,31 @@ +import { useSelector, shallowEqual } from 'react-redux'; + +/** + * useContent hook + * + * This hook returns the current content that is stored in the Redux store in the + * `content` reducer, and returns it along with the related state (loading/loaded/error). + * + * @export + * @return {{ data: ContentData, loading: boolean, loaded: boolean, error: Error }} + */ +export function useContent() { + const data = useSelector((state) => state.content.data, shallowEqual); + const loading = useSelector((state) => state.content.get.loading); + const loaded = useSelector((state) => state.content.get.loaded); + const error = useSelector((state) => state.content.get.error, shallowEqual); + + return { data, loading, loaded, error }; +} + +// For reference purposes: Potential future useQuery version +// export function useContent() { +// // the cache will need to know the current location +// const pathname = useLocation(); +// const query = useQuery(getContentQuery({ path })) + +// // This might not be needed if we rename the properties +// const {isLoading: loading, isSuccess: loaded, ...rest} = query; + +// return { loading, loaded, ...rest }; +// } diff --git a/src/hooks/index.js b/src/hooks/index.js new file mode 100644 index 0000000000..ab9a86a472 --- /dev/null +++ b/src/hooks/index.js @@ -0,0 +1,2 @@ +export useClipboard from '@plone/volto/hooks/clipboard/useClipboard'; +export useToken from '@plone/volto/hooks/userSession/useToken'; diff --git a/src/hooks/userSession/useToken.js b/src/hooks/userSession/useToken.js new file mode 100644 index 0000000000..2d7d350f8d --- /dev/null +++ b/src/hooks/userSession/useToken.js @@ -0,0 +1,5 @@ +import { useSelector, shallowEqual } from 'react-redux'; + +export function useToken() { + return useSelector((state) => state.userSession.token, shallowEqual); +} diff --git a/theme/themes/pastanaga/extras/contents.less b/theme/themes/pastanaga/extras/contents.less index 149384714a..c4cea98911 100644 --- a/theme/themes/pastanaga/extras/contents.less +++ b/theme/themes/pastanaga/extras/contents.less @@ -94,6 +94,7 @@ .contents-table-wrapper { width: 100%; + overflow-x: auto; .ui.attached.table { width: 100%; diff --git a/theme/themes/pastanaga/extras/search.less b/theme/themes/pastanaga/extras/search.less index 0d803481d8..5f9f14a14e 100644 --- a/theme/themes/pastanaga/extras/search.less +++ b/theme/themes/pastanaga/extras/search.less @@ -75,3 +75,9 @@ text-align: center; } } + +.block.search { + .advanced-facet-hidden { + display: none !important; + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 24407fedae..249118acfe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3258,6 +3258,7 @@ __metadata: express: 4.17.3 filesize: 6 full-icu: 1.4.0 + github-slugger: 1.4.0 glob: 7.1.6 history: 4.10.1 hoist-non-react-statics: 3.3.2 @@ -12914,6 +12915,13 @@ __metadata: languageName: node linkType: hard +"github-slugger@npm:1.4.0": + version: 1.4.0 + resolution: "github-slugger@npm:1.4.0" + checksum: 4f52e7a21f5c6a4c5328f01fe4fe13ae8881fea78bfe31f9e72c4038f97e3e70d52fb85aa7633a52c501dc2486874474d9abd22aa61cbe9b113099a495551c6b + languageName: node + linkType: hard + "github-slugger@npm:^1.0.0": version: 1.5.0 resolution: "github-slugger@npm:1.5.0"