@eeacms/volto-bise-policy 1.0.1 → 1.0.3

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.
@@ -1,547 +0,0 @@
1
- /**
2
- * More component.
3
- * @module components/manage/Toolbar/More
4
- */
5
-
6
- import React, { Component } from 'react';
7
- import { defineMessages, injectIntl } from 'react-intl';
8
- import PropTypes from 'prop-types';
9
- import { connect } from 'react-redux';
10
- import { compose } from 'redux';
11
- import { Link, withRouter } from 'react-router-dom';
12
- import { find } from 'lodash';
13
- import { toast } from 'react-toastify';
14
- import { Toast } from '@plone/volto/components';
15
- import { Pluggable, Plug } from '@plone/volto/components/manage/Pluggable';
16
- import {
17
- FormattedDate,
18
- Icon,
19
- Display,
20
- Workflow,
21
- } from '@plone/volto/components';
22
- import {
23
- applyWorkingCopy,
24
- createWorkingCopy,
25
- removeWorkingCopy,
26
- } from '@plone/volto/actions';
27
- import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers';
28
- import config from '@plone/volto/registry';
29
-
30
- import rightArrowSVG from '@plone/volto/icons/right-key.svg';
31
- import userSVG from '@plone/volto/icons/user.svg';
32
- import applySVG from '@plone/volto/icons/ready.svg';
33
- import removeSVG from '@plone/volto/icons/circle-dismiss.svg';
34
-
35
- const messages = defineMessages({
36
- personalTools: {
37
- id: 'Personal tools',
38
- defaultMessage: 'Personal tools',
39
- },
40
- history: {
41
- id: 'History',
42
- defaultMessage: 'History',
43
- },
44
- sharing: {
45
- id: 'Sharing',
46
- defaultMessage: 'Sharing',
47
- },
48
- rules: {
49
- id: 'Rules',
50
- defaultMessage: 'Rules',
51
- },
52
- aliases: {
53
- id: 'URL Management',
54
- defaultMessage: 'URL Management',
55
- },
56
- ManageTranslations: {
57
- id: 'Manage Translations',
58
- defaultMessage: 'Manage Translations',
59
- },
60
- manageContent: {
61
- id: 'Manage content…',
62
- defaultMessage: 'Manage content…',
63
- },
64
- CreateWorkingCopy: {
65
- id: 'Create working copy',
66
- defaultMessage: 'Create working copy',
67
- },
68
- applyWorkingCopy: {
69
- id: 'Apply working copy',
70
- defaultMessage: 'Apply working copy',
71
- },
72
- removeWorkingCopy: {
73
- id: 'Remove working copy',
74
- defaultMessage: 'Remove working copy',
75
- },
76
- viewWorkingCopy: {
77
- id: 'View working copy',
78
- defaultMessage: 'View working copy',
79
- },
80
- workingAppliedTitle: {
81
- id: 'Changes applied.',
82
- defaultMessage: 'Changes applied',
83
- },
84
- workingCopyAppliedBy: {
85
- id:
86
- 'Made by {creator} on {date}. This is not a working copy anymore, but the main content.',
87
- defaultMessage:
88
- 'Made by {creator} on {date}. This is not a working copy anymore, but the main content.',
89
- },
90
- workingCopyRemovedTitle: {
91
- id: 'The working copy was discarded',
92
- defaultMessage: 'The working copy was discarded',
93
- },
94
- Unauthorized: {
95
- id: 'Unauthorized',
96
- defaultMessage: 'Unauthorized',
97
- },
98
- workingCopyErrorUnauthorized: {
99
- id: 'workingCopyErrorUnauthorized',
100
- defaultMessage: 'You are not authorized to perform this operation.',
101
- },
102
- Error: {
103
- id: 'Error',
104
- defaultMessage: 'Error',
105
- },
106
- workingCopyGenericError: {
107
- id: 'workingCopyGenericError',
108
- defaultMessage: 'An error occurred while performing this operation.',
109
- },
110
- });
111
-
112
- /**
113
- * More container class.
114
- * @class More
115
- * @extends Component
116
- */
117
- class More extends Component {
118
- static propTypes = {
119
- actions: PropTypes.shape({
120
- object: PropTypes.arrayOf(PropTypes.object),
121
- object_buttons: PropTypes.arrayOf(PropTypes.object),
122
- user: PropTypes.arrayOf(PropTypes.object),
123
- }),
124
- pathname: PropTypes.string.isRequired,
125
- content: PropTypes.shape({
126
- title: PropTypes.string,
127
- '@type': PropTypes.string,
128
- is_folderish: PropTypes.bool,
129
- review_state: PropTypes.string,
130
- }),
131
- loadComponent: PropTypes.func.isRequired,
132
- closeMenu: PropTypes.func.isRequired,
133
- };
134
-
135
- /**
136
- * Default properties.
137
- * @property {Object} defaultProps Default properties.
138
- * @static
139
- */
140
- static defaultProps = {
141
- actions: null,
142
- content: null,
143
- };
144
- state = {
145
- openManageTranslations: false,
146
- pushed: false,
147
- };
148
-
149
- push = (selector) => {
150
- this.setState(() => ({
151
- pushed: true,
152
- }));
153
- this.props.loadComponent(selector);
154
- document.removeEventListener('mousedown', this.handleClickOutside, false);
155
- };
156
-
157
- componentDidUpdate(prevProps, prevState) {
158
- let erroredAction = '';
159
- if (
160
- prevProps.workingCopy.apply.loading &&
161
- this.props.workingCopy.apply.error
162
- ) {
163
- erroredAction = 'apply';
164
- } else if (
165
- prevProps.workingCopy.create.loading &&
166
- this.props.workingCopy.create.error
167
- ) {
168
- erroredAction = 'create';
169
- } else if (
170
- prevProps.workingCopy.remove.loading &&
171
- this.props.workingCopy.remove.error
172
- ) {
173
- erroredAction = 'remove';
174
- }
175
-
176
- if (erroredAction) {
177
- const errorStatus = this.props.workingCopy[erroredAction].error.status;
178
- if (errorStatus === 401 || errorStatus === 403) {
179
- toast.error(
180
- <Toast
181
- error
182
- title={this.props.intl.formatMessage(messages.Unauthorized)}
183
- content={this.props.intl.formatMessage(
184
- messages.workingCopyErrorUnauthorized,
185
- )}
186
- />,
187
- {
188
- toastId: 'workingCopyErrorUnauthorized',
189
- autoClose: 10000,
190
- },
191
- );
192
- } else {
193
- toast.error(
194
- <Toast
195
- error
196
- title={this.props.intl.formatMessage(messages.Error)}
197
- content={this.props.intl.formatMessage(
198
- messages.workingCopyGenericError,
199
- )}
200
- />,
201
- {
202
- toastId: 'workingCopyGenericError',
203
- autoClose: 10000,
204
- },
205
- );
206
- }
207
- }
208
- }
209
-
210
- /**
211
- * Render method.
212
- * @method render
213
- * @returns {string} Markup for the component.
214
- */
215
- render() {
216
- const path = getBaseUrl(this.props.pathname);
217
- const editAction = find(this.props.actions.object, { id: 'edit' });
218
- const historyAction = find(this.props.actions.object, { id: 'history' });
219
- const sharingAction = find(this.props.actions.object, {
220
- id: 'local_roles',
221
- });
222
-
223
- const rulesAction = find(this.props.actions.object, {
224
- id: 'contentrules',
225
- });
226
-
227
- const aliasesAction = find(this.props.actions.object_buttons, {
228
- id: 'redirection',
229
- });
230
- const { content, intl } = this.props;
231
-
232
- const dateOptions = {
233
- year: 'numeric',
234
- month: 'long',
235
- day: 'numeric',
236
- };
237
-
238
- const isMultilingual =
239
- config.settings.isMultilingual ||
240
- (this.props.subsite &&
241
- config.settings.bise.multilingualSubsites.includes(
242
- flattenToAppURL(this.props.subsite['@id']),
243
- ));
244
-
245
- return (
246
- <div
247
- className="menu-more pastanaga-menu"
248
- style={{
249
- flex: this.props.theToolbar.current
250
- ? `0 0 ${
251
- this.props.theToolbar.current.getBoundingClientRect().width
252
- }px`
253
- : null,
254
- }}
255
- >
256
- <header>
257
- <h2>{this.props.content.title}</h2>
258
- <button
259
- className="more-user"
260
- aria-label={this.props.intl.formatMessage(messages.personalTools)}
261
- onClick={() => this.push('personalTools')}
262
- tabIndex={0}
263
- >
264
- <Icon
265
- name={userSVG}
266
- size="30px"
267
- title={this.props.intl.formatMessage(messages.personalTools)}
268
- />
269
- </button>
270
- </header>
271
- <div className="pastanaga-menu-list">
272
- <ul>
273
- <Pluggable name="toolbar-more-menu-list" />
274
- <Plug pluggable="toolbar-more-menu-list" id="state">
275
- {this.props.content['@type'] !== 'Plone Site' && (
276
- // Plone Site does not have workflow
277
- <li className="state-select">
278
- <Workflow pathname={path} />
279
- </li>
280
- )}
281
- </Plug>
282
- <Plug pluggable="toolbar-more-menu-list" id="view">
283
- {this.props.content['@type'] !== 'Plone Site' && (
284
- // Plone Site does not have view (yet)
285
- <li className="display-select">
286
- {editAction && <Display pathname={path} />}
287
- </li>
288
- )}
289
- </Plug>
290
- <Plug pluggable="toolbar-more-menu-list" id="history">
291
- {this.props.content['@type'] !== 'Plone Site' && (
292
- // Plone Site does not have history (yet)
293
- <li>
294
- <Link to={`${path}/historyview`}>
295
- <div>
296
- <span className="pastanaga-menu-label">
297
- {historyAction?.title ||
298
- this.props.intl.formatMessage(messages.history)}
299
- </span>
300
- <span className="pastanaga-menu-value" />
301
- </div>
302
- <Icon name={rightArrowSVG} size="24px" />
303
- </Link>
304
- </li>
305
- )}
306
- </Plug>
307
- <Plug pluggable="toolbar-more-menu-list" id="sharing">
308
- {sharingAction && (
309
- <li>
310
- <Link to={`${path}/sharing`}>
311
- {this.props.intl.formatMessage(messages.sharing)}
312
- <Icon name={rightArrowSVG} size="24px" />
313
- </Link>
314
- </li>
315
- )}
316
- </Plug>
317
- <Plug pluggable="toolbar-more-menu-list" id="aliases">
318
- {aliasesAction && (
319
- <li>
320
- <Link to={`${path}/aliases`}>
321
- {this.props.intl.formatMessage(messages.aliases)}
322
- <Icon name={rightArrowSVG} size="24px" />
323
- </Link>
324
- </li>
325
- )}
326
- </Plug>
327
- <Plug pluggable="toolbar-more-menu-list" id="rules">
328
- {rulesAction && (
329
- <li>
330
- <Link to={`${path}/rules`}>
331
- {this.props.intl.formatMessage(messages.rules)}
332
- <Icon name={rightArrowSVG} size="24px" />
333
- </Link>
334
- </li>
335
- )}
336
- </Plug>
337
- </ul>
338
- </div>
339
- <Pluggable name="toolbar-more-manage-content">
340
- {(pluggables) => (
341
- <>
342
- {pluggables.length > 0 && (
343
- <>
344
- <header>
345
- <h2>
346
- {this.props.intl.formatMessage(messages.manageContent)}
347
- </h2>
348
- </header>
349
- <div className="pastanaga-menu-list">
350
- <ul>
351
- {pluggables.map((p) => (
352
- <>{p()}</>
353
- ))}
354
- </ul>
355
- </div>
356
- </>
357
- )}
358
- </>
359
- )}
360
- </Pluggable>
361
- {config.settings.hasWorkingCopySupport &&
362
- this.props.content['@type'] !== 'Plone Site' && (
363
- <>
364
- {!this.props.content.working_copy && (
365
- <Plug pluggable="toolbar-more-manage-content" id="workingcopy">
366
- <li>
367
- <button
368
- aria-label={this.props.intl.formatMessage(
369
- messages.CreateWorkingCopy,
370
- )}
371
- onClick={() => {
372
- this.props.createWorkingCopy(path).then((response) => {
373
- this.props.history.push(
374
- flattenToAppURL(response['@id']),
375
- );
376
- this.props.closeMenu();
377
- });
378
- }}
379
- >
380
- {this.props.intl.formatMessage(
381
- messages.CreateWorkingCopy,
382
- )}
383
-
384
- <Icon name={rightArrowSVG} size="24px" />
385
- </button>
386
- </li>
387
- </Plug>
388
- )}
389
- {this.props.content.working_copy &&
390
- this.props.content.working_copy_of && (
391
- <Plug
392
- pluggable="toolbar-more-manage-content"
393
- id="workingcopy"
394
- >
395
- <li>
396
- <button
397
- aria-label={this.props.intl.formatMessage(
398
- messages.applyWorkingCopy,
399
- )}
400
- onClick={() => {
401
- this.props.applyWorkingCopy(path).then((response) => {
402
- this.props.history.push(
403
- flattenToAppURL(
404
- this.props.content.working_copy_of['@id'],
405
- ),
406
- );
407
- this.props.closeMenu();
408
- toast.info(
409
- <Toast
410
- info
411
- title={intl.formatMessage(
412
- messages.workingAppliedTitle,
413
- )}
414
- content={intl.formatMessage(
415
- messages.workingCopyAppliedBy,
416
- {
417
- creator: content.working_copy?.creator_name,
418
- date: (
419
- <FormattedDate
420
- date={content.working_copy?.created}
421
- format={dateOptions}
422
- />
423
- ),
424
- },
425
- )}
426
- />,
427
- {
428
- toastId: 'workingcopyapplyinfo',
429
- autoClose: 10000,
430
- },
431
- );
432
- });
433
- }}
434
- >
435
- {this.props.intl.formatMessage(
436
- messages.applyWorkingCopy,
437
- )}
438
-
439
- <Icon
440
- name={applySVG}
441
- size="24px"
442
- title={this.props.intl.formatMessage(
443
- messages.applyWorkingCopy,
444
- )}
445
- />
446
- </button>
447
- </li>
448
- <li>
449
- <button
450
- aria-label={this.props.intl.formatMessage(
451
- messages.removeWorkingCopy,
452
- )}
453
- onClick={() => {
454
- this.props
455
- .removeWorkingCopy(path)
456
- .then((response) => {
457
- this.props.history.push(
458
- flattenToAppURL(
459
- this.props.content.working_copy_of['@id'],
460
- ),
461
- );
462
- this.props.closeMenu();
463
- toast.info(
464
- <Toast
465
- info
466
- title={intl.formatMessage(
467
- messages.workingCopyRemovedTitle,
468
- )}
469
- />,
470
- {
471
- toastId: 'workingcopyremovednotice',
472
- autoClose: 10000,
473
- },
474
- );
475
- });
476
- }}
477
- >
478
- {this.props.intl.formatMessage(
479
- messages.removeWorkingCopy,
480
- )}
481
-
482
- <Icon
483
- name={removeSVG}
484
- size="24px"
485
- color="#e40166"
486
- title={this.props.intl.formatMessage(
487
- messages.removeWorkingCopy,
488
- )}
489
- />
490
- </button>
491
- </li>
492
- </Plug>
493
- )}
494
- {this.props.content.working_copy &&
495
- !this.props.content.working_copy_of && (
496
- <Plug
497
- pluggable="toolbar-more-manage-content"
498
- id="workingcopy"
499
- >
500
- <li>
501
- <Link
502
- to={flattenToAppURL(
503
- this.props.content.working_copy['@id'],
504
- )}
505
- onClick={() => this.props.closeMenu()}
506
- >
507
- {this.props.intl.formatMessage(
508
- messages.viewWorkingCopy,
509
- )}
510
- <Icon name={rightArrowSVG} size="24px" />
511
- </Link>
512
- </li>
513
- </Plug>
514
- )}
515
- </>
516
- )}
517
- {editAction && isMultilingual && (
518
- <Plug pluggable="toolbar-more-manage-content" id="multilingual">
519
- <li>
520
- <Link to={`${path}/manage-translations`}>
521
- {this.props.intl.formatMessage(messages.ManageTranslations)}
522
-
523
- <Icon name={rightArrowSVG} size="24px" />
524
- </Link>
525
- </li>
526
- </Plug>
527
- )}
528
- </div>
529
- );
530
- }
531
- }
532
-
533
- export default compose(
534
- injectIntl,
535
- withRouter,
536
- connect(
537
- (state, props) => ({
538
- actions: state.actions.actions,
539
- pathname: props.pathname,
540
- content: state.content.data,
541
- lang: state.intl.locale,
542
- workingCopy: state.workingCopy,
543
- subsite: state.content.data?.['@components']?.subsite,
544
- }),
545
- { applyWorkingCopy, createWorkingCopy, removeWorkingCopy },
546
- ),
547
- )(More);
@@ -1,156 +0,0 @@
1
- /*******************************
2
- Container
3
- *******************************/
4
-
5
- .has--size--full:not(.block-editor-columnsBlock),
6
- .full-width {
7
- width: calc(100vw - var(--scrollbar-width, @scrollbarWidth)) !important;
8
- margin-left: calc(-50vw + var(--scrollbar-width, @scrollbarWidth) / 2) !important;
9
- margin-right: calc(-50vw + var(--scrollbar-width, @scrollbarWidth) / 2) !important;
10
- }
11
-
12
- @media only screen and (min-width: @largestMobileScreen) {
13
- body.has-toolbar {
14
- .has--size--full:not(.block-editor-columnsBlock),
15
- .full-width {
16
- width: calc(100vw - @toolbarWidth - var(--scrollbar-width, @scrollbarWidth)) !important;
17
- margin-left: calc(-50vw + (@toolbarWidth + var(--scrollbar-width, @scrollbarWidth)) / 2) !important;
18
- margin-right: calc(-50vw + (@toolbarWidth + var(--scrollbar-width, @scrollbarWidth)) / 2) !important;
19
- }
20
- }
21
-
22
- body.has-toolbar-collapsed {
23
- .has--size--full:not(.block-editor-columnsBlock),
24
- .full-width {
25
- width: calc(100vw - @toolbarWidthMin - var(--scrollbar-width, @scrollbarWidth)) !important;
26
- margin-left: calc(-50vw + (var(--scrollbar-width, @scrollbarWidth) + @toolbarWidthMin) / 2) !important;
27
- margin-right: calc(-50vw + (var(--scrollbar-width, @scrollbarWidth) + @toolbarWidthMin) / 2) !important;
28
- }
29
- }
30
- }
31
-
32
- .section-add,
33
- .section-edit {
34
- #page-add .container,
35
- #page-edit .container {
36
- max-width: @containerWidth !important;
37
- }
38
- }
39
-
40
- /* Mobile */
41
- @media only screen and (max-width: @largestMobileScreen) {
42
- .ui.container {
43
- width: @mobileWidth !important;
44
- margin-left: @mobileGutter !important;
45
- margin-right: @mobileGutter !important;
46
- }
47
- .ui.grid.container {
48
- width: @mobileGridWidth !important;
49
- }
50
- .ui.relaxed.grid.container {
51
- width: @mobileRelaxedGridWidth !important;
52
- }
53
- .ui.very.relaxed.grid.container {
54
- width: @mobileVeryRelaxedGridWidth !important;
55
- }
56
- }
57
-
58
- body.has-toolbar {
59
- /* Tablet */
60
- @media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) {
61
- .ui.container {
62
- width: calc(@tabletWidth - @toolbarWidth);
63
- }
64
- .ui.grid.container {
65
- width: calc(@tabletGridWidth - @toolbarWidth) !important;
66
- }
67
- .ui.relaxed.grid.container {
68
- width: calc(@tabletRelaxedGridWidth - @toolbarWidth) !important;
69
- }
70
- .ui.very.relaxed.grid.container {
71
- width: calc(@tabletVeryRelaxedGridWidth - @toolbarWidth) !important;
72
- }
73
- }
74
-
75
- /* Small Monitor */
76
- @media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) {
77
- .ui.container {
78
- width: calc(@computerWidth - @toolbarWidth);
79
- }
80
- .ui.grid.container {
81
- width: calc(@computerGridWidth - @toolbarWidth) !important;
82
- }
83
- .ui.relaxed.grid.container {
84
- width: calc(@computerRelaxedGridWidth - @toolbarWidth) !important;
85
- }
86
- .ui.very.relaxed.grid.container {
87
- width: calc(@computerVeryRelaxedGridWidth - @toolbarWidth) !important;
88
- }
89
- }
90
-
91
- /* Large Monitor */
92
- @media only screen and (min-width: @largeMonitorBreakpoint) {
93
- .ui.container {
94
- width: calc(@largeMonitorWidth - @toolbarWidth);
95
- }
96
- .ui.grid.container {
97
- width: calc(@largeMonitorGridWidth - @toolbarWidth) !important;
98
- }
99
- .ui.relaxed.grid.container {
100
- width: calc(@largeMonitorRelaxedGridWidth - @toolbarWidth) !important;
101
- }
102
- .ui.very.relaxed.grid.container {
103
- width: calc(@largeMonitorVeryRelaxedGridWidth - @toolbarWidth) !important;
104
- }
105
- }
106
- }
107
-
108
- body.has-toolbar-collapsed {
109
- /* Tablet */
110
- @media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) {
111
- .ui.container {
112
- width: calc(@tabletWidth - @toolbarWidthMin);
113
- }
114
- .ui.grid.container {
115
- width: calc(@tabletGridWidth - @toolbarWidthMin) !important;
116
- }
117
- .ui.relaxed.grid.container {
118
- width: calc(@tabletRelaxedGridWidth - @toolbarWidthMin) !important;
119
- }
120
- .ui.very.relaxed.grid.container {
121
- width: calc(@tabletVeryRelaxedGridWidth - @toolbarWidthMin) !important;
122
- }
123
- }
124
-
125
- /* Small Monitor */
126
- @media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) {
127
- .ui.container {
128
- width: calc(@computerWidth - @toolbarWidthMin);
129
- }
130
- .ui.grid.container {
131
- width: calc(@computerGridWidth - @toolbarWidthMin) !important;
132
- }
133
- .ui.relaxed.grid.container {
134
- width: calc(@computerRelaxedGridWidth - @toolbarWidthMin) !important;
135
- }
136
- .ui.very.relaxed.grid.container {
137
- width: calc(@computerVeryRelaxedGridWidth - @toolbarWidthMin) !important;
138
- }
139
- }
140
-
141
- /* Large Monitor */
142
- @media only screen and (min-width: @largeMonitorBreakpoint) {
143
- .ui.container {
144
- width: calc(@largeMonitorWidth - @toolbarWidthMin);
145
- }
146
- .ui.grid.container {
147
- width: calc(@largeMonitorGridWidth - @toolbarWidthMin) !important;
148
- }
149
- .ui.relaxed.grid.container {
150
- width: calc(@largeMonitorRelaxedGridWidth - @toolbarWidthMin) !important;
151
- }
152
- .ui.very.relaxed.grid.container {
153
- width: calc(@largeMonitorVeryRelaxedGridWidth - @toolbarWidthMin) !important;
154
- }
155
- }
156
- }