@plone/volto 16.7.0 → 16.8.0

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.draft CHANGED
@@ -1,25 +1,15 @@
1
- ## 16.7.0 (2023-01-11)
1
+ ## 16.8.0 (2023-01-18)
2
2
 
3
3
  ### Feature
4
4
 
5
- - Show project name and version in control panel @sneridagh [#4176](https://github.com/plone/volto/issues/4176)
6
- - Enhance Cypress content creation command @sneridagh [#4210](https://github.com/plone/volto/issues/4210)
5
+ - Autocomplete widget support for QueryStringWidget @sneridagh [#4177](https://github.com/plone/volto/issues/4177)
6
+ - Enhance the StyleWrapper classNames generator by adding look around classNames depending on the sorounding previous/next blocks. @sneridagh [#4260](https://github.com/plone/volto/issues/4260)
7
7
 
8
8
  ### Bugfix
9
9
 
10
- - Improve matching in keyboard slash menu. [davisagli] [#4187](https://github.com/plone/volto/issues/4187)
11
- - (fix): sidebar is not displaying correctly when clicking on a lead image field. @dobri1408 [#4191](https://github.com/plone/volto/issues/4191)
12
- - Cleanup `package.json` scripts section @sneridagh [#4193](https://github.com/plone/volto/issues/4193)
13
- - Fixed condition to select without vocabulary @SaraBianchi [#4200](https://github.com/plone/volto/issues/4200)
14
- - fix iframe covering the page due to a react-error-overlay bug @reebalazs [#4242](https://github.com/plone/volto/issues/4242)
10
+ - Fix typo in 4260 @sneridagh [#4268](https://github.com/plone/volto/issues/4268)
15
11
 
16
12
  ### Documentation
17
13
 
18
- - Add description for different types of blocks. @MAX-786 [#3827](https://github.com/plone/volto/issues/3827)
19
- - Update makefile to use Vale for spell, grammar, and style checking. Fix linkcheckbroken to return the correct exit code for broken links. Fix broken links. [stevepiercy] [#4181](https://github.com/plone/volto/issues/4181)
20
- - Add todo regarding management of Plone's backend. Update versions. [stevepiercy] [#4198](https://github.com/plone/volto/issues/4198)
21
- - Pin Sphinx<5,>=3 due to sphinx-book-theme 0.3.3 requirement. [stevepiercy] [#4199](https://github.com/plone/volto/issues/4199)
22
- - Add message about the status of Volto and Plone 6 Installation docs, directing the reader to the main Plone 6 docs. [stevepiercy] [#4209](https://github.com/plone/volto/issues/4209)
23
- - Clean up Glossary and integrate with main docs. See https://github.com/plone/documentation/issues/1415. [stevepiercy] [#4211](https://github.com/plone/volto/issues/4211)
24
- - Add some instructions for dealing with untranspiled add-ons and a lazy loading example for functional components. [cguardia] [#4233](https://github.com/plone/volto/issues/4233)
14
+ - Update links to docs to use correct versions. [stevepiercy] [#4256](https://github.com/plone/volto/issues/4256)
25
15
 
package/CHANGELOG.md CHANGED
@@ -8,6 +8,22 @@
8
8
 
9
9
  <!-- towncrier release notes start -->
10
10
 
11
+ ## 16.8.0 (2023-01-18)
12
+
13
+ ### Feature
14
+
15
+ - Autocomplete widget support for QueryStringWidget @sneridagh [#4177](https://github.com/plone/volto/issues/4177)
16
+ - Enhance the StyleWrapper classNames generator by adding look around classNames depending on the sorounding previous/next blocks. @sneridagh [#4260](https://github.com/plone/volto/issues/4260)
17
+
18
+ ### Bugfix
19
+
20
+ - Fix typo in 4260 @sneridagh [#4268](https://github.com/plone/volto/issues/4268)
21
+
22
+ ### Documentation
23
+
24
+ - Update links to docs to use correct versions. [stevepiercy] [#4256](https://github.com/plone/volto/issues/4256)
25
+
26
+
11
27
  ## 16.7.0 (2023-01-11)
12
28
 
13
29
  ### Feature
@@ -17,6 +33,7 @@
17
33
 
18
34
  ### Bugfix
19
35
 
36
+ - Use Grid instead of Table in Diffview @erral
20
37
  - Improve matching in keyboard slash menu. [davisagli] [#4187](https://github.com/plone/volto/issues/4187)
21
38
  - (fix): sidebar is not displaying correctly when clicking on a lead image field. @dobri1408 [#4191](https://github.com/plone/volto/issues/4191)
22
39
  - Cleanup `package.json` scripts section @sneridagh [#4193](https://github.com/plone/volto/issues/4193)
package/README.md CHANGED
@@ -278,7 +278,7 @@ make start-backend-docker
278
278
 
279
279
  or running Plone on your machine (advanced), additional dependencies might be
280
280
  required, only for Plone experienced integrators/developers. Check the [Plone
281
- Installation Documentation](https://docs.plone.org/manage/installing/installation.html).
281
+ Installation Documentation](https://6.docs.plone.org/install/index.html).
282
282
 
283
283
  ```shell
284
284
  make build-backend
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "16.7.0",
12
+ "version": "16.8.0",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plone/volto-slate",
3
- "version": "16.7.0",
3
+ "version": "16.8.0",
4
4
  "description": "Slate.js integration with Volto",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -1,15 +1,26 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
- import { buildStyleClassNamesFromData } from '@plone/volto/helpers';
3
+ import {
4
+ buildStyleClassNamesFromData,
5
+ buildStyleClassNamesExtenders,
6
+ } from '@plone/volto/helpers';
4
7
 
5
8
  const StyleWrapper = (props) => {
6
- const { children, data = {} } = props;
7
- const styles = buildStyleClassNamesFromData(data.styles);
9
+ let classNames = [];
10
+ const { children, content, data = {}, block } = props;
11
+ classNames = buildStyleClassNamesFromData(data.styles);
12
+
13
+ classNames = buildStyleClassNamesExtenders({
14
+ block,
15
+ content,
16
+ data,
17
+ classNames,
18
+ });
8
19
  const rewrittenChildren = React.Children.map(children, (child) => {
9
20
  if (React.isValidElement(child)) {
10
21
  const childProps = {
11
22
  ...props,
12
- className: cx([child.props.className, ...styles]),
23
+ className: cx([child.props.className, ...classNames]),
13
24
  };
14
25
  return React.cloneElement(child, childProps);
15
26
  }
@@ -14,6 +14,7 @@ import { getQuerystring } from '@plone/volto/actions';
14
14
  import { Icon } from '@plone/volto/components';
15
15
  import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
16
16
  import cx from 'classnames';
17
+ import config from '@plone/volto/registry';
17
18
 
18
19
  import {
19
20
  Option,
@@ -193,6 +194,23 @@ export class QuerystringWidgetComponent extends Component {
193
194
  />
194
195
  </Form.Field>
195
196
  );
197
+ case 'autocomplete':
198
+ const AutoCompleteComponent = config.widgets.widget.autocomplete;
199
+ const vocabulary = { '@id': this.props.indexes[row.i].vocabulary };
200
+ return (
201
+ <Form.Field style={{ flex: '1 0 auto', maxWidth: '92%' }}>
202
+ <AutoCompleteComponent
203
+ {...props}
204
+ vocabulary={vocabulary}
205
+ wrapped={false}
206
+ id={`id-${index}`}
207
+ title={`title-${index}`}
208
+ onChange={(_d, data) => {
209
+ this.onChangeValue(index, data);
210
+ }}
211
+ />
212
+ </Form.Field>
213
+ );
196
214
  case 'ReferenceWidget':
197
215
  default:
198
216
  // if (row.o === 'plone.app.querystring.operation.string.relativePath') {
@@ -7,3 +7,5 @@ export const styleClassNameConverters = {
7
7
  noprefix: (name, value) => value,
8
8
  bool: (name, value) => (value ? name : ''),
9
9
  };
10
+
11
+ export const styleClassNameExtenders = [];
@@ -24,7 +24,7 @@ import { loadables } from './Loadables';
24
24
  import { workflowMapping } from './Workflows';
25
25
 
26
26
  import { contentIcons } from './ContentIcons';
27
- import { styleClassNameConverters } from './Style';
27
+ import { styleClassNameConverters, styleClassNameExtenders } from './Style';
28
28
  import {
29
29
  controlPanelsIcons,
30
30
  filterControlPanels,
@@ -169,6 +169,7 @@ let config = {
169
169
  workflowMapping,
170
170
  errorHandlers: [], // callables for unhandled errors
171
171
  styleClassNameConverters,
172
+ styleClassNameExtenders,
172
173
  },
173
174
  experimental: {
174
175
  addBlockButton: {
@@ -481,3 +481,41 @@ export const buildStyleClassNamesFromData = (obj = {}, prefix = '') => {
481
481
  )
482
482
  .filter((v) => !!v);
483
483
  };
484
+
485
+ /**
486
+ * Generate classNames from extenders
487
+ *
488
+ * @function buildStyleClassNamesExtenders
489
+ * @param {Object} params An object with data, content and block (current block id)
490
+ * @return {Array} Extender classNames resultant array
491
+ */
492
+ export const buildStyleClassNamesExtenders = ({ block, content, data }) => {
493
+ return config.settings.styleClassNameExtenders.reduce(
494
+ (acc, extender) => extender({ block, content, data, classNames: acc }),
495
+ [],
496
+ );
497
+ };
498
+
499
+ /**
500
+ * Return previous/next blocks given the content object and the current block id
501
+ *
502
+ * @function getPreviousNextBlock
503
+ * @param {Object} params An object with the content object and block (current block id)
504
+ * @return {Array} An array with the signature [previousBlock, nextBlock]
505
+ */
506
+ export const getPreviousNextBlock = ({ content, block }) => {
507
+ const previousBlock =
508
+ content['blocks'][
509
+ content['blocks_layout'].items[
510
+ content['blocks_layout'].items.indexOf(block) - 1
511
+ ]
512
+ ];
513
+ const nextBlock =
514
+ content['blocks'][
515
+ content['blocks_layout'].items[
516
+ content['blocks_layout'].items.indexOf(block) + 1
517
+ ]
518
+ ];
519
+
520
+ return [previousBlock, nextBlock];
521
+ };
@@ -17,6 +17,8 @@ import {
17
17
  applyBlockDefaults,
18
18
  applySchemaDefaults,
19
19
  buildStyleClassNamesFromData,
20
+ buildStyleClassNamesExtenders,
21
+ getPreviousNextBlock,
20
22
  } from './Blocks';
21
23
 
22
24
  import config from '@plone/volto/registry';
@@ -938,4 +940,250 @@ describe('Blocks', () => {
938
940
  expect(buildStyleClassNamesFromData(styles)).toEqual([]);
939
941
  });
940
942
  });
943
+
944
+ describe('getPreviousNextBlock', () => {
945
+ it('basic functionality', () => {
946
+ const content = {
947
+ blocks: {
948
+ 1: {
949
+ '@type': 'slate',
950
+ styles: {
951
+ backgroundColor: 'grey',
952
+ },
953
+ },
954
+ 2: {
955
+ '@type': 'slate',
956
+ },
957
+ 3: {
958
+ '@type': 'slate',
959
+ styles: {
960
+ backgroundColor: 'grey',
961
+ },
962
+ },
963
+ },
964
+ blocks_layout: {
965
+ items: [1, 2, 3],
966
+ },
967
+ };
968
+ const block = 2;
969
+ const [previousBlock, nextBlock] = getPreviousNextBlock({
970
+ content,
971
+ block,
972
+ });
973
+ expect(previousBlock).toEqual({
974
+ '@type': 'slate',
975
+ styles: {
976
+ backgroundColor: 'grey',
977
+ },
978
+ });
979
+ expect(nextBlock).toEqual({
980
+ '@type': 'slate',
981
+ styles: {
982
+ backgroundColor: 'grey',
983
+ },
984
+ });
985
+ });
986
+ });
987
+
988
+ describe('buildStyleClassNamesExtenders', () => {
989
+ beforeAll(() => {
990
+ // Example styleClassNameExtenders
991
+ config.settings.styleClassNameExtenders = [
992
+ ({ block, content, data, classNames }) => {
993
+ let styles = [];
994
+ const [previousBlock, nextBlock] = getPreviousNextBlock({
995
+ content,
996
+ block,
997
+ });
998
+
999
+ if (nextBlock?.['@type']) {
1000
+ styles.push(`next--is--${nextBlock['@type']}`);
1001
+ }
1002
+
1003
+ if (data?.['@type'] === previousBlock?.['@type']) {
1004
+ styles.push('previous--is--same--block-type');
1005
+ }
1006
+
1007
+ if (data?.['@type'] === nextBlock?.['@type']) {
1008
+ styles.push('next--is--same--block-type');
1009
+ }
1010
+
1011
+ if (data?.['@type'] !== previousBlock?.['@type']) {
1012
+ styles.push('is--first--of--block-type');
1013
+ }
1014
+
1015
+ if (data?.['@type'] !== nextBlock?.['@type']) {
1016
+ styles.push('is--last--of--block-type');
1017
+ }
1018
+
1019
+ const previousColor =
1020
+ previousBlock?.styles?.backgroundColor ?? 'transparent';
1021
+ const currentColor = data?.styles?.backgroundColor ?? 'transparent';
1022
+ const nextColor = nextBlock?.styles?.backgroundColor ?? 'transparent';
1023
+
1024
+ if (currentColor === previousColor) {
1025
+ styles.push('previous--has--same--backgroundColor');
1026
+ } else if (currentColor !== previousColor) {
1027
+ styles.push('previous--has--different--backgroundColor');
1028
+ }
1029
+
1030
+ if (currentColor === nextColor) {
1031
+ styles.push('next--has--same--backgroundColor');
1032
+ } else if (currentColor !== nextColor) {
1033
+ styles.push('next--has--different--backgroundColor');
1034
+ }
1035
+
1036
+ return [...classNames, ...styles];
1037
+ },
1038
+ ];
1039
+ });
1040
+
1041
+ it('slate grey + slate + slate grey ', () => {
1042
+ const content = {
1043
+ blocks: {
1044
+ 1: {
1045
+ '@type': 'slate',
1046
+ styles: {
1047
+ backgroundColor: 'grey',
1048
+ },
1049
+ },
1050
+ 2: {
1051
+ '@type': 'slate',
1052
+ },
1053
+ 3: {
1054
+ '@type': 'slate',
1055
+ styles: {
1056
+ backgroundColor: 'grey',
1057
+ },
1058
+ },
1059
+ },
1060
+ blocks_layout: {
1061
+ items: [1, 2, 3],
1062
+ },
1063
+ };
1064
+ const block = 2;
1065
+ const data = content['blocks'][2];
1066
+
1067
+ expect(
1068
+ buildStyleClassNamesExtenders({ block, content, data }),
1069
+ ).toStrictEqual([
1070
+ 'next--is--slate',
1071
+ 'previous--is--same--block-type',
1072
+ 'next--is--same--block-type',
1073
+ 'previous--has--different--backgroundColor',
1074
+ 'next--has--different--backgroundColor',
1075
+ ]);
1076
+ });
1077
+
1078
+ it('slate grey + slate grey + slate grey ', () => {
1079
+ const content = {
1080
+ blocks: {
1081
+ 1: {
1082
+ '@type': 'slate',
1083
+ styles: {
1084
+ backgroundColor: 'grey',
1085
+ },
1086
+ },
1087
+ 2: {
1088
+ '@type': 'slate',
1089
+ styles: {
1090
+ backgroundColor: 'grey',
1091
+ },
1092
+ },
1093
+ 3: {
1094
+ '@type': 'slate',
1095
+ styles: {
1096
+ backgroundColor: 'grey',
1097
+ },
1098
+ },
1099
+ },
1100
+ blocks_layout: {
1101
+ items: [1, 2, 3],
1102
+ },
1103
+ };
1104
+ const block = 2;
1105
+ const data = content['blocks'][2];
1106
+
1107
+ expect(
1108
+ buildStyleClassNamesExtenders({ block, content, data }),
1109
+ ).toStrictEqual([
1110
+ 'next--is--slate',
1111
+ 'previous--is--same--block-type',
1112
+ 'next--is--same--block-type',
1113
+ 'previous--has--same--backgroundColor',
1114
+ 'next--has--same--backgroundColor',
1115
+ ]);
1116
+ });
1117
+
1118
+ it('grid + slate grey + slate grey ', () => {
1119
+ const content = {
1120
+ blocks: {
1121
+ 1: {
1122
+ '@type': '__grid',
1123
+ },
1124
+ 2: {
1125
+ '@type': 'slate',
1126
+ styles: {
1127
+ backgroundColor: 'grey',
1128
+ },
1129
+ },
1130
+ 3: {
1131
+ '@type': 'slate',
1132
+ styles: {
1133
+ backgroundColor: 'grey',
1134
+ },
1135
+ },
1136
+ },
1137
+ blocks_layout: {
1138
+ items: [1, 2, 3],
1139
+ },
1140
+ };
1141
+ const block = 2;
1142
+ const data = content['blocks'][2];
1143
+
1144
+ expect(
1145
+ buildStyleClassNamesExtenders({ block, content, data }),
1146
+ ).toStrictEqual([
1147
+ 'next--is--slate',
1148
+ 'next--is--same--block-type',
1149
+ 'is--first--of--block-type',
1150
+ 'previous--has--different--backgroundColor',
1151
+ 'next--has--same--backgroundColor',
1152
+ ]);
1153
+ });
1154
+
1155
+ it('grid + grid + slate grey ', () => {
1156
+ const content = {
1157
+ blocks: {
1158
+ 1: {
1159
+ '@type': '__grid',
1160
+ },
1161
+ 2: {
1162
+ '@type': '__grid',
1163
+ },
1164
+ 3: {
1165
+ '@type': 'slate',
1166
+ styles: {
1167
+ backgroundColor: 'grey',
1168
+ },
1169
+ },
1170
+ },
1171
+ blocks_layout: {
1172
+ items: [1, 2, 3],
1173
+ },
1174
+ };
1175
+ const block = 2;
1176
+ const data = content['blocks'][2];
1177
+
1178
+ expect(
1179
+ buildStyleClassNamesExtenders({ block, content, data }),
1180
+ ).toStrictEqual([
1181
+ 'next--is--slate',
1182
+ 'previous--is--same--block-type',
1183
+ 'is--last--of--block-type',
1184
+ 'previous--has--same--backgroundColor',
1185
+ 'next--has--different--backgroundColor',
1186
+ ]);
1187
+ });
1188
+ });
941
1189
  });
@@ -56,6 +56,8 @@ export {
56
56
  applyBlockDefaults,
57
57
  applySchemaDefaults,
58
58
  buildStyleClassNamesFromData,
59
+ buildStyleClassNamesExtenders,
60
+ getPreviousNextBlock,
59
61
  } from '@plone/volto/helpers/Blocks/Blocks';
60
62
  export BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
61
63
  export ScrollToTop from '@plone/volto/helpers/ScrollToTop/ScrollToTop';
@@ -20,7 +20,10 @@ import {
20
20
  } from '@plone/volto/config/RichTextEditor/Blocks';
21
21
  import FromHTMLCustomBlockFn from '@plone/volto/config/RichTextEditor/FromHTML';
22
22
  import { contentIcons } from '@plone/volto/config/ContentIcons';
23
- import { styleClassNameConverters } from '@plone/volto/config/Style';
23
+ import {
24
+ styleClassNameConverters,
25
+ styleClassNameExtenders,
26
+ } from '@plone/volto/config/Style';
24
27
 
25
28
  import {
26
29
  controlPanelsIcons,
@@ -76,6 +79,7 @@ config.set('settings', {
76
79
  downloadableObjects: ['File'],
77
80
  viewableInBrowserObjects: [],
78
81
  styleClassNameConverters,
82
+ styleClassNameExtenders,
79
83
  });
80
84
  config.set('blocks', {
81
85
  blocksConfig: {
package/news/4160.bug DELETED
@@ -1,2 +0,0 @@
1
- Use Grid instead of Table in Diffview
2
- [erral]