@plone/volto 19.0.0-alpha.4 → 19.0.0-alpha.6

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 (118) hide show
  1. package/.eslintrc +20 -0
  2. package/CHANGELOG.md +62 -0
  3. package/README.md +0 -2
  4. package/cypress/support/commands.js +8 -6
  5. package/locales/af.json +1 -1
  6. package/locales/ar.json +1 -1
  7. package/locales/bg.json +1 -1
  8. package/locales/bn.json +1 -1
  9. package/locales/ca/LC_MESSAGES/volto.po +16 -1
  10. package/locales/ca.json +1 -1
  11. package/locales/cs.json +1 -1
  12. package/locales/cy.json +1 -1
  13. package/locales/da.json +1 -1
  14. package/locales/de/LC_MESSAGES/volto.po +19 -4
  15. package/locales/de.json +1 -1
  16. package/locales/el.json +1 -1
  17. package/locales/en/LC_MESSAGES/volto.po +16 -1
  18. package/locales/en.json +1 -1
  19. package/locales/en_AU.json +1 -1
  20. package/locales/en_GB.json +1 -1
  21. package/locales/eo.json +1 -1
  22. package/locales/es/LC_MESSAGES/volto.po +16 -1
  23. package/locales/es.json +1 -1
  24. package/locales/et.json +1 -1
  25. package/locales/eu/LC_MESSAGES/volto.po +16 -1
  26. package/locales/eu.json +1 -1
  27. package/locales/fa.json +1 -1
  28. package/locales/fi/LC_MESSAGES/volto.po +16 -1
  29. package/locales/fi.json +1 -1
  30. package/locales/fr/LC_MESSAGES/volto.po +16 -1
  31. package/locales/fr.json +1 -1
  32. package/locales/fu.json +1 -1
  33. package/locales/gl.json +1 -1
  34. package/locales/he.json +1 -1
  35. package/locales/hi/LC_MESSAGES/volto.po +16 -1
  36. package/locales/hi.json +1 -1
  37. package/locales/hr.json +1 -1
  38. package/locales/hu.json +1 -1
  39. package/locales/hy.json +1 -1
  40. package/locales/id.json +1 -1
  41. package/locales/it/LC_MESSAGES/volto.po +16 -1
  42. package/locales/it.json +1 -1
  43. package/locales/ja/LC_MESSAGES/volto.po +16 -1
  44. package/locales/ja.json +1 -1
  45. package/locales/ka.json +1 -1
  46. package/locales/kn.json +1 -1
  47. package/locales/ko.json +1 -1
  48. package/locales/lt.json +1 -1
  49. package/locales/lv.json +1 -1
  50. package/locales/mi.json +1 -1
  51. package/locales/mk.json +1 -1
  52. package/locales/my.json +1 -1
  53. package/locales/nb_NO.json +1 -1
  54. package/locales/nl/LC_MESSAGES/volto.po +16 -1
  55. package/locales/nl.json +1 -1
  56. package/locales/nn.json +1 -1
  57. package/locales/pl.json +1 -1
  58. package/locales/pt/LC_MESSAGES/volto.po +16 -1
  59. package/locales/pt.json +1 -1
  60. package/locales/pt_BR/LC_MESSAGES/volto.po +25 -10
  61. package/locales/pt_BR.json +1 -1
  62. package/locales/rm.json +1 -1
  63. package/locales/ro/LC_MESSAGES/volto.po +16 -1
  64. package/locales/ro.json +1 -1
  65. package/locales/ru/LC_MESSAGES/volto.po +16 -1
  66. package/locales/ru.json +1 -1
  67. package/locales/sk.json +1 -1
  68. package/locales/sl.json +1 -1
  69. package/locales/sm.json +1 -1
  70. package/locales/sq.json +1 -1
  71. package/locales/sr.json +1 -1
  72. package/locales/sr@cyrl.json +1 -1
  73. package/locales/sr@latn.json +1 -1
  74. package/locales/sv.json +1 -1
  75. package/locales/ta.json +1 -1
  76. package/locales/te.json +1 -1
  77. package/locales/th.json +1 -1
  78. package/locales/to.json +1 -1
  79. package/locales/tr.json +1 -1
  80. package/locales/uk.json +1 -1
  81. package/locales/vi.json +1 -1
  82. package/locales/volto.pot +17 -2
  83. package/locales/zh_CN/LC_MESSAGES/volto.po +16 -1
  84. package/locales/zh_CN.json +1 -1
  85. package/locales/zh_Hant.json +1 -1
  86. package/locales/zh_Hant_HK.json +1 -1
  87. package/package.json +7 -7
  88. package/src/components/manage/Blocks/Image/Edit.jsx +5 -1
  89. package/src/components/manage/Blocks/LeadImage/Edit.jsx +2 -2
  90. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +1 -1
  91. package/src/components/manage/Blocks/Maps/Edit.jsx +2 -1
  92. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +21 -4
  93. package/src/components/manage/Blocks/Teaser/Data.jsx +21 -7
  94. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +1 -1
  95. package/src/components/manage/Blocks/Video/Edit.jsx +2 -1
  96. package/src/components/manage/Contents/Contents.jsx +20 -2
  97. package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
  98. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +156 -175
  99. package/src/components/manage/Form/InlineForm.jsx +2 -2
  100. package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
  101. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +2 -1
  102. package/src/components/manage/Toolbar/PersonalTools.jsx +2 -1
  103. package/src/components/manage/Widgets/FileWidget.jsx +14 -8
  104. package/src/components/manage/Widgets/ImageWidget.jsx +160 -34
  105. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +2 -1
  106. package/src/components/theme/Avatar/Avatar.jsx +2 -1
  107. package/src/components/theme/PreviewImage/PreviewImage.jsx +1 -1
  108. package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
  109. package/src/middleware/api.js +1 -1
  110. package/src/middleware/storeProtectLoadUtils.test.js +3 -3
  111. package/theme/themes/pastanaga/extras/blocks.less +19 -0
  112. package/theme/themes/pastanaga/extras/contents.less +12 -0
  113. package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +18 -2
  114. package/types/components/manage/Controlpanels/index.d.ts +1 -1
  115. package/types/components/manage/Widgets/ImageWidget.d.ts +41 -1
  116. package/types/components/manage/Widgets/RecurrenceWidget/Utils.d.ts +12 -18
  117. package/types/helpers/Helmet/Helmet.d.ts +1 -1
  118. package/cypress/downloads/downloads.html +0 -0
