@eeacms/volto-eea-website-policy 1.2.1 → 1.3.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
CHANGED
|
@@ -4,6 +4,22 @@ 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.3.0](https://github.com/eea/volto-eea-website-policy/compare/1.2.2...1.3.0) - 7 February 2023
|
|
8
|
+
|
|
9
|
+
#### :nail_care: Enhancements
|
|
10
|
+
|
|
11
|
+
- refactor(Toolbar): Upgrade Toolbar.jsx shadow customization to Volto 16.10.0 [Alin Voinea - [`d759206`](https://github.com/eea/volto-eea-website-policy/commit/d759206b48f31e1835da1b5cc99f4b640812b6a0)]
|
|
12
|
+
- refactor(Controlpanel): Cleanup obsolete shadow ContentTypeLayout [Alin Voinea - [`7469ea9`](https://github.com/eea/volto-eea-website-policy/commit/7469ea9670d1dcf9dc98d6e3f4537244069222fa)]
|
|
13
|
+
- refactor(config): Move some common settings to volto-eea-website-theme - refs #160747 [Alin Voinea - [`e7b8508`](https://github.com/eea/volto-eea-website-policy/commit/e7b85082449406962d2e90e0362ac596f127a0e5)]
|
|
14
|
+
|
|
15
|
+
#### :hammer_and_wrench: Others
|
|
16
|
+
|
|
17
|
+
- Release 1.3.0 [Alin Voinea - [`8a8e906`](https://github.com/eea/volto-eea-website-policy/commit/8a8e9061aedbbec89d7ab7e7493cfcabefdd3bc5)]
|
|
18
|
+
### [1.2.2](https://github.com/eea/volto-eea-website-policy/compare/1.2.1...1.2.2) - 25 January 2023
|
|
19
|
+
|
|
20
|
+
#### :hammer_and_wrench: Others
|
|
21
|
+
|
|
22
|
+
- Safely set extractScripts.errorPages [Alin Voinea - [`439fb46`](https://github.com/eea/volto-eea-website-policy/commit/439fb46167aa24fe1ae87c1721894aceb89a1a55)]
|
|
7
23
|
### [1.2.1](https://github.com/eea/volto-eea-website-policy/compare/1.2.0...1.2.1) - 29 December 2022
|
|
8
24
|
|
|
9
25
|
### [1.2.0](https://github.com/eea/volto-eea-website-policy/compare/1.1.0...1.2.0) - 28 December 2022
|
package/package.json
CHANGED
|
@@ -29,7 +29,12 @@ import {
|
|
|
29
29
|
unlockContent,
|
|
30
30
|
} from '@plone/volto/actions';
|
|
31
31
|
import { Icon } from '@plone/volto/components';
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
BodyClass,
|
|
34
|
+
getBaseUrl,
|
|
35
|
+
getCookieOptions,
|
|
36
|
+
hasApiExpander,
|
|
37
|
+
} from '@plone/volto/helpers';
|
|
33
38
|
import { Pluggable } from '@plone/volto/components/manage/Pluggable';
|
|
34
39
|
|
|
35
40
|
import penSVG from '@plone/volto/icons/pen.svg';
|
|
@@ -104,7 +109,7 @@ const messages = defineMessages({
|
|
|
104
109
|
},
|
|
105
110
|
});
|
|
106
111
|
|
|
107
|
-
|
|
112
|
+
let toolbarComponents = {
|
|
108
113
|
personalTools: { component: PersonalTools, wrapper: null },
|
|
109
114
|
more: { component: More, wrapper: null },
|
|
110
115
|
types: { component: Types, wrapper: null, contentAsProps: true },
|
|
@@ -197,8 +202,20 @@ class Toolbar extends Component {
|
|
|
197
202
|
* @returns {undefined}
|
|
198
203
|
*/
|
|
199
204
|
componentDidMount() {
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
// Do not trigger the actions action if the expander is present
|
|
206
|
+
if (!hasApiExpander('actions', getBaseUrl(this.props.pathname))) {
|
|
207
|
+
this.props.listActions(getBaseUrl(this.props.pathname));
|
|
208
|
+
}
|
|
209
|
+
// Do not trigger the types action if the expander is present
|
|
210
|
+
if (!hasApiExpander('types', getBaseUrl(this.props.pathname))) {
|
|
211
|
+
this.props.getTypes(getBaseUrl(this.props.pathname));
|
|
212
|
+
}
|
|
213
|
+
toolbarComponents = {
|
|
214
|
+
...(config.settings
|
|
215
|
+
? config.settings.additionalToolbarComponents || {}
|
|
216
|
+
: {}),
|
|
217
|
+
...toolbarComponents,
|
|
218
|
+
};
|
|
202
219
|
this.props.setExpandedToolbar(this.state.expanded);
|
|
203
220
|
document.addEventListener('mousedown', this.handleClickOutside, false);
|
|
204
221
|
}
|
|
@@ -211,8 +228,14 @@ class Toolbar extends Component {
|
|
|
211
228
|
*/
|
|
212
229
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
213
230
|
if (nextProps.pathname !== this.props.pathname) {
|
|
214
|
-
|
|
215
|
-
|
|
231
|
+
// Do not trigger the actions action if the expander is present
|
|
232
|
+
if (!hasApiExpander('actions', getBaseUrl(nextProps.pathname))) {
|
|
233
|
+
this.props.listActions(getBaseUrl(nextProps.pathname));
|
|
234
|
+
}
|
|
235
|
+
// Do not trigger the types action if the expander is present
|
|
236
|
+
if (!hasApiExpander('types', getBaseUrl(nextProps.pathname))) {
|
|
237
|
+
this.props.getTypes(getBaseUrl(nextProps.pathname));
|
|
238
|
+
}
|
|
216
239
|
}
|
|
217
240
|
|
|
218
241
|
// Unlock
|
|
@@ -534,9 +557,13 @@ class Toolbar extends Component {
|
|
|
534
557
|
</button>
|
|
535
558
|
</>
|
|
536
559
|
)}
|
|
560
|
+
<Pluggable name="main.toolbar.top" />
|
|
537
561
|
</div>
|
|
538
562
|
<div className="toolbar-bottom">
|
|
539
|
-
<Pluggable
|
|
563
|
+
<Pluggable
|
|
564
|
+
name="main.toolbar.bottom"
|
|
565
|
+
params={{ onClickHandler: this.toggleMenu }}
|
|
566
|
+
/>
|
|
540
567
|
{!this.props.hideDefaultViewButtons && (
|
|
541
568
|
<button
|
|
542
569
|
className="user"
|
package/src/index.js
CHANGED
|
@@ -1,37 +1,9 @@
|
|
|
1
1
|
import { runtimeConfig } from '@plone/volto/runtime_config';
|
|
2
|
-
import installCallout from '@plone/volto-slate/editor/plugins/Callout';
|
|
3
2
|
import installContextNavigationBlock from '@eeacms/volto-eea-website-policy/components/Blocks/ContextNavigation';
|
|
4
3
|
import installLayoutSettingsBlock from '@eeacms/volto-eea-website-policy/components/Blocks/LayoutSettings';
|
|
5
4
|
import { addStylingFieldsetSchemaEnhancer } from '@eeacms/volto-eea-website-policy/components/Blocks/schema';
|
|
6
5
|
|
|
7
6
|
const applyConfig = (config) => {
|
|
8
|
-
// if (process.env.NODE_ENV === 'production') {
|
|
9
|
-
// // Restrict block-style to Layout only
|
|
10
|
-
// config.settings.layoutOnlyBlockStyles = true;
|
|
11
|
-
// // Restrict slate metadata mentions to Layout only
|
|
12
|
-
// config.settings.layoutOnlySlateMetadataMentions = true;
|
|
13
|
-
// }
|
|
14
|
-
// Callout slate button
|
|
15
|
-
config = installCallout(config);
|
|
16
|
-
|
|
17
|
-
// Remove blockquote slate button
|
|
18
|
-
config.settings.slate.toolbarButtons = config.settings.slate.toolbarButtons.filter(
|
|
19
|
-
(item) => item !== 'blockquote',
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
// Disable tags on View
|
|
23
|
-
config.settings.showTags = false;
|
|
24
|
-
|
|
25
|
-
// Enable Title block
|
|
26
|
-
config.blocks.blocksConfig.title.restricted = false;
|
|
27
|
-
|
|
28
|
-
// Enable description block (also for cypress)
|
|
29
|
-
config.blocks.blocksConfig.description.restricted = false;
|
|
30
|
-
config.blocks.requiredBlocks = [];
|
|
31
|
-
|
|
32
|
-
// Date format for EU
|
|
33
|
-
config.settings.dateLocale = 'en-gb';
|
|
34
|
-
|
|
35
7
|
// #137187 Keycloak integration
|
|
36
8
|
if (runtimeConfig['RAZZLE_KEYCLOAK'] === 'Yes') {
|
|
37
9
|
config.settings.externalRoutes = [
|
|
@@ -131,6 +103,14 @@ const applyConfig = (config) => {
|
|
|
131
103
|
config.blocks.blocksConfig.imagecards.restricted = true;
|
|
132
104
|
}
|
|
133
105
|
|
|
106
|
+
config.settings.apiExpanders = [
|
|
107
|
+
...config.settings.apiExpanders,
|
|
108
|
+
{
|
|
109
|
+
match: '',
|
|
110
|
+
GET_CONTENT: ['subsite'],
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
|
|
134
114
|
// Done
|
|
135
115
|
return config;
|
|
136
116
|
};
|
|
@@ -1,520 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Content Type component.
|
|
3
|
-
* @module components/manage/Controlpanels/ContentTypeLayout
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import React, { Component } from 'react';
|
|
7
|
-
import PropTypes from 'prop-types';
|
|
8
|
-
import { connect } from 'react-redux';
|
|
9
|
-
import { compose } from 'redux';
|
|
10
|
-
import { Link } from 'react-router-dom';
|
|
11
|
-
import {
|
|
12
|
-
getParentUrl,
|
|
13
|
-
hasBlocksData,
|
|
14
|
-
getBlocksFieldname,
|
|
15
|
-
getBlocksLayoutFieldname,
|
|
16
|
-
} from '@plone/volto/helpers';
|
|
17
|
-
import { Portal } from 'react-portal';
|
|
18
|
-
import { Button, Segment } from 'semantic-ui-react';
|
|
19
|
-
import { toast } from 'react-toastify';
|
|
20
|
-
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
|
21
|
-
import { nth, join } from 'lodash';
|
|
22
|
-
import {
|
|
23
|
-
Error,
|
|
24
|
-
Form,
|
|
25
|
-
Icon,
|
|
26
|
-
Toolbar,
|
|
27
|
-
Sidebar,
|
|
28
|
-
Toast,
|
|
29
|
-
} from '@plone/volto/components';
|
|
30
|
-
import {
|
|
31
|
-
getSchema,
|
|
32
|
-
updateSchema,
|
|
33
|
-
getControlpanel,
|
|
34
|
-
updateControlpanel,
|
|
35
|
-
} from '@plone/volto/actions';
|
|
36
|
-
|
|
37
|
-
import saveSVG from '@plone/volto/icons/save.svg';
|
|
38
|
-
import clearSVG from '@plone/volto/icons/clear.svg';
|
|
39
|
-
import backSVG from '@plone/volto/icons/back.svg';
|
|
40
|
-
|
|
41
|
-
const messages = defineMessages({
|
|
42
|
-
changesSaved: {
|
|
43
|
-
id: 'Changes saved.',
|
|
44
|
-
defaultMessage: 'Changes saved.',
|
|
45
|
-
},
|
|
46
|
-
back: {
|
|
47
|
-
id: 'Back',
|
|
48
|
-
defaultMessage: 'Back',
|
|
49
|
-
},
|
|
50
|
-
save: {
|
|
51
|
-
id: 'Save',
|
|
52
|
-
defaultMessage: 'Save',
|
|
53
|
-
},
|
|
54
|
-
cancel: {
|
|
55
|
-
id: 'Cancel',
|
|
56
|
-
defaultMessage: 'Cancel',
|
|
57
|
-
},
|
|
58
|
-
info: {
|
|
59
|
-
id: 'Info',
|
|
60
|
-
defaultMessage: 'Info',
|
|
61
|
-
},
|
|
62
|
-
enable: {
|
|
63
|
-
id: 'Enable editable Blocks',
|
|
64
|
-
defaultMessage: 'Enable editable Blocks',
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* ContentTypeLayout class.
|
|
70
|
-
* @class ContentTypeLayout
|
|
71
|
-
* @extends Component
|
|
72
|
-
*/
|
|
73
|
-
class ContentTypeLayout extends Component {
|
|
74
|
-
/**
|
|
75
|
-
* Property types.
|
|
76
|
-
* @property {Object} propTypes Property types.
|
|
77
|
-
* @static
|
|
78
|
-
*/
|
|
79
|
-
static propTypes = {
|
|
80
|
-
updateControlpanel: PropTypes.func.isRequired,
|
|
81
|
-
getControlpanel: PropTypes.func.isRequired,
|
|
82
|
-
getSchema: PropTypes.func.isRequired,
|
|
83
|
-
updateSchema: PropTypes.func.isRequired,
|
|
84
|
-
id: PropTypes.string.isRequired,
|
|
85
|
-
parent: PropTypes.string.isRequired,
|
|
86
|
-
pathname: PropTypes.string.isRequired,
|
|
87
|
-
schemaRequest: PropTypes.objectOf(PropTypes.any).isRequired,
|
|
88
|
-
cpanelRequest: PropTypes.objectOf(PropTypes.any).isRequired,
|
|
89
|
-
schema: PropTypes.objectOf(PropTypes.any),
|
|
90
|
-
controlpanel: PropTypes.shape({
|
|
91
|
-
'@id': PropTypes.string,
|
|
92
|
-
data: PropTypes.object,
|
|
93
|
-
schema: PropTypes.object,
|
|
94
|
-
title: PropTypes.string,
|
|
95
|
-
}),
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Default properties.
|
|
100
|
-
* @property {Object} defaultProps Default properties.
|
|
101
|
-
* @static
|
|
102
|
-
*/
|
|
103
|
-
static defaultProps = {
|
|
104
|
-
schema: {},
|
|
105
|
-
controlpanel: null,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Constructor
|
|
110
|
-
* @method constructor
|
|
111
|
-
* @param {Object} props Component properties
|
|
112
|
-
* @constructs ContentTypeLayout
|
|
113
|
-
*/
|
|
114
|
-
constructor(props) {
|
|
115
|
-
super(props);
|
|
116
|
-
|
|
117
|
-
this.state = {
|
|
118
|
-
visual: false,
|
|
119
|
-
content: null,
|
|
120
|
-
readOnlyBehavior: null,
|
|
121
|
-
error: null,
|
|
122
|
-
isClient: false,
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
this.onCancel = this.onCancel.bind(this);
|
|
126
|
-
this.onSubmit = this.onSubmit.bind(this);
|
|
127
|
-
this.onEnableBlocks = this.onEnableBlocks.bind(this);
|
|
128
|
-
this.onEnableBlocksBehavior = this.onEnableBlocksBehavior.bind(this);
|
|
129
|
-
this.onDisableBlocksBehavior = this.onDisableBlocksBehavior.bind(this);
|
|
130
|
-
this.form = React.createRef();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Component did mount
|
|
135
|
-
* @method componentDidMount
|
|
136
|
-
* @returns {undefined}
|
|
137
|
-
*/
|
|
138
|
-
componentDidMount() {
|
|
139
|
-
this.props.getControlpanel(join([this.props.parent, this.props.id], '/'));
|
|
140
|
-
this.props.getSchema(this.props.id);
|
|
141
|
-
this.setState({ isClient: true });
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Component will receive props
|
|
146
|
-
* @method componentWillReceiveProps
|
|
147
|
-
* @param {Object} nextProps Next properties
|
|
148
|
-
* @returns {undefined}
|
|
149
|
-
*/
|
|
150
|
-
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
151
|
-
// Control Panel GET
|
|
152
|
-
if (
|
|
153
|
-
this.props.cpanelRequest.get.loading &&
|
|
154
|
-
nextProps.cpanelRequest.get.error
|
|
155
|
-
) {
|
|
156
|
-
this.setState({
|
|
157
|
-
error: nextProps.cpanelRequest.get.error,
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Schema GET
|
|
162
|
-
if (this.props.schemaRequest.loading && nextProps.schemaRequest.loaded) {
|
|
163
|
-
const properties = nextProps.schema?.properties || {};
|
|
164
|
-
const content = {};
|
|
165
|
-
for (const key in properties) {
|
|
166
|
-
const value = properties[key].default;
|
|
167
|
-
if (value) {
|
|
168
|
-
content[key] = value;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (hasBlocksData(properties)) {
|
|
173
|
-
this.setState({
|
|
174
|
-
visual: true,
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
const blocksFieldName = getBlocksFieldname(properties);
|
|
178
|
-
const blocksLayoutFieldname = getBlocksLayoutFieldname(properties);
|
|
179
|
-
content[blocksFieldName] = properties[blocksFieldName]?.default || {};
|
|
180
|
-
content[blocksLayoutFieldname] = properties[blocksLayoutFieldname]
|
|
181
|
-
?.default || { items: [] };
|
|
182
|
-
|
|
183
|
-
const blocksBehavior = properties[blocksFieldName]?.behavior || '';
|
|
184
|
-
this.setState({
|
|
185
|
-
readOnlyBehavior: !blocksBehavior.includes('generated')
|
|
186
|
-
? blocksBehavior
|
|
187
|
-
: '',
|
|
188
|
-
});
|
|
189
|
-
} else {
|
|
190
|
-
this.setState({
|
|
191
|
-
visual: false,
|
|
192
|
-
readOnlyBehavior: '',
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
this.setState({
|
|
197
|
-
content: content,
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Schema updated
|
|
202
|
-
if (
|
|
203
|
-
this.props.schemaRequest.update.loading &&
|
|
204
|
-
nextProps.schemaRequest.update.loaded
|
|
205
|
-
) {
|
|
206
|
-
this.props.getSchema(this.props.id);
|
|
207
|
-
toast.info(
|
|
208
|
-
<Toast
|
|
209
|
-
info
|
|
210
|
-
title={this.props.intl.formatMessage(messages.info)}
|
|
211
|
-
content={this.props.intl.formatMessage(messages.changesSaved)}
|
|
212
|
-
/>,
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Blocks behavior disabled
|
|
217
|
-
if (
|
|
218
|
-
this.props.cpanelRequest.update.loading &&
|
|
219
|
-
nextProps.cpanelRequest.update.loaded
|
|
220
|
-
) {
|
|
221
|
-
this.onEnableBlocks();
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Submit handler
|
|
227
|
-
* @method onSubmit
|
|
228
|
-
* @param {object} data Form data.
|
|
229
|
-
* @returns {undefined}
|
|
230
|
-
*/
|
|
231
|
-
onSubmit(data) {
|
|
232
|
-
const schema = { properties: {} };
|
|
233
|
-
Object.keys(data)
|
|
234
|
-
.filter((k) => data[k])
|
|
235
|
-
.forEach((k) => (schema.properties[k] = { default: data[k] }));
|
|
236
|
-
this.props.updateSchema(this.props.id, schema);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Cancel handler
|
|
241
|
-
* @method onCancel
|
|
242
|
-
* @returns {undefined}
|
|
243
|
-
*/
|
|
244
|
-
onCancel() {
|
|
245
|
-
const url = getParentUrl(this.props.pathname);
|
|
246
|
-
this.props.history.push(getParentUrl(url));
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Enable blocks handler
|
|
251
|
-
* @method onEnableBlocks
|
|
252
|
-
* @returns {undefined}
|
|
253
|
-
*/
|
|
254
|
-
onEnableBlocks() {
|
|
255
|
-
const { properties = {} } = this.props.schema;
|
|
256
|
-
const blocksFieldName = getBlocksFieldname(properties);
|
|
257
|
-
const blocksLayoutFieldname = getBlocksLayoutFieldname(properties);
|
|
258
|
-
const schema = {
|
|
259
|
-
fieldsets: [
|
|
260
|
-
{
|
|
261
|
-
id: 'layout',
|
|
262
|
-
title: 'Layout',
|
|
263
|
-
fields: ['blocks', 'blocks_layout'],
|
|
264
|
-
},
|
|
265
|
-
],
|
|
266
|
-
properties: {
|
|
267
|
-
blocks: {
|
|
268
|
-
title: 'Blocks',
|
|
269
|
-
type: 'dict',
|
|
270
|
-
widget: 'json',
|
|
271
|
-
factory: 'JSONField',
|
|
272
|
-
default: properties[blocksFieldName]?.default || {},
|
|
273
|
-
},
|
|
274
|
-
blocks_layout: {
|
|
275
|
-
title: 'Blocks Layout',
|
|
276
|
-
type: 'dict',
|
|
277
|
-
widget: 'json',
|
|
278
|
-
factory: 'JSONField',
|
|
279
|
-
default: properties[blocksLayoutFieldname]?.default || { items: [] },
|
|
280
|
-
},
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
|
-
this.props.updateSchema(this.props.id, schema);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Disable Blocks behavior handler
|
|
288
|
-
* @method onDisableBlocksBehavior
|
|
289
|
-
* @returns {undefined}
|
|
290
|
-
*/
|
|
291
|
-
onDisableBlocksBehavior() {
|
|
292
|
-
this.props.updateControlpanel(this.props.controlpanel['@id'], {
|
|
293
|
-
[this.state.readOnlyBehavior]: false,
|
|
294
|
-
'volto.blocks.editable.layout': true,
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Enable Blocks behavior handler
|
|
300
|
-
* @method onEnableBlocksBehavior
|
|
301
|
-
* @returns {undefined}
|
|
302
|
-
*/
|
|
303
|
-
onEnableBlocksBehavior() {
|
|
304
|
-
this.props.updateControlpanel(this.props.controlpanel['@id'], {
|
|
305
|
-
'volto.blocks.editable.layout': true,
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Render method.
|
|
311
|
-
* @method render
|
|
312
|
-
* @returns {string} Markup for the component.
|
|
313
|
-
*/
|
|
314
|
-
render() {
|
|
315
|
-
// Error
|
|
316
|
-
if (this.state.error) {
|
|
317
|
-
return <Error error={this.state.error} />;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (!this.state.visual) {
|
|
321
|
-
// Still loading
|
|
322
|
-
if (!this.state.content) {
|
|
323
|
-
return <div />;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Blocks are not enabled
|
|
327
|
-
return (
|
|
328
|
-
<>
|
|
329
|
-
<Segment
|
|
330
|
-
placeholder
|
|
331
|
-
id="page-controlpanel-layout"
|
|
332
|
-
className="ui container center aligned"
|
|
333
|
-
>
|
|
334
|
-
<div>
|
|
335
|
-
<FormattedMessage
|
|
336
|
-
id="Can not edit Layout for <strong>{type}</strong> content-type as it doesn't have support for <strong>Volto Blocks</strong> enabled"
|
|
337
|
-
defaultMessage="Can not edit Layout for <strong>{type}</strong> content-type as it doesn't have support for <strong>Volto Blocks</strong> enabled"
|
|
338
|
-
values={{
|
|
339
|
-
strong: (...chunks) => <strong>{chunks}</strong>,
|
|
340
|
-
type: this.props?.controlpanel?.title || this.props.id,
|
|
341
|
-
}}
|
|
342
|
-
/>
|
|
343
|
-
</div>
|
|
344
|
-
<div className="ui divider"></div>
|
|
345
|
-
<Button
|
|
346
|
-
primary
|
|
347
|
-
onClick={this.onEnableBlocksBehavior}
|
|
348
|
-
content={this.props.intl.formatMessage(messages.enable)}
|
|
349
|
-
/>
|
|
350
|
-
</Segment>
|
|
351
|
-
<Portal
|
|
352
|
-
node={this.state.isClient && document.getElementById('toolbar')}
|
|
353
|
-
>
|
|
354
|
-
<Toolbar
|
|
355
|
-
pathname={this.props.pathname}
|
|
356
|
-
hideDefaultViewButtons
|
|
357
|
-
inner={
|
|
358
|
-
<>
|
|
359
|
-
<Link className="item" to="#" onClick={() => this.onCancel()}>
|
|
360
|
-
<Icon
|
|
361
|
-
name={backSVG}
|
|
362
|
-
size="30px"
|
|
363
|
-
className="contents circled"
|
|
364
|
-
title={this.props.intl.formatMessage(messages.back)}
|
|
365
|
-
/>
|
|
366
|
-
</Link>
|
|
367
|
-
</>
|
|
368
|
-
}
|
|
369
|
-
/>
|
|
370
|
-
</Portal>
|
|
371
|
-
</>
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (this.state.readOnlyBehavior) {
|
|
376
|
-
return (
|
|
377
|
-
<>
|
|
378
|
-
<Segment
|
|
379
|
-
placeholder
|
|
380
|
-
id="page-controlpanel-layout"
|
|
381
|
-
className="ui container center aligned"
|
|
382
|
-
>
|
|
383
|
-
<div>
|
|
384
|
-
<FormattedMessage
|
|
385
|
-
id="Can not edit Layout for <strong>{type}</strong> content-type as the <strong>Blocks behavior</strong> is enabled and <strong>read-only</strong>"
|
|
386
|
-
defaultMessage="Can not edit Layout for <strong>{type}</strong> content-type as the <strong>Blocks behavior</strong> is enabled and <strong>read-only</strong>"
|
|
387
|
-
values={{
|
|
388
|
-
strong: (...chunks) => <strong>{chunks}</strong>,
|
|
389
|
-
type: this.props?.controlpanel?.title || this.props.id,
|
|
390
|
-
}}
|
|
391
|
-
/>
|
|
392
|
-
</div>
|
|
393
|
-
<div className="ui divider"></div>
|
|
394
|
-
<Button
|
|
395
|
-
primary
|
|
396
|
-
onClick={this.onDisableBlocksBehavior}
|
|
397
|
-
content={this.props.intl.formatMessage(messages.enable)}
|
|
398
|
-
/>
|
|
399
|
-
</Segment>
|
|
400
|
-
<Portal
|
|
401
|
-
node={this.state.isClient && document.getElementById('toolbar')}
|
|
402
|
-
>
|
|
403
|
-
<Toolbar
|
|
404
|
-
pathname={this.props.pathname}
|
|
405
|
-
hideDefaultViewButtons
|
|
406
|
-
inner={
|
|
407
|
-
<>
|
|
408
|
-
<Link className="item" to="#" onClick={() => this.onCancel()}>
|
|
409
|
-
<Icon
|
|
410
|
-
name={backSVG}
|
|
411
|
-
size="30px"
|
|
412
|
-
className="contents circled"
|
|
413
|
-
title={this.props.intl.formatMessage(messages.back)}
|
|
414
|
-
/>
|
|
415
|
-
</Link>
|
|
416
|
-
</>
|
|
417
|
-
}
|
|
418
|
-
/>
|
|
419
|
-
</Portal>
|
|
420
|
-
</>
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Render layout editor
|
|
425
|
-
const blocksFieldName = getBlocksFieldname(
|
|
426
|
-
this.props.schema?.properties || {},
|
|
427
|
-
);
|
|
428
|
-
const blocksLayoutFieldname = getBlocksLayoutFieldname(
|
|
429
|
-
this.props.schema?.properties || {},
|
|
430
|
-
);
|
|
431
|
-
return (
|
|
432
|
-
<div id="page-controlpanel-layout">
|
|
433
|
-
<Form
|
|
434
|
-
isAdminForm
|
|
435
|
-
ref={this.form}
|
|
436
|
-
schema={{
|
|
437
|
-
fieldsets: [
|
|
438
|
-
{
|
|
439
|
-
id: 'layout',
|
|
440
|
-
title: 'Layout',
|
|
441
|
-
fields: [blocksFieldName, blocksLayoutFieldname],
|
|
442
|
-
},
|
|
443
|
-
],
|
|
444
|
-
properties: {
|
|
445
|
-
...this.props.schema.properties[blocksFieldName],
|
|
446
|
-
...this.props.schema.properties[blocksLayoutFieldname],
|
|
447
|
-
},
|
|
448
|
-
required: [],
|
|
449
|
-
}}
|
|
450
|
-
formData={this.state.content}
|
|
451
|
-
onSubmit={this.onSubmit}
|
|
452
|
-
onCancel={this.onCancel}
|
|
453
|
-
pathname={this.props.pathname}
|
|
454
|
-
visual={this.state.visual}
|
|
455
|
-
hideActions
|
|
456
|
-
/>
|
|
457
|
-
<Portal
|
|
458
|
-
node={this.state.isClient && document.getElementById('sidebar')}
|
|
459
|
-
>
|
|
460
|
-
<Sidebar settingsTab={true} documentTab={false} />
|
|
461
|
-
</Portal>
|
|
462
|
-
<Portal
|
|
463
|
-
node={this.state.isClient && document.getElementById('toolbar')}
|
|
464
|
-
>
|
|
465
|
-
<Toolbar
|
|
466
|
-
pathname={this.props.pathname}
|
|
467
|
-
hideDefaultViewButtons
|
|
468
|
-
inner={
|
|
469
|
-
<>
|
|
470
|
-
<Button
|
|
471
|
-
id="toolbar-save"
|
|
472
|
-
className="save"
|
|
473
|
-
aria-label={this.props.intl.formatMessage(messages.save)}
|
|
474
|
-
onClick={() => this.form.current.onSubmit()}
|
|
475
|
-
disabled={this.props.schemaRequest.update.loading}
|
|
476
|
-
loading={this.props.schemaRequest.update.loading}
|
|
477
|
-
>
|
|
478
|
-
<Icon
|
|
479
|
-
name={saveSVG}
|
|
480
|
-
className="circled"
|
|
481
|
-
size="30px"
|
|
482
|
-
title={this.props.intl.formatMessage(messages.save)}
|
|
483
|
-
/>
|
|
484
|
-
</Button>
|
|
485
|
-
<Button
|
|
486
|
-
className="cancel"
|
|
487
|
-
aria-label={this.props.intl.formatMessage(messages.cancel)}
|
|
488
|
-
onClick={() => this.onCancel()}
|
|
489
|
-
>
|
|
490
|
-
<Icon
|
|
491
|
-
name={clearSVG}
|
|
492
|
-
className="circled"
|
|
493
|
-
size="30px"
|
|
494
|
-
title={this.props.intl.formatMessage(messages.cancel)}
|
|
495
|
-
/>
|
|
496
|
-
</Button>
|
|
497
|
-
</>
|
|
498
|
-
}
|
|
499
|
-
/>
|
|
500
|
-
</Portal>
|
|
501
|
-
</div>
|
|
502
|
-
);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
export default compose(
|
|
507
|
-
injectIntl,
|
|
508
|
-
connect(
|
|
509
|
-
(state, props) => ({
|
|
510
|
-
schema: state.schema.schema,
|
|
511
|
-
schemaRequest: state.schema,
|
|
512
|
-
cpanelRequest: state.controlpanels,
|
|
513
|
-
controlpanel: state.controlpanels.controlpanel,
|
|
514
|
-
pathname: props.location.pathname,
|
|
515
|
-
id: nth(props.location.pathname.split('/'), -2),
|
|
516
|
-
parent: nth(props.location.pathname.split('/'), -3),
|
|
517
|
-
}),
|
|
518
|
-
{ getSchema, updateSchema, getControlpanel, updateControlpanel },
|
|
519
|
-
),
|
|
520
|
-
)(ContentTypeLayout);
|