@plone/volto 17.0.0-alpha.14 → 17.0.0-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +25 -0
  3. package/cypress/support/commands.js +18 -0
  4. package/locales/ca/LC_MESSAGES/volto.po +41 -0
  5. package/locales/ca.json +1 -1
  6. package/locales/de/LC_MESSAGES/volto.po +41 -0
  7. package/locales/de.json +1 -1
  8. package/locales/en/LC_MESSAGES/volto.po +41 -0
  9. package/locales/en.json +1 -1
  10. package/locales/es/LC_MESSAGES/volto.po +41 -0
  11. package/locales/es.json +1 -1
  12. package/locales/eu/LC_MESSAGES/volto.po +41 -0
  13. package/locales/eu.json +1 -1
  14. package/locales/fi/LC_MESSAGES/volto.po +41 -0
  15. package/locales/fi.json +1 -1
  16. package/locales/fr/LC_MESSAGES/volto.po +41 -0
  17. package/locales/fr.json +1 -1
  18. package/locales/it/LC_MESSAGES/volto.po +41 -0
  19. package/locales/it.json +1 -1
  20. package/locales/ja/LC_MESSAGES/volto.po +41 -0
  21. package/locales/ja.json +1 -1
  22. package/locales/nl/LC_MESSAGES/volto.po +41 -0
  23. package/locales/nl.json +1 -1
  24. package/locales/pt/LC_MESSAGES/volto.po +41 -0
  25. package/locales/pt.json +1 -1
  26. package/locales/pt_BR/LC_MESSAGES/volto.po +41 -0
  27. package/locales/pt_BR.json +1 -1
  28. package/locales/ro/LC_MESSAGES/volto.po +41 -0
  29. package/locales/ro.json +1 -1
  30. package/locales/volto.pot +42 -1
  31. package/locales/zh_CN/LC_MESSAGES/volto.po +41 -0
  32. package/locales/zh_CN.json +1 -1
  33. package/package.json +1 -1
  34. package/packages/volto-slate/package.json +1 -1
  35. package/packages/volto-slate/src/actions/index.js +1 -1
  36. package/packages/volto-slate/src/blocks/Text/index.js +10 -2
  37. package/packages/volto-slate/src/editor/index.js +4 -4
  38. package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +2 -2
  39. package/packages/volto-slate/src/editor/ui/index.js +15 -15
  40. package/packages/volto-slate/src/index.js +2 -2
  41. package/src/components/manage/AnchorPlugin/index.jsx +2 -2
  42. package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +3 -1
  43. package/src/components/manage/Blocks/Block/BlocksForm.jsx +19 -2
  44. package/src/components/manage/Blocks/Block/Edit.jsx +1 -1
  45. package/src/components/manage/Blocks/Block/Style.jsx +2 -2
  46. package/src/components/manage/Blocks/Container/Data.jsx +32 -0
  47. package/src/components/manage/Blocks/Container/Edit.jsx +174 -0
  48. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +120 -0
  49. package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +84 -0
  50. package/src/components/manage/Blocks/Container/SimpleContainerToolbar.jsx +54 -0
  51. package/src/components/manage/Blocks/Grid/Edit.jsx +33 -0
  52. package/src/components/manage/Blocks/Grid/View.jsx +42 -0
  53. package/src/components/manage/Blocks/Grid/adapter.js +14 -0
  54. package/src/components/manage/Blocks/Grid/grid-1.svg +6 -0
  55. package/src/components/manage/Blocks/Grid/grid-2.svg +9 -0
  56. package/src/components/manage/Blocks/Grid/grid-3.svg +10 -0
  57. package/src/components/manage/Blocks/Grid/grid-4.svg +11 -0
  58. package/src/components/manage/Blocks/Grid/schema.js +35 -0
  59. package/src/components/manage/Blocks/Grid/templates.js +47 -0
  60. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +2 -1
  61. package/src/components/manage/Blocks/Image/schema.js +11 -0
  62. package/src/components/manage/Blocks/Listing/DefaultTemplate.jsx +18 -3
  63. package/src/components/manage/Blocks/Listing/getAsyncData.js +3 -5
  64. package/src/components/manage/Blocks/Search/components/index.js +13 -13
  65. package/src/components/manage/Blocks/Search/hocs/index.js +2 -2
  66. package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +2 -2
  67. package/src/components/manage/Blocks/Teaser/schema.js +5 -0
  68. package/src/components/manage/Blocks/ToC/variations/index.js +3 -1
  69. package/src/components/manage/DragDropList/DragDropList.jsx +18 -13
  70. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +38 -0
  71. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +34 -0
  72. package/src/components/manage/TemplateChooser/template.svg +10 -0
  73. package/src/components/theme/Anontools/Anontools.stories.jsx +16 -6
  74. package/src/components/theme/Component/Component.jsx +1 -1
  75. package/src/components/theme/View/RenderBlocks.jsx +56 -27
  76. package/src/components/theme/View/RenderEmptyBlock.jsx +5 -0
  77. package/src/config/Blocks.jsx +44 -0
  78. package/src/config/RichTextEditor/Blocks.jsx +2 -2
  79. package/src/config/RichTextEditor/FromHTML.jsx +2 -2
  80. package/src/config/RichTextEditor/Styles.jsx +1 -1
  81. package/src/constants/Indexes.js +3 -1
  82. package/src/express-middleware/devproxy.js +1 -1
  83. package/src/express-middleware/files.js +3 -3
  84. package/src/express-middleware/images.js +4 -4
  85. package/src/express-middleware/robotstxt.js +1 -1
  86. package/src/express-middleware/sitemap.js +1 -1
  87. package/src/express-middleware/static.js +3 -3
  88. package/src/helpers/Blocks/Blocks.js +26 -0
  89. package/src/helpers/Blocks/Blocks.test.js +21 -0
  90. package/src/helpers/Extensions/index.js +2 -1
  91. package/src/helpers/Utils/UseDetectClickOutside.stories.jsx +191 -0
  92. package/src/helpers/Utils/Utils.js +25 -0
  93. package/src/helpers/index.js +11 -10
  94. package/src/icons/grid-block.svg +11 -0
  95. package/src/middleware/index.js +2 -2
  96. package/src/start-server.js +2 -2
  97. package/theme/themes/pastanaga/extras/blocks.less +3 -1
  98. package/theme/themes/pastanaga/extras/grid.less +426 -0
  99. package/theme/themes/pastanaga/extras/main.less +1 -0
