@eeacms/volto-eea-website-theme 1.0.0 → 1.1.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.md +7 -1
- package/package.json +1 -1
- package/src/customizations/volto/components/manage/Form/Form.jsx +15 -6
- package/src/customizations/volto/components/manage/Form/ModalForm.jsx +6 -1
- package/src/customizations/volto/components/manage/Sharing/Sharing.jsx +153 -136
- package/src/customizations/volto/components/manage/Widgets/ObjectBrowserWidget.jsx +21 -11
package/CHANGELOG.md
CHANGED
@@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
4
4
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
6
6
|
|
7
|
-
### [1.
|
7
|
+
### [1.1.0](https://github.com/eea/volto-eea-website-theme/compare/1.0.0...1.1.0) - 28 October 2022
|
8
|
+
|
9
|
+
#### :nail_care: Enhancements
|
10
|
+
|
11
|
+
- refactor(customizations): Upgrade to volto 16.alpha.45 [Alin Voinea - [`930b77f`](https://github.com/eea/volto-eea-website-theme/commit/930b77fa6113d423a82704883a349bc1f919bb85)]
|
12
|
+
|
13
|
+
## [1.0.0](https://github.com/eea/volto-eea-website-theme/compare/0.7.7...1.0.0) - 28 October 2022
|
8
14
|
|
9
15
|
#### :nail_care: Enhancements
|
10
16
|
|
package/package.json
CHANGED
@@ -74,6 +74,7 @@ class Form extends Component {
|
|
74
74
|
onCancel: PropTypes.func,
|
75
75
|
submitLabel: PropTypes.string,
|
76
76
|
resetAfterSubmit: PropTypes.bool,
|
77
|
+
resetOnCancel: PropTypes.bool,
|
77
78
|
isEditForm: PropTypes.bool,
|
78
79
|
isAdminForm: PropTypes.bool,
|
79
80
|
title: PropTypes.string,
|
@@ -105,6 +106,7 @@ class Form extends Component {
|
|
105
106
|
onCancel: null,
|
106
107
|
submitLabel: null,
|
107
108
|
resetAfterSubmit: false,
|
109
|
+
resetOnCancel: false,
|
108
110
|
isEditForm: false,
|
109
111
|
isAdminForm: false,
|
110
112
|
title: null,
|
@@ -399,7 +401,7 @@ class Form extends Component {
|
|
399
401
|
if (event) {
|
400
402
|
event.preventDefault();
|
401
403
|
}
|
402
|
-
if (this.props.resetAfterSubmit) {
|
404
|
+
if (this.props.resetOnCancel || this.props.resetAfterSubmit) {
|
403
405
|
this.setState({
|
404
406
|
formData: this.props.formData,
|
405
407
|
});
|
@@ -418,11 +420,13 @@ class Form extends Component {
|
|
418
420
|
event.preventDefault();
|
419
421
|
}
|
420
422
|
|
421
|
-
const errors =
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
423
|
+
const errors = this.props.schema
|
424
|
+
? FormValidation.validateFieldsPerFieldset({
|
425
|
+
schema: this.props.schema,
|
426
|
+
formData: this.state.formData,
|
427
|
+
formatMessage: this.props.intl.formatMessage,
|
428
|
+
})
|
429
|
+
: {};
|
426
430
|
|
427
431
|
if (keys(errors).length > 0) {
|
428
432
|
const activeIndex = FormValidation.showFirstTabWithErrors({
|
@@ -653,6 +657,11 @@ class Form extends Component {
|
|
653
657
|
{this.props.title}
|
654
658
|
</Segment>
|
655
659
|
),
|
660
|
+
item.description && (
|
661
|
+
<Message attached="bottom">
|
662
|
+
{item.description}
|
663
|
+
</Message>
|
664
|
+
),
|
656
665
|
...map(item.fields, (field, index) => (
|
657
666
|
<Field
|
658
667
|
{...schema.properties[field]}
|
@@ -94,6 +94,7 @@ class ModalForm extends Component {
|
|
94
94
|
loadingMessage: null,
|
95
95
|
submitError: null,
|
96
96
|
className: null,
|
97
|
+
dimmer: null,
|
97
98
|
};
|
98
99
|
|
99
100
|
/**
|
@@ -224,7 +225,11 @@ class ModalForm extends Component {
|
|
224
225
|
|
225
226
|
const state_errors = keys(this.state.errors).length > 0;
|
226
227
|
return (
|
227
|
-
<Modal
|
228
|
+
<Modal
|
229
|
+
dimmer={this.props.dimmer}
|
230
|
+
open={this.props.open}
|
231
|
+
className={this.props.className}
|
232
|
+
>
|
228
233
|
<Header>{this.props.title}</Header>
|
229
234
|
<Dimmer active={this.props.loading}>
|
230
235
|
<Loader>
|
@@ -4,6 +4,7 @@
|
|
4
4
|
*/
|
5
5
|
import React, { Component } from 'react';
|
6
6
|
import PropTypes from 'prop-types';
|
7
|
+
import { Plug, Pluggable } from '@plone/volto/components/manage/Pluggable';
|
7
8
|
import { Helmet } from '@plone/volto/helpers';
|
8
9
|
import { connect } from 'react-redux';
|
9
10
|
import { compose } from 'redux';
|
@@ -291,146 +292,162 @@ class SharingComponent extends Component {
|
|
291
292
|
<Container id="page-sharing">
|
292
293
|
<Helmet title={this.props.intl.formatMessage(messages.sharing)} />
|
293
294
|
<Segment.Group raised>
|
294
|
-
<
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
<
|
309
|
-
<
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
295
|
+
<Pluggable name="sharing-component" />
|
296
|
+
<Plug pluggable="sharing-component" id="sharing-component-title">
|
297
|
+
<Segment className="primary">
|
298
|
+
<FormattedMessage
|
299
|
+
id="Sharing for {title}"
|
300
|
+
defaultMessage="Sharing for {title}"
|
301
|
+
values={{ title: <q>{this.props.title}</q> }}
|
302
|
+
/>
|
303
|
+
</Segment>
|
304
|
+
</Plug>
|
305
|
+
<Plug
|
306
|
+
pluggable="sharing-component"
|
307
|
+
id="sharing-component-description"
|
308
|
+
>
|
309
|
+
<Segment secondary>
|
310
|
+
<FormattedMessage
|
311
|
+
id="You can control who can view and edit your item using the list below."
|
312
|
+
defaultMessage="You can control who can view and edit your item using the list below."
|
313
|
+
/>
|
314
|
+
</Segment>
|
315
|
+
</Plug>
|
316
|
+
<Plug pluggable="sharing-component" id="sharing-component-search">
|
317
|
+
<Segment>
|
318
|
+
<Form onSubmit={this.onSearch}>
|
319
|
+
<Form.Field>
|
320
|
+
<Input
|
321
|
+
name="SearchableText"
|
322
|
+
action={{ icon: 'search' }}
|
323
|
+
placeholder={this.props.intl.formatMessage(
|
324
|
+
messages.searchForUserOrGroup,
|
325
|
+
)}
|
326
|
+
onChange={this.onChangeSearch}
|
327
|
+
/>
|
328
|
+
</Form.Field>
|
329
|
+
</Form>
|
330
|
+
</Segment>
|
331
|
+
</Plug>
|
332
|
+
<Plug
|
333
|
+
pluggable="sharing-component"
|
334
|
+
id="sharing-component-form"
|
335
|
+
dependencies={[this.state.entries, this.props.available_roles]}
|
336
|
+
>
|
337
|
+
<Form onSubmit={this.onSubmit}>
|
338
|
+
<Table celled padded striped attached>
|
339
|
+
<Table.Header>
|
340
|
+
<Table.Row>
|
341
|
+
<Table.HeaderCell>
|
342
|
+
<FormattedMessage id="Name" defaultMessage="Name" />
|
331
343
|
</Table.HeaderCell>
|
332
|
-
))}
|
333
|
-
</Table.Row>
|
334
|
-
</Table.Header>
|
335
|
-
<Table.Body>
|
336
|
-
{this.state.entries?.map((entry) => (
|
337
|
-
<Table.Row key={entry.id}>
|
338
|
-
<Table.Cell>
|
339
|
-
<IconOld
|
340
|
-
name={entry.type === 'user' ? 'user' : 'users'}
|
341
|
-
title={
|
342
|
-
entry.type === 'user'
|
343
|
-
? this.props.intl.formatMessage(messages.user)
|
344
|
-
: this.props.intl.formatMessage(messages.group)
|
345
|
-
}
|
346
|
-
/>{' '}
|
347
|
-
{entry.title}
|
348
|
-
{entry.login && ` (${entry.login})`}
|
349
|
-
</Table.Cell>
|
350
344
|
{this.props.available_roles?.map((role) => (
|
351
|
-
<Table.
|
352
|
-
{
|
353
|
-
|
354
|
-
name="check circle outline"
|
355
|
-
title={this.props.intl.formatMessage(
|
356
|
-
messages.globalRole,
|
357
|
-
)}
|
358
|
-
color="blue"
|
359
|
-
/>
|
360
|
-
)}
|
361
|
-
{entry.roles[role.id] === 'acquired' && (
|
362
|
-
<IconOld
|
363
|
-
name="check circle outline"
|
364
|
-
color="green"
|
365
|
-
title={this.props.intl.formatMessage(
|
366
|
-
messages.inheritedValue,
|
367
|
-
)}
|
368
|
-
/>
|
369
|
-
)}
|
370
|
-
{typeof entry.roles[role.id] === 'boolean' && (
|
371
|
-
<Checkbox
|
372
|
-
onChange={this.onChange}
|
373
|
-
value={`${entry.id}:${role.id}`}
|
374
|
-
checked={entry.roles[role.id]}
|
375
|
-
disabled={entry.login === this.props.login}
|
376
|
-
/>
|
377
|
-
)}
|
378
|
-
</Table.Cell>
|
345
|
+
<Table.HeaderCell key={role.id}>
|
346
|
+
{role.title}
|
347
|
+
</Table.HeaderCell>
|
379
348
|
))}
|
380
349
|
</Table.Row>
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
350
|
+
</Table.Header>
|
351
|
+
<Table.Body>
|
352
|
+
{this.state.entries?.map((entry) => (
|
353
|
+
<Table.Row key={entry.id}>
|
354
|
+
<Table.Cell>
|
355
|
+
<IconOld
|
356
|
+
name={entry.type === 'user' ? 'user' : 'users'}
|
357
|
+
title={
|
358
|
+
entry.type === 'user'
|
359
|
+
? this.props.intl.formatMessage(messages.user)
|
360
|
+
: this.props.intl.formatMessage(messages.group)
|
361
|
+
}
|
362
|
+
/>{' '}
|
363
|
+
{entry.title}
|
364
|
+
{entry.login && ` (${entry.login})`}
|
365
|
+
</Table.Cell>
|
366
|
+
{this.props.available_roles?.map((role) => (
|
367
|
+
<Table.Cell key={role.id}>
|
368
|
+
{entry.roles[role.id] === 'global' && (
|
369
|
+
<IconOld
|
370
|
+
name="check circle outline"
|
371
|
+
title={this.props.intl.formatMessage(
|
372
|
+
messages.globalRole,
|
373
|
+
)}
|
374
|
+
color="blue"
|
375
|
+
/>
|
376
|
+
)}
|
377
|
+
{entry.roles[role.id] === 'acquired' && (
|
378
|
+
<IconOld
|
379
|
+
name="check circle outline"
|
380
|
+
color="green"
|
381
|
+
title={this.props.intl.formatMessage(
|
382
|
+
messages.inheritedValue,
|
383
|
+
)}
|
384
|
+
/>
|
385
|
+
)}
|
386
|
+
{typeof entry.roles[role.id] === 'boolean' && (
|
387
|
+
<Checkbox
|
388
|
+
onChange={this.onChange}
|
389
|
+
value={`${entry.id}:${role.id}`}
|
390
|
+
checked={entry.roles[role.id]}
|
391
|
+
disabled={entry.login === this.props.login}
|
392
|
+
/>
|
393
|
+
)}
|
394
|
+
</Table.Cell>
|
395
|
+
))}
|
396
|
+
</Table.Row>
|
397
|
+
))}
|
398
|
+
</Table.Body>
|
399
|
+
</Table>
|
400
|
+
<Segment attached>
|
401
|
+
<Form.Field>
|
402
|
+
<Checkbox
|
403
|
+
checked={this.state.inherit}
|
404
|
+
onChange={this.onToggleInherit}
|
405
|
+
label={this.props.intl.formatMessage(messages.inherit)}
|
406
|
+
/>
|
407
|
+
</Form.Field>
|
408
|
+
<p className="help">
|
409
|
+
<FormattedMessage
|
410
|
+
id="By default, permissions from the container of this item are inherited. If you disable this, only the explicitly defined sharing permissions will be valid. In the overview, the symbol {inherited} indicates an inherited value. Similarly, the symbol {global} indicates a global role, which is managed by the site administrator."
|
411
|
+
defaultMessage="By default, permissions from the container of this item are inherited. If you disable this, only the explicitly defined sharing permissions will be valid. In the overview, the symbol {inherited} indicates an inherited value. Similarly, the symbol {global} indicates a global role, which is managed by the site administrator."
|
412
|
+
values={{
|
413
|
+
inherited: (
|
414
|
+
<IconOld name="check circle outline" color="green" />
|
415
|
+
),
|
416
|
+
global: (
|
417
|
+
<IconOld name="check circle outline" color="blue" />
|
418
|
+
),
|
419
|
+
}}
|
420
|
+
/>
|
421
|
+
</p>
|
422
|
+
</Segment>
|
423
|
+
<Segment className="actions" attached clearing>
|
424
|
+
<Button
|
425
|
+
basic
|
426
|
+
icon
|
427
|
+
primary
|
428
|
+
floated="right"
|
429
|
+
type="submit"
|
430
|
+
aria-label={this.props.intl.formatMessage(messages.save)}
|
431
|
+
title={this.props.intl.formatMessage(messages.save)}
|
432
|
+
loading={this.props.updateRequest.loading}
|
433
|
+
onClick={this.onSubmit}
|
434
|
+
>
|
435
|
+
<Icon className="circled" name={aheadSVG} size="30px" />
|
436
|
+
</Button>
|
437
|
+
<Button
|
438
|
+
basic
|
439
|
+
icon
|
440
|
+
secondary
|
441
|
+
aria-label={this.props.intl.formatMessage(messages.cancel)}
|
442
|
+
title={this.props.intl.formatMessage(messages.cancel)}
|
443
|
+
floated="right"
|
444
|
+
onClick={this.onCancel}
|
445
|
+
>
|
446
|
+
<Icon className="circled" name={clearSVG} size="30px" />
|
447
|
+
</Button>
|
448
|
+
</Segment>
|
449
|
+
</Form>
|
450
|
+
</Plug>
|
434
451
|
</Segment.Group>
|
435
452
|
{this.state.isClient && (
|
436
453
|
<Portal node={document.getElementById('toolbar')}>
|
@@ -65,6 +65,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
65
65
|
description: PropTypes.string,
|
66
66
|
mode: PropTypes.string, // link, image, multiple
|
67
67
|
return: PropTypes.string, // single, multiple
|
68
|
+
initialPath: PropTypes.string,
|
68
69
|
required: PropTypes.bool,
|
69
70
|
error: PropTypes.arrayOf(PropTypes.string),
|
70
71
|
value: PropTypes.oneOfType([
|
@@ -74,6 +75,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
74
75
|
onChange: PropTypes.func.isRequired,
|
75
76
|
openObjectBrowser: PropTypes.func.isRequired,
|
76
77
|
allowExternals: PropTypes.bool,
|
78
|
+
placeholder: PropTypes.string,
|
77
79
|
};
|
78
80
|
|
79
81
|
/**
|
@@ -88,6 +90,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
88
90
|
value: [],
|
89
91
|
mode: 'multiple',
|
90
92
|
return: 'multiple',
|
93
|
+
initialPath: '',
|
91
94
|
allowExternals: false,
|
92
95
|
};
|
93
96
|
|
@@ -148,7 +151,10 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
148
151
|
};
|
149
152
|
|
150
153
|
onChange = (item) => {
|
151
|
-
let value =
|
154
|
+
let value =
|
155
|
+
this.props.mode === 'multiple' && this.props.value
|
156
|
+
? [...this.props.value]
|
157
|
+
: [];
|
152
158
|
value = value.filter((item) => item != null);
|
153
159
|
const maxSize =
|
154
160
|
this.props.widgetOptions?.pattern_options?.maximumSelectionSize || -1;
|
@@ -239,7 +245,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
239
245
|
} else {
|
240
246
|
this.props.onChange(this.props.id, [
|
241
247
|
{
|
242
|
-
'@id':
|
248
|
+
'@id': flattenToAppURL(link),
|
243
249
|
title: removeProtocol(link),
|
244
250
|
},
|
245
251
|
]);
|
@@ -273,15 +279,17 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
273
279
|
ev.preventDefault();
|
274
280
|
this.props.openObjectBrowser({
|
275
281
|
mode: this.props.mode,
|
276
|
-
currentPath: this.props.location.pathname,
|
282
|
+
currentPath: this.props.initialPath || this.props.location.pathname,
|
277
283
|
propDataName: 'value',
|
278
284
|
onSelectItem: (url, item) => {
|
279
285
|
this.onChange(item);
|
280
286
|
},
|
281
|
-
selectableTypes:
|
282
|
-
?.selectableTypes
|
283
|
-
|
284
|
-
|
287
|
+
selectableTypes:
|
288
|
+
this.props.widgetOptions?.pattern_options?.selectableTypes ||
|
289
|
+
this.props.selectableTypes,
|
290
|
+
maximumSelectionSize:
|
291
|
+
this.props.widgetOptions?.pattern_options?.maximumSelectionSize ||
|
292
|
+
this.props.maximumSelectionSize,
|
285
293
|
});
|
286
294
|
};
|
287
295
|
|
@@ -349,7 +357,8 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
349
357
|
|
350
358
|
{items.length === 0 && this.props.mode === 'multiple' && (
|
351
359
|
<div className="placeholder" ref={this.placeholderRef}>
|
352
|
-
{this.props.
|
360
|
+
{this.props.placeholder ??
|
361
|
+
this.props.intl.formatMessage(messages.placeholder)}
|
353
362
|
</div>
|
354
363
|
)}
|
355
364
|
{this.props.allowExternals &&
|
@@ -359,9 +368,10 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
359
368
|
onKeyDown={this.onKeyDownManualLink}
|
360
369
|
onChange={this.onManualLinkInput}
|
361
370
|
value={this.state.manualLinkInput}
|
362
|
-
placeholder={
|
363
|
-
|
364
|
-
|
371
|
+
placeholder={
|
372
|
+
this.props.placeholder ??
|
373
|
+
this.props.intl.formatMessage(messages.placeholder)
|
374
|
+
}
|
365
375
|
/>
|
366
376
|
)}
|
367
377
|
</div>
|