@@ -1,10 +1,11 @@
1
1
  /**
2
- * Users controlpanel user.
3
- * @module components/manage/Controlpanels/UsersControlpanelUser
2
+ * RenderUsers component.
3
+ * @module components/manage/Controlpanels/Users/RenderUsers
4
4
  */
5
5
  import PropTypes from 'prop-types';
6
- import React, { Component } from 'react';
7
- import { FormattedMessage, injectIntl } from 'react-intl';
6
+ import { useState } from 'react';
7
+ import { FormattedMessage, useIntl } from 'react-intl';
8
+ import { useDispatch, useSelector } from 'react-redux';
8
9
  import { Dropdown, Table, Checkbox } from 'semantic-ui-react';
9
10
  import trashSVG from '@plone/volto/icons/delete.svg';
10
11
  import editSVG from '@plone/volto/icons/editing.svg';
@@ -13,199 +14,179 @@ import Toast from '@plone/volto/components/manage/Toast/Toast';
13
14
  import { ModalForm } from '@plone/volto/components/manage/Form';
14
15
  import { updateUser } from '@plone/volto/actions/users/users';
15
16
  import ploneSVG from '@plone/volto/icons/plone.svg';
16
- import { compose } from 'redux';
17
- import { connect } from 'react-redux';
18
17
  import { messages } from '@plone/volto/helpers/MessageLabels/MessageLabels';
19
18
  import { canAssignRole } from '@plone/volto/helpers/User/User';
20
19
  import { toast } from 'react-toastify';
21
20
 
22
21
  /**
23
- * UsersControlpanelUser class.
24
- * @class UsersControlpanelUser
25
- * @extends Component
22
+ * RenderUsers functional component.
23
+ * @function RenderUsers
26
24
  */
