@eeacms/volto-eea-website-theme 1.33.2 → 2.0.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.
Files changed (54) hide show
  1. package/.eslintrc.js +7 -2
  2. package/CHANGELOG.md +44 -20
  3. package/docker-compose.yml +1 -1
  4. package/jest-addon.config.js +3 -0
  5. package/package.json +2 -1
  6. package/src/components/manage/Blocks/LayoutSettings/index.js +3 -1
  7. package/src/components/manage/Blocks/Title/index.js +3 -1
  8. package/src/components/manage/Blocks/Title/schema.js +3 -1
  9. package/src/components/theme/Banner/View.jsx +12 -5
  10. package/src/components/theme/DraftBackground/DraftBackground.jsx +32 -4
  11. package/src/components/theme/DraftBackground/DraftBackground.test.jsx +85 -0
  12. package/src/config.js +2 -0
  13. package/src/customizations/@plone/volto-slate/blocks/Text/TextBlockView.jsx +32 -0
  14. package/src/customizations/@plone/volto-slate/editor/render.jsx +75 -0
  15. package/src/customizations/@plone/volto-slate/elementEditor/utils.js +76 -75
  16. package/src/customizations/volto/components/manage/Blocks/Grid/Edit.jsx +70 -0
  17. package/src/customizations/volto/components/manage/Blocks/Grid/View.jsx +61 -0
  18. package/src/customizations/volto/components/manage/Blocks/Grid/readme.md +1 -0
  19. package/src/customizations/volto/components/manage/Blocks/Image/Edit.jsx +82 -23
  20. package/src/customizations/volto/components/manage/Blocks/Image/Edit.test.jsx +10 -3
  21. package/src/customizations/volto/components/manage/Blocks/Image/View.jsx +110 -111
  22. package/src/customizations/volto/components/manage/Blocks/Image/schema.js +17 -2
  23. package/src/customizations/volto/components/manage/Blocks/LeadImage/Edit.jsx +35 -14
  24. package/src/customizations/volto/components/manage/Blocks/LeadImage/View.jsx +65 -79
  25. package/src/customizations/volto/components/manage/Display/Display.jsx +306 -0
  26. package/src/customizations/volto/components/manage/Display/Readme.md +1 -0
  27. package/src/customizations/volto/components/manage/Sidebar/SidebarPopup copy.jsx +82 -0
  28. package/src/customizations/volto/components/manage/Toolbar/More.jsx +541 -0
  29. package/src/customizations/volto/components/manage/UniversalLink/UniversalLink.jsx +3 -1
  30. package/src/customizations/volto/components/manage/Widgets/ObjectBrowserWidget.jsx +24 -14
  31. package/src/customizations/volto/components/manage/Widgets/README.md +1 -0
  32. package/src/customizations/volto/components/manage/Workflow/README.txt +1 -0
  33. package/src/customizations/volto/components/manage/Workflow/Workflow.jsx +324 -0
  34. package/src/customizations/volto/components/manage/Workflow/Workflow.test.jsx +81 -0
  35. package/src/customizations/volto/components/theme/Comments/Comments.jsx +1 -2
  36. package/src/customizations/volto/components/theme/ContactForm/ContactForm.jsx +1 -1
  37. package/src/customizations/volto/components/theme/EventDetails/EventDetails.jsx +1 -0
  38. package/src/index.js +20 -14
  39. package/src/middleware/ok.js +4 -2
  40. package/src/middleware/voltoCustom.js +4 -2
  41. package/src/slate.js +10 -8
  42. package/src/customizations/@plone/volto-slate/editor/plugins/StyleMenu/README.txt +0 -1
  43. package/src/customizations/@plone/volto-slate/editor/plugins/StyleMenu/StyleMenu.jsx +0 -157
  44. package/src/customizations/@plone/volto-slate/editor/plugins/StyleMenu/utils.js +0 -168
  45. package/src/customizations/volto/components/manage/Add/Add.jsx +0 -498
  46. package/src/customizations/volto/components/manage/Add/readme.md +0 -1
  47. package/src/customizations/volto/components/manage/Contents/ContentsPropertiesModal.jsx +0 -232
  48. package/src/customizations/volto/components/manage/Form/Form.jsx +0 -810
  49. package/src/customizations/volto/components/manage/Form/Form.test.jsx +0 -1124
  50. package/src/customizations/volto/components/manage/Form/ModalForm.jsx +0 -326
  51. package/src/customizations/volto/components/manage/Sharing/Sharing.jsx +0 -528
  52. package/src/customizations/volto/components/manage/Sharing/Sharing.test.jsx +0 -72
  53. package/src/customizations/volto/components/manage/Widgets/ObjectBrowserWidget.test.jsx +0 -193
  54. package/src/customizations/volto/components/theme/AppExtras/AppExtras.jsx +0 -27
