@eeacms/volto-embed 7.0.2 → 9.0.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 +20 -17
- package/cypress.config.js +15 -5
- package/locales/de/LC_MESSAGES/volto.po +65 -9
- package/locales/en/LC_MESSAGES/volto.po +65 -9
- package/locales/it/LC_MESSAGES/volto.po +65 -9
- package/locales/ro/LC_MESSAGES/volto.po +65 -9
- package/locales/volto.pot +66 -10
- package/package.json +3 -4
- package/src/Blocks/EmbedMaps/Edit.jsx +31 -0
- package/src/Blocks/EmbedMaps/Edit.test.js +75 -0
- package/src/Blocks/EmbedMaps/View.jsx +71 -0
- package/src/Blocks/EmbedMaps/View.test.js +60 -0
- package/src/Blocks/EmbedMaps/index.js +22 -0
- package/src/Blocks/EmbedMaps/schema.js +62 -0
- package/src/Blocks/Maps/Edit.jsx +1 -0
- package/src/Blocks/Maps/Edit.test.js +79 -0
- package/src/Blocks/Maps/View.jsx +5 -1
- package/src/Blocks/Maps/View.test.js +67 -0
- package/src/Blocks/Maps/schema.js +40 -54
- package/src/Blocks/index.js +5 -1
- package/src/EmbedMap/EmbedMap.jsx +106 -0
- package/src/EmbedMap/EmbedMap.test.js +66 -0
- package/src/EmbedMap/style.less +16 -0
- package/src/PrivacyProtection/PrivacyProtection.jsx +86 -84
- package/src/Toolbar/Enlarge.jsx +28 -15
- package/src/Toolbar/FigureNote.jsx +2 -3
- package/src/Toolbar/Toolbar.test.js +96 -0
- package/src/Toolbar/styles.less +1 -2
- package/src/Views/MapView.jsx +13 -0
- package/src/Views/MapView.test.js +68 -0
- package/src/Widgets/MapsViewWidget.jsx +5 -0
- package/src/Widgets/MapsWidget.jsx +223 -0
- package/src/helpers.js +16 -0
- package/src/index.js +7 -0
- package/src/Blocks/Maps/Edit.test.jsx +0 -119
|
@@ -1,67 +1,53 @@
|
|
|
1
1
|
import { defineMessages } from 'react-intl';
|
|
2
2
|
|
|
3
3
|
const messages = defineMessages({
|
|
4
|
-
Maps: {
|
|
5
|
-
id: 'Maps',
|
|
6
|
-
defaultMessage: 'Maps',
|
|
7
|
-
},
|
|
8
|
-
AltText: {
|
|
9
|
-
id: 'Alt text',
|
|
10
|
-
defaultMessage: 'Alt text',
|
|
11
|
-
},
|
|
12
|
-
MapsURL: {
|
|
13
|
-
id: 'Maps URL',
|
|
14
|
-
defaultMessage: 'Maps URL',
|
|
15
|
-
},
|
|
16
|
-
Alignment: {
|
|
17
|
-
id: 'Alignment',
|
|
18
|
-
defaultMessage: 'Alignment',
|
|
19
|
-
},
|
|
20
4
|
CSSHeight: {
|
|
21
|
-
id: '
|
|
5
|
+
id: 'CSS height',
|
|
22
6
|
defineMessages: 'CSS height',
|
|
23
7
|
},
|
|
24
8
|
CSSHeightDescription: {
|
|
25
|
-
id: '
|
|
9
|
+
id: 'Iframe height',
|
|
26
10
|
defineMessages: 'Iframe height',
|
|
27
11
|
},
|
|
28
12
|
});
|
|
29
13
|
|
|
30
|
-
export const MapsSchema = (props) =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
14
|
+
export const MapsSchema = (props) => {
|
|
15
|
+
return {
|
|
16
|
+
title: props.intl.messages['Maps'],
|
|
17
|
+
block: 'Maps',
|
|
18
|
+
fieldsets: [
|
|
19
|
+
{
|
|
20
|
+
id: 'default',
|
|
21
|
+
title: 'Default',
|
|
22
|
+
fields: ['url', 'title', 'align', 'height'],
|
|
23
|
+
},
|
|
24
|
+
],
|
|
40
25
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
26
|
+
properties: {
|
|
27
|
+
url: {
|
|
28
|
+
title: props.intl.messages['Maps URL'],
|
|
29
|
+
widget: 'url',
|
|
30
|
+
},
|
|
31
|
+
title: {
|
|
32
|
+
title: props.intl.messages['Alt text'],
|
|
33
|
+
},
|
|
34
|
+
align: {
|
|
35
|
+
title: props.intl.messages['Alignment'],
|
|
36
|
+
widget: 'align',
|
|
37
|
+
},
|
|
38
|
+
height: {
|
|
39
|
+
title: (
|
|
40
|
+
<a
|
|
41
|
+
rel="noreferrer"
|
|
42
|
+
target="_blank"
|
|
43
|
+
href="https://developer.mozilla.org/en-US/docs/Web/CSS/height"
|
|
44
|
+
>
|
|
45
|
+
{props.intl.formatMessage(messages.CSSHeight)}
|
|
46
|
+
</a>
|
|
47
|
+
),
|
|
48
|
+
description: props.intl.formatMessage(messages.CSSHeightDescription),
|
|
49
|
+
},
|
|
45
50
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
align: {
|
|
50
|
-
title: props.intl.formatMessage(messages.Alignment),
|
|
51
|
-
widget: 'align',
|
|
52
|
-
},
|
|
53
|
-
height: {
|
|
54
|
-
title: (
|
|
55
|
-
<a
|
|
56
|
-
rel="noreferrer"
|
|
57
|
-
target="_blank"
|
|
58
|
-
href="https://developer.mozilla.org/en-US/docs/Web/CSS/height"
|
|
59
|
-
>
|
|
60
|
-
{props.intl.formatMessage(messages.CSSHeight)}
|
|
61
|
-
</a>
|
|
62
|
-
),
|
|
63
|
-
description: props.intl.formatMessage(messages.CSSHeightDescription),
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
required: [],
|
|
67
|
-
});
|
|
51
|
+
required: [],
|
|
52
|
+
};
|
|
53
|
+
};
|
package/src/Blocks/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import installMaps from './Maps';
|
|
2
|
+
import installEmbedMaps from './EmbedMaps';
|
|
2
3
|
|
|
3
4
|
export default function installBlocks(config) {
|
|
4
|
-
return [installMaps].reduce(
|
|
5
|
+
return [installMaps, installEmbedMaps].reduce(
|
|
6
|
+
(acc, apply) => apply(acc),
|
|
7
|
+
config,
|
|
8
|
+
);
|
|
5
9
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
+
import { compose } from 'redux';
|
|
3
|
+
import { connect } from 'react-redux';
|
|
4
|
+
import { defineMessages, injectIntl } from 'react-intl';
|
|
5
|
+
import cx from 'classnames';
|
|
6
|
+
import {
|
|
7
|
+
FigureNote,
|
|
8
|
+
Sources,
|
|
9
|
+
MoreInfo,
|
|
10
|
+
Share,
|
|
11
|
+
Enlarge,
|
|
12
|
+
} from '@eeacms/volto-embed/Toolbar';
|
|
13
|
+
import PrivacyProtection from '@eeacms/volto-embed/PrivacyProtection/PrivacyProtection';
|
|
14
|
+
|
|
15
|
+
import './style.less';
|
|
16
|
+
|
|
17
|
+
const messages = defineMessages({
|
|
18
|
+
EmbededGoogleMaps: {
|
|
19
|
+
id: 'Embeded Google Maps',
|
|
20
|
+
defaultMessage: 'Embeded Google Maps',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
function EmbedMap({ data, intl, id, screen }) {
|
|
25
|
+
const el = useRef();
|
|
26
|
+
const [mobile, setMobile] = useState(false);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (el.current) {
|
|
30
|
+
const visWidth = el.current.offsetWidth;
|
|
31
|
+
|
|
32
|
+
if (visWidth < 600 && !mobile) {
|
|
33
|
+
setMobile(true);
|
|
34
|
+
} else if (visWidth >= 600 && mobile) {
|
|
35
|
+
setMobile(false);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}, [screen, mobile]);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
ref={el}
|
|
43
|
+
className={cx(
|
|
44
|
+
'block maps align',
|
|
45
|
+
{
|
|
46
|
+
center: !Boolean(data.align),
|
|
47
|
+
},
|
|
48
|
+
data.align,
|
|
49
|
+
)}
|
|
50
|
+
>
|
|
51
|
+
<div
|
|
52
|
+
className={cx('maps-inner', {
|
|
53
|
+
'full-width': data.align === 'full',
|
|
54
|
+
})}
|
|
55
|
+
>
|
|
56
|
+
<PrivacyProtection
|
|
57
|
+
data={data}
|
|
58
|
+
id={id}
|
|
59
|
+
height={data.height}
|
|
60
|
+
useVisibilitySensor={data.useVisibilitySensor ?? true}
|
|
61
|
+
>
|
|
62
|
+
<iframe
|
|
63
|
+
title={intl.formatMessage(messages.EmbededGoogleMaps)}
|
|
64
|
+
src={data.url}
|
|
65
|
+
className="google-map"
|
|
66
|
+
frameBorder="0"
|
|
67
|
+
allowFullScreen
|
|
68
|
+
style={data.height ? { height: data.height } : {}}
|
|
69
|
+
/>
|
|
70
|
+
</PrivacyProtection>
|
|
71
|
+
</div>
|
|
72
|
+
<div className={cx('visualization-toolbar', { mobile })}>
|
|
73
|
+
<div className="left-col">
|
|
74
|
+
{data.with_notes && <FigureNote notes={data.figure_note || []} />}
|
|
75
|
+
{data.with_sources && <Sources sources={data.sources} />}
|
|
76
|
+
{data.with_more_info && <MoreInfo href={data['@id']} />}
|
|
77
|
+
</div>
|
|
78
|
+
<div className="right-col">
|
|
79
|
+
{data.with_enlarge && (
|
|
80
|
+
<Enlarge className="enlarge-embed-maps">
|
|
81
|
+
<EmbedMap
|
|
82
|
+
data={{
|
|
83
|
+
...data,
|
|
84
|
+
height: '100%',
|
|
85
|
+
with_notes: false,
|
|
86
|
+
with_sources: false,
|
|
87
|
+
with_more_info: false,
|
|
88
|
+
with_share: false,
|
|
89
|
+
with_enlarge: false,
|
|
90
|
+
}}
|
|
91
|
+
id={id}
|
|
92
|
+
intl={intl}
|
|
93
|
+
/>
|
|
94
|
+
</Enlarge>
|
|
95
|
+
)}
|
|
96
|
+
{data.with_share && <Share href={data['@id']} />}
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default compose(
|
|
104
|
+
injectIntl,
|
|
105
|
+
connect((state) => ({ screen: state.screen })),
|
|
106
|
+
)(EmbedMap);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer from 'react-test-renderer';
|
|
3
|
+
import configureStore from 'redux-mock-store';
|
|
4
|
+
import { Provider } from 'react-intl-redux';
|
|
5
|
+
import config from '@plone/volto/registry';
|
|
6
|
+
|
|
7
|
+
import EmbedMap from './EmbedMap';
|
|
8
|
+
|
|
9
|
+
const mockStore = configureStore();
|
|
10
|
+
|
|
11
|
+
jest.mock('@plone/volto/components', () => ({
|
|
12
|
+
__esModule: true,
|
|
13
|
+
UniversalLink: ({ children, href }) => {
|
|
14
|
+
return <a href={href}>{children}</a>;
|
|
15
|
+
},
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
config.blocks.blocksConfig = {
|
|
19
|
+
...config.blocks.blocksConfig,
|
|
20
|
+
maps: {
|
|
21
|
+
id: 'maps',
|
|
22
|
+
title: 'Maps',
|
|
23
|
+
group: 'media',
|
|
24
|
+
extensions: {},
|
|
25
|
+
variations: [],
|
|
26
|
+
restricted: false,
|
|
27
|
+
mostUsed: true,
|
|
28
|
+
sidebarTab: 1,
|
|
29
|
+
security: {
|
|
30
|
+
addPermission: [],
|
|
31
|
+
view: [],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
test('renders map component', () => {
|
|
37
|
+
const store = mockStore({
|
|
38
|
+
intl: {
|
|
39
|
+
locale: 'en',
|
|
40
|
+
messages: {},
|
|
41
|
+
},
|
|
42
|
+
content: {
|
|
43
|
+
create: {},
|
|
44
|
+
},
|
|
45
|
+
connected_data_parameters: {},
|
|
46
|
+
});
|
|
47
|
+
const component = renderer.create(
|
|
48
|
+
<Provider store={store}>
|
|
49
|
+
<EmbedMap
|
|
50
|
+
id="my-map"
|
|
51
|
+
data={{
|
|
52
|
+
with_notes: false,
|
|
53
|
+
with_sources: false,
|
|
54
|
+
with_more_info: true,
|
|
55
|
+
with_share: true,
|
|
56
|
+
with_enlarge: true,
|
|
57
|
+
url:
|
|
58
|
+
'https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3027.7835278268726!2d14.38842915203974!3d40.634655679238854!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x133b994881d943cb%3A0x6ab93db57d3272f0!2sHotel+Mediterraneo+Sorrento!5e0!3m2!1sen!2ses!4v1550168740166',
|
|
59
|
+
useVisibilitySensor: false,
|
|
60
|
+
}}
|
|
61
|
+
/>
|
|
62
|
+
</Provider>,
|
|
63
|
+
);
|
|
64
|
+
const json = component.toJSON();
|
|
65
|
+
expect(json).toMatchSnapshot();
|
|
66
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.embed-map .block.maps .maps-inner {
|
|
2
|
+
margin-bottom: 1rem;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.ui.modal.enlarge-modal.enlarge-embed-maps {
|
|
6
|
+
.content,
|
|
7
|
+
.content .block.maps,
|
|
8
|
+
.content .block.maps .maps-inner {
|
|
9
|
+
height: 100%;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.close.icon {
|
|
13
|
+
top: 2rem;
|
|
14
|
+
right: 2rem;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import cx from 'classnames';
|
|
3
|
+
import { isNumber } from 'lodash';
|
|
3
4
|
import { compose } from 'redux';
|
|
4
5
|
import { useSelector, useDispatch } from 'react-redux';
|
|
5
|
-
import VisibilitySensor from 'react-visibility-sensor';
|
|
6
6
|
import {
|
|
7
7
|
Placeholder,
|
|
8
8
|
Dimmer,
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
getConnectedDataParametersForContext,
|
|
22
22
|
getFilteredURL,
|
|
23
23
|
} from '@eeacms/volto-datablocks/helpers';
|
|
24
|
+
import { VisibilitySensor } from '@eeacms/volto-datablocks/components';
|
|
24
25
|
|
|
25
26
|
import { createImageUrl } from './helpers';
|
|
26
27
|
import { ProtectionSchema } from './schema';
|
|
@@ -86,7 +87,7 @@ const PrivacyProtection = (props) => {
|
|
|
86
87
|
intl,
|
|
87
88
|
path,
|
|
88
89
|
cookies,
|
|
89
|
-
|
|
90
|
+
useVisibilitySensor = true,
|
|
90
91
|
} = props;
|
|
91
92
|
const {
|
|
92
93
|
enabled = false,
|
|
@@ -96,7 +97,6 @@ const PrivacyProtection = (props) => {
|
|
|
96
97
|
} = data.dataprotection || {};
|
|
97
98
|
|
|
98
99
|
const [image, setImage] = React.useState(null);
|
|
99
|
-
const [visible, setVisibility] = useState(false);
|
|
100
100
|
const defaultShow = canShow(privacy_cookie_key, cookies);
|
|
101
101
|
const [show, setShow] = useState(defaultShow);
|
|
102
102
|
const [remember, setRemember] = useState(
|
|
@@ -112,6 +112,12 @@ const PrivacyProtection = (props) => {
|
|
|
112
112
|
});
|
|
113
113
|
const url = getFilteredURL(data.url, connected_data_parameters);
|
|
114
114
|
|
|
115
|
+
const height = React.useMemo(() => {
|
|
116
|
+
if (!props.height || enabled || !show) return 'auto';
|
|
117
|
+
if (isNumber(props.height)) return `${props.height}px`;
|
|
118
|
+
return props.height;
|
|
119
|
+
}, [props.height, enabled, show]);
|
|
120
|
+
|
|
115
121
|
React.useEffect(() => {
|
|
116
122
|
if (bgImg) {
|
|
117
123
|
setImage(createImageUrl(bgImg)); //create imageUrl from uploaded image
|
|
@@ -160,96 +166,92 @@ const PrivacyProtection = (props) => {
|
|
|
160
166
|
});
|
|
161
167
|
}
|
|
162
168
|
}, [enabled, url, path, dispatch, bgImg, show, intl, editable]);
|
|
169
|
+
|
|
163
170
|
return (
|
|
164
171
|
<VisibilitySensor
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
Placeholder={() => (
|
|
173
|
+
<Placeholder style={{ height: '100%', width: '100%' }}>
|
|
174
|
+
<Placeholder.Image rectangular />
|
|
175
|
+
</Placeholder>
|
|
176
|
+
)}
|
|
177
|
+
useVisibilitySensor={useVisibilitySensor}
|
|
170
178
|
>
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
>
|
|
201
|
-
<div className="
|
|
202
|
-
<div className="
|
|
203
|
-
<
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
179
|
+
<div
|
|
180
|
+
className={cx('privacy-protection-wrapper', className)}
|
|
181
|
+
style={{
|
|
182
|
+
position: 'relative',
|
|
183
|
+
overflow: 'hidden',
|
|
184
|
+
height,
|
|
185
|
+
minHeight: height !== 'auto' ? height : '200px',
|
|
186
|
+
}}
|
|
187
|
+
>
|
|
188
|
+
{!enabled || show ? (
|
|
189
|
+
children
|
|
190
|
+
) : !__DEVELOPMENT__ && !image ? (
|
|
191
|
+
<Dimmer active>
|
|
192
|
+
<Loader />
|
|
193
|
+
</Dimmer>
|
|
194
|
+
) : (
|
|
195
|
+
<div
|
|
196
|
+
className="privacy-protection"
|
|
197
|
+
style={
|
|
198
|
+
image
|
|
199
|
+
? {
|
|
200
|
+
backgroundImage: `url(${image})`,
|
|
201
|
+
backgroundRepeat: 'no-repeat',
|
|
202
|
+
backgroundSize: 'cover',
|
|
203
|
+
backgroundPosition: 'center -70px',
|
|
204
|
+
}
|
|
205
|
+
: {}
|
|
206
|
+
}
|
|
207
|
+
>
|
|
208
|
+
<div className="overlay">
|
|
209
|
+
<div className="wrapped">
|
|
210
|
+
<div className="privacy-button">
|
|
211
|
+
<Button
|
|
212
|
+
primary
|
|
213
|
+
onClick={() => {
|
|
214
|
+
setShow(true);
|
|
215
|
+
if (remember) {
|
|
216
|
+
saveCookie(privacy_cookie_key, cookies);
|
|
217
|
+
}
|
|
218
|
+
}}
|
|
219
|
+
>
|
|
220
|
+
Show external content
|
|
221
|
+
</Button>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
{!editable && (
|
|
225
|
+
<div className="privacy-toggle">
|
|
226
|
+
<Checkbox
|
|
227
|
+
toggle
|
|
228
|
+
label="Remember my choice"
|
|
229
|
+
id={`remember-choice-${id}`}
|
|
230
|
+
onChange={(ev, { checked }) => {
|
|
231
|
+
setRemember(checked);
|
|
211
232
|
}}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
</Button>
|
|
233
|
+
checked={remember}
|
|
234
|
+
/>
|
|
215
235
|
</div>
|
|
236
|
+
)}
|
|
216
237
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
/>
|
|
228
|
-
</div>
|
|
238
|
+
<p className="discreet">
|
|
239
|
+
Your choice will be saved in a cookie managed by{' '}
|
|
240
|
+
{config.settings.ownDomain || '.eea.europa.eu'} that will
|
|
241
|
+
expire in {getExpDays()} days.
|
|
242
|
+
</p>
|
|
243
|
+
<p className="discreet">
|
|
244
|
+
{serializeNodes(
|
|
245
|
+
privacy_statement ||
|
|
246
|
+
ProtectionSchema().properties.privacy_statement
|
|
247
|
+
.defaultValue,
|
|
229
248
|
)}
|
|
230
|
-
|
|
231
|
-
<p className="discreet">
|
|
232
|
-
Your choice will be saved in a cookie managed by{' '}
|
|
233
|
-
{config.settings.ownDomain || '.eea.europa.eu'} that will
|
|
234
|
-
expire in {getExpDays()} days.
|
|
235
|
-
</p>
|
|
236
|
-
<p className="discreet">
|
|
237
|
-
{serializeNodes(
|
|
238
|
-
privacy_statement ||
|
|
239
|
-
ProtectionSchema().properties.privacy_statement
|
|
240
|
-
.defaultValue,
|
|
241
|
-
)}
|
|
242
|
-
</p>
|
|
243
|
-
</div>
|
|
249
|
+
</p>
|
|
244
250
|
</div>
|
|
245
251
|
</div>
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
<Placeholder style={{ height: '100%', width: '100%' }}>
|
|
250
|
-
<Placeholder.Image rectangular />
|
|
251
|
-
</Placeholder>
|
|
252
|
-
)}
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
254
|
+
</div>
|
|
253
255
|
</VisibilitySensor>
|
|
254
256
|
);
|
|
255
257
|
};
|
package/src/Toolbar/Enlarge.jsx
CHANGED
|
@@ -1,29 +1,42 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
+
import { isFunction } from 'lodash';
|
|
2
3
|
import { Modal } from 'semantic-ui-react';
|
|
4
|
+
import cx from 'classnames';
|
|
3
5
|
|
|
4
|
-
const
|
|
6
|
+
const Enlarge = ({ children, className, onClick }) => {
|
|
5
7
|
const [isOpen, setIsOpen] = useState(false);
|
|
6
8
|
|
|
7
9
|
return (
|
|
8
10
|
<div className="enlarge">
|
|
9
|
-
<button
|
|
11
|
+
<button
|
|
12
|
+
className="trigger-button"
|
|
13
|
+
onClick={() => {
|
|
14
|
+
if (isFunction(onClick)) {
|
|
15
|
+
onClick({ setOpen: setIsOpen });
|
|
16
|
+
} else {
|
|
17
|
+
setIsOpen(true);
|
|
18
|
+
}
|
|
19
|
+
}}
|
|
20
|
+
>
|
|
10
21
|
<i className="ri-fullscreen-line" />
|
|
11
22
|
Enlarge
|
|
12
23
|
</button>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
{children && (
|
|
25
|
+
<Modal
|
|
26
|
+
open={isOpen}
|
|
27
|
+
closeIcon={
|
|
28
|
+
<span className="close icon">
|
|
29
|
+
<i class="ri-close-line" />
|
|
30
|
+
</span>
|
|
31
|
+
}
|
|
32
|
+
onClose={() => setIsOpen(false)}
|
|
33
|
+
className={cx('enlarge-modal', className)}
|
|
34
|
+
>
|
|
35
|
+
<Modal.Content>{children}</Modal.Content>
|
|
36
|
+
</Modal>
|
|
37
|
+
)}
|
|
25
38
|
</div>
|
|
26
39
|
);
|
|
27
40
|
};
|
|
28
41
|
|
|
29
|
-
export default
|
|
42
|
+
export default Enlarge;
|
|
@@ -38,8 +38,7 @@ export default function FigureNote({ notes = [] }) {
|
|
|
38
38
|
<button className={cx('trigger-button', { open })}>Note</button>
|
|
39
39
|
</div>
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</Popup>
|
|
41
|
+
content={serializeText(notes)}
|
|
42
|
+
/>
|
|
44
43
|
);
|
|
45
44
|
}
|