27
- class RenderUsers extends Component {
28
- /**
29
- * Property types.
30
- * @property {Object} propTypes Property types.
31
- * @static
32
- */
33
- static propTypes = {
34
- user: PropTypes.shape({
35
- username: PropTypes.string,
36
- fullname: PropTypes.string,
37
- roles: PropTypes.arrayOf(PropTypes.string),
38
- }).isRequired,
39
- roles: PropTypes.arrayOf(
40
- PropTypes.shape({
41
- id: PropTypes.string,
42
- }),
43
- ).isRequired,
44
- onDelete: PropTypes.func.isRequired,
45
- isUserManager: PropTypes.bool.isRequired,
46
- };
25
+ const RenderUsers = (props) => {
26
+ const [user, setUser] = useState({});
47
27
 
48
- /**
49
- * Constructor
50
- * @method constructor
51
- * @param {Object} props Component properties
52
- * @constructs Sharing
53
- */
54
- constructor(props) {
55
- super(props);
56
- this.state = {
57
- user: {},
58
- };
59
- this.onChange = this.onChange.bind(this);
60
- this.onEditUserError = this.onEditUserError.bind(this);
61
- this.onEditUserSubmit = this.onEditUserSubmit.bind(this);
62
- }
28
+ const intl = useIntl();
29
+ const dispatch = useDispatch();
30
+ const updateRequest = useSelector((state) => state.users?.update);
31
+
32
+ const {
33
+ user: propsUser,
34
+ listUsers,
35
+ updateUser: updateUserRole,
36
+ isUserManager,
37
+ roles,
38
+ inheritedRole,
39
+ userschema,
40
+ onDelete,
41
+ } = props;
42
+
43
+ // Use dispatch to call updateUser action
44
+ const updateUserData = (userId, userData) => {
45
+ dispatch(updateUser(userId, userData))
46
+ .then(() => {
47
+ // Handle success
48
+ setUser({});
49
+ if (listUsers) {
50
+ listUsers();
51
+ }
52
+ toast.success(
53
+ <Toast
54
+ success
55
+ title={intl.formatMessage(messages.success)}
56
+ content={intl.formatMessage(messages.updateUserSuccess)}
57
+ />,
58
+ );
59
+ })
60
+ .catch(() => {
61
+ // Handle error
62
+ toast.error(
63
+ <Toast
64
+ error
65
+ title={intl.formatMessage(messages.error)}
66
+ content={intl.formatMessage(messages.thereWereSomeErrors)}
67
+ />,
68
+ );
69
+ });
70
+ };
63
71
 
64
72
  /**
65
73
  * @param {*} event
66
74
  * @param {*} { value }
67
- * @memberof UsersControlpanelUser
68
75
  */
76
+ const onChange = (_event, { value }) => {
77
+ const [userId, role] = value.split('&role=');
78
+ updateUserRole(userId, role);
79
+ };
69
80
 
70
- onChange(event, { value }) {
71
- const [user, role] = value.split('&role=');
72
- this.props.updateUser(user, role);
73
- }
74
-
75
- componentDidUpdate(prevProps) {
76
- if (
77
- prevProps.updateRequest.loading &&
78
- this.props.updateRequest.loaded &&
79
- this.state?.user?.id === this.props?.user?.id
80
- ) {
81
- this.setState({ user: {} });
82
- this.props.listUsers();
83
- return toast.success(
84
- <Toast
85
- success
86
- title={this.props.intl.formatMessage(messages.success)}
87
- content={this.props.intl.formatMessage(messages.updateUserSuccess)}
88
- />,
89
- );
90
- }
91
- }
92
-
93
- onEditUserSubmit(data, callback) {
81
+ const onEditUserSubmit = (data) => {
94
82
  // Do not handle groups and roles in this form
95
83
  delete data.groups;
96
84
  delete data.roles;
97
- this.props.updateUserData(data.id, data);
98
- }
99
-
100
- onEditUserError() {
101
- return toast.error(
102
- <Toast
103
- error
104
- title={this.props.intl.formatMessage(messages.error)}
105
- content={this.props.intl.formatMessage(
106
- messages.addUserFormPasswordAndSendPasswordTogetherNotAllowed,
107
- )}
108
- />,
109
- );
110
- }
85
+ updateUserData(data.id, data);
86
+ };
111
87
 
112
- onClickEdit(props) {
113
- const { formData } = props;
114
- this.setState({ user: { ...formData } });
115
- }
88
+ const onClickEdit = (formProps) => {
89
+ const { formData } = formProps;
90
+ setUser({ ...formData });
91
+ };
116
92
 
117
- canDeleteUser() {
118
- if (this.props.isUserManager) return true;
119
- return !this.props.user.roles.includes('Manager');
120
- }
93
+ const canDeleteUser = () => {
94
+ if (isUserManager) return true;
95
+ return !propsUser.roles.includes('Manager');
96
+ };
121
97
 
122
- /**
123
- * Render method.
124
- * @method render
125
- * @returns {string} Markup for the component.
126
- */
127
- render() {
128
- return (
129
- <Table.Row key={this.props.user.username}>
130
- <Table.Cell className="fullname">
131
- {this.props.user.fullname
132
- ? this.props.user.fullname
133
- : this.props.user.username}{' '}
134
- ({this.props.user.username})
98
+ return (
99
+ <Table.Row key={propsUser.username}>
100
+ <Table.Cell className="fullname">
101
+ {propsUser.fullname ? propsUser.fullname : propsUser.username} (
102
+ {propsUser.username})
103
+ </Table.Cell>
104
+ {roles.map((role) => (
105
+ <Table.Cell key={role.id}>
106
+ {inheritedRole && inheritedRole.includes(role.id) ? (
107
+ <Icon
108
+ name={ploneSVG}
109
+ size="20px"
110
+ color="#007EB1"
111
+ title={'plone-svg'}
112
+ />
113
+ ) : (
114
+ <Checkbox
115
+ checked={propsUser.roles.includes(role.id)}
116
+ onChange={onChange}
117
+ value={`${propsUser.id}&role=${role.id}`}
118
+ disabled={!canAssignRole(isUserManager, role)}
119
+ />
120
+ )}
135
121
  </Table.Cell>
136
- {this.props.roles.map((role) => (
137
- <Table.Cell key={role.id}>
138
- {this.props.inheritedRole &&
139
- this.props.inheritedRole.includes(role.id) ? (
140
- <Icon
141
- name={ploneSVG}
142
- size="20px"
143
- color="#007EB1"
144
- title={'plone-svg'}
145
- />
146
- ) : (
147
- <Checkbox
148
- checked={this.props.user.roles.includes(role.id)}
149
- onChange={this.onChange}
150
- value={`${this.props.user.id}&role=${role.id}`}
151
- disabled={!canAssignRole(this.props.isUserManager, role)}
152
- />
153
- )}
154
- </Table.Cell>
155
- ))}
156
- <Table.Cell textAlign="right">
157
- {this.canDeleteUser() && (
158
- <Dropdown icon="ellipsis horizontal">
159
- <Dropdown.Menu className="left">
160
- {this.props.userschema && (
161
- <Dropdown.Item
162
- id="edit-user-button"
163
- onClick={() => {
164
- this.onClickEdit({ formData: this.props.user });
165
- }}
166
- value={this.props.user['@id']}
167
- >
168
- <Icon name={editSVG} size="15px" />
169
- <FormattedMessage id="Edit" defaultMessage="Edit" />
170
- </Dropdown.Item>
171
- )}
122
+ ))}
123
+ <Table.Cell textAlign="right">
124
+ {canDeleteUser() && (
125
+ <Dropdown icon="ellipsis horizontal">
126
+ <Dropdown.Menu className="left">
127
+ {userschema && (
172
128
  <Dropdown.Item
173
- id="delete-user-button"
174
- onClick={this.props.onDelete}
175
- value={this.props.user['@id']}
129
+ id="edit-user-button"
130
+ onClick={() => {
131
+ onClickEdit({ formData: propsUser });
132
+ }}
133
+ value={propsUser['@id']}
176
134
  >
177
- <Icon name={trashSVG} size="15px" />
178
- <FormattedMessage id="Delete" defaultMessage="Delete" />
135
+ <Icon name={editSVG} size="15px" />
136
+ <FormattedMessage id="Edit" defaultMessage="Edit" />
179
137
  </Dropdown.Item>
180
- </Dropdown.Menu>
181
- </Dropdown>
182
- )}
183
- </Table.Cell>
184
- {Object.keys(this.state.user).length > 0 &&
185
- this.props.userschema.loaded && (
186
- <ModalForm
187
- className="modal"
188
- onSubmit={this.onEditUserSubmit}
189
- submitError={this.state.editUserError}
190
- formData={this.state.user}
191
- onCancel={() => this.setState({ user: {} })}
192
- title={this.props.intl.formatMessage(
193
- messages.updateUserFormTitle,
194
138
  )}
195
- loading={this.props.updateRequest.loading}
196
- schema={this.props.userschema.userschema}
197
- />
198
- )}
199
- </Table.Row>
200
- );
201
- }
202
- }
203
- export default compose(
204
- injectIntl,
205
- connect(
206
- (state, props) => ({
207
- updateRequest: state.users?.update,
139
+ <Dropdown.Item
140
+ id="delete-user-button"
141
+ onClick={onDelete}
142
+ value={propsUser['@id']}
143
+ >
144
+ <Icon name={trashSVG} size="15px" />
145
+ <FormattedMessage id="Delete" defaultMessage="Delete" />
146
+ </Dropdown.Item>
147
+ </Dropdown.Menu>
148
+ </Dropdown>
149
+ )}
150
+ </Table.Cell>
151
+ {Object.keys(user).length > 0 && userschema.loaded && (
152
+ <ModalForm
153
+ className="modal"
154
+ onSubmit={onEditUserSubmit}
155
+ submitError={user.editUserError}
156
+ formData={user}
157
+ onCancel={() => setUser({})}
158
+ title={intl.formatMessage(messages.updateUserFormTitle)}
159
+ loading={updateRequest.loading}
160
+ schema={userschema.userschema}
161
+ />
162
+ )}
163
+ </Table.Row>
164
+ );
165
+ };
166
+
167
+ // PropTypes to the component
168
+ RenderUsers.propTypes = {
169
+ user: PropTypes.shape({
170
+ id: PropTypes.string,
171
+ username: PropTypes.string,
172
+ fullname: PropTypes.string,
173
+ roles: PropTypes.arrayOf(PropTypes.string),
174
+ '@id': PropTypes.string,
175
+ }).isRequired,
176
+ roles: PropTypes.arrayOf(
177
+ PropTypes.shape({
178
+ id: PropTypes.string,
208
179
  }),
209
- { updateUserData: updateUser },
210
- ),
211
- )(RenderUsers);
180
+ ).isRequired,
181
+ onDelete: PropTypes.func.isRequired,
182
+ isUserManager: PropTypes.bool.isRequired,
183
+ listUsers: PropTypes.func,
184
+ updateUser: PropTypes.func.isRequired,
185
+ inheritedRole: PropTypes.arrayOf(PropTypes.string),
186
+ userschema: PropTypes.shape({
187
+ loaded: PropTypes.bool,
188
+ userschema: PropTypes.object,
189
+ }),
190
+ };
191
+
192
+ export default RenderUsers;
@@ -158,7 +158,7 @@ const InlineForm = (props) => {
158
158
  onChangeField(id, value, itemInfo);
159
159
  }}
160
160
  key={field}
161
- error={errors?.[block]?.[field] || {}}
161
+ error={errors?.[block]?.[field] || []}
162
162
  block={block}
163
163
  />
164
164
  ))}