@@ -0,0 +1,324 @@
1
+ import React, { useEffect } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { compose } from 'redux';
4
+ import { useDispatch, useSelector, shallowEqual } from 'react-redux';
5
+ import { uniqBy } from 'lodash';
6
+ import { toast } from 'react-toastify';
7
+ import { defineMessages, useIntl } from 'react-intl';
8
+ import { useHistory } from 'react-router-dom';
9
+ import { Icon, Toast } from '@plone/volto/components';
10
+ import { FormFieldWrapper } from '@plone/volto/components';
11
+ import {
12
+ flattenToAppURL,
13
+ getWorkflowOptions,
14
+ getCurrentStateMapping,
15
+ } from '@plone/volto/helpers';
16
+ import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
17
+
18
+ import {
19
+ getContent,
20
+ getWorkflow,
21
+ transitionWorkflow,
22
+ } from '@plone/volto/actions';
23
+ import downSVG from '@plone/volto/icons/down-key.svg';
24
+ import upSVG from '@plone/volto/icons/up-key.svg';
25
+ import checkSVG from '@plone/volto/icons/check.svg';
26
+
27
+ const messages = defineMessages({
28
+ messageUpdated: {
29
+ id: 'Workflow updated.',
30
+ defaultMessage: 'Workflow updated.',
31
+ },
32
+ messageNoWorkflow: {
33
+ id: 'No workflow',
34
+ defaultMessage: 'No workflow',
35
+ },
36
+ notAllowedToUpdateWorkflow: {
37
+ id: 'notAllowedToUpdateWorkflow',
38
+ defaultMessage: 'Please fill out all the required fields',
39
+ },
40
+ state: {
41
+ id: 'State',
42
+ defaultMessage: 'State',
43
+ },
44
+ });
45
+
46
+ const SingleValue = injectLazyLibs('reactSelect')(({ children, ...props }) => {
47
+ const stateDecorator = {
48
+ marginRight: '10px',
49
+ display: 'inline-block',
50
+ backgroundColor: props.selectProps.value.color || null,
51
+ content: ' ',
52
+ height: '10px',
53
+ width: '10px',
54
+ borderRadius: '50%',
55
+ };
56
+ const { SingleValue } = props.reactSelect.components;
57
+ return (
58
+ <SingleValue {...props}>
59
+ <span style={stateDecorator} />
60
+ {children}
61
+ </SingleValue>
62
+ );
63
+ });
64
+
65
+ const Option = injectLazyLibs('reactSelect')((props) => {
66
+ const stateDecorator = {
67
+ marginRight: '10px',
68
+ display: 'inline-block',
69
+ backgroundColor:
70
+ props.selectProps.value.value === props.data.value
71
+ ? props.selectProps.value.color
72
+ : null,
73
+ content: ' ',
74
+ height: '10px',
75
+ width: '10px',
76
+ borderRadius: '50%',
77
+ border:
78
+ props.selectProps.value.value !== props.data.value
79
+ ? `1px solid ${props.data.color}`
80
+ : null,
81
+ };
82
+
83
+ const { Option } = props['reactSelect'].components;
84
+ return (
85
+ <Option {...props}>
86
+ <span style={stateDecorator} />
87
+ <div style={{ marginRight: 'auto' }}>{props.label}</div>
88
+ {props.isFocused && !props.isSelected && (
89
+ <Icon name={checkSVG} size="18px" color="#b8c6c8" />
90
+ )}
91
+ {props.isSelected && <Icon name={checkSVG} size="18px" color="#007bc1" />}
92
+ </Option>
93
+ );
94
+ });
95
+
96
+ const DropdownIndicator = injectLazyLibs('reactSelect')((props) => {
97
+ const { DropdownIndicator } = props.reactSelect.components;
98
+ return (
99
+ <DropdownIndicator {...props} data-testid="workflow-select-dropdown">
100
+ {props.selectProps.menuIsOpen ? (
101
+ <Icon name={upSVG} size="24px" color="#007bc1" />
102
+ ) : (
103
+ <Icon name={downSVG} size="24px" color="#007bc1" />
104
+ )}
105
+ </DropdownIndicator>
106
+ );
107
+ });
108
+
109
+ const selectTheme = (theme) => ({
110
+ ...theme,
111
+ borderRadius: 0,
112
+ colors: {
113
+ ...theme.colors,
114
+ primary25: 'hotpink',
115
+ primary: '#b8c6c8',
116
+ },
117
+ });
118
+
119
+ const customSelectStyles = {
120
+ control: (styles, state) => ({
121
+ ...styles,
122
+ border: 'none',
123
+ borderBottom: '2px solid #b8c6c8',
124
+ boxShadow: 'none',
125
+ borderBottomStyle: state.menuIsOpen ? 'dotted' : 'solid',
126
+ }),
127
+ menu: (styles, state) => ({
128
+ ...styles,
129
+ top: null,
130
+ marginTop: 0,
131
+ boxShadow: 'none',
132
+ borderBottom: '2px solid #b8c6c8',
133
+ }),
134
+ indicatorSeparator: (styles) => ({
135
+ ...styles,
136
+ width: null,
137
+ }),
138
+ valueContainer: (styles) => ({
139
+ ...styles,
140
+ padding: 0,
141
+ }),
142
+ option: (styles, state) => ({
143
+ ...styles,
144
+ backgroundColor: null,
145
+ minHeight: '50px',
146
+ display: 'flex',
147
+ justifyContent: 'space-between',
148
+ alignItems: 'center',
149
+ padding: '12px 12px',
150
+ color: state.isSelected
151
+ ? '#007bc1'
152
+ : state.isFocused
153
+ ? '#4a4a4a'
154
+ : 'inherit',
155
+ ':active': {
156
+ backgroundColor: null,
157
+ },
158
+ span: {
159
+ flex: '0 0 auto',
160
+ },
161
+ svg: {
162
+ flex: '0 0 auto',
163
+ },
164
+ }),
165
+ };
166
+
167
+ function useWorkflow() {
168
+ const history = useSelector((state) => state.workflow.history, shallowEqual);
169
+ const transitions = useSelector(
170
+ (state) => state.workflow.transitions,
171
+ shallowEqual,
172
+ );
173
+ const editingProgressSteps = useSelector((state) =>
174
+ state?.editingProgress?.editing?.loaded === true
175
+ ? state?.editingProgress?.result?.steps
176
+ : [],
177
+ );
178
+ const workflowLoaded = useSelector((state) => state.workflow.get?.loaded);
179
+ const loaded = useSelector((state) => state.workflow.transition.loaded);
180
+ const currentStateValue = useSelector(
181
+ (state) => getCurrentStateMapping(state.workflow.currentState),
182
+ shallowEqual,
183
+ );
184
+
185
+ return {
186
+ loaded,
187
+ history,
188
+ transitions,
189
+ currentStateValue,
190
+ workflowLoaded,
191
+ editingProgressSteps,
192
+ };
193
+ }
194
+
195
+ const filter_remaining_steps = (values, key) => {
196
+ return values.filter((value) => {
197
+ const is_not_ready = !value.is_ready;
198
+
199
+ if (!is_not_ready) {
200
+ return false;
201
+ }
202
+
203
+ const states = value.states;
204
+ const required_for_all = states?.indexOf('all') !== -1;
205
+
206
+ return (
207
+ (is_not_ready && required_for_all) ||
208
+ (is_not_ready && states?.indexOf(key) !== -1)
209
+ );
210
+ });
211
+ };
212
+
213
+ const Workflow = (props) => {
214
+ const intl = useIntl();
215
+ const history = useHistory();
216
+ const dispatch = useDispatch();
217
+ const {
218
+ loaded,
219
+ currentStateValue,
220
+ transitions,
221
+ workflowLoaded,
222
+ editingProgressSteps,
223
+ } = useWorkflow();
224
+ const content = useSelector((state) => state.content?.data, shallowEqual);
225
+ const [selectedOption, setSelectedOption] = React.useState(currentStateValue);
226
+ const { pathname } = props;
227
+
228
+ useEffect(() => {
229
+ dispatch(getWorkflow(pathname));
230
+ dispatch(getContent(pathname));
231
+ }, [dispatch, pathname, loaded]);
232
+
233
+ const transition = (selectedOption) => {
234
+ if (
235
+ filter_remaining_steps(
236
+ editingProgressSteps,
237
+ props?.content?.review_state || '',
238
+ ).length === 0
239
+ ) {
240
+ dispatch(transitionWorkflow(flattenToAppURL(selectedOption.url)));
241
+ setSelectedOption(selectedOption);
242
+ toast.success(
243
+ <Toast
244
+ success
245
+ title={intl.formatMessage(messages.messageUpdated)}
246
+ content=""
247
+ />,
248
+ );
249
+ } else {
250
+ toast.error(
251
+ <Toast
252
+ error
253
+ title={intl.formatMessage(messages.notAllowedToUpdateWorkflow)}
254
+ content=""
255
+ />,
256
+ );
257
+ }
258
+ };
259
+
260
+ useEffect(() => {
261
+ if (selectedOption?.value === 'createNewVersion' && workflowLoaded) {
262
+ history.push(`${pathname}.1`);
263
+ }
264
+ }, [history, pathname, selectedOption?.value, workflowLoaded]);
265
+
266
+ const { Placeholder } = props.reactSelect.components;
267
+ const Select = props.reactSelect.default;
268
+
269
+ const filterd_transitions = transitions.filter((transition) => {
270
+ if (
271
+ transition?.['@id']?.endsWith('markForDeletion') &&
272
+ props.content?.review_state === 'published'
273
+ ) {
274
+ return false;
275
+ }
276
+ return true;
277
+ });
278
+
279
+ return (
280
+ <FormFieldWrapper
281
+ id="state-select"
282
+ title={intl.formatMessage(messages.state)}
283
+ intl={intl}
284
+ {...props}
285
+ >
286
+ <Select
287
+ name="state-select"
288
+ className="react-select-container"
289
+ classNamePrefix="react-select"
290
+ isDisabled={!content.review_state || filterd_transitions.length === 0}
291
+ options={uniqBy(
292
+ filterd_transitions.map((transition) =>
293
+ getWorkflowOptions(transition),
294
+ ),
295
+ 'label',
296
+ ).concat(currentStateValue)}
297
+ styles={customSelectStyles}
298
+ theme={selectTheme}
299
+ components={{
300
+ DropdownIndicator,
301
+ Placeholder,
302
+ Option,
303
+ SingleValue,
304
+ }}
305
+ onChange={transition}
306
+ value={
307
+ content.review_state
308
+ ? currentStateValue
309
+ : {
310
+ label: intl.formatMessage(messages.messageNoWorkflow),
311
+ value: 'noworkflow',
312
+ }
313
+ }
314
+ isSearchable={false}
315
+ />
316
+ </FormFieldWrapper>
317
+ );
318
+ };
319
+
320
+ Workflow.propTypes = {
321
+ pathname: PropTypes.string.isRequired,
322
+ };
323
+
324
+ export default compose(injectLazyLibs(['reactSelect']))(Workflow);
@@ -0,0 +1,81 @@
1
+ import React from 'react';
2
+ import configureStore from 'redux-mock-store';
3
+ import { Provider } from 'react-intl-redux';
4
+ import { waitFor, render, screen } from '@testing-library/react';
5
+ import { MemoryRouter } from 'react-router-dom';
6
+ import config from '@plone/volto/registry';
7
+
8
+ import Workflow from './Workflow';
9
+
10
+ const mockStore = configureStore();
11
+
12
+ jest.mock('@plone/volto/helpers/Loadable/Loadable');
13
+ beforeAll(
14
+ async () =>
15
+ await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
16
+ );
17
+
18
+ beforeEach(() => {
19
+ config.settings.workflowMapping = {
20
+ published: { value: 'published', color: '#007bc1' },
21
+ publish: { value: 'publish', color: '#007bc1' },
22
+ private: { value: 'private', color: '#ed4033' },
23
+ pending: { value: 'pending', color: '#f6a808' },
24
+ send_back: { value: 'private', color: '#ed4033' },
25
+ retract: { value: 'private', color: '#ed4033' },
26
+ submit: { value: 'review', color: '#f4e037' },
27
+ };
28
+ });
29
+
30
+ describe('Workflow', () => {
31
+ it('renders an empty workflow component', async () => {
32
+ const store = mockStore({
33
+ workflow: {
34
+ currentState: { id: 'published', title: 'Published' },
35
+ history: [],
36
+ transition: { loaded: true },
37
+ transitions: [],
38
+ },
39
+ intl: {
40
+ locale: 'en',
41
+ messages: {},
42
+ },
43
+ content: { data: { review_state: 'published' } },
44
+ });
45
+ const { container } = render(
46
+ <Provider store={store}>
47
+ <MemoryRouter>
48
+ <Workflow pathname="/test" />
49
+ </MemoryRouter>
50
+ </Provider>,
51
+ );
52
+ await waitFor(() => screen.getByText(/Published/));
53
+ expect(container).toMatchSnapshot();
54
+ });
55
+
56
+ it('renders a workflow component', async () => {
57
+ const store = mockStore({
58
+ workflow: {
59
+ currentState: { id: 'private', title: 'Private' },
60
+ history: [{ review_state: 'private' }],
61
+ transition: { loaded: true },
62
+ transitions: [{ '@id': 'http://publish', title: 'Publish' }],
63
+ },
64
+ intl: {
65
+ locale: 'en',
66
+ messages: {},
67
+ },
68
+ content: { data: { review_state: 'private' } },
69
+ });
70
+
71
+ const { container } = render(
72
+ <Provider store={store}>
73
+ <MemoryRouter>
74
+ <Workflow pathname="/test" />
75
+ </MemoryRouter>
76
+ </Provider>,
77
+ );
78
+ await waitFor(() => screen.getByText('Private'));
79
+ expect(container).toMatchSnapshot();
80
+ });
81
+ });
@@ -33,8 +33,7 @@ const messages = defineMessages({
33
33
  defaultMessage: 'Comments',
34
34
  },
35
35
  commentDescription: {
36
- id:
37
- 'You can add a comment by filling out the form below. Plain text formatting.',
36
+ id: 'You can add a comment by filling out the form below. Plain text formatting.',
38
37
  defaultMessage:
39
38
  'You can add a comment by filling out the form below. Plain text formatting.',
40
39
  },
@@ -12,7 +12,7 @@ export class ContactFormComponent extends Component {
12
12
  }
13
13
 
14
14
  render() {
15
- const remoteUrl = config.settings.contactForm;
15
+ const remoteUrl = config.settings.contactForm || '/';
16
16
  return (
17
17
  <Container id="page-document">
18
18
  <p>
@@ -143,6 +143,7 @@ const EventDetails = ({ content, display_as = 'aside' }) => {
143
143
  className="ics-download"
144
144
  target="_blank"
145
145
  href={`${expandToBackendURL(content['@id'])}/ics_view`}
146
+ rel="noopener"
146
147
  >
147
148
  {intl.formatMessage(messages.downloadEvent)}
148
149
  </a>
package/src/index.js CHANGED
@@ -35,11 +35,7 @@ import { v4 as uuid } from 'uuid';
35
35
  import * as eea from './config';
36
36
  import React from 'react';
37
37
 
38
- const restrictedBlocks = [
39
- '__grid', // Grid/Teaser block (kitconcept)
40
- 'imagesGrid',
41
- 'teaser',
42
- ];
38
+ const restrictedBlocks = ['imagesGrid', 'teaser', 'dataFigure', 'plotly_chart'];
43
39
 
44
40
  /**
45
41
  * Customizes the variations of a tabs block by modifying their schema and semantic icons.
@@ -131,6 +127,12 @@ const applyConfig = (config) => {
131
127
  ...(config.settings.eea || {}),
132
128
  };
133
129
 
130
+ //include site title in <title>
131
+ if (!config.settings.siteTitleFormat) {
132
+ config.settings.siteTitleFormat = { includeSiteTitle: true };
133
+ } else config.settings.siteTitleFormat.includeSiteTitle = true;
134
+ config.settings.titleAndSiteTitleSeparator = '|';
135
+
134
136
  // #160689 Redirect contact-form to contact-us
135
137
  config.settings.contactForm = '/contact';
136
138
 
@@ -185,11 +187,13 @@ const applyConfig = (config) => {
185
187
 
186
188
  //Apply the image position style for image and leadimage blocks
187
189
  if (config.blocks.blocksConfig.leadimage) {
188
- config.blocks.blocksConfig.leadimage.schemaEnhancer = addStylingFieldsetSchemaEnhancerImagePosition;
190
+ config.blocks.blocksConfig.leadimage.schemaEnhancer =
191
+ addStylingFieldsetSchemaEnhancerImagePosition;
189
192
  }
190
193
 
191
194
  if (config.blocks.blocksConfig.image) {
192
- config.blocks.blocksConfig.image.schemaEnhancer = addStylingFieldsetSchemaEnhancerImagePosition;
195
+ config.blocks.blocksConfig.image.schemaEnhancer =
196
+ addStylingFieldsetSchemaEnhancerImagePosition;
193
197
  }
194
198
 
195
199
  // Set Languages in nextcloud-video-block
@@ -197,9 +201,8 @@ const applyConfig = (config) => {
197
201
  config?.blocks?.blocksConfig?.nextCloudVideo?.subtitlesLanguages &&
198
202
  config?.settings?.eea?.languages?.length > 0
199
203
  )
200
- config.blocks.blocksConfig.nextCloudVideo.subtitlesLanguages = config.settings.eea.languages.map(
201
- (el) => [el.code, el.name],
202
- );
204
+ config.blocks.blocksConfig.nextCloudVideo.subtitlesLanguages =
205
+ config.settings.eea.languages.map((el) => [el.code, el.name]);
203
206
 
204
207
  // Enable Title block
205
208
  config.blocks.blocksConfig.title.restricted = false;
@@ -224,7 +227,7 @@ const applyConfig = (config) => {
224
227
  };
225
228
  config.views.errorViews = {
226
229
  ...config.views.errorViews,
227
- '404': NotFound,
230
+ 404: NotFound,
228
231
  };
229
232
  // Apply slate text block customization
230
233
  if (config.blocks.blocksConfig.slate) {
@@ -467,19 +470,22 @@ const applyConfig = (config) => {
467
470
 
468
471
  // Group
469
472
  if (config.blocks.blocksConfig.group) {
470
- config.blocks.blocksConfig.group.schemaEnhancer = addStylingFieldsetSchemaEnhancer;
473
+ config.blocks.blocksConfig.group.schemaEnhancer =
474
+ addStylingFieldsetSchemaEnhancer;
471
475
  }
472
476
 
473
477
  // Columns
474
478
  if (config.blocks.blocksConfig.columnsBlock) {
475
479
  config.blocks.blocksConfig.columnsBlock.mostUsed = true;
476
- config.blocks.blocksConfig.columnsBlock.schemaEnhancer = addStylingFieldsetSchemaEnhancer;
480
+ config.blocks.blocksConfig.columnsBlock.schemaEnhancer =
481
+ addStylingFieldsetSchemaEnhancer;
477
482
  }
478
483
 
479
484
  // Listing
480
485
  if (config.blocks.blocksConfig.listing) {
481
486
  config.blocks.blocksConfig.listing.title = 'Listing (Content)';
482
- config.blocks.blocksConfig.listing.schemaEnhancer = addStylingFieldsetSchemaEnhancer;
487
+ config.blocks.blocksConfig.listing.schemaEnhancer =
488
+ addStylingFieldsetSchemaEnhancer;
483
489
  }
484
490
 
485
491
  // Block chooser
@@ -7,9 +7,11 @@ const ok = function (req, res, next) {
7
7
  res.send('ok');
8
8
  };
9
9
 
10
- export default function (express) {
10
+ const okMiddleware = function (express) {
11
11
  const middleware = express.Router();
12
12
  middleware.all(config?.settings?.okRoute || '/ok', ok);
13
13
  middleware.id = 'ok';
14
14
  return middleware;
15
- }
15
+ };
16
+
17
+ export default okMiddleware;
@@ -29,9 +29,11 @@ function voltoCustomMiddleware(req, res, next) {
29
29
  });
30
30
  }
31
31
 
32
- export default function (express) {
32
+ const registervoltoCustomMiddleware = function (express) {
33
33
  const middleware = express.Router();
34
34
  middleware.all(['**/voltoCustom.css$'], voltoCustomMiddleware);
35
35
  middleware.id = 'voltoCustom.css';
36
36
  return middleware;
37
- }
37
+ };
38
+
39
+ export default registervoltoCustomMiddleware;
package/src/slate.js CHANGED
@@ -150,8 +150,8 @@ export default function installSlate(config) {
150
150
  config = installCallout(config);
151
151
 
152
152
  try {
153
- renderLinkElement = require('@eeacms/volto-anchors/helpers')
154
- .renderLinkElement;
153
+ renderLinkElement =
154
+ require('@eeacms/volto-anchors/helpers').renderLinkElement;
155
155
  } catch {}
156
156
 
157
157
  installSlateToolbarButton({
@@ -190,14 +190,16 @@ export default function installSlate(config) {
190
190
  );
191
191
 
192
192
  // Remove blockquote, italic, strikethrough slate button from toolbarButtons
193
- config.settings.slate.toolbarButtons = config.settings.slate.toolbarButtons.filter(
194
- (item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
195
- );
193
+ config.settings.slate.toolbarButtons =
194
+ config.settings.slate.toolbarButtons.filter(
195
+ (item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
196
+ );
196
197
 
197
198
  // Remove blockquote, italic, strikethrough slate button from expandedToolbarButtons
198
- config.settings.slate.expandedToolbarButtons = config.settings.slate.expandedToolbarButtons.filter(
199
- (item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
200
- );
199
+ config.settings.slate.expandedToolbarButtons =
200
+ config.settings.slate.expandedToolbarButtons.filter(
201
+ (item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
202
+ );
201
203
 
202
204
  // Remove 'underline' and 'italic' hotkeys
203
205
  config.settings.slate.hotkeys = Object.keys(config.settings.slate.hotkeys)
@@ -1 +0,0 @@
1
- This customization fixes bugs with styleMenu not highlighting selected styles in some scenarios. This should be removed after https://github.com/plone/volto/pull/4852