@plone/volto 18.32.3 → 18.32.4
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 +17 -0
- package/package.json +2 -3
- package/src/components/manage/Contents/Contents.jsx +8 -2
- package/src/components/manage/Widgets/FormFieldWrapper.jsx +168 -146
- package/src/reducers/users/users.js +1 -1
- package/theme/themes/pastanaga/extras/main.less +0 -2
- package/types/components/manage/Widgets/FormFieldWrapper.d.ts +5 -28
- package/types/components/manage/Widgets/index.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,23 @@ myst:
|
|
|
17
17
|
|
|
18
18
|
<!-- towncrier release notes start -->
|
|
19
19
|
|
|
20
|
+
## 18.32.4 (2026-03-12)
|
|
21
|
+
|
|
22
|
+
### Feature
|
|
23
|
+
|
|
24
|
+
- If a delete operation fails, display the error message returned by the API (if any). @cekk [#7888](https://github.com/plone/volto/issues/7888)
|
|
25
|
+
|
|
26
|
+
### Bugfix
|
|
27
|
+
|
|
28
|
+
- Update the users controlpanel to be compatible with the new response format of the users endpoint introduced in https://github.com/plone/plone.restapi/pull/1971. @jnptk
|
|
29
|
+
|
|
30
|
+
### Internal
|
|
31
|
+
|
|
32
|
+
- Remove the `immutable` dependency, since it is not a direct dependency. @wesleybl [#7974](https://github.com/plone/volto/issues/7974)
|
|
33
|
+
- Update pnpm to 9.15.9. @wesleybl [#7975](https://github.com/plone/volto/issues/7975)
|
|
34
|
+
- Revert: "Backport #7672: Convert FormFieldWrapper to functional component (18.x.x)" @sneridagh [#7994](https://github.com/plone/volto/issues/7994)
|
|
35
|
+
- Update dependencies: webpack 5.105.4 @davisagli
|
|
36
|
+
|
|
20
37
|
## 18.32.3 (2026-03-04)
|
|
21
38
|
|
|
22
39
|
### Bugfix
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
}
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "18.32.
|
|
12
|
+
"version": "18.32.4",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git@github.com:plone/volto.git"
|
|
@@ -168,7 +168,6 @@
|
|
|
168
168
|
"hoist-non-react-statics": "3.3.2",
|
|
169
169
|
"http-proxy-middleware": "2.0.1",
|
|
170
170
|
"image-extensions": "1.1.0",
|
|
171
|
-
"immutable": "3",
|
|
172
171
|
"is-hotkey": "0.2.0",
|
|
173
172
|
"is-url": "1.2.4",
|
|
174
173
|
"jotai": "2.11.3",
|
|
@@ -363,7 +362,7 @@
|
|
|
363
362
|
"use-trace-update": "1.3.2",
|
|
364
363
|
"vitest": "^3.0.4",
|
|
365
364
|
"wait-on": "6.0.0",
|
|
366
|
-
"webpack": "5.
|
|
365
|
+
"webpack": "5.105.4",
|
|
367
366
|
"webpack-bundle-analyzer": "4.10.1",
|
|
368
367
|
"webpack-dev-server": "4.11.1",
|
|
369
368
|
"webpack-node-externals": "3.0.0",
|
|
@@ -504,11 +504,17 @@ class Contents extends Component {
|
|
|
504
504
|
}
|
|
505
505
|
|
|
506
506
|
if (this.props.deleteRequest.loading && nextProps.deleteRequest.error) {
|
|
507
|
+
const deleteErrorMessageTitle = this.props.intl.formatMessage(
|
|
508
|
+
messages.deleteError,
|
|
509
|
+
);
|
|
510
|
+
const deleteErrorMessageContent =
|
|
511
|
+
nextProps.deleteRequest.error?.response?.body?.message ||
|
|
512
|
+
deleteErrorMessageTitle;
|
|
507
513
|
this.props.toastify.toast.error(
|
|
508
514
|
<Toast
|
|
509
515
|
error
|
|
510
|
-
title={
|
|
511
|
-
content={
|
|
516
|
+
title={deleteErrorMessageTitle}
|
|
517
|
+
content={deleteErrorMessageContent}
|
|
512
518
|
/>,
|
|
513
519
|
);
|
|
514
520
|
}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* FormFieldWrapper component.
|
|
3
3
|
* @module components/manage/Widgets/FormFieldWrapper
|
|
4
4
|
*/
|
|
5
|
-
import React from 'react';
|
|
5
|
+
import React, { Component } from 'react';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
import { Form, Grid, Icon as IconOld, Label } from 'semantic-ui-react';
|
|
8
8
|
import map from 'lodash/map';
|
|
9
9
|
import cx from 'classnames';
|
|
10
|
-
import { defineMessages,
|
|
10
|
+
import { defineMessages, injectIntl } from 'react-intl';
|
|
11
11
|
import LanguageSVG from '@plone/volto/icons/language.svg';
|
|
12
12
|
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
13
13
|
|
|
@@ -31,156 +31,178 @@ const messages = defineMessages({
|
|
|
31
31
|
},
|
|
32
32
|
});
|
|
33
33
|
/**
|
|
34
|
-
* FormFieldWrapper component.
|
|
35
|
-
* @
|
|
36
|
-
* @
|
|
37
|
-
* @returns {JSX.Element} Markup for the component.
|
|
34
|
+
* FormFieldWrapper component class.
|
|
35
|
+
* @class FormFieldWrapper
|
|
36
|
+
* @extends Component
|
|
38
37
|
*/
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
38
|
+
class FormFieldWrapper extends Component {
|
|
39
|
+
/**
|
|
40
|
+
* Property types.
|
|
41
|
+
* @property {Object} propTypes Property types.
|
|
42
|
+
* @static
|
|
43
|
+
*/
|
|
44
|
+
static propTypes = {
|
|
45
|
+
id: PropTypes.string.isRequired,
|
|
46
|
+
title: PropTypes.string.isRequired,
|
|
47
|
+
description: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
|
48
|
+
required: PropTypes.bool,
|
|
49
|
+
error: PropTypes.arrayOf(PropTypes.string),
|
|
50
|
+
wrapped: PropTypes.bool,
|
|
51
|
+
columns: PropTypes.number,
|
|
52
|
+
draggable: PropTypes.bool,
|
|
53
|
+
isDisabled: PropTypes.bool,
|
|
54
|
+
onEdit: PropTypes.func,
|
|
55
|
+
className: PropTypes.string,
|
|
56
|
+
onDelete: PropTypes.func,
|
|
57
|
+
intl: PropTypes.object,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Default properties
|
|
62
|
+
* @property {Object} defaultProps Default properties.
|
|
63
|
+
* @static
|
|
64
|
+
*/
|
|
65
|
+
static defaultProps = {
|
|
66
|
+
description: null,
|
|
67
|
+
required: false,
|
|
68
|
+
error: [],
|
|
69
|
+
wrapped: true,
|
|
70
|
+
columns: 2,
|
|
71
|
+
onDelete: null,
|
|
72
|
+
intl: null,
|
|
73
|
+
isDisabled: null,
|
|
74
|
+
draggable: null,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Render method.
|
|
79
|
+
* @method render
|
|
80
|
+
* @returns {string} Markup for the component.
|
|
81
|
+
*/
|
|
82
|
+
render() {
|
|
83
|
+
const {
|
|
84
|
+
id,
|
|
85
|
+
title,
|
|
86
|
+
description,
|
|
87
|
+
fieldSet,
|
|
88
|
+
required,
|
|
89
|
+
error,
|
|
90
|
+
wrapped,
|
|
91
|
+
columns,
|
|
92
|
+
draggable,
|
|
93
|
+
onEdit,
|
|
94
|
+
className,
|
|
95
|
+
isDisabled,
|
|
96
|
+
onDelete,
|
|
97
|
+
intl,
|
|
98
|
+
noForInFieldLabel,
|
|
99
|
+
multilingual_options,
|
|
100
|
+
} = this.props;
|
|
101
|
+
|
|
102
|
+
const languageIndependent = multilingual_options?.language_independent;
|
|
59
103
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
104
|
+
const wdg = (
|
|
105
|
+
<>
|
|
106
|
+
{this.props.children}
|
|
63
107
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
108
|
+
{map(error, (message) => (
|
|
109
|
+
<Label key={message} basic color="red" className="form-error-label">
|
|
110
|
+
{message}
|
|
111
|
+
</Label>
|
|
112
|
+
))}
|
|
113
|
+
</>
|
|
114
|
+
);
|
|
71
115
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
/>
|
|
98
|
-
)}
|
|
99
|
-
{title}
|
|
100
|
-
{languageIndependent && (
|
|
101
|
-
<div className="languageIndependent-icon">
|
|
102
|
-
<Icon
|
|
103
|
-
title={intl.formatMessage(
|
|
104
|
-
messages.language_independent_icon_title,
|
|
105
|
-
)}
|
|
106
|
-
name={LanguageSVG}
|
|
107
|
-
size="24px"
|
|
108
|
-
color="#555"
|
|
116
|
+
return wrapped ? (
|
|
117
|
+
<Form.Field
|
|
118
|
+
inline
|
|
119
|
+
required={required}
|
|
120
|
+
error={error && error.length > 0}
|
|
121
|
+
className={cx(
|
|
122
|
+
description ? 'help' : '',
|
|
123
|
+
className,
|
|
124
|
+
`field-wrapper-${id}`,
|
|
125
|
+
languageIndependent ? 'language-independent-field' : null,
|
|
126
|
+
)}
|
|
127
|
+
>
|
|
128
|
+
<Grid>
|
|
129
|
+
<Grid.Row stretched>
|
|
130
|
+
{columns === 2 && (
|
|
131
|
+
<Grid.Column width="4">
|
|
132
|
+
<div className="wrapper">
|
|
133
|
+
<label
|
|
134
|
+
id={`fieldset-${fieldSet}-field-label-${id}`}
|
|
135
|
+
htmlFor={noForInFieldLabel ? null : `field-${id}`}
|
|
136
|
+
>
|
|
137
|
+
{draggable && onEdit && (
|
|
138
|
+
<i
|
|
139
|
+
aria-hidden="true"
|
|
140
|
+
className="grey bars icon drag handle"
|
|
109
141
|
/>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<IconOld name="write square" size="large" color="blue" />
|
|
128
|
-
</button>
|
|
129
|
-
<button
|
|
130
|
-
aria-label={intl.formatMessage(messages.delete)}
|
|
131
|
-
className="item ui noborder button"
|
|
132
|
-
onClick={(evt) => {
|
|
133
|
-
evt.preventDefault();
|
|
134
|
-
onDelete(id);
|
|
135
|
-
}}
|
|
136
|
-
>
|
|
137
|
-
<IconOld name="close" size="large" color="red" />
|
|
138
|
-
</button>
|
|
139
|
-
</div>
|
|
142
|
+
)}
|
|
143
|
+
{title}
|
|
144
|
+
{languageIndependent && (
|
|
145
|
+
<div className="languageIndependent-icon">
|
|
146
|
+
<Icon
|
|
147
|
+
title={intl.formatMessage(
|
|
148
|
+
messages.language_independent_icon_title,
|
|
149
|
+
)}
|
|
150
|
+
name={LanguageSVG}
|
|
151
|
+
size="24px"
|
|
152
|
+
color="#555"
|
|
153
|
+
/>
|
|
154
|
+
</div>
|
|
155
|
+
)}
|
|
156
|
+
</label>
|
|
157
|
+
</div>
|
|
158
|
+
</Grid.Column>
|
|
140
159
|
)}
|
|
141
|
-
{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
160
|
+
<Grid.Column width={columns === 2 ? 8 : 12}>
|
|
161
|
+
{onEdit && !isDisabled && (
|
|
162
|
+
<div className="toolbar" style={{ zIndex: '2' }}>
|
|
163
|
+
<button
|
|
164
|
+
aria-label={intl.formatMessage(messages.edit)}
|
|
165
|
+
className="item ui noborder button"
|
|
166
|
+
onClick={(evt) => {
|
|
167
|
+
evt.preventDefault();
|
|
168
|
+
onEdit(id);
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
<IconOld name="write square" size="large" color="blue" />
|
|
172
|
+
</button>
|
|
173
|
+
<button
|
|
174
|
+
aria-label={intl.formatMessage(messages.delete)}
|
|
175
|
+
className="item ui noborder button"
|
|
176
|
+
onClick={(evt) => {
|
|
177
|
+
evt.preventDefault();
|
|
178
|
+
onDelete(id);
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
<IconOld name="close" size="large" color="red" />
|
|
182
|
+
</button>
|
|
183
|
+
</div>
|
|
184
|
+
)}
|
|
185
|
+
{wdg}
|
|
153
186
|
</Grid.Column>
|
|
154
187
|
</Grid.Row>
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
columns: PropTypes.number,
|
|
175
|
-
draggable: PropTypes.bool,
|
|
176
|
-
isDisabled: PropTypes.bool,
|
|
177
|
-
onEdit: PropTypes.func,
|
|
178
|
-
className: PropTypes.string,
|
|
179
|
-
onDelete: PropTypes.func,
|
|
180
|
-
fieldSet: PropTypes.string,
|
|
181
|
-
noForInFieldLabel: PropTypes.bool,
|
|
182
|
-
multilingual_options: PropTypes.object,
|
|
183
|
-
children: PropTypes.node,
|
|
184
|
-
};
|
|
188
|
+
{description && (
|
|
189
|
+
<Grid.Row stretched>
|
|
190
|
+
<Grid.Column stretched width="12">
|
|
191
|
+
<p className="help">
|
|
192
|
+
{this.props.multilingual_options
|
|
193
|
+
? `${intl.formatMessage(messages.language_independent)} `
|
|
194
|
+
: null}
|
|
195
|
+
{description}
|
|
196
|
+
</p>
|
|
197
|
+
</Grid.Column>
|
|
198
|
+
</Grid.Row>
|
|
199
|
+
)}
|
|
200
|
+
</Grid>
|
|
201
|
+
</Form.Field>
|
|
202
|
+
) : (
|
|
203
|
+
<>{wdg}</>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
185
207
|
|
|
186
|
-
export default FormFieldWrapper;
|
|
208
|
+
export default injectIntl(FormFieldWrapper);
|
|
@@ -117,7 +117,7 @@ export default function users(state = initialState, action = {}) {
|
|
|
117
117
|
case `${LIST_USERS}_SUCCESS`:
|
|
118
118
|
return {
|
|
119
119
|
...state,
|
|
120
|
-
users: action.result,
|
|
120
|
+
users: action.result.items ? action.result.items : action.result,
|
|
121
121
|
[getRequestKey(action.type)]: {
|
|
122
122
|
loading: false,
|
|
123
123
|
loaded: true,
|
|
@@ -1,28 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* @returns {JSX.Element} Markup for the component.
|
|
7
|
-
*/
|
|
8
|
-
declare function FormFieldWrapper({ id, title, description, fieldSet, required, error, wrapped, columns, draggable, onEdit, className, isDisabled, onDelete, noForInFieldLabel, multilingual_options, children, }: any): JSX.Element;
|
|
9
|
-
declare namespace FormFieldWrapper {
|
|
10
|
-
namespace propTypes {
|
|
11
|
-
let id: any;
|
|
12
|
-
let title: any;
|
|
13
|
-
let description: any;
|
|
14
|
-
let required: any;
|
|
15
|
-
let error: any;
|
|
16
|
-
let wrapped: any;
|
|
17
|
-
let columns: any;
|
|
18
|
-
let draggable: any;
|
|
19
|
-
let isDisabled: any;
|
|
20
|
-
let onEdit: any;
|
|
21
|
-
let className: any;
|
|
22
|
-
let onDelete: any;
|
|
23
|
-
let fieldSet: any;
|
|
24
|
-
let noForInFieldLabel: any;
|
|
25
|
-
let multilingual_options: any;
|
|
26
|
-
let children: any;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
1
|
+
declare const _default: React.FC<import("react-intl").WithIntlProps<any>> & {
|
|
2
|
+
WrappedComponent: React.ComponentType<any>;
|
|
3
|
+
};
|
|
4
|
+
export default _default;
|
|
5
|
+
import React from 'react';
|
|
@@ -121,4 +121,4 @@ export declare const ColorPickerWidget: import("@loadable/component").LoadableCo
|
|
|
121
121
|
export declare const DatetimeWidget: import("@loadable/component").LoadableClassComponent<any>;
|
|
122
122
|
export declare const TimeWidget: import("@loadable/component").LoadableClassComponent<any>;
|
|
123
123
|
export declare const RecurrenceWidget: import("@loadable/component").LoadableClassComponent<any>;
|
|
124
|
-
export declare const FormFieldWrapper: import("@loadable/component").LoadableComponent<any
|
|
124
|
+
export declare const FormFieldWrapper: import("@loadable/component").LoadableComponent<import("react-intl").WithIntlProps<any>>;
|