@@ -2,10 +2,15 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { ConditionalLink, UniversalLink } from '@plone/volto/components';
4
4
  import { flattenToAppURL } from '@plone/volto/helpers';
5
-
6
5
  import { isInternalURL } from '@plone/volto/helpers/Url/Url';
7
6
 
8
- const DefaultTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
7
+ const DefaultTemplate = ({
8
+ headlineTag,
9
+ items,
10
+ linkTitle,
11
+ linkHref,
12
+ isEditMode,
13
+ }) => {
9
14
  let link = null;
10
15
  let href = linkHref?.[0]?.['@id'] || '';
11
16
 
@@ -19,6 +24,16 @@ const DefaultTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
19
24
  link = <UniversalLink href={href}>{linkTitle || href}</UniversalLink>;
20
25
  }
21
26
 
27
+ const getTitleTag = (tag) => {
28
+ const level = tag.slice(-1);
29
+ if (/\d/.test(level)) {
30
+ return `h${Number(level) + 1}`;
31
+ } else {
32
+ return 'h3';
33
+ }
34
+ };
35
+ const TitleTag = headlineTag ? getTitleTag(headlineTag) : 'h3';
36
+
22
37
  return (
23
38
  <>
24
39
  <div className="items">
@@ -26,7 +41,7 @@ const DefaultTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
26
41
  <div className="listing-item" key={item['@id']}>
27
42
  <ConditionalLink item={item} condition={!isEditMode}>
28
43
  <div className="listing-body">
29
- <h4>{item.title ? item.title : item.id}</h4>
44
+ <TitleTag>{item.title ? item.title : item.id}</TitleTag>
30
45
  <p>{item.description}</p>
31
46
  </div>
32
47
  </ConditionalLink>
@@ -1,13 +1,13 @@
1
1
  import { getQueryStringResults } from '@plone/volto/actions';
2
2
  import { resolveBlockExtensions } from '@plone/volto/helpers';
3
3
 
4
- const getListingBlockAsyncData = ({
4
+ export default function getListingBlockAsyncData({
5
5
  dispatch,
6
6
  id,
7
7
  data,
8
8
  path,
9
9
  blocksConfig,
10
- }) => {
10
+ }) {
11
11
  const { resolvedExtensions } = resolveBlockExtensions(data, blocksConfig);
12
12
 
13
13
  return [
@@ -24,6 +24,4 @@ const getListingBlockAsyncData = ({
24
24
  ),
25
25
  ),
26
26
  ];
27
- };
28
-
29
- export default getListingBlockAsyncData;
27
+ }
@@ -1,13 +1,13 @@
1
- export SearchDetails from './SearchDetails';
2
- export Facets from './Facets';
3
- export SelectFacet from './SelectFacet';
4
- export CheckboxFacet from './CheckboxFacet';
5
- export DateRangeFacet from './DateRangeFacet';
6
- export SearchInput from './SearchInput';
7
- export FilterList from './FilterList';
8
- export SortOn from './SortOn';
9
- export ToggleFacet from './ToggleFacet';
10
- export SelectFacetFilterListEntry from './SelectFacetFilterListEntry';
11
- export ToggleFacetFilterListEntry from './ToggleFacetFilterListEntry';
12
- export DateRangeFacetFilterListEntry from './DateRangeFacetFilterListEntry';
13
- export ViewSwitcher from './ViewSwitcher';
1
+ export { default as SearchDetails } from './SearchDetails';
2
+ export { default as Facets } from './Facets';
3
+ export { default as SelectFacet } from './SelectFacet';
4
+ export { default as CheckboxFacet } from './CheckboxFacet';
5
+ export { default as DateRangeFacet } from './DateRangeFacet';
6
+ export { default as SearchInput } from './SearchInput';
7
+ export { default as FilterList } from './FilterList';
8
+ export { default as SortOn } from './SortOn';
9
+ export { default as ToggleFacet } from './ToggleFacet';
10
+ export { default as SelectFacetFilterListEntry } from './SelectFacetFilterListEntry';
11
+ export { default as ToggleFacetFilterListEntry } from './ToggleFacetFilterListEntry';
12
+ export { default as DateRangeFacetFilterListEntry } from './DateRangeFacetFilterListEntry';
13
+ export { default as ViewSwitcher } from './ViewSwitcher';
@@ -1,2 +1,2 @@
1
- export withQueryString from './withQueryString';
2
- export withSearch from './withSearch';
1
+ export { default as withQueryString } from './withQueryString';
2
+ export { default as withSearch } from './withSearch';
@@ -10,7 +10,7 @@ function getDisplayName(WrappedComponent) {
10
10
  * A HOC that injects querystring metadata information from the backend.
11
11
  *
12
12
  */
13
- export default (WrappedComponent) => {
13
+ export default function withQueryString(WrappedComponent) {
14
14
  function WithQueryString(props) {
15
15
  const dispatch = useDispatch();
16
16
 
@@ -29,4 +29,4 @@ export default (WrappedComponent) => {
29
29
  WrappedComponent,
30
30
  )})`;
31
31
  return WithQueryString;
32
- };
32
+ }
@@ -101,3 +101,8 @@ export const TeaserSchema = ({ intl }) => {
101
101
 
102
102
  return schema;
103
103
  };
104
+
105
+ export const gridTeaserDisableStylingSchema = ({ schema, formData, intl }) => {
106
+ schema.fieldsets = schema.fieldsets.filter((item) => item.id !== 'styling');
107
+ return schema;
108
+ };
@@ -1,7 +1,7 @@
1
1
  import DefaultTocRenderer from './DefaultTocRenderer';
2
2
  import HorizontalMenu from './HorizontalMenu';
3
3
 
4
- export default [
4
+ const ToCVariations = [
5
5
  {
6
6
  id: 'default',
7
7
  title: 'Listing (default)',
@@ -14,3 +14,5 @@ export default [
14
14
  view: HorizontalMenu,
15
15
  },
16
16
  ];
17
+
18
+ export default ToCVariations;
@@ -53,6 +53,7 @@ const DragDropList = (props) => {
53
53
  const {
54
54
  childList,
55
55
  children,
56
+ direction = 'vertical',
56
57
  onMoveItem,
57
58
  as = 'div',
58
59
  style,
@@ -128,6 +129,7 @@ const DragDropList = (props) => {
128
129
  >
129
130
  <Droppable
130
131
  droppableId={uid}
132
+ direction={direction}
131
133
  renderClone={(provided, snapshot, rubric) => {
132
134
  const index = rubric.source.index;
133
135
  return children({
@@ -160,19 +162,22 @@ const DragDropList = (props) => {
160
162
  </Draggable>
161
163
  ))}
162
164
  {provided.placeholder}
163
- {!isEmpty(placeholderProps) && snapshot.isDraggingOver && (
164
- <div
165
- style={{
166
- position: 'absolute',
167
- top: placeholderProps.clientY,
168
- left: placeholderProps.clientX,
169
- height: placeholderProps.clientHeight,
170
- background: '#eee',
171
- width: placeholderProps.clientWidth,
172
- borderRadius: '3px',
173
- }}
174
- />
175
- )}
165
+ {/* TODO: Fix the ghost problem if horizontal dnd is present */}
166
+ {direction !== 'horizontal' &&
167
+ !isEmpty(placeholderProps) &&
168
+ snapshot.isDraggingOver && (
169
+ <div
170
+ style={{
171
+ position: 'absolute',
172
+ top: placeholderProps.clientY,
173
+ left: placeholderProps.clientX,
174
+ height: placeholderProps.clientHeight,
175
+ background: '#eee',
176
+ width: placeholderProps.clientWidth,
177
+ borderRadius: '3px',
178
+ }}
179
+ />
180
+ )}
176
181
  </AsDomComponent>
177
182
  )}
178
183
  </Droppable>
@@ -0,0 +1,38 @@
1
+ import PropTypes from 'prop-types';
2
+ import { useIntl } from 'react-intl';
3
+ import { Button, Grid, Message } from 'semantic-ui-react';
4
+
5
+ const TemplateChooser = ({ templates, onSelectTemplate }) => {
6
+ const intl = useIntl();
7
+ return (
8
+ <div className="template-chooser">
9
+ <Message>
10
+ <Grid columns={templates(intl).length}>
11
+ {templates(intl).map((template, index) => (
12
+ <Grid.Column key={template.id}>
13
+ <Button
14
+ className="template-chooser-item"
15
+ onClick={() => onSelectTemplate(index)}
16
+ >
17
+ <img src={template.image} alt="" />
18
+ <div className="template-chooser-title">
19
+ {intl.formatMessage({
20
+ id: template.id,
21
+ defaultMessage: template.title,
22
+ })}
23
+ </div>
24
+ </Button>
25
+ </Grid.Column>
26
+ ))}
27
+ </Grid>
28
+ </Message>
29
+ </div>
30
+ );
31
+ };
32
+
33
+ TemplateChooser.propTypes = {
34
+ templates: PropTypes.func.isRequired,
35
+ onSelectTemplate: PropTypes.func.isRequired,
36
+ };
37
+
38
+ export default TemplateChooser;
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import renderer from 'react-test-renderer';
3
+ import configureStore from 'redux-mock-store';
4
+ import { Provider } from 'react-intl-redux';
5
+ import TemplateChooser from './TemplateChooser';
6
+ import templateSVG from './template.svg';
7
+
8
+ const mockStore = configureStore();
9
+
10
+ test('renders a TemplateChooser component', () => {
11
+ const store = mockStore({
12
+ intl: {
13
+ locale: 'en',
14
+ messages: { templateid: 'Template default translation' },
15
+ },
16
+ });
17
+
18
+ const component = renderer.create(
19
+ <Provider store={store}>
20
+ <TemplateChooser
21
+ templates={() => [
22
+ {
23
+ image: templateSVG,
24
+ id: 'templateid',
25
+ defaultMessage: 'Template default translation',
26
+ },
27
+ ]}
28
+ onSelectTemplate={() => {}}
29
+ />
30
+ </Provider>,
31
+ );
32
+ const json = component.toJSON();
33
+ expect(json).toMatchSnapshot();
34
+ });
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="96" height="96" fill="#9FD1E5" rx="3"/>
4
+ <g fill="#FFF" opacity=".9" transform="translate(9 21)">
5
+ <rect width="78" height="29"/>
6
+ <rect width="36" height="8" y="33"/>
7
+ <rect width="77" height="10" y="45"/>
8
+ </g>
9
+ </g>
10
+ </svg>
@@ -1,15 +1,25 @@
1
1
  import React from 'react';
2
- import { Anontools as AnontoolsDefault } from './Anontools';
2
+ import AnontoolsDefault from './Anontools';
3
3
  import Wrapper from '@plone/volto/storybook';
4
4
 
5
5
  const AnontoolsComponent = ({ children, ...args }) => {
6
6
  return (
7
- <Wrapper location={{ pathname: '/folder2/folder21/doc212' }}>
7
+ <Wrapper
8
+ anonymous
9
+ location={{ pathname: '/folder2/folder21/doc212' }}
10
+ customStore={{
11
+ content: {
12
+ data: { '@id': 'http://myreturnURL' },
13
+ get: {
14
+ loaded: false,
15
+ loading: false,
16
+ error: null,
17
+ },
18
+ },
19
+ }}
20
+ >
8
21
  <div className="ui segment form attached" style={{ width: '400px' }}>
9
- <AnontoolsDefault
10
- userSession={{ token: null }}
11
- content={{ '@id': 'myid' }}
12
- />
22
+ <AnontoolsDefault />
13
23
  </div>
14
24
  </Wrapper>
15
25
  );
@@ -1,7 +1,7 @@
1
1
  import registry from '@plone/volto/registry';
2
2
 
3
3
  /**
4
- * A component that can autommatically look up its implementation from the
4
+ * A component that can automatically look up its implementation from the
5
5
  * registry based on the provided component `componentName`
6
6
  */
7
7
  const Component = ({ componentName, dependencies, ...rest }) => {
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { getBaseUrl, applyBlockDefaults } from '@plone/volto/helpers';
3
- import { defineMessages, injectIntl } from 'react-intl';
3
+ import { defineMessages, useIntl } from 'react-intl';
4
4
  import { map } from 'lodash';
5
+ import { MaybeWrap } from '@plone/volto/components';
5
6
  import {
6
7
  getBlocksFieldname,
7
8
  getBlocksLayoutFieldname,
@@ -10,6 +11,7 @@ import {
10
11
  import StyleWrapper from '@plone/volto/components/manage/Blocks/Block/StyleWrapper';
11
12
  import config from '@plone/volto/registry';
12
13
  import { ViewDefaultBlock } from '@plone/volto/components';
14
+ import RenderEmptyBlock from './RenderEmptyBlock';
13
15
 
14
16
  const messages = defineMessages({
15
17
  unknownBlock: {
@@ -23,7 +25,8 @@ const messages = defineMessages({
23
25
  });
24
26
 
25
27
  const RenderBlocks = (props) => {
26
- const { content, intl, location, metadata } = props;
28
+ const { content, location, metadata, blockWrapperTag } = props;
29
+ const intl = useIntl();
27
30
  const blocksFieldname = getBlocksFieldname(content);
28
31
  const blocksLayoutFieldname = getBlocksLayoutFieldname(content);
29
32
  const blocksConfig = props.blocksConfig || config.blocks.blocksConfig;
@@ -43,30 +46,56 @@ const RenderBlocks = (props) => {
43
46
  properties: content,
44
47
  });
45
48
 
46
- return Block ? (
47
- <StyleWrapper
48
- key={block}
49
- {...props}
50
- id={block}
51
- block={block}
52
- data={blockData}
53
- >
54
- <Block
55
- id={block}
56
- metadata={metadata}
57
- properties={content}
58
- data={blockData}
59
- path={getBaseUrl(location?.pathname || '')}
60
- blocksConfig={blocksConfig}
61
- />
62
- </StyleWrapper>
63
- ) : blockData ? (
64
- <div key={block}>
65
- {intl.formatMessage(messages.unknownBlock, {
66
- block: content[blocksFieldname]?.[block]?.['@type'],
67
- })}
68
- </div>
69
- ) : (
49
+ if (content[blocksFieldname]?.[block]?.['@type'] === 'empty') {
50
+ return (
51
+ <MaybeWrap
52
+ key={block}
53
+ condition={blockWrapperTag}
54
+ as={blockWrapperTag}
55
+ >
56
+ <RenderEmptyBlock />
57
+ </MaybeWrap>
58
+ );
59
+ }
60
+
61
+ if (Block) {
62
+ return (
63
+ <MaybeWrap
64
+ key={block}
65
+ condition={blockWrapperTag}
66
+ as={blockWrapperTag}
67
+ >
68
+ <StyleWrapper
69
+ key={block}
70
+ {...props}
71
+ id={block}
72
+ block={block}
73
+ data={blockData}
74
+ >
75
+ <Block
76
+ id={block}
77
+ metadata={metadata}
78
+ properties={content}
79
+ data={blockData}
80
+ path={getBaseUrl(location?.pathname || '')}
81
+ blocksConfig={blocksConfig}
82
+ />
83
+ </StyleWrapper>
84
+ </MaybeWrap>
85
+ );
86
+ }
87
+
88
+ if (blockData) {
89
+ return (
90
+ <div key={block}>
91
+ {intl.formatMessage(messages.unknownBlock, {
92
+ block: content[blocksFieldname]?.[block]?.['@type'],
93
+ })}
94
+ </div>
95
+ );
96
+ }
97
+
98
+ return (
70
99
  <div key={block}>{intl.formatMessage(messages.invalidBlock)}</div>
71
100
  );
72
101
  })}
@@ -76,4 +105,4 @@ const RenderBlocks = (props) => {
76
105
  );
77
106
  };
78
107
 
79
- export default injectIntl(RenderBlocks);
108
+ export default RenderBlocks;
@@ -0,0 +1,5 @@
1
+ const RenderEmptyBlock = () => {
2
+ return null;
3
+ };
4
+
5
+ export default RenderEmptyBlock;
@@ -42,6 +42,7 @@ import tableSVG from '@plone/volto/icons/table.svg';
42
42
  import listingBlockSVG from '@plone/volto/icons/content-listing.svg';
43
43
  import tocSVG from '@plone/volto/icons/list-bullet.svg';
44
44
  import searchSVG from '@plone/volto/icons/zoom.svg';
45
+ import gridSVG from '@plone/volto/icons/grid-block.svg';
45
46
  import imagesSVG from '@plone/volto/icons/images.svg';
46
47
 
47
48
  import ImageGalleryListingBlockTemplate from '@plone/volto/components/manage/Blocks/Listing/ImageGallery';
@@ -50,6 +51,14 @@ import TextSettingsSchema from '@plone/volto/components/manage/Blocks/Text/Schem
50
51
  import ImageSettingsSchema from '@plone/volto/components/manage/Blocks/Image/LayoutSchema';
51
52
  import ToCSettingsSchema from '@plone/volto/components/manage/Blocks/ToC/Schema';
52
53
 
54
+ import GridBlockView from '@plone/volto/components/manage/Blocks/Grid/View';
55
+ import GridBlockEdit from '@plone/volto/components/manage/Blocks/Grid/Edit';
56
+ import { GridBlockDataAdapter } from '@plone/volto/components/manage/Blocks/Grid/adapter';
57
+ import { GridBlockSchema } from '@plone/volto/components/manage/Blocks/Grid/schema';
58
+ import GridTemplates from '@plone/volto/components/manage/Blocks/Grid/templates';
59
+ import { gridTeaserDisableStylingSchema } from '@plone/volto/components/manage/Blocks/Teaser/schema';
60
+ import { gridImageDisableSizeAndPositionHandlersSchema } from '@plone/volto/components/manage/Blocks/Image/schema';
61
+
53
62
  import SearchBlockView from '@plone/volto/components/manage/Blocks/Search/SearchBlockView';
54
63
  import SearchBlockEdit from '@plone/volto/components/manage/Blocks/Search/SearchBlockEdit';
55
64
 
@@ -458,6 +467,27 @@ const blocksConfig = {
458
467
  },
459
468
  },
460
469
  },
470
+ // This next block is not named just grid for some reasons:
471
+ // 1.- Naming it grid will collide with the SemanticUI CSS of the Grid component
472
+ // 2.- It would prevent the transition from the old grid
473
+ // (based on @kitconcept/volto-blocks-grid) without having to perform any migration.
474
+ // This way, both can co-exist at the same time.
475
+ gridBlock: {
476
+ id: 'gridBlock',
477
+ title: 'Grid',
478
+ icon: gridSVG,
479
+ group: 'common',
480
+ view: GridBlockView,
481
+ edit: GridBlockEdit,
482
+ blockSchema: GridBlockSchema,
483
+ dataAdapter: GridBlockDataAdapter,
484
+ restricted: false,
485
+ mostUsed: true,
486
+ sidebarTab: 1,
487
+ templates: GridTemplates,
488
+ maxLength: 4,
489
+ allowedBlocks: ['image', 'listing', 'slate', 'teaser'],
490
+ },
461
491
  teaser: {
462
492
  id: 'teaser',
463
493
  title: 'Teaser',
@@ -481,6 +511,20 @@ const blocksConfig = {
481
511
  },
482
512
  };
483
513
 
514
+ // This is required in order to initialize the inner blocksConfig
515
+ // for the grid block, since we need to modify how the inner teaser
516
+ // block behave in it (= no schemaEnhancer fields for teasers inside a grid)
517
+ // Afterwards, it can be further customized in add-ons using the same technique.
518
+ blocksConfig.gridBlock.blocksConfig = { ...blocksConfig };
519
+ blocksConfig.gridBlock.blocksConfig.teaser = {
520
+ ...blocksConfig.teaser,
521
+ schemaEnhancer: gridTeaserDisableStylingSchema,
522
+ };
523
+ blocksConfig.gridBlock.blocksConfig.image = {
524
+ ...blocksConfig.image,
525
+ schemaEnhancer: gridImageDisableSizeAndPositionHandlersSchema,
526
+ };
527
+
484
528
  const requiredBlocks = ['title'];
485
529
 
486
530
  const initialBlocks = {};
@@ -1,4 +1,4 @@
1
- export default (props) => {
1
+ export default function Blocks(props) {
2
2
  const { draftJs, immutableLib } = props;
3
3
  const { DefaultDraftBlockRenderMap } = draftJs;
4
4
  const { Map } = immutableLib;
@@ -27,4 +27,4 @@ export default (props) => {
27
27
  const listBlockTypes = ['unordered-list-item', 'ordered-list-item'];
28
28
 
29
29
  return { extendedBlockRenderMap, blockStyleFn, listBlockTypes };
30
- };
30
+ }
@@ -1,8 +1,8 @@
1
- export default (element) => {
1
+ export default function FromHTMLCustomBlockFn(element) {
2
2
  if (element.className === 'callout') {
3
3
  return {
4
4
  type: 'callout',
5
5
  };
6
6
  }
7
7
  return null;
8
- };
8
+ }
@@ -13,7 +13,7 @@ import orderedListSVG from '@plone/volto/icons/list-numbered.svg';
13
13
  import blockquoteSVG from '@plone/volto/icons/quote.svg';
14
14
  import calloutSVG from '@plone/volto/icons/megaphone.svg';
15
15
 
16
- export default function (props) {
16
+ export default function Styles(props) {
17
17
  const createInlineStyleButton = props.draftJsCreateInlineStyleButton.default;
18
18
  const createBlockStyleButton = props.draftJsCreateBlockStyleButton.default;
19
19
 
@@ -3,7 +3,7 @@
3
3
  * @module constants/indexes
4
4
  */
5
5
 
6
- export default {
6
+ const Indexes = {
7
7
  sortable_title: { label: 'Title', type: 'string', sort_on: 'sortable_title' },
8
8
  review_state: { label: 'Review state', type: 'string' },
9
9
  ModificationDate: {
@@ -35,6 +35,8 @@ export default {
35
35
  Type: { label: 'Type', type: 'string' },
36
36
  };
37
37
 
38
+ export default Indexes;
39
+
38
40
  export const defaultIndexes = [
39
41
  'review_state',
40
42
  'ModificationDate',
@@ -37,7 +37,7 @@ function getEnv() {
37
37
  return _env;
38
38
  }
39
39
 
40
- export default function () {
40
+ export default function devProxyMiddleware() {
41
41
  const middleware = express.Router();
42
42
  const devProxy = createProxyMiddleware(filter, {
43
43
  selfHandleResponse: true,
@@ -9,7 +9,7 @@ const HEADERS = [
9
9
  'Content-Type',
10
10
  ];
11
11
 
12
- function fileMiddleware(req, res, next) {
12
+ function filesMiddlewareFn(req, res, next) {
13
13
  getAPIResourceWithAuth(req)
14
14
  .then((resource) => {
15
15
  // Just forward the headers that we need
@@ -24,10 +24,10 @@ function fileMiddleware(req, res, next) {
24
24
  .catch(next);
25
25
  }
26
26
 
27
- export default function () {
27
+ export default function filesMiddleware() {
28
28
  const middleware = express.Router();
29
29
 
30
- middleware.all(['**/@@download/*', '**/@@display-file/*'], fileMiddleware);
30
+ middleware.all(['**/@@download/*', '**/@@display-file/*'], filesMiddlewareFn);
31
31
  middleware.id = 'filesResourcesProcessor';
32
32
  return middleware;
33
33
  }
@@ -3,7 +3,7 @@ import { getAPIResourceWithAuth } from '@plone/volto/helpers';
3
3
 
4
4
  const HEADERS = ['content-type', 'content-disposition', 'cache-control'];
5
5
 
6
- function imageMiddleware(req, res, next) {
6
+ function imageMiddlewareFn(req, res, next) {
7
7
  getAPIResourceWithAuth(req)
8
8
  .then((resource) => {
9
9
  // Just forward the headers that we need
@@ -17,11 +17,11 @@ function imageMiddleware(req, res, next) {
17
17
  .catch(next);
18
18
  }
19
19
 
20
- export default function () {
20
+ export default function imagesMiddleware() {
21
21
  const middleware = express.Router();
22
22
 
23
- middleware.all(['**/@@images/*'], imageMiddleware);
24
- middleware.all(['/@portrait/*'], imageMiddleware);
23
+ middleware.all(['**/@@images/*'], imageMiddlewareFn);
24
+ middleware.all(['/@portrait/*'], imageMiddlewareFn);
25
25
  middleware.id = 'imageResourcesProcessor';
26
26
  return middleware;
27
27
  }
@@ -22,7 +22,7 @@ const envRobots = function (req, res, next) {
22
22
  res.send(process.env.VOLTO_ROBOTSTXT);
23
23
  };
24
24
 
25
- export default function () {
25
+ export default function robotstxtMiddleware() {
26
26
  const middleware = express.Router();
27
27
  if (process.env.VOLTO_ROBOTSTXT) {
28
28
  middleware.all('**/robots.txt', envRobots);
@@ -47,7 +47,7 @@ export const sitemapIndex = function (req, res, next) {
47
47
  });
48
48
  };
49
49
 
50
- export default function () {
50
+ export default function sitemapMiddleware() {
51
51
  const middleware = express.Router();
52
52
 
53
53
  middleware.all('**/sitemap.xml.gz', sitemap);