@eeacms/volto-bise-policy 1.0.0 → 1.0.1

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 (105) hide show
  1. package/CHANGELOG.md +15 -2
  2. package/package.json +3 -1
  3. package/src/components/manage/Blocks/NewsletterSignup/Edit.jsx +30 -0
  4. package/src/components/manage/Blocks/NewsletterSignup/View.jsx +13 -0
  5. package/src/components/manage/Blocks/NewsletterSignup/index.js +49 -0
  6. package/src/components/manage/Blocks/NewsletterSignup/schema.js +25 -0
  7. package/src/components/manage/Blocks/index.js +2 -0
  8. package/src/customizations/@eeacms/volto-eea-design-system/ui/Header/HeaderMenuPopUp.js +354 -0
  9. package/src/customizations/@eeacms/volto-eea-website-theme/components/theme/SubsiteClass.jsx +70 -0
  10. package/src/customizations/volto/components/manage/Edit/Edit.jsx +519 -0
  11. package/src/customizations/volto/components/manage/Form/BlockDataForm.jsx +28 -0
  12. package/src/customizations/volto/components/manage/Form/BlocksToolbar.jsx +214 -0
  13. package/src/customizations/volto/components/manage/Form/Field.jsx +269 -0
  14. package/src/customizations/volto/components/manage/Form/Form.jsx +804 -0
  15. package/src/customizations/volto/components/theme/Header/Header.jsx +151 -131
  16. package/src/index.js +31 -5
  17. package/theme/collections/message.overrides +10 -0
  18. package/theme/elements/container.overrides +156 -0
  19. package/theme/elements/segment.variables +1 -0
  20. package/theme/extras/header.overrides +107 -13
  21. package/theme/extras/header.variables +12 -0
  22. package/theme/extras/keyfacts.less +3 -3
  23. package/theme/extras/pluggables.less +17 -16
  24. package/theme/fonts/OpenSans-Bold.ttf +0 -0
  25. package/theme/fonts/OpenSans-Regular.ttf +0 -0
  26. package/theme/fonts/OpenSans-Semibold.ttf +0 -0
  27. package/theme/fonts/Rajdhani-Bold.ttf +0 -0
  28. package/theme/fonts/Rajdhani-Regular.ttf +0 -0
  29. package/theme/globals/helpers.less +75 -0
  30. package/theme/globals/natura2000.less +53 -0
  31. package/theme/globals/site.overrides +204 -4
  32. package/theme/globals/site.variables +5 -0
  33. package/theme/modules/accordion.overrides +3 -0
  34. package/theme/modules/accordion.variables +7 -0
  35. package/theme/modules/tab.overrides +176 -0
  36. package/theme/theme.config +1 -0
  37. package/theme/views/card.variables +2 -0
  38. package/locales/bg/LC_MESSAGES/volto.po +0 -14
  39. package/locales/bg.json +0 -1
  40. package/locales/bs/LC_MESSAGES/volto.po +0 -14
  41. package/locales/bs.json +0 -1
  42. package/locales/cs/LC_MESSAGES/volto.po +0 -14
  43. package/locales/cs.json +0 -1
  44. package/locales/da/LC_MESSAGES/volto.po +0 -14
  45. package/locales/da.json +0 -1
  46. package/locales/de/LC_MESSAGES/volto.po +0 -29
  47. package/locales/de.json +0 -1
  48. package/locales/el/LC_MESSAGES/volto.po +0 -14
  49. package/locales/el.json +0 -1
  50. package/locales/en/LC_MESSAGES/volto.po +0 -14
  51. package/locales/en.json +0 -1
  52. package/locales/es/LC_MESSAGES/volto.po +0 -24
  53. package/locales/es.json +0 -1
  54. package/locales/et/LC_MESSAGES/volto.po +0 -14
  55. package/locales/et.json +0 -1
  56. package/locales/eu/LC_MESSAGES/volto.po +0 -19
  57. package/locales/eu.json +0 -1
  58. package/locales/fi/LC_MESSAGES/volto.po +0 -14
  59. package/locales/fi.json +0 -1
  60. package/locales/fr/LC_MESSAGES/volto.po +0 -29
  61. package/locales/fr.json +0 -1
  62. package/locales/ga/LC_MESSAGES/volto.po +0 -14
  63. package/locales/ga.json +0 -1
  64. package/locales/hr/LC_MESSAGES/volto.po +0 -14
  65. package/locales/hr.json +0 -1
  66. package/locales/hu/LC_MESSAGES/volto.po +0 -14
  67. package/locales/hu.json +0 -1
  68. package/locales/is/LC_MESSAGES/volto.po +0 -14
  69. package/locales/is.json +0 -1
  70. package/locales/it/LC_MESSAGES/volto.po +0 -14
  71. package/locales/it.json +0 -1
  72. package/locales/ja/LC_MESSAGES/volto.po +0 -21
  73. package/locales/ja.json +0 -1
  74. package/locales/lt/LC_MESSAGES/volto.po +0 -14
  75. package/locales/lt.json +0 -1
  76. package/locales/lv/LC_MESSAGES/volto.po +0 -14
  77. package/locales/lv.json +0 -1
  78. package/locales/mk/LC_MESSAGES/volto.po +0 -14
  79. package/locales/mk.json +0 -1
  80. package/locales/mt/LC_MESSAGES/volto.po +0 -14
  81. package/locales/mt.json +0 -1
  82. package/locales/nl/LC_MESSAGES/volto.po +0 -33
  83. package/locales/nl.json +0 -1
  84. package/locales/no/LC_MESSAGES/volto.po +0 -14
  85. package/locales/no.json +0 -1
  86. package/locales/pl/LC_MESSAGES/volto.po +0 -14
  87. package/locales/pl.json +0 -1
  88. package/locales/pt/LC_MESSAGES/volto.po +0 -22
  89. package/locales/pt.json +0 -1
  90. package/locales/pt_BR/LC_MESSAGES/volto.po +0 -20
  91. package/locales/pt_BR.json +0 -1
  92. package/locales/ro/LC_MESSAGES/volto.po +0 -20
  93. package/locales/ro.json +0 -1
  94. package/locales/sh/LC_MESSAGES/volto.po +0 -14
  95. package/locales/sh.json +0 -1
  96. package/locales/sk/LC_MESSAGES/volto.po +0 -14
  97. package/locales/sk.json +0 -1
  98. package/locales/sl/LC_MESSAGES/volto.po +0 -14
  99. package/locales/sl.json +0 -1
  100. package/locales/sq/LC_MESSAGES/volto.po +0 -14
  101. package/locales/sq.json +0 -1
  102. package/locales/sv/LC_MESSAGES/volto.po +0 -14
  103. package/locales/sv.json +0 -1
  104. package/locales/tr/LC_MESSAGES/volto.po +0 -14
  105. package/locales/tr.json +0 -1
