@eeacms/volto-clms-theme 1.0.41 → 1.0.45
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 +117 -0
- package/Jenkinsfile +17 -19
- package/package.json +5 -3
- package/src/actions/geonetwork/import_geonetwork.js +21 -0
- package/src/actions/index.js +16 -0
- package/src/actions/registry/registry.js +21 -0
- package/src/actions/userschema/userschema.js +17 -0
- package/src/components/Blocks/CclHomeBgImageBlock/CclGreenBgView.jsx +32 -8
- package/src/components/Blocks/CclHomeBgImageBlock/CclHomeBgImageBlockEdit.jsx +5 -1
- package/src/components/Blocks/CclHomeBgImageBlock/CclHomeBgImageSchema.js +36 -7
- package/src/components/Blocks/CclRelatedListingBlock/CclRelatedListingEdit.jsx +95 -0
- package/src/components/Blocks/CclRelatedListingBlock/CclRelatedListingView.jsx +67 -0
- package/src/components/Blocks/CclRelatedListingBlock/schema.js +34 -0
- package/src/components/Blocks/CclTextLinkCarouselBlock/CclTextLinkCarouselEdit.jsx +38 -0
- package/src/components/Blocks/CclTextLinkCarouselBlock/CclTextLinkCarouselView.jsx +41 -0
- package/src/components/Blocks/CclTextLinkCarouselBlock/TextLinkCarouselSchema.js +18 -0
- package/src/components/Blocks/CustomTemplates/VoltoListingBlock/CclListingWorkOpportunities.jsx +5 -15
- package/src/components/Blocks/CustomTemplates/VoltoTabsBlock/CclCarouselView.jsx +39 -13
- package/src/components/Blocks/CustomTemplates/VoltoTabsBlock/CclProductTabsView.jsx +6 -1
- package/src/components/Blocks/CustomTemplates/VoltoTabsBlock/CclVerticalFaqTabsView.jsx +19 -60
- package/src/components/Blocks/CustomTemplates/VoltoTabsBlock/FixTemplates.jsx +19 -0
- package/src/components/Blocks/CustomTemplates/VoltoTabsBlock/custom.less +55 -1
- package/src/components/Blocks/CustomTemplates/VoltoTabsBlock/index.js +2 -0
- package/src/components/Blocks/customBlocks.js +97 -26
- package/src/components/CLMSDatasetDetailView/CLMSDatasetDetailView.jsx +175 -15
- package/src/components/CLMSDatasetDetailView/DataSetInfoContent.jsx +20 -13
- package/src/components/CLMSDatasetDetailView/MetadataContent.jsx +26 -7
- package/src/components/CLMSDownloadCartView/CLMSDownloadCartView.jsx +5 -1
- package/src/components/CLMSProfileView/CLMSApiTokensView.jsx +55 -33
- package/src/components/CLMSProfileView/CLMSProfileView.jsx +28 -15
- package/src/components/CLMSProfileView/CLMSUserProfileView.jsx +37 -64
- package/src/components/CclCard/CclCard.jsx +1 -7
- package/src/components/CclCard/cards.less +1 -1
- package/src/components/CclLoginModal/CclLoginModal.jsx +83 -0
- package/src/components/CclLoginModal/ccl-login-modal.css +3 -0
- package/src/components/CclModal/CclModal.jsx +20 -5
- package/src/components/Widgets/ContactWidget.jsx +91 -0
- package/src/components/Widgets/DistributionInfoWidget.jsx +40 -0
- package/src/components/Widgets/GeonetworkIdentifiersWidget.jsx +48 -0
- package/src/components/Widgets/TextLinkWidget.jsx +41 -0
- package/src/constants/ActionTypes.js +1 -0
- package/src/customizations/volto/components/theme/Header/Header.jsx +31 -31
- package/src/customizations/volto/components/theme/SearchWidget/SearchWidget.jsx +11 -3
- package/src/index.js +13 -8
- package/src/reducers/geonetwork/import_geonetwork_reducer.js +45 -0
- package/src/reducers/index.js +9 -3
- package/src/reducers/registry/registry.js +46 -0
- package/src/reducers/tokens/tokens.js +14 -10
- package/src/reducers/userschema/userschema.js +48 -0
- package/theme/clms/css/breadcrumbs.css +1 -0
- package/theme/clms/css/carousel.css +109 -11
- package/theme/clms/css/forms.css +6 -1
- package/theme/clms/css/home.css +29 -4
- package/theme/clms/css/maps.css +4 -0
- package/theme/clms/css/maps.less +4 -0
- package/theme/clms/css/styles.less +12 -3
- package/src/components/Blocks/CclTechnicalLibrariesList/CclTechnicalLibrariesListEdit.jsx +0 -63
- package/src/components/Blocks/CclTechnicalLibrariesList/CclTechnicalLibrariesListView.jsx +0 -43
- package/src/components/Blocks/CclTechnicalLibrariesList/TechnicalLibrariesListSchema.js +0 -17
- package/src/components/CLMSServiceDeskView/CLMSServiceDeskView.jsx +0 -113
|
@@ -67,7 +67,7 @@ const messages = defineMessages({
|
|
|
67
67
|
},
|
|
68
68
|
createdToken: {
|
|
69
69
|
id: 'Created token name',
|
|
70
|
-
defaultMessage: '
|
|
70
|
+
defaultMessage: 'The token has been created successfuly',
|
|
71
71
|
},
|
|
72
72
|
copyButton: {
|
|
73
73
|
id: 'Copy created token button',
|
|
@@ -144,11 +144,12 @@ class CLMSApiTokensView extends Component {
|
|
|
144
144
|
ip_range: PropTypes.string,
|
|
145
145
|
issued: PropTypes.string,
|
|
146
146
|
key_id: PropTypes.string,
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
public_key: PropTypes.string,
|
|
148
|
+
private_key: PropTypes.string,
|
|
149
149
|
}),
|
|
150
150
|
),
|
|
151
151
|
};
|
|
152
|
+
|
|
152
153
|
constructor(props) {
|
|
153
154
|
super(props);
|
|
154
155
|
this.handleChange = this.handleChange.bind(this);
|
|
@@ -184,12 +185,9 @@ class CLMSApiTokensView extends Component {
|
|
|
184
185
|
onClose() {
|
|
185
186
|
this.componentDidMount();
|
|
186
187
|
this.setState({
|
|
187
|
-
value: '',
|
|
188
|
-
createdToken: false,
|
|
189
|
-
modal: false,
|
|
190
|
-
tokenTitle: '',
|
|
191
|
-
textToCopy: '',
|
|
192
188
|
createNewToken: false,
|
|
189
|
+
public_key: undefined,
|
|
190
|
+
private_key: undefined,
|
|
193
191
|
});
|
|
194
192
|
}
|
|
195
193
|
|
|
@@ -203,10 +201,10 @@ class CLMSApiTokensView extends Component {
|
|
|
203
201
|
|
|
204
202
|
handleClick() {
|
|
205
203
|
this.setState({
|
|
206
|
-
createdToken: true,
|
|
207
204
|
modal: false,
|
|
208
|
-
button: false,
|
|
209
205
|
createNewToken: true,
|
|
206
|
+
public_key: undefined,
|
|
207
|
+
private_key: undefined,
|
|
210
208
|
});
|
|
211
209
|
}
|
|
212
210
|
|
|
@@ -225,14 +223,14 @@ class CLMSApiTokensView extends Component {
|
|
|
225
223
|
this.props.getUser(this.props.userId);
|
|
226
224
|
this.props.getTokens();
|
|
227
225
|
this.setState({
|
|
228
|
-
value:
|
|
229
|
-
tokenTitle:
|
|
226
|
+
value: undefined,
|
|
227
|
+
tokenTitle: undefined,
|
|
230
228
|
button: false,
|
|
231
|
-
createNewToken: true,
|
|
229
|
+
// createNewToken: true,
|
|
232
230
|
modal: false,
|
|
233
231
|
createdToken: false,
|
|
234
|
-
textToCopy:
|
|
235
|
-
key_id:
|
|
232
|
+
textToCopy: undefined,
|
|
233
|
+
key_id: undefined,
|
|
236
234
|
});
|
|
237
235
|
}
|
|
238
236
|
|
|
@@ -263,21 +261,36 @@ class CLMSApiTokensView extends Component {
|
|
|
263
261
|
{this.props.intl.formatMessage(messages.ApiTokens)}
|
|
264
262
|
</h1>
|
|
265
263
|
<div>
|
|
266
|
-
<
|
|
264
|
+
<h2>{this.props.intl.formatMessage(messages.title)}</h2>
|
|
267
265
|
<p>{this.props.intl.formatMessage(messages.description)}</p>
|
|
268
266
|
{this.props.createdTokens?.map((item) => (
|
|
269
267
|
<>
|
|
270
268
|
<div>
|
|
271
269
|
<p>{item.title}</p>
|
|
272
270
|
<p>{item.key_id}</p>
|
|
273
|
-
<
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
271
|
+
<CclModal
|
|
272
|
+
onClick={() => this.onClose}
|
|
273
|
+
trigger={
|
|
274
|
+
<CclButton mode={'filled'}>
|
|
275
|
+
{this.props.intl.formatMessage(messages.deleteButton)}
|
|
276
|
+
</CclButton>
|
|
277
|
+
}
|
|
278
|
+
size="small"
|
|
278
279
|
>
|
|
279
|
-
|
|
280
|
-
|
|
280
|
+
<h4>This token will be deleted forever</h4>
|
|
281
|
+
<p>
|
|
282
|
+
You will not be able to use this token again. Only
|
|
283
|
+
delete your tokens when you are absolutely sure of it
|
|
284
|
+
</p>
|
|
285
|
+
<CclButton
|
|
286
|
+
mode={'filled'}
|
|
287
|
+
onClick={() => {
|
|
288
|
+
this.deleteToken(item.key_id);
|
|
289
|
+
}}
|
|
290
|
+
>
|
|
291
|
+
{'I confirm that I want to delete this token'}
|
|
292
|
+
</CclButton>
|
|
293
|
+
</CclModal>
|
|
281
294
|
</div>
|
|
282
295
|
</>
|
|
283
296
|
))}
|
|
@@ -351,31 +364,40 @@ class CLMSApiTokensView extends Component {
|
|
|
351
364
|
<>
|
|
352
365
|
{(this.state.createdToken === true && (
|
|
353
366
|
<div>
|
|
354
|
-
<
|
|
367
|
+
<h3>
|
|
355
368
|
{this.props.intl.formatMessage(
|
|
356
369
|
messages.createdToken,
|
|
357
370
|
)}
|
|
358
|
-
</
|
|
371
|
+
</h3>
|
|
359
372
|
<form className="ccl-form search-form">
|
|
360
373
|
{this.props.newTokens?.map((item) => (
|
|
361
374
|
<>
|
|
362
|
-
{(item
|
|
375
|
+
{(item?.private_key && (
|
|
363
376
|
<>
|
|
364
|
-
<
|
|
365
|
-
|
|
377
|
+
<p>{'Download your service key.'}</p>
|
|
378
|
+
<p>
|
|
379
|
+
{
|
|
380
|
+
"This is the only time your private key will be displayed - it will not be stored on the server, and can't be recovered should you fail to save it."
|
|
381
|
+
}
|
|
382
|
+
</p>
|
|
383
|
+
<p>
|
|
384
|
+
{
|
|
385
|
+
'You should copy & paste this key into a .json file, and store this file in a location accessible only to your service application. This key grants anyone in possession of it full access to this account. You should therefore make sure to protect it with the least file system permissions possible.'
|
|
386
|
+
}
|
|
387
|
+
</p>
|
|
388
|
+
|
|
389
|
+
<textarea
|
|
366
390
|
disabled="disabled"
|
|
367
|
-
type="text"
|
|
368
|
-
className="ccl-text-input"
|
|
369
391
|
id="created_token"
|
|
370
392
|
name="createdToken"
|
|
371
|
-
|
|
372
|
-
|
|
393
|
+
class="ccl-text-input"
|
|
394
|
+
value={JSON.stringify(item)}
|
|
373
395
|
/>
|
|
374
396
|
<CclButton
|
|
375
397
|
mode={'filled'}
|
|
376
398
|
onClick={() => {
|
|
377
399
|
navigator.clipboard.writeText(
|
|
378
|
-
item
|
|
400
|
+
JSON.stringify(item),
|
|
379
401
|
);
|
|
380
402
|
}}
|
|
381
403
|
>
|
|
@@ -3,18 +3,20 @@
|
|
|
3
3
|
* @module components/CLMSProfileView/CLMSProfileView
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import {
|
|
7
|
+
CLMSApiTokensView,
|
|
8
|
+
CLMSUserProfileView,
|
|
9
|
+
} from '@eeacms/volto-clms-theme/components/CLMSProfileView';
|
|
6
10
|
import React, { Component } from 'react';
|
|
11
|
+
import { getUser, updateUser } from '@plone/volto/actions';
|
|
12
|
+
|
|
13
|
+
import CclTabs from '@eeacms/volto-clms-theme/components/CclTab/CclTabs';
|
|
7
14
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { connect } from 'react-redux';
|
|
9
15
|
import { compose } from 'redux';
|
|
10
|
-
import
|
|
11
|
-
import { getUser, updateUser } from '@plone/volto/actions';
|
|
16
|
+
import { connect } from 'react-redux';
|
|
12
17
|
import { getBaseUrl } from '@plone/volto/helpers';
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
CLMSUserProfileView,
|
|
16
|
-
CLMSApiTokensView,
|
|
17
|
-
} from '@eeacms/volto-clms-theme/components/CLMSProfileView';
|
|
18
|
+
import { getExtraBreadcrumbItems } from '../../actions';
|
|
19
|
+
import jwtDecode from 'jwt-decode';
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* CLMSProfileView class.
|
|
@@ -32,13 +34,18 @@ class CLMSProfileView extends Component {
|
|
|
32
34
|
children: PropTypes.instanceOf(Array),
|
|
33
35
|
user: PropTypes.shape({
|
|
34
36
|
'@id': PropTypes.string,
|
|
35
|
-
|
|
37
|
+
are_you_registering_on_behalf_on_an_organisation_: PropTypes.bool,
|
|
38
|
+
country: PropTypes.string,
|
|
36
39
|
email: PropTypes.string,
|
|
37
40
|
fullname: PropTypes.string,
|
|
41
|
+
how_do_you_intend_to_use_the_products: PropTypes.arrayOf(
|
|
42
|
+
PropTypes.string,
|
|
43
|
+
),
|
|
38
44
|
id: PropTypes.string,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
organisation_institutional_domain: PropTypes.arrayOf(PropTypes.string),
|
|
46
|
+
organisation_name: PropTypes.string,
|
|
47
|
+
organisation_url: PropTypes.string,
|
|
48
|
+
professional_thematic_domain: PropTypes.arrayOf(PropTypes.string),
|
|
42
49
|
roles: PropTypes.array,
|
|
43
50
|
username: PropTypes.string,
|
|
44
51
|
return_url: PropTypes.string,
|
|
@@ -56,8 +63,14 @@ class CLMSProfileView extends Component {
|
|
|
56
63
|
*/
|
|
57
64
|
render() {
|
|
58
65
|
const loggedIn = !!this.props.userId;
|
|
66
|
+
this.props.getExtraBreadcrumbItems([
|
|
67
|
+
{
|
|
68
|
+
title: 'Profile',
|
|
69
|
+
pathname: this.props.location.pathname,
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
59
72
|
return (
|
|
60
|
-
|
|
73
|
+
<div className="ccl-container ">
|
|
61
74
|
{loggedIn && (
|
|
62
75
|
<>
|
|
63
76
|
<CclTabs>
|
|
@@ -70,7 +83,7 @@ class CLMSProfileView extends Component {
|
|
|
70
83
|
</CclTabs>
|
|
71
84
|
</>
|
|
72
85
|
)}
|
|
73
|
-
|
|
86
|
+
</div>
|
|
74
87
|
);
|
|
75
88
|
}
|
|
76
89
|
}
|
|
@@ -83,6 +96,6 @@ export default compose(
|
|
|
83
96
|
? jwtDecode(state.userSession.token).sub
|
|
84
97
|
: '',
|
|
85
98
|
}),
|
|
86
|
-
{ getUser, updateUser, getBaseUrl },
|
|
99
|
+
{ getUser, updateUser, getBaseUrl, getExtraBreadcrumbItems },
|
|
87
100
|
),
|
|
88
101
|
)(CLMSProfileView);
|
|
@@ -14,6 +14,7 @@ import { toast } from 'react-toastify';
|
|
|
14
14
|
import { getUser, updateUser } from '@plone/volto/actions';
|
|
15
15
|
import { getBaseUrl } from '@plone/volto/helpers';
|
|
16
16
|
import { Container } from 'semantic-ui-react';
|
|
17
|
+
import { getUserSchema } from '../../actions';
|
|
17
18
|
|
|
18
19
|
const messages = defineMessages({
|
|
19
20
|
UserProfile: {
|
|
@@ -83,13 +84,18 @@ class CLMSUserProfileView extends Component {
|
|
|
83
84
|
static propTypes = {
|
|
84
85
|
user: PropTypes.shape({
|
|
85
86
|
'@id': PropTypes.string,
|
|
86
|
-
|
|
87
|
+
are_you_registering_on_behalf_on_an_organisation_: PropTypes.bool,
|
|
88
|
+
country: PropTypes.string,
|
|
87
89
|
email: PropTypes.string,
|
|
88
90
|
fullname: PropTypes.string,
|
|
91
|
+
how_do_you_intend_to_use_the_products: PropTypes.arrayOf(
|
|
92
|
+
PropTypes.string,
|
|
93
|
+
),
|
|
89
94
|
id: PropTypes.string,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
organisation_institutional_domain: PropTypes.arrayOf(PropTypes.string),
|
|
96
|
+
organisation_name: PropTypes.string,
|
|
97
|
+
organisation_url: PropTypes.string,
|
|
98
|
+
professional_thematic_domain: PropTypes.arrayOf(PropTypes.string),
|
|
93
99
|
roles: PropTypes.array,
|
|
94
100
|
username: PropTypes.string,
|
|
95
101
|
return_url: PropTypes.string,
|
|
@@ -100,10 +106,12 @@ class CLMSUserProfileView extends Component {
|
|
|
100
106
|
getUser: PropTypes.func.isRequired,
|
|
101
107
|
updateUser: PropTypes.func.isRequired,
|
|
102
108
|
getBaseUrl: PropTypes.func.isRequired,
|
|
109
|
+
getUserSchema: PropTypes.func.isRequired,
|
|
103
110
|
};
|
|
104
111
|
|
|
105
112
|
componentDidMount() {
|
|
106
113
|
this.props.getUser(this.props.userId);
|
|
114
|
+
this.props.getUserSchema();
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
/**
|
|
@@ -140,66 +148,30 @@ class CLMSUserProfileView extends Component {
|
|
|
140
148
|
<>
|
|
141
149
|
{loggedIn && (
|
|
142
150
|
<Container>
|
|
143
|
-
<h1 className="page-title">
|
|
144
|
-
{this.props.intl.formatMessage(messages.UserProfile)}
|
|
145
|
-
</h1>
|
|
146
151
|
<div>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
messages.emailDescription,
|
|
171
|
-
),
|
|
172
|
-
title: this.props.intl.formatMessage(
|
|
173
|
-
messages.emailTitle,
|
|
174
|
-
),
|
|
175
|
-
type: 'string',
|
|
176
|
-
},
|
|
177
|
-
portrait: {
|
|
178
|
-
description: this.props.intl.formatMessage(
|
|
179
|
-
messages.portraitDescription,
|
|
180
|
-
),
|
|
181
|
-
title: this.props.intl.formatMessage(
|
|
182
|
-
messages.portraitTitle,
|
|
183
|
-
),
|
|
184
|
-
type: 'object',
|
|
185
|
-
},
|
|
186
|
-
location: {
|
|
187
|
-
description: this.props.intl.formatMessage(
|
|
188
|
-
messages.locationDescription,
|
|
189
|
-
),
|
|
190
|
-
title: this.props.intl.formatMessage(
|
|
191
|
-
messages.locationTitle,
|
|
192
|
-
),
|
|
193
|
-
type: 'string',
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
required: ['email'],
|
|
197
|
-
}}
|
|
198
|
-
onSubmit={this.onSubmit}
|
|
199
|
-
onCancel={this.onCancel}
|
|
200
|
-
loading={this.props.loading}
|
|
201
|
-
/>
|
|
202
|
-
)}
|
|
152
|
+
<h1 className="page-title">
|
|
153
|
+
{this.props.intl.formatMessage(messages.UserProfile)}
|
|
154
|
+
</h1>
|
|
155
|
+
<p>
|
|
156
|
+
Use this form to update your profile details. Be aware that if
|
|
157
|
+
you change your fullname and e-mail address they will be
|
|
158
|
+
rewriten when you log in again next time. This is because we are
|
|
159
|
+
using EU Login to enter this site. <br />
|
|
160
|
+
If you want to change your fullname and e-mail address, please
|
|
161
|
+
do so in your{' '}
|
|
162
|
+
<a href="https://ecas.ec.europa.eu/cas/">EU Login account</a>.
|
|
163
|
+
</p>
|
|
164
|
+
<div>
|
|
165
|
+
{this.props?.userschema?.loaded && (
|
|
166
|
+
<Form
|
|
167
|
+
formData={this.props.user}
|
|
168
|
+
schema={this.props.userschema.userschema}
|
|
169
|
+
onSubmit={this.onSubmit.bind(this)}
|
|
170
|
+
onCancel={this.onCancel}
|
|
171
|
+
loading={this.props.userschema.loading}
|
|
172
|
+
/>
|
|
173
|
+
)}
|
|
174
|
+
</div>
|
|
203
175
|
</div>
|
|
204
176
|
</Container>
|
|
205
177
|
)}
|
|
@@ -218,7 +190,8 @@ export default compose(
|
|
|
218
190
|
: '',
|
|
219
191
|
loaded: state.users.get.loaded,
|
|
220
192
|
loading: state.users.update.loading,
|
|
193
|
+
userschema: state.userschema,
|
|
221
194
|
}),
|
|
222
|
-
{ getUser, updateUser, getBaseUrl },
|
|
195
|
+
{ getUser, updateUser, getBaseUrl, getUserSchema },
|
|
223
196
|
),
|
|
224
197
|
)(CLMSUserProfileView);
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
3
|
import './cards.less';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
|
-
import CclButton from '@eeacms/volto-clms-theme/components/CclButton/CclButton';
|
|
6
5
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
7
6
|
import * as mime from 'react-native-mime-types';
|
|
8
7
|
|
|
@@ -56,14 +55,9 @@ function CclCard(props) {
|
|
|
56
55
|
</div>
|
|
57
56
|
<div className="card-text">
|
|
58
57
|
<div className="card-title">
|
|
59
|
-
<a href={card?.
|
|
60
|
-
{card?.title || 'Card default title'}
|
|
61
|
-
</a>
|
|
58
|
+
<a href={url}>{card?.title || 'Card default title'}</a>
|
|
62
59
|
</div>
|
|
63
60
|
<div className="card-description">{card?.description}</div>
|
|
64
|
-
<div className="card-button">
|
|
65
|
-
<CclButton url={url}>Access to product</CclButton>
|
|
66
|
-
</div>
|
|
67
61
|
{children}
|
|
68
62
|
</div>
|
|
69
63
|
</>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import CclModal from '@eeacms/volto-clms-theme/components/CclModal/CclModal';
|
|
4
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
5
|
+
import { getRegistry } from '@eeacms/volto-clms-theme/actions';
|
|
6
|
+
import { FormattedMessage } from 'react-intl';
|
|
7
|
+
import config from '@plone/volto/registry';
|
|
8
|
+
import { toPublicURL } from '@plone/volto/helpers/Url/Url';
|
|
9
|
+
import './ccl-login-modal.css';
|
|
10
|
+
/**
|
|
11
|
+
* Login Modal component doc.
|
|
12
|
+
* @function CclLoginModal
|
|
13
|
+
* @example <CclLoginModal />
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
function CclLoginModal() {
|
|
17
|
+
const dispatch = useDispatch();
|
|
18
|
+
const registryRecords = useSelector((state) => state.registry.records);
|
|
19
|
+
const [loginUrl, setLoginUrl] = React.useState('');
|
|
20
|
+
const registry_key = config.settings?.registry?.login_url || null;
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (registryRecords && registry_key in registryRecords) {
|
|
24
|
+
setLoginUrl(registryRecords[registry_key]);
|
|
25
|
+
}
|
|
26
|
+
}, [registryRecords, registry_key]);
|
|
27
|
+
|
|
28
|
+
function modalStatus(status) {
|
|
29
|
+
if (status === true) {
|
|
30
|
+
dispatch(getRegistry(registry_key));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<CclModal
|
|
36
|
+
trigger={
|
|
37
|
+
<div className="header-login-link">
|
|
38
|
+
<FormattedMessage
|
|
39
|
+
id="loginRegister"
|
|
40
|
+
defaultMessage="Register/Login"
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
}
|
|
44
|
+
size="tiny"
|
|
45
|
+
modalStatus={modalStatus}
|
|
46
|
+
>
|
|
47
|
+
<div className="modal-login-title">Registration / Login</div>
|
|
48
|
+
<div className="modal-login-text">
|
|
49
|
+
<p>
|
|
50
|
+
This site uses EU Login to handle user registration and login. You can
|
|
51
|
+
read more about this service in the{' '}
|
|
52
|
+
<a href="https://ecas.ec.europa.eu/cas/about.html">
|
|
53
|
+
EU Login site help
|
|
54
|
+
</a>
|
|
55
|
+
.
|
|
56
|
+
</p>
|
|
57
|
+
<p>
|
|
58
|
+
{' '}
|
|
59
|
+
When you clik on the following link, you will be sent to EU Login and
|
|
60
|
+
after a successful login there you will be redirected back to this
|
|
61
|
+
site.
|
|
62
|
+
</p>
|
|
63
|
+
<p>
|
|
64
|
+
If you have any issues or questions, please contact us using the
|
|
65
|
+
<a href="/en/contact-service-helpdesk"> helpdesk</a>.
|
|
66
|
+
</p>
|
|
67
|
+
</div>
|
|
68
|
+
<a
|
|
69
|
+
href={toPublicURL(loginUrl) || '#'}
|
|
70
|
+
className="ccl-button ccl-button-green"
|
|
71
|
+
>
|
|
72
|
+
Login using EU Login
|
|
73
|
+
</a>
|
|
74
|
+
</CclModal>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
CclLoginModal.propTypes = {
|
|
79
|
+
title: PropTypes.string.isRequired,
|
|
80
|
+
children: PropTypes.node.isRequired,
|
|
81
|
+
marginBottom: PropTypes.bool,
|
|
82
|
+
};
|
|
83
|
+
export default CclLoginModal;
|
|
@@ -3,13 +3,28 @@ import { Modal } from 'semantic-ui-react';
|
|
|
3
3
|
import './modal.less';
|
|
4
4
|
|
|
5
5
|
function CclModal(props) {
|
|
6
|
+
let {
|
|
7
|
+
trigger,
|
|
8
|
+
children,
|
|
9
|
+
size = 'fullscreen',
|
|
10
|
+
modalStatus = () => {},
|
|
11
|
+
} = props;
|
|
6
12
|
const [open, setOpen] = React.useState(false);
|
|
7
|
-
|
|
13
|
+
|
|
14
|
+
function openModal() {
|
|
15
|
+
setOpen(true);
|
|
16
|
+
modalStatus(true);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function closeModal() {
|
|
20
|
+
setOpen(false);
|
|
21
|
+
modalStatus(false);
|
|
22
|
+
}
|
|
8
23
|
|
|
9
24
|
return (
|
|
10
25
|
<Modal
|
|
11
|
-
onClose={() =>
|
|
12
|
-
onOpen={() =>
|
|
26
|
+
onClose={() => closeModal()}
|
|
27
|
+
onOpen={() => openModal()}
|
|
13
28
|
open={open}
|
|
14
29
|
trigger={trigger}
|
|
15
30
|
className={'modal-clms'}
|
|
@@ -21,8 +36,8 @@ function CclModal(props) {
|
|
|
21
36
|
<span
|
|
22
37
|
className="ccl-icon-close"
|
|
23
38
|
aria-label="Close"
|
|
24
|
-
onClick={() =>
|
|
25
|
-
onKeyDown={() =>
|
|
39
|
+
onClick={() => closeModal()}
|
|
40
|
+
onKeyDown={() => closeModal()}
|
|
26
41
|
tabIndex="0"
|
|
27
42
|
role="button"
|
|
28
43
|
></span>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import ObjectListWidget from '@plone/volto/components/manage/Widgets/ObjectListWidget';
|
|
4
|
+
|
|
5
|
+
const ItemSchema = {
|
|
6
|
+
title: 'Contact',
|
|
7
|
+
properties: {
|
|
8
|
+
organisationName: {
|
|
9
|
+
title: 'Organisation Name',
|
|
10
|
+
description: 'Enter the Organisation Name of the contact.',
|
|
11
|
+
type: 'string',
|
|
12
|
+
},
|
|
13
|
+
deliveryPoint: {
|
|
14
|
+
title: 'Delivery Point',
|
|
15
|
+
description: 'Enter the Delivery Point of the contact.',
|
|
16
|
+
type: 'string',
|
|
17
|
+
},
|
|
18
|
+
city: {
|
|
19
|
+
title: 'City',
|
|
20
|
+
description: 'Enter the City of the contact.',
|
|
21
|
+
type: 'string',
|
|
22
|
+
},
|
|
23
|
+
administrativeArea: {
|
|
24
|
+
title: 'Administrative Area',
|
|
25
|
+
description: 'Enter the Administrative Area of the contact.',
|
|
26
|
+
type: 'string',
|
|
27
|
+
},
|
|
28
|
+
postalCode: {
|
|
29
|
+
title: 'Postal Code',
|
|
30
|
+
description: 'Enter the Postal Code of the contact.',
|
|
31
|
+
type: 'string',
|
|
32
|
+
},
|
|
33
|
+
country: {
|
|
34
|
+
title: 'Country',
|
|
35
|
+
description: 'Enter the Country of the contact.',
|
|
36
|
+
type: 'string',
|
|
37
|
+
},
|
|
38
|
+
electronicMailAddress: {
|
|
39
|
+
title: 'Electronic Mail Address',
|
|
40
|
+
description: 'Enter the Electronic Mail Address of the contact.',
|
|
41
|
+
type: 'string',
|
|
42
|
+
},
|
|
43
|
+
url: {
|
|
44
|
+
title: 'URL',
|
|
45
|
+
description: 'Enter the URL of the contact.',
|
|
46
|
+
type: 'string',
|
|
47
|
+
},
|
|
48
|
+
urlTitle: {
|
|
49
|
+
title: 'URL Title',
|
|
50
|
+
description: 'Enter the URL Title of the contact.',
|
|
51
|
+
type: 'string',
|
|
52
|
+
},
|
|
53
|
+
roleCode: {
|
|
54
|
+
title: 'Role Code',
|
|
55
|
+
description: 'Enter the Role Code of the contact.',
|
|
56
|
+
type: 'string',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
fieldsets: [
|
|
60
|
+
{
|
|
61
|
+
id: 'default',
|
|
62
|
+
title: 'Contact',
|
|
63
|
+
fields: [
|
|
64
|
+
'organisationName',
|
|
65
|
+
'deliveryPoint',
|
|
66
|
+
'city',
|
|
67
|
+
'administrativeArea',
|
|
68
|
+
'postalCode',
|
|
69
|
+
'country',
|
|
70
|
+
'electronicMailAddress',
|
|
71
|
+
'url',
|
|
72
|
+
'urlTitle',
|
|
73
|
+
'roleCode',
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
required: [],
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const ContactWidget = (props) => {
|
|
81
|
+
return (
|
|
82
|
+
<ObjectListWidget
|
|
83
|
+
schema={ItemSchema}
|
|
84
|
+
{...props}
|
|
85
|
+
value={props.value?.items || props.default?.items || []}
|
|
86
|
+
onChange={(id, value) => props.onChange(id, { items: value })}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default ContactWidget;
|