@eeacms/volto-eea-website-theme 1.34.0 → 2.0.1
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/.eslintrc.js +7 -2
- package/CHANGELOG.md +53 -1
- package/docker-compose.yml +1 -1
- package/jest-addon.config.js +3 -0
- package/package.json +2 -1
- package/src/components/manage/Blocks/LayoutSettings/index.js +3 -1
- package/src/components/manage/Blocks/Title/index.js +3 -1
- package/src/components/manage/Blocks/Title/schema.js +3 -1
- package/src/components/theme/Banner/View.jsx +12 -5
- package/src/components/theme/DraftBackground/DraftBackground.jsx +30 -21
- package/src/components/theme/DraftBackground/DraftBackground.test.jsx +85 -0
- package/src/config.js +2 -0
- package/src/customizations/@plone/volto-slate/blocks/Text/TextBlockView.jsx +32 -0
- package/src/customizations/@plone/volto-slate/editor/render.jsx +75 -0
- package/src/customizations/@plone/volto-slate/elementEditor/utils.js +76 -75
- package/src/customizations/volto/components/manage/Blocks/Grid/Edit.jsx +70 -0
- package/src/customizations/volto/components/manage/Blocks/Grid/View.jsx +61 -0
- package/src/customizations/volto/components/manage/Blocks/Grid/readme.md +1 -0
- package/src/customizations/volto/components/manage/Blocks/Image/Edit.jsx +82 -23
- package/src/customizations/volto/components/manage/Blocks/Image/Edit.test.jsx +10 -3
- package/src/customizations/volto/components/manage/Blocks/Image/View.jsx +110 -111
- package/src/customizations/volto/components/manage/Blocks/Image/schema.js +17 -2
- package/src/customizations/volto/components/manage/Blocks/LeadImage/Edit.jsx +35 -14
- package/src/customizations/volto/components/manage/Blocks/LeadImage/View.jsx +65 -79
- package/src/customizations/volto/components/manage/Display/Display.jsx +306 -0
- package/src/customizations/volto/components/manage/Display/Readme.md +1 -0
- package/src/customizations/volto/components/manage/Sidebar/SidebarPopup copy.jsx +82 -0
- package/src/customizations/volto/components/manage/Toolbar/More.jsx +541 -0
- package/src/customizations/volto/components/manage/UniversalLink/UniversalLink.jsx +3 -1
- package/src/customizations/volto/components/manage/Widgets/ObjectBrowserWidget.jsx +24 -14
- package/src/customizations/volto/components/manage/Widgets/README.md +1 -0
- package/src/customizations/volto/components/manage/Workflow/README.txt +1 -0
- package/src/customizations/volto/components/manage/Workflow/Workflow.jsx +324 -0
- package/src/customizations/volto/components/manage/Workflow/Workflow.test.jsx +81 -0
- package/src/customizations/volto/components/theme/Comments/Comments.jsx +1 -2
- package/src/customizations/volto/components/theme/ContactForm/ContactForm.jsx +1 -1
- package/src/customizations/volto/components/theme/EventDetails/EventDetails.jsx +1 -0
- package/src/index.js +21 -16
- package/src/middleware/ok.js +4 -2
- package/src/middleware/voltoCustom.js +4 -2
- package/src/slate.js +10 -8
- package/src/customizations/@plone/volto-slate/editor/plugins/StyleMenu/README.txt +0 -1
- package/src/customizations/@plone/volto-slate/editor/plugins/StyleMenu/StyleMenu.jsx +0 -157
- package/src/customizations/@plone/volto-slate/editor/plugins/StyleMenu/utils.js +0 -168
- package/src/customizations/volto/components/manage/Add/Add.jsx +0 -498
- package/src/customizations/volto/components/manage/Add/readme.md +0 -1
- package/src/customizations/volto/components/manage/Contents/ContentsPropertiesModal.jsx +0 -232
- package/src/customizations/volto/components/manage/Form/Form.jsx +0 -810
- package/src/customizations/volto/components/manage/Form/Form.test.jsx +0 -1124
- package/src/customizations/volto/components/manage/Form/ModalForm.jsx +0 -326
- package/src/customizations/volto/components/manage/Sharing/Sharing.jsx +0 -528
- package/src/customizations/volto/components/manage/Sharing/Sharing.test.jsx +0 -72
- package/src/customizations/volto/components/manage/Widgets/ObjectBrowserWidget.test.jsx +0 -193
- package/src/customizations/volto/components/theme/AppExtras/AppExtras.jsx +0 -27
@@ -0,0 +1,70 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import cx from 'classnames';
|
3
|
+
import { useState } from 'react';
|
4
|
+
import ContainerEdit from '@plone/volto/components/manage/Blocks/Container/Edit';
|
5
|
+
|
6
|
+
const convertTeaserToGridIfNecessary = (data) => {
|
7
|
+
if (data?.['@type'] === 'teaserGrid')
|
8
|
+
return {
|
9
|
+
...data,
|
10
|
+
'@type': 'gridBlock',
|
11
|
+
blocks_layout: { items: data?.columns.map((c) => c.id) },
|
12
|
+
blocks: data?.columns?.reduce((acc, current) => {
|
13
|
+
return {
|
14
|
+
...acc,
|
15
|
+
[current?.id]: current,
|
16
|
+
};
|
17
|
+
}, {}),
|
18
|
+
};
|
19
|
+
return data;
|
20
|
+
};
|
21
|
+
|
22
|
+
const GridBlockEdit = (props) => {
|
23
|
+
const { data } = props;
|
24
|
+
|
25
|
+
const columnsLength =
|
26
|
+
data?.blocks_layout?.items?.length || data?.columns?.length || 0;
|
27
|
+
|
28
|
+
const [selectedBlock, setSelectedBlock] = useState(null);
|
29
|
+
|
30
|
+
//convert to gridBlock if necessary
|
31
|
+
if (data?.['@type'] === 'teaserGrid') {
|
32
|
+
props.onChangeBlock(props.block, convertTeaserToGridIfNecessary(data));
|
33
|
+
}
|
34
|
+
|
35
|
+
return (
|
36
|
+
<div
|
37
|
+
className={cx({
|
38
|
+
one: columnsLength === 1,
|
39
|
+
two: columnsLength === 2,
|
40
|
+
three: columnsLength === 3,
|
41
|
+
four: columnsLength >= 4,
|
42
|
+
'grid-items': true,
|
43
|
+
})}
|
44
|
+
// This is required to enabling a small "in-between" clickable area
|
45
|
+
// for bringing the Grid sidebar alive once you have selected an inner block
|
46
|
+
onClick={(e) => {
|
47
|
+
if (!e.block) setSelectedBlock(null);
|
48
|
+
}}
|
49
|
+
role="presentation"
|
50
|
+
>
|
51
|
+
<ContainerEdit
|
52
|
+
{...props}
|
53
|
+
data={data}
|
54
|
+
selectedBlock={selectedBlock}
|
55
|
+
setSelectedBlock={setSelectedBlock}
|
56
|
+
direction="horizontal"
|
57
|
+
/>
|
58
|
+
</div>
|
59
|
+
);
|
60
|
+
};
|
61
|
+
|
62
|
+
GridBlockEdit.propTypes = {
|
63
|
+
block: PropTypes.string.isRequired,
|
64
|
+
onChangeBlock: PropTypes.func.isRequired,
|
65
|
+
pathname: PropTypes.string.isRequired,
|
66
|
+
selected: PropTypes.bool.isRequired,
|
67
|
+
manage: PropTypes.bool.isRequired,
|
68
|
+
};
|
69
|
+
|
70
|
+
export default GridBlockEdit;
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { Grid } from 'semantic-ui-react';
|
2
|
+
import cx from 'classnames';
|
3
|
+
import { RenderBlocks } from '@plone/volto/components';
|
4
|
+
import { withBlockExtensions } from '@plone/volto/helpers';
|
5
|
+
import config from '@plone/volto/registry';
|
6
|
+
|
7
|
+
const convertTeaserToGridIfNecessary = (data) => {
|
8
|
+
if (data?.['@type'] === 'teaserGrid')
|
9
|
+
return {
|
10
|
+
...data,
|
11
|
+
'@type': 'gridBlock',
|
12
|
+
blocks_layout: { items: data?.columns.map((c) => c.id) },
|
13
|
+
blocks: data?.columns?.reduce((acc, current) => {
|
14
|
+
return {
|
15
|
+
...acc,
|
16
|
+
[current?.id]: current,
|
17
|
+
};
|
18
|
+
}, {}),
|
19
|
+
};
|
20
|
+
return data;
|
21
|
+
};
|
22
|
+
|
23
|
+
const GridBlockView = (props) => {
|
24
|
+
const { data, path, className, style } = props;
|
25
|
+
const metadata = props.metadata || props.properties;
|
26
|
+
const columns = data?.blocks_layout?.items || data?.columns;
|
27
|
+
const blocksConfig =
|
28
|
+
config.blocks.blocksConfig[data['@type']].blocksConfig ||
|
29
|
+
props.blocksConfig;
|
30
|
+
const location = {
|
31
|
+
pathname: path,
|
32
|
+
};
|
33
|
+
|
34
|
+
return (
|
35
|
+
<div
|
36
|
+
className={cx('block', data['@type'], className, {
|
37
|
+
one: columns?.length === 1,
|
38
|
+
two: columns?.length === 2,
|
39
|
+
three: columns?.length === 3,
|
40
|
+
four: columns?.length === 4,
|
41
|
+
})}
|
42
|
+
style={style}
|
43
|
+
>
|
44
|
+
{data.headline && <h2 className="headline">{data.headline}</h2>}
|
45
|
+
|
46
|
+
<Grid stackable stretched columns={columns?.length}>
|
47
|
+
<RenderBlocks
|
48
|
+
{...props}
|
49
|
+
blockWrapperTag={Grid.Column}
|
50
|
+
metadata={metadata}
|
51
|
+
content={convertTeaserToGridIfNecessary(data)}
|
52
|
+
location={location}
|
53
|
+
blocksConfig={blocksConfig}
|
54
|
+
isContainer
|
55
|
+
/>
|
56
|
+
</Grid>
|
57
|
+
</div>
|
58
|
+
);
|
59
|
+
};
|
60
|
+
|
61
|
+
export default withBlockExtensions(GridBlockView);
|
@@ -0,0 +1 @@
|
|
1
|
+
These two customizations ensure backward compatibility with the legacy @kitconcept/volto-blocks-grid. For more details, refer to the ticket here: https://taskman.eionet.europa.eu/issues/265726.
|
@@ -16,7 +16,6 @@ import { isEqual } from 'lodash';
|
|
16
16
|
|
17
17
|
import { Icon, ImageSidebar, SidebarPortal } from '@plone/volto/components';
|
18
18
|
import { Icon as IconSemantic } from 'semantic-ui-react';
|
19
|
-
import { withBlockExtensions } from '@plone/volto/helpers';
|
20
19
|
import { createContent } from '@plone/volto/actions';
|
21
20
|
import { Copyright } from '@eeacms/volto-eea-design-system/ui';
|
22
21
|
|
@@ -24,13 +23,33 @@ import {
|
|
24
23
|
flattenToAppURL,
|
25
24
|
getBaseUrl,
|
26
25
|
isInternalURL,
|
26
|
+
withBlockExtensions,
|
27
|
+
validateFileUploadSize,
|
27
28
|
} from '@plone/volto/helpers';
|
29
|
+
import config from '@plone/volto/registry';
|
28
30
|
|
29
31
|
import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';
|
30
32
|
import clearSVG from '@plone/volto/icons/clear.svg';
|
31
33
|
import navTreeSVG from '@plone/volto/icons/nav.svg';
|
32
34
|
import aheadSVG from '@plone/volto/icons/ahead.svg';
|
33
35
|
import uploadSVG from '@plone/volto/icons/upload.svg';
|
36
|
+
|
37
|
+
// please Volto 16 test
|
38
|
+
export const getImageBlockSizes = function (data) {
|
39
|
+
if (data.align === 'full') return '100vw';
|
40
|
+
if (data.align === 'center') {
|
41
|
+
if (data.size === 'l') return '100vw';
|
42
|
+
if (data.size === 'm') return '50vw';
|
43
|
+
if (data.size === 's') return '25vw';
|
44
|
+
}
|
45
|
+
if (data.align === 'left' || data.align === 'right') {
|
46
|
+
if (data.size === 'l') return '50vw';
|
47
|
+
if (data.size === 'm') return '25vw';
|
48
|
+
if (data.size === 's') return '15vw';
|
49
|
+
}
|
50
|
+
return undefined;
|
51
|
+
};
|
52
|
+
|
34
53
|
const Dropzone = loadable(() => import('react-dropzone'));
|
35
54
|
|
36
55
|
const messages = defineMessages({
|
@@ -38,6 +57,10 @@ const messages = defineMessages({
|
|
38
57
|
id: 'Browse the site, drop an image, or type an URL',
|
39
58
|
defaultMessage: 'Browse the site, drop an image, or type an URL',
|
40
59
|
},
|
60
|
+
uploadingImage: {
|
61
|
+
id: 'Uploading image',
|
62
|
+
defaultMessage: 'Uploading image',
|
63
|
+
},
|
41
64
|
});
|
42
65
|
|
43
66
|
/**
|
@@ -56,7 +79,7 @@ class Edit extends Component {
|
|
56
79
|
block: PropTypes.string.isRequired,
|
57
80
|
index: PropTypes.number.isRequired,
|
58
81
|
data: PropTypes.objectOf(PropTypes.any).isRequired,
|
59
|
-
content: PropTypes.objectOf(PropTypes.any)
|
82
|
+
content: PropTypes.objectOf(PropTypes.any),
|
60
83
|
request: PropTypes.shape({
|
61
84
|
loading: PropTypes.bool,
|
62
85
|
loaded: PropTypes.bool,
|
@@ -85,6 +108,7 @@ class Edit extends Component {
|
|
85
108
|
* @returns {undefined}
|
86
109
|
*/
|
87
110
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
111
|
+
// Update block data after upload finished
|
88
112
|
if (
|
89
113
|
this.props.request.loading &&
|
90
114
|
nextProps.request.loaded &&
|
@@ -96,6 +120,8 @@ class Edit extends Component {
|
|
96
120
|
this.props.onChangeBlock(this.props.block, {
|
97
121
|
...this.props.data,
|
98
122
|
url: nextProps.content['@id'],
|
123
|
+
image_field: 'image',
|
124
|
+
image_scales: { image: [nextProps.content.image] },
|
99
125
|
alt: '',
|
100
126
|
});
|
101
127
|
}
|
@@ -123,6 +149,7 @@ class Edit extends Component {
|
|
123
149
|
onUploadImage = (e) => {
|
124
150
|
e.stopPropagation();
|
125
151
|
const file = e.target.files[0];
|
152
|
+
if (!validateFileUploadSize(file, this.props.intl.formatMessage)) return;
|
126
153
|
this.setState({
|
127
154
|
uploading: true,
|
128
155
|
});
|
@@ -167,6 +194,8 @@ class Edit extends Component {
|
|
167
194
|
this.props.onChangeBlock(this.props.block, {
|
168
195
|
...this.props.data,
|
169
196
|
url: flattenToAppURL(this.state.url),
|
197
|
+
image_field: undefined,
|
198
|
+
image_scales: undefined,
|
170
199
|
});
|
171
200
|
};
|
172
201
|
|
@@ -176,23 +205,25 @@ class Edit extends Component {
|
|
176
205
|
* @param {array} files File objects
|
177
206
|
* @returns {undefined}
|
178
207
|
*/
|
179
|
-
onDrop = (
|
180
|
-
this.
|
181
|
-
|
182
|
-
|
208
|
+
onDrop = (files) => {
|
209
|
+
if (!validateFileUploadSize(files[0], this.props.intl.formatMessage)) {
|
210
|
+
this.setState({ dragging: false });
|
211
|
+
return;
|
212
|
+
}
|
213
|
+
this.setState({ uploading: true });
|
183
214
|
|
184
|
-
readAsDataURL(
|
215
|
+
readAsDataURL(files[0]).then((data) => {
|
185
216
|
const fields = data.match(/^data:(.*);(.*),(.*)$/);
|
186
217
|
this.props.createContent(
|
187
218
|
getBaseUrl(this.props.pathname),
|
188
219
|
{
|
189
220
|
'@type': 'Image',
|
190
|
-
title:
|
221
|
+
title: files[0].name,
|
191
222
|
image: {
|
192
223
|
data: fields[3],
|
193
224
|
encoding: fields[2],
|
194
225
|
'content-type': fields[1],
|
195
|
-
filename:
|
226
|
+
filename: files[0].name,
|
196
227
|
},
|
197
228
|
},
|
198
229
|
this.props.block,
|
@@ -234,6 +265,7 @@ class Edit extends Component {
|
|
234
265
|
* @returns {string} Markup for the component.
|
235
266
|
*/
|
236
267
|
render() {
|
268
|
+
const Image = config.getComponent({ name: 'Image' }).component;
|
237
269
|
const { data } = this.props;
|
238
270
|
const placeholder =
|
239
271
|
this.props.data.placeholder ||
|
@@ -265,7 +297,7 @@ class Edit extends Component {
|
|
265
297
|
>
|
266
298
|
{data.url ? (
|
267
299
|
<>
|
268
|
-
<
|
300
|
+
<Image
|
269
301
|
className={cx(
|
270
302
|
{
|
271
303
|
'full-width': data.align === 'full',
|
@@ -275,18 +307,23 @@ class Edit extends Component {
|
|
275
307
|
},
|
276
308
|
data?.styles?.objectPosition,
|
277
309
|
)}
|
310
|
+
item={
|
311
|
+
data.image_scales
|
312
|
+
? {
|
313
|
+
'@id': data.url,
|
314
|
+
image_field: data.image_field,
|
315
|
+
image_scales: data.image_scales,
|
316
|
+
}
|
317
|
+
: undefined
|
318
|
+
}
|
278
319
|
src={
|
279
|
-
|
320
|
+
data.image_scales
|
321
|
+
? undefined
|
322
|
+
: isInternalURL(data.url)
|
280
323
|
? // Backwards compat in the case that the block is storing the full server URL
|
281
324
|
(() => {
|
282
|
-
if (data.align === 'full')
|
283
|
-
return `${flattenToAppURL(
|
284
|
-
data.url,
|
285
|
-
)}/@@images/image/huge`;
|
286
325
|
if (data.size === 'l')
|
287
|
-
return `${flattenToAppURL(
|
288
|
-
data.url,
|
289
|
-
)}/@@images/image/great`;
|
326
|
+
return `${flattenToAppURL(data.url)}/@@images/image`;
|
290
327
|
if (data.size === 'm')
|
291
328
|
return `${flattenToAppURL(
|
292
329
|
data.url,
|
@@ -295,13 +332,14 @@ class Edit extends Component {
|
|
295
332
|
return `${flattenToAppURL(
|
296
333
|
data.url,
|
297
334
|
)}/@@images/image/mini`;
|
298
|
-
return `${flattenToAppURL(
|
299
|
-
data.url,
|
300
|
-
)}/@@images/image/great`;
|
335
|
+
return `${flattenToAppURL(data.url)}/@@images/image`;
|
301
336
|
})()
|
302
337
|
: data.url
|
303
338
|
}
|
339
|
+
sizes={config.blocks.blocksConfig.image.getSizes(data)}
|
304
340
|
alt={data.alt || ''}
|
341
|
+
loading="lazy"
|
342
|
+
responsive={true}
|
305
343
|
/>
|
306
344
|
<div className={`copyright-wrapper ${copyrightPosition}`}>
|
307
345
|
{copyright && showCopyright ? (
|
@@ -332,7 +370,11 @@ class Edit extends Component {
|
|
332
370
|
{this.state.dragging && <Dimmer active></Dimmer>}
|
333
371
|
{this.state.uploading && (
|
334
372
|
<Dimmer active>
|
335
|
-
<Loader indeterminate>
|
373
|
+
<Loader indeterminate>
|
374
|
+
{this.props.intl.formatMessage(
|
375
|
+
messages.uploadingImage,
|
376
|
+
)}
|
377
|
+
</Loader>
|
336
378
|
</Dimmer>
|
337
379
|
)}
|
338
380
|
<div className="no-image-wrapper">
|
@@ -345,7 +387,24 @@ class Edit extends Component {
|
|
345
387
|
onClick={(e) => {
|
346
388
|
e.stopPropagation();
|
347
389
|
e.preventDefault();
|
348
|
-
this.props.openObjectBrowser(
|
390
|
+
this.props.openObjectBrowser({
|
391
|
+
onSelectItem: (
|
392
|
+
url,
|
393
|
+
{ title, image_field, image_scales },
|
394
|
+
) => {
|
395
|
+
this.props.onChangeBlock(
|
396
|
+
this.props.block,
|
397
|
+
{
|
398
|
+
...this.props.data,
|
399
|
+
url,
|
400
|
+
image_field,
|
401
|
+
image_scales,
|
402
|
+
alt:
|
403
|
+
this.props.data.alt || title || '',
|
404
|
+
},
|
405
|
+
);
|
406
|
+
},
|
407
|
+
});
|
349
408
|
}}
|
350
409
|
>
|
351
410
|
<Icon name={navTreeSVG} size="24px" />
|
@@ -1,10 +1,16 @@
|
|
1
|
-
import
|
1
|
+
import config from '@plone/volto/registry';
|
2
|
+
import '@testing-library/jest-dom/extend-expect';
|
2
3
|
import { render } from '@testing-library/react';
|
4
|
+
import React from 'react';
|
3
5
|
import { Provider } from 'react-intl-redux';
|
4
6
|
import configureMockStore from 'redux-mock-store';
|
5
7
|
import Edit from './Edit';
|
6
|
-
import
|
7
|
-
import '
|
8
|
+
import { Image } from '@plone/volto/components';
|
9
|
+
import { getImageBlockSizes } from './Edit';
|
10
|
+
|
11
|
+
config.set('components', {
|
12
|
+
Image: { component: Image },
|
13
|
+
});
|
8
14
|
|
9
15
|
const mockStore = configureMockStore();
|
10
16
|
const { settings } = config;
|
@@ -25,6 +31,7 @@ config.blocks.blocksConfig = {
|
|
25
31
|
addPermission: [],
|
26
32
|
view: [],
|
27
33
|
},
|
34
|
+
getSizes: getImageBlockSizes,
|
28
35
|
},
|
29
36
|
};
|
30
37
|
const blockId = '1234';
|
@@ -9,8 +9,12 @@ import PropTypes from 'prop-types';
|
|
9
9
|
import { UniversalLink } from '@plone/volto/components';
|
10
10
|
import { Icon } from 'semantic-ui-react';
|
11
11
|
import cx from 'classnames';
|
12
|
-
import {
|
13
|
-
|
12
|
+
import {
|
13
|
+
flattenToAppURL,
|
14
|
+
isInternalURL,
|
15
|
+
withBlockExtensions,
|
16
|
+
} from '@plone/volto/helpers';
|
17
|
+
import config from '@plone/volto/registry';
|
14
18
|
import { Copyright } from '@eeacms/volto-eea-design-system/ui';
|
15
19
|
|
16
20
|
/**
|
@@ -19,131 +23,126 @@ import { Copyright } from '@eeacms/volto-eea-design-system/ui';
|
|
19
23
|
* @extends Component
|
20
24
|
*/
|
21
25
|
export const View = (props) => {
|
22
|
-
const { data, detached } = props;
|
23
|
-
const href = data?.href?.[0]?.['@id'] || '';
|
26
|
+
const { className, data, detached, style } = props;
|
24
27
|
const { copyright, copyrightIcon, copyrightPosition } = data;
|
25
|
-
|
26
|
-
const [viewLoaded, setViewLoaded] = React.useState(false);
|
27
|
-
|
28
|
+
const href = data?.href?.[0]?.['@id'] || '';
|
28
29
|
const showCopyright = data?.size === 'l' || !data.size;
|
29
30
|
|
30
|
-
|
31
|
-
setViewLoaded(true);
|
32
|
-
}, []);
|
31
|
+
const Image = config.getComponent({ name: 'Image' }).component;
|
33
32
|
|
34
33
|
return (
|
35
34
|
<>
|
36
|
-
|
35
|
+
<div
|
36
|
+
className={cx(
|
37
|
+
'block image align',
|
38
|
+
{
|
39
|
+
center: !Boolean(data.align),
|
40
|
+
detached,
|
41
|
+
},
|
42
|
+
data.align,
|
43
|
+
className,
|
44
|
+
)}
|
45
|
+
style={style}
|
46
|
+
>
|
37
47
|
<div
|
38
48
|
className={cx(
|
39
|
-
'block
|
49
|
+
'image-block-container',
|
40
50
|
{
|
41
|
-
|
42
|
-
|
51
|
+
large: data.size === 'l',
|
52
|
+
medium: data.size === 'm',
|
53
|
+
small: data.size === 's',
|
43
54
|
},
|
44
|
-
data
|
55
|
+
data?.align ? data?.align : '',
|
45
56
|
)}
|
46
57
|
>
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
isInternalURL(data.url)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
return `${flattenToAppURL(
|
87
|
-
data.url,
|
88
|
-
)}/@@images/image/preview`;
|
89
|
-
if (data.size === 's')
|
90
|
-
return `${flattenToAppURL(
|
91
|
-
data.url,
|
92
|
-
)}/@@images/image/mini`;
|
58
|
+
{data.url && (
|
59
|
+
<>
|
60
|
+
{(() => {
|
61
|
+
const image = (
|
62
|
+
<>
|
63
|
+
<Image
|
64
|
+
className={cx(
|
65
|
+
{
|
66
|
+
'full-width': data.align === 'full',
|
67
|
+
large: data.size === 'l',
|
68
|
+
medium: data.size === 'm',
|
69
|
+
small: data.size === 's',
|
70
|
+
},
|
71
|
+
data?.styles?.objectPosition,
|
72
|
+
)}
|
73
|
+
item={
|
74
|
+
data.image_scales
|
75
|
+
? {
|
76
|
+
'@id': data.url,
|
77
|
+
image_field: data.image_field,
|
78
|
+
image_scales: data.image_scales,
|
79
|
+
}
|
80
|
+
: undefined
|
81
|
+
}
|
82
|
+
src={
|
83
|
+
data.image_scales
|
84
|
+
? undefined
|
85
|
+
: isInternalURL(data.url)
|
86
|
+
? // Backwards compat in the case that the block is storing the full server URL
|
87
|
+
(() => {
|
88
|
+
if (data.size === 'l')
|
89
|
+
return `${flattenToAppURL(
|
90
|
+
data.url,
|
91
|
+
)}/@@images/image`;
|
92
|
+
if (data.size === 'm')
|
93
|
+
return `${flattenToAppURL(
|
94
|
+
data.url,
|
95
|
+
)}/@@images/image/preview`;
|
96
|
+
if (data.size === 's')
|
93
97
|
return `${flattenToAppURL(
|
94
98
|
data.url,
|
95
|
-
)}/@@images/image/
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
99
|
+
)}/@@images/image/mini`;
|
100
|
+
return `${flattenToAppURL(
|
101
|
+
data.url,
|
102
|
+
)}/@@images/image`;
|
103
|
+
})()
|
104
|
+
: data.url
|
105
|
+
}
|
106
|
+
sizes={config.blocks.blocksConfig.image.getSizes(data)}
|
107
|
+
alt={data.alt || ''}
|
108
|
+
loading="lazy"
|
109
|
+
responsive={true}
|
110
|
+
/>
|
111
|
+
<div
|
112
|
+
className={`copyright-wrapper ${
|
113
|
+
copyrightPosition ? copyrightPosition : 'left'
|
114
|
+
}`}
|
115
|
+
>
|
116
|
+
{copyright && showCopyright ? (
|
117
|
+
<Copyright copyrightPosition={copyrightPosition}>
|
118
|
+
<Copyright.Icon>
|
119
|
+
<Icon className={copyrightIcon} />
|
120
|
+
</Copyright.Icon>
|
121
|
+
<Copyright.Text>{copyright}</Copyright.Text>
|
122
|
+
</Copyright>
|
123
|
+
) : (
|
124
|
+
''
|
125
|
+
)}
|
126
|
+
</div>
|
127
|
+
</>
|
128
|
+
);
|
129
|
+
if (href) {
|
130
|
+
return (
|
131
|
+
<UniversalLink
|
132
|
+
href={href}
|
133
|
+
openLinkInNewTab={data.openLinkInNewTab}
|
134
|
+
>
|
135
|
+
{image}
|
136
|
+
</UniversalLink>
|
128
137
|
);
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
{image}
|
136
|
-
</UniversalLink>
|
137
|
-
);
|
138
|
-
} else {
|
139
|
-
return image;
|
140
|
-
}
|
141
|
-
})()}
|
142
|
-
</>
|
143
|
-
)}
|
144
|
-
</div>
|
138
|
+
} else {
|
139
|
+
return image;
|
140
|
+
}
|
141
|
+
})()}
|
142
|
+
</>
|
143
|
+
)}
|
145
144
|
</div>
|
146
|
-
|
145
|
+
</div>
|
147
146
|
</>
|
148
147
|
);
|
149
148
|
};
|