@@ -0,0 +1,519 @@
1
+ /**
2
+ * Edit container.
3
+ * @module components/manage/Edit/Edit
4
+ */
5
+
6
+ import React, { Component } from 'react';
7
+ import PropTypes from 'prop-types';
8
+ import { Helmet } from '@plone/volto/helpers';
9
+ import { connect } from 'react-redux';
10
+ import { compose } from 'redux';
11
+ import { asyncConnect, hasApiExpander } from '@plone/volto/helpers';
12
+ import { defineMessages, injectIntl } from 'react-intl';
13
+ import { Button, Grid, Menu } from 'semantic-ui-react';
14
+ import { Portal } from 'react-portal';
15
+ import qs from 'query-string';
16
+ import { find } from 'lodash';
17
+ import { toast } from 'react-toastify';
18
+
19
+ import {
20
+ Forbidden,
21
+ Form,
22
+ Icon,
23
+ Sidebar,
24
+ Toast,
25
+ Toolbar,
26
+ Unauthorized,
27
+ CompareLanguages,
28
+ TranslationObject,
29
+ } from '@plone/volto/components';
30
+ import {
31
+ updateContent,
32
+ getContent,
33
+ lockContent,
34
+ unlockContent,
35
+ getSchema,
36
+ listActions,
37
+ } from '@plone/volto/actions';
38
+ import { getBaseUrl, hasBlocksData } from '@plone/volto/helpers';
39
+ import { preloadLazyLibs } from '@plone/volto/helpers/Loadable';
40
+
41
+ import saveSVG from '@plone/volto/icons/save.svg';
42
+ import clearSVG from '@plone/volto/icons/clear.svg';
43
+
44
+ import config from '@plone/volto/registry';
45
+
46
+ const messages = defineMessages({
47
+ edit: {
48
+ id: 'Edit {title}',
49
+ defaultMessage: 'Edit {title}',
50
+ },
51
+ save: {
52
+ id: 'Save',
53
+ defaultMessage: 'Save',
54
+ },
55
+ cancel: {
56
+ id: 'Cancel',
57
+ defaultMessage: 'Cancel',
58
+ },
59
+ error: {
60
+ id: 'Error',
61
+ defaultMessage: 'Error',
62
+ },
63
+ });
64
+
65
+ /**
66
+ * Edit class.
67
+ * @class Edit
68
+ * @extends Component
69
+ */
70
+ class Edit extends Component {
71
+ /**
72
+ * Property types.
73
+ * @property {Object} propTypes Property types.
74
+ * @static
75
+ */
76
+ static propTypes = {
77
+ updateContent: PropTypes.func.isRequired,
78
+ getContent: PropTypes.func.isRequired,
79
+ getSchema: PropTypes.func.isRequired,
80
+ lockContent: PropTypes.func.isRequired,
81
+ unlockContent: PropTypes.func.isRequired,
82
+ updateRequest: PropTypes.shape({
83
+ loading: PropTypes.bool,
84
+ loaded: PropTypes.bool,
85
+ }).isRequired,
86
+ schemaRequest: PropTypes.shape({
87
+ loading: PropTypes.bool,
88
+ loaded: PropTypes.bool,
89
+ }).isRequired,
90
+ getRequest: PropTypes.shape({
91
+ loading: PropTypes.bool,
92
+ loaded: PropTypes.bool,
93
+ }).isRequired,
94
+ pathname: PropTypes.string.isRequired,
95
+ returnUrl: PropTypes.string,
96
+ content: PropTypes.shape({
97
+ '@type': PropTypes.string,
98
+ }),
99
+ schema: PropTypes.objectOf(PropTypes.any),
100
+ objectActions: PropTypes.array,
101
+ newId: PropTypes.string,
102
+ };
103
+
104
+ /**
105
+ * Default properties
106
+ * @property {Object} defaultProps Default properties.
107
+ * @static
108
+ */
109
+ static defaultProps = {
110
+ schema: null,
111
+ content: null,
112
+ returnUrl: null,
113
+ };
114
+
115
+ /**
116
+ * Constructor
117
+ * @method constructor
118
+ * @param {Object} props Component properties
119
+ * @constructs EditComponent
120
+ */
121
+ constructor(props) {
122
+ super(props);
123
+ this.state = {
124
+ visual: true,
125
+ isClient: false,
126
+ error: null,
127
+ formSelected: 'editForm',
128
+ newId: null,
129
+ };
130
+ this.onCancel = this.onCancel.bind(this);
131
+ this.onSubmit = this.onSubmit.bind(this);
132
+ }
133
+
134
+ /**
135
+ * Component did mount
136
+ * @method componentDidMount
137
+ * @returns {undefined}
138
+ */
139
+ componentDidMount() {
140
+ if (this.props.getRequest.loaded && this.props.content?.['@type']) {
141
+ this.props.getSchema(
142
+ this.props.content['@type'],
143
+ getBaseUrl(this.props.pathname),
144
+ );
145
+ }
146
+ this.setState({
147
+ isClient: true,
148
+ comparingLanguage: null,
149
+ });
150
+ }
151
+
152
+ /**
153
+ * Component will receive props
154
+ * @method componentWillReceiveProps
155
+ * @param {Object} nextProps Next properties
156
+ * @returns {undefined}
157
+ */
158
+ UNSAFE_componentWillReceiveProps(nextProps) {
159
+ if (this.props.getRequest.loading && nextProps.getRequest.loaded) {
160
+ if (nextProps.content['@type']) {
161
+ this.props.getSchema(
162
+ nextProps.content['@type'],
163
+ getBaseUrl(this.props.pathname),
164
+ );
165
+ }
166
+ }
167
+ if (this.props.schemaRequest.loading && nextProps.schemaRequest.loaded) {
168
+ if (!hasBlocksData(nextProps.schema.properties)) {
169
+ this.setState({
170
+ visual: false,
171
+ });
172
+ }
173
+ }
174
+ // Hack for make the Plone site editable by Volto Editor without checkings
175
+ if (this.props?.content?.['@type'] === 'Plone Site') {
176
+ this.setState({
177
+ visual: true,
178
+ });
179
+ }
180
+ if (this.props.updateRequest.loading && nextProps.updateRequest.loaded) {
181
+ this.props.history.push(
182
+ this.props.returnUrl || getBaseUrl(this.props.pathname),
183
+ );
184
+ }
185
+
186
+ if (this.props.updateRequest.loading && nextProps.updateRequest.error) {
187
+ const message =
188
+ nextProps.updateRequest.error?.response?.body?.error?.message ||
189
+ nextProps.updateRequest.error?.response?.body?.message ||
190
+ nextProps.updateRequest.error?.response?.text ||
191
+ '';
192
+
193
+ const error =
194
+ new DOMParser().parseFromString(message, 'text/html')?.all[0]
195
+ ?.textContent || message;
196
+
197
+ this.setState({ error: error });
198
+
199
+ toast.error(
200
+ <Toast
201
+ error
202
+ title={this.props.intl.formatMessage(messages.error)}
203
+ content={`${nextProps.updateRequest.error.status} ${error}`}
204
+ />,
205
+ );
206
+ }
207
+
208
+ if (
209
+ nextProps.compare_to &&
210
+ ((this.state.compareTo &&
211
+ nextProps.compare_to['@id'] !== this.state.compareTo['@id']) ||
212
+ !this.state.compareTo)
213
+ ) {
214
+ this.setState({ compareTo: nextProps.compare_to });
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Component will unmount
220
+ * @method componentWillUnmount
221
+ * @returns {undefined}
222
+ */
223
+ componentWillUnmount() {
224
+ if (this.props.content?.lock?.locked) {
225
+ const baseUrl = getBaseUrl(this.props.pathname);
226
+ const { newId } = this.state;
227
+ // Unlock the page, taking a possible id change into account
228
+ this.props.unlockContent(
229
+ newId ? baseUrl.replace(/\/[^/]*$/, '/' + newId) : baseUrl,
230
+ );
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Submit handler
236
+ * @method onSubmit
237
+ * @param {object} data Form data.
238
+ * @returns {undefined}
239
+ */
240
+ onSubmit(data) {
241
+ const lock_token = this.props.content?.lock?.token;
242
+ const headers = lock_token ? { 'Lock-Token': lock_token } : {};
243
+ // if the id has changed, remember it for unlock control
244
+ if ('id' in data) {
245
+ this.setState({ newId: data.id });
246
+ }
247
+ this.props.updateContent(getBaseUrl(this.props.pathname), data, headers);
248
+ }
249
+
250
+ /**
251
+ * Cancel handler
252
+ * @method onCancel
253
+ * @returns {undefined}
254
+ */
255
+ onCancel() {
256
+ this.props.history.push(
257
+ this.props.returnUrl || getBaseUrl(this.props.pathname),
258
+ );
259
+ }
260
+
261
+ setComparingLanguage(lang, content_id) {
262
+ this.setState({ comparingLanguage: lang });
263
+ this.props.getContent(content_id, null, 'compare_to', null);
264
+ }
265
+
266
+ form = React.createRef();
267
+ toolbarRef = React.createRef;
268
+ /**
269
+ * Render method.
270
+ * @method render
271
+ * @returns {string} Markup for the component.
272
+ */
273
+ render() {
274
+ const editPermission = find(this.props.objectActions, { id: 'edit' });
275
+
276
+ const pageEdit = (
277
+ <Form
278
+ isEditForm
279
+ ref={this.form}
280
+ schema={this.props.schema}
281
+ type={this.props.content?.['@type']}
282
+ formData={this.props.content}
283
+ requestError={this.state.error}
284
+ onSubmit={this.onSubmit}
285
+ hideActions
286
+ pathname={this.props.pathname}
287
+ visual={this.state.visual}
288
+ title={
289
+ this.props?.schema?.title
290
+ ? this.props.intl.formatMessage(messages.edit, {
291
+ title: this.props.schema.title,
292
+ })
293
+ : null
294
+ }
295
+ loading={this.props.updateRequest.loading}
296
+ isFormSelected={this.state.formSelected === 'editForm'}
297
+ onSelectForm={() => {
298
+ this.setState({ formSelected: 'editForm' });
299
+ }}
300
+ />
301
+ );
302
+
303
+ return (
304
+ <div id="page-edit">
305
+ {this.props.objectActions?.length > 0 && (
306
+ <>
307
+ {editPermission && (
308
+ <>
309
+ <Helmet
310
+ title={
311
+ this.props?.schema?.title
312
+ ? this.props.intl.formatMessage(messages.edit, {
313
+ title: this.props.schema.title,
314
+ })
315
+ : null
316
+ }
317
+ >
318
+ {this.props.content?.language && (
319
+ <html lang={this.props.content.language.token} />
320
+ )}
321
+ </Helmet>
322
+
323
+ {this.state.comparingLanguage && this.state.compareTo ? (
324
+ <Grid
325
+ celled="internally"
326
+ stackable
327
+ columns={2}
328
+ id="page-compare-translation"
329
+ >
330
+ <Grid.Column className="source-object">
331
+ <TranslationObject
332
+ translationObject={this.state.compareTo}
333
+ schema={this.props.schema}
334
+ pathname={this.props.pathname}
335
+ visual={this.state.visual}
336
+ isFormSelected={
337
+ this.state.formSelected === 'translationObjectForm'
338
+ }
339
+ onSelectForm={() => {
340
+ this.setState({
341
+ formSelected: 'translationObjectForm',
342
+ });
343
+ }}
344
+ />
345
+ </Grid.Column>
346
+ <Grid.Column>
347
+ <div className="new-translation">
348
+ <Menu pointing secondary attached tabular>
349
+ <Menu.Item
350
+ name={this.props.content.language?.token.toUpperCase()}
351
+ active={true}
352
+ >
353
+ {this.props.content.language?.token.toUpperCase()}
354
+ </Menu.Item>
355
+ </Menu>
356
+
357
+ {pageEdit}
358
+ </div>
359
+ </Grid.Column>
360
+ </Grid>
361
+ ) : (
362
+ pageEdit
363
+ )}
364
+ </>
365
+ )}
366
+
367
+ {editPermission && this.state.visual && this.state.isClient && (
368
+ <Portal node={document.getElementById('sidebar')}>
369
+ <Sidebar />
370
+ </Portal>
371
+ )}
372
+ </>
373
+ )}
374
+ {!editPermission && (
375
+ <>
376
+ {this.props.token ? (
377
+ <Forbidden
378
+ pathname={this.props.pathname}
379
+ staticContext={this.props.staticContext}
380
+ />
381
+ ) : (
382
+ <Unauthorized
383
+ pathname={this.props.pathname}
384
+ staticContext={this.props.staticContext}
385
+ />
386
+ )}
387
+ </>
388
+ )}
389
+ {this.state.isClient && (
390
+ <Portal node={document.getElementById('toolbar')}>
391
+ <Toolbar
392
+ pathname={this.props.pathname}
393
+ hideDefaultViewButtons
394
+ inner={
395
+ <>
396
+ <Button
397
+ id="toolbar-save"
398
+ className="save"
399
+ aria-label={this.props.intl.formatMessage(messages.save)}
400
+ onClick={() => this.form.current.onSubmit()}
401
+ disabled={this.props.updateRequest.loading}
402
+ loading={this.props.updateRequest.loading}
403
+ >
404
+ <Icon
405
+ name={saveSVG}
406
+ className="circled"
407
+ size="30px"
408
+ title={this.props.intl.formatMessage(messages.save)}
409
+ />
410
+ </Button>
411
+ <Button
412
+ className="cancel"
413
+ aria-label={this.props.intl.formatMessage(messages.cancel)}
414
+ onClick={() => this.onCancel()}
415
+ >
416
+ <Icon
417
+ name={clearSVG}
418
+ className="circled"
419
+ size="30px"
420
+ title={this.props.intl.formatMessage(messages.cancel)}
421
+ />
422
+ </Button>
423
+
424
+ {config.settings.isMultilingual && (
425
+ <CompareLanguages
426
+ content={this.props.content}
427
+ visual={this.state.visual}
428
+ setComparingLanguage={(lang, id) => {
429
+ this.setComparingLanguage(lang, id);
430
+ }}
431
+ comparingLanguage={this.state.comparingLanguage}
432
+ pathname={this.props.location.pathname}
433
+ toolbarRef={this.toolbarRef}
434
+ />
435
+ )}
436
+ </>
437
+ }
438
+ />
439
+ </Portal>
440
+ )}
441
+ </div>
442
+ );
443
+ }
444
+ }
445
+
446
+ export const __test__ = compose(
447
+ injectIntl,
448
+ connect(
449
+ (state, props) => ({
450
+ objectActions: state.actions.actions.object,
451
+ token: state.userSession.token,
452
+ content: state.content.data,
453
+ compare_to: state.content.subrequests?.compare_to?.data,
454
+ schema: state.schema.schema,
455
+ getRequest: state.content.get,
456
+ schemaRequest: state.schema,
457
+ updateRequest: state.content.update,
458
+ createRequest: state.content.create,
459
+ pathname: props.location.pathname,
460
+ returnUrl: qs.parse(props.location.search).return_url,
461
+ }),
462
+ {
463
+ updateContent,
464
+ getContent,
465
+ getSchema,
466
+ lockContent,
467
+ unlockContent,
468
+ },
469
+ ),
470
+ )(Edit);
471
+
472
+ export default compose(
473
+ injectIntl,
474
+ asyncConnect([
475
+ {
476
+ key: 'actions',
477
+ promise: async ({ location, store: { dispatch } }) => {
478
+ // Do not trigger the actions action if the expander is present
479
+ if (!hasApiExpander('actions', getBaseUrl(location.pathname))) {
480
+ return await dispatch(listActions(getBaseUrl(location.pathname)));
481
+ }
482
+ },
483
+ },
484
+ {
485
+ key: 'content',
486
+ promise: async ({ location, store: { dispatch } }) => {
487
+ const content = await dispatch(
488
+ getContent(getBaseUrl(location.pathname)),
489
+ );
490
+ if (content?.lock !== undefined) {
491
+ await dispatch(lockContent(getBaseUrl(location.pathname)));
492
+ }
493
+ return content;
494
+ },
495
+ },
496
+ ]),
497
+ connect(
498
+ (state, props) => ({
499
+ objectActions: state.actions.actions.object,
500
+ token: state.userSession.token,
501
+ content: state.content.data,
502
+ compare_to: state.content.subrequests?.compare_to?.data,
503
+ schema: state.schema.schema,
504
+ getRequest: state.content.get,
505
+ schemaRequest: state.schema,
506
+ updateRequest: state.content.update,
507
+ pathname: props.location.pathname,
508
+ returnUrl: qs.parse(props.location.search).return_url,
509
+ }),
510
+ {
511
+ updateContent,
512
+ getContent,
513
+ getSchema,
514
+ lockContent,
515
+ unlockContent,
516
+ },
517
+ ),
518
+ preloadLazyLibs('cms'),
519
+ )(Edit);
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { InlineForm } from '@plone/volto/components';
3
+ import { withVariationSchemaEnhancer } from '@plone/volto/helpers';
4
+
5
+ const EnhancedBlockDataForm = withVariationSchemaEnhancer(InlineForm);
6
+
7
+ export default function BlockDataForm(props) {
8
+ const { onChangeBlock, block } = props;
9
+
10
+ if (!onChangeBlock) {
11
+ // eslint-disable-next-line no-console
12
+ console.warn(
13
+ 'BlockDataForm component is used without passing down onChangeBlock as props',
14
+ );
15
+ }
16
+
17
+ const onChangeFormData = React.useCallback(
18
+ (data) => onChangeBlock(block, data),
19
+ [block, onChangeBlock],
20
+ );
21
+
22
+ return (
23
+ <EnhancedBlockDataForm
24
+ {...props}
25
+ onChangeFormData={onChangeBlock ? onChangeFormData : undefined}
26
+ />
27
+ );
28
+ }