@plone/volto 18.0.0-alpha.34 → 18.0.0-alpha.35

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.
package/CHANGELOG.md CHANGED
@@ -17,6 +17,17 @@ myst:
17
17
 
18
18
  <!-- towncrier release notes start -->
19
19
 
20
+ ## 18.0.0-alpha.35 (2024-06-13)
21
+
22
+ ### Breaking
23
+
24
+ - Improve container detection, `config.settings.containerBlockTypes` is no longer needed @sneridagh [#6099](https://github.com/plone/volto/issues/6099)
25
+
26
+ ### Bugfix
27
+
28
+ - Support nested directories in public folder add-on sync folders both in dev and build mode @sneridagh [#6098](https://github.com/plone/volto/issues/6098)
29
+ - export getFieldURL from Url.js in helpers @dobri1408 [#6100](https://github.com/plone/volto/issues/6100)
30
+
20
31
  ## 18.0.0-alpha.34 (2024-06-13)
21
32
 
22
33
  ### Feature
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "18.0.0-alpha.34",
12
+ "version": "18.0.0-alpha.35",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -236,9 +236,9 @@
236
236
  "url": "^0.11.3",
237
237
  "use-deep-compare-effect": "1.8.1",
238
238
  "uuid": "^8.3.2",
239
- "@plone/volto-slate": "18.0.0-alpha.13",
239
+ "@plone/registry": "1.6.0",
240
240
  "@plone/scripts": "3.6.2",
241
- "@plone/registry": "1.6.0"
241
+ "@plone/volto-slate": "18.0.0-alpha.13"
242
242
  },
243
243
  "devDependencies": {
244
244
  "@babel/core": "^7.0.0",
@@ -358,8 +358,8 @@
358
358
  "webpack-dev-server": "4.11.1",
359
359
  "webpack-node-externals": "3.0.0",
360
360
  "why": "0.6.2",
361
- "@plone/volto-coresandbox": "1.0.0",
362
- "@plone/types": "1.0.0-alpha.15"
361
+ "@plone/types": "1.0.0-alpha.16",
362
+ "@plone/volto-coresandbox": "1.0.0"
363
363
  },
364
364
  "volta": {
365
365
  "node": "20.9.0"
package/razzle.config.js CHANGED
@@ -168,7 +168,13 @@ const defaultModify = ({
168
168
  files.forEach((file) => {
169
169
  const sourcePath = path.join(sourceDir, file);
170
170
  const targetPath = path.join(targetDir, file);
171
- fs.copyFileSync(sourcePath, targetPath);
171
+ const isDirectory = fs.statSync(sourcePath).isDirectory();
172
+ if (isDirectory) {
173
+ fs.mkdirSync(targetPath, { recursive: true });
174
+ mergeDirectories(sourcePath, targetPath);
175
+ } else {
176
+ fs.copyFileSync(sourcePath, targetPath);
177
+ }
172
178
  });
173
179
  };
174
180
 
@@ -178,7 +178,6 @@ let config = {
178
178
  querystringSearchGet: false,
179
179
  blockSettingsTabFieldsetsInitialStateOpen: true,
180
180
  excludeLinksAndReferencesMenuItem: false,
181
- containerBlockTypes: ['gridBlock'],
182
181
  siteTitleFormat: {
183
182
  includeSiteTitle: false,
184
183
  titleAndSiteTitleSeparator: '-',
@@ -693,6 +693,19 @@ export const getPreviousNextBlock = ({ content, block }) => {
693
693
  return [previousBlock, nextBlock];
694
694
  };
695
695
 
696
+ /**
697
+ * Check if a block is a container block
698
+ * check blocks from data as well since some add-ons use that
699
+ * such as @eeacms/volto-tabs-block
700
+ */
701
+ export function isBlockContainer(block) {
702
+ return (
703
+ block &&
704
+ (hasBlocksData(block) ||
705
+ (block.hasOwnProperty('data') && hasBlocksData(block.data)))
706
+ );
707
+ }
708
+
696
709
  /**
697
710
  * Given a `block` object and a list of block types, return a list of block ids matching the types
698
711
  *
@@ -701,8 +714,6 @@ export const getPreviousNextBlock = ({ content, block }) => {
701
714
  * @return {Array} An array of block ids
702
715
  */
703
716
  export function findBlocks(blocks, types, result = []) {
704
- const containerBlockTypes = config.settings.containerBlockTypes;
705
-
706
717
  Object.keys(blocks).forEach((blockId) => {
707
718
  const block = blocks[blockId];
708
719
  // check blocks from data as well since some add-ons use that
@@ -710,7 +721,7 @@ export function findBlocks(blocks, types, result = []) {
710
721
  const child_blocks = block.blocks || block.data?.blocks;
711
722
  if (types.includes(block['@type'])) {
712
723
  result.push(blockId);
713
- } else if (containerBlockTypes.includes(block['@type']) || child_blocks) {
724
+ } else if (isBlockContainer(block)) {
714
725
  findBlocks(child_blocks, types, result);
715
726
  }
716
727
  });
@@ -718,6 +729,9 @@ export function findBlocks(blocks, types, result = []) {
718
729
  return result;
719
730
  }
720
731
 
732
+ /**
733
+ * Build a block's hierarchy that the order tab can understand and uses
734
+ */
721
735
  export const getBlocksHierarchy = (properties) => {
722
736
  const blocksFieldName = getBlocksFieldname(properties);
723
737
  const blocksLayoutFieldname = getBlocksLayoutFieldname(properties);
@@ -725,10 +739,9 @@ export const getBlocksHierarchy = (properties) => {
725
739
  id: n,
726
740
  title: properties[blocksFieldName][n]?.['@type'],
727
741
  data: properties[blocksFieldName][n],
728
- children:
729
- properties[blocksFieldName][n]?.['@type'] === 'gridBlock'
730
- ? getBlocksHierarchy(properties[blocksFieldName][n])
731
- : [],
742
+ children: isBlockContainer(properties[blocksFieldName][n])
743
+ ? getBlocksHierarchy(properties[blocksFieldName][n])
744
+ : [],
732
745
  }));
733
746
  };
734
747
 
@@ -23,6 +23,7 @@ import {
23
23
  blocksFormGenerator,
24
24
  findBlocks,
25
25
  findContainer,
26
+ isBlockContainer,
26
27
  } from './Blocks';
27
28
 
28
29
  import config from '@plone/volto/registry';
@@ -1642,4 +1643,58 @@ describe('findContainer', () => {
1642
1643
  });
1643
1644
  });
1644
1645
  });
1646
+
1647
+ describe('isBlockContainer', () => {
1648
+ const blocksData = { blocks: {}, blocks_layout: { items: [] } };
1649
+
1650
+ it('basic test', () => {
1651
+ const formData = {
1652
+ title: 'Example',
1653
+ blocks: {
1654
+ 1: { title: 'title', '@type': 'title' },
1655
+ 2: { title: 'an image', '@type': 'image' },
1656
+ 3: { title: 'description', '@type': 'description' },
1657
+ 4: { title: 'a container', '@type': 'container', ...blocksData },
1658
+ },
1659
+ blocks_layout: {
1660
+ items: ['1', '2', '3', '4'],
1661
+ },
1662
+ };
1663
+
1664
+ const container = isBlockContainer(formData);
1665
+ expect(container).toBeTruthy();
1666
+ });
1667
+
1668
+ it('in data key (EEA add-ons)', () => {
1669
+ const formData = {
1670
+ title: 'Example',
1671
+ data: {
1672
+ blocks: {
1673
+ 1: { title: 'title', '@type': 'title' },
1674
+ 2: { title: 'an image', '@type': 'image' },
1675
+ 3: { title: 'description', '@type': 'description' },
1676
+ 4: { title: 'a container', '@type': 'container', ...blocksData },
1677
+ },
1678
+ blocks_layout: {
1679
+ items: ['1', '2', '3', '4'],
1680
+ },
1681
+ },
1682
+ };
1683
+
1684
+ const container = isBlockContainer(formData);
1685
+ expect(container).toBeTruthy();
1686
+ });
1687
+
1688
+ it('not a container', () => {
1689
+ const formData = {
1690
+ title: 'Example',
1691
+ styles: {
1692
+ color: 'red',
1693
+ },
1694
+ };
1695
+
1696
+ const container = isBlockContainer(formData);
1697
+ expect(container).toBeFalsy();
1698
+ });
1699
+ });
1645
1700
  });