@@ -199,7 +199,7 @@ const InlineForm = (props) => {
199
199
  onChangeField(id, value);
200
200
  }}
201
201
  key={field}
202
- error={errors?.[block]?.[field] || {}}
202
+ error={errors?.[block]?.[field] || []}
203
203
  block={block}
204
204
  />
205
205
  ))}
@@ -3,6 +3,7 @@ import { Button, Segment, Popup } from 'semantic-ui-react';
3
3
  import { useIntl, defineMessages } from 'react-intl';
4
4
  import cx from 'classnames';
5
5
  import Icon from '@plone/volto/components/theme/Icon/Icon';
6
+ import Image from '@plone/volto/components/theme/Image/Image';
6
7
  import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
7
8
  import { getContentIcon } from '@plone/volto/helpers/Content/Content';
8
9
  import config from '@plone/volto/registry';
@@ -69,7 +70,7 @@ const ObjectBrowserNav = ({
69
70
  }
70
71
  >
71
72
  {item['@type'] === 'Image' ? (
72
- <img
73
+ <Image
73
74
  src={`${item['@id']}/@@images/image/preview`}
74
75
  alt={item.title}
75
76
  style={{
@@ -1,6 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import { useIntl } from 'react-intl';
3
3
  import { Button, Grid, Message } from 'semantic-ui-react';
4
+ import Image from '@plone/volto/components/theme/Image/Image';
4
5
 
5
6
  const TemplateChooser = ({ templates, onSelectTemplate }) => {
6
7
  const intl = useIntl();
@@ -15,7 +16,7 @@ const TemplateChooser = ({ templates, onSelectTemplate }) => {
15
16
  className="template-chooser-item"
16
17
  onClick={() => onSelectTemplate(index)}
17
18
  >
18
- <img src={template.image} alt="" />
19
+ <Image src={template.image} alt="" />
19
20
  <div className="template-chooser-title">
20
21
  {intl.formatMessage({
21
22
  id: template.id,
@@ -7,6 +7,7 @@ import cx from 'classnames';
7
7
  import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
8
8
 
9
9
  import Icon from '@plone/volto/components/theme/Icon/Icon';
10
+ import Image from '@plone/volto/components/theme/Image/Image';
10
11
  import { getUser } from '@plone/volto/actions/users/users';
11
12
  import { Pluggable } from '@plone/volto/components/manage/Pluggable';
12
13
  import { expandToBackendURL, getBaseUrl } from '@plone/volto/helpers/Url/Url';
@@ -96,7 +97,7 @@ const PersonalTools = (props) => {
96
97
  </header>
97
98
  <div className={cx('avatar', { default: !user.portrait })}>
98
99
  {user.portrait ? (
99
- <img
100
+ <Image
100
101
  src={expandToBackendURL(user.portrait)}
101
102
  alt={intl.formatMessage(messages.userAvatar)}
102
103
  />
@@ -15,7 +15,6 @@ import UniversalLink from '@plone/volto/components/manage/UniversalLink/Universa
15
15
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
16
16
  import Image from '@plone/volto/components/theme/Image/Image';
17
17
  import loadable from '@loadable/component';
18
- import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
19
18
  import { validateFileUploadSize } from '@plone/volto/helpers/FormValidation/FormValidation';
20
19
  import { defineMessages, useIntl } from 'react-intl';
21
20
  import { toast } from 'react-toastify';
@@ -90,18 +89,25 @@ const FileWidget = (props) => {
90
89
  const [fileType, setFileType] = React.useState(false);
91
90
  const intl = useIntl();
92
91
 
92
+ const imgAttrs = React.useMemo(() => {
93
+ const data = {};
94
+ if (value?.download) {
95
+ data.item = {
96
+ '@id': value.download.substring(0, value.download.indexOf('/@@images')),
97
+ image: value,
98
+ };
99
+ } else if (value?.data) {
100
+ data.src = `data:${value['content-type']};${value.encoding},${value.data}`;
101
+ }
102
+ return data;
103
+ }, [value]);
104
+
93
105
  React.useEffect(() => {
94
106
  if (value && imageMimetypes.includes(value['content-type'])) {
95
107
  setFileType(true);
96
108
  }
97
109
  }, [value]);
98
110
 
99
- const imgsrc = value?.download
100
- ? `${flattenToAppURL(value?.download)}?id=${Date.now()}`
101
- : null || value?.data
102
- ? `data:${value['content-type']};${value.encoding},${value.data}`
103
- : null;
104
-
105
111
  /**
106
112
  * Drop handler
107
113
  * @method onDrop
@@ -175,7 +181,7 @@ const FileWidget = (props) => {
175
181
  <Image
176
182
  className="image-preview small ui image"
177
183
  id={`field-${id}-image`}
178
- src={imgsrc}
184
+ {...imgAttrs}
179
185
  />
180
186
  ) : (
181
187
  <div className="dropzone-placeholder">