@@ -30,6 +30,7 @@ export {
30
30
  removeProtocol,
31
31
  URLUtils,
32
32
  flattenScales,
33
+ getFieldURL,
33
34
  } from '@plone/volto/helpers/Url/Url';
34
35
  export { generateRobots } from '@plone/volto/helpers/Robots/Robots';
35
36
  export {
@@ -134,6 +134,12 @@ export function applySchemaDefaults({ data, schema, intl }: {
134
134
  * @return {Object} Derived data, with the defaults extracted from the schema
135
135
  */
136
136
  export function applyBlockDefaults({ data, intl, navRoot, contentType, ...rest }: any, blocksConfig: any): any;
137
+ /**
138
+ * Check if a block is a container block
139
+ * check blocks from data as well since some add-ons use that
140
+ * such as @eeacms/volto-tabs-block
141
+ */
142
+ export function isBlockContainer(block: any): boolean;
137
143
  /**
138
144
  * Given a `block` object and a list of block types, return a list of block ids matching the types
139
145
  *
@@ -18,7 +18,7 @@ export { getWidgetView } from "./Widget/widget";
18
18
  export { getSiteAsyncPropExtender } from "./Site";
19
19
  export { ContentTypeCondition } from "./Slots";
20
20
  export { getAuthToken, persistAuthToken } from "@plone/volto/helpers/AuthToken/AuthToken";
21
- export { addAppURL, expandToBackendURL, flattenHTMLToAppURL, flattenToAppURL, stripQuerystring, toPublicURL, isInternalURL, getParentUrl, getBaseUrl, getView, isCmsUi, getId, isUrl, normalizeUrl, removeProtocol, URLUtils, flattenScales } from "@plone/volto/helpers/Url/Url";
21
+ export { addAppURL, expandToBackendURL, flattenHTMLToAppURL, flattenToAppURL, stripQuerystring, toPublicURL, isInternalURL, getParentUrl, getBaseUrl, getView, isCmsUi, getId, isUrl, normalizeUrl, removeProtocol, URLUtils, flattenScales, getFieldURL } from "@plone/volto/helpers/Url/Url";
22
22
  export { nestContent, getLayoutFieldname, getContentIcon, getLanguageIndependentFields } from "@plone/volto/helpers/Content/Content";
23
23
  export { addBlock, insertBlock, blockHasValue, changeBlock, deleteBlock, emptyBlocksForm, getBlocks, getBlocksFieldname, getBlocksLayoutFieldname, hasBlocksData, moveBlock, mutateBlock, nextBlockId, previousBlockId, applyBlockDefaults, applySchemaDefaults, blocksFormGenerator, buildStyleClassNamesFromData, buildStyleClassNamesExtenders, buildStyleObjectFromData, getPreviousNextBlock, findBlocks, getBlocksHierarchy, moveBlockEnhanced } from "@plone/volto/helpers/Blocks/Blocks";
24
24
  export { getSimpleDefaultBlocks, getDefaultBlocks } from "@plone/volto/helpers/Blocks/defaultBlocks";