@eeacms/volto-clms-theme 1.0.171 → 1.0.172

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 CHANGED
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ ### [1.0.172](https://github.com/eea/volto-clms-theme/compare/1.0.171...1.0.172) - 16 February 2023
8
+
9
+ #### :bug: Bug Fixes
10
+
11
+ - fix: Tabs with search routing bug [ionlizarazu - [`c226cab`](https://github.com/eea/volto-clms-theme/commit/c226cab406a04f13b3c1515f10ba9b2b9ae83771)]
12
+
13
+ #### :hammer_and_wrench: Others
14
+
15
+ - refactor the DatasetView Geonetwork importer options with a search and pagination [ionlizarazu - [`5b0271c`](https://github.com/eea/volto-clms-theme/commit/5b0271cea041dd29b549970b26fce2ae6f8da113)]
16
+ - add the option to set a batch size to the paginated items on init [ionlizarazu - [`3d6d4b1`](https://github.com/eea/volto-clms-theme/commit/3d6d4b1d5c28c2dcdb4d6e4ae1849699cc80c9b3)]
17
+ - clear and optmize RoutingHOC [ionlizarazu - [`b3e6ed3`](https://github.com/eea/volto-clms-theme/commit/b3e6ed30ce24c83970067ead4434d3cce8005fa2)]
18
+ - use RelatedListing block view also for dataset TechnicalLibrary listing, so we can get the pagination with the same code [ionlizarazu - [`7e25908`](https://github.com/eea/volto-clms-theme/commit/7e25908ede212683fbf20e8ec6631e3290150691)]
19
+ - sort imports [ionlizarazu - [`c94f028`](https://github.com/eea/volto-clms-theme/commit/c94f028b0a66918817b15882cc2b2648bfca6660)]
7
20
  ### [1.0.171](https://github.com/eea/volto-clms-theme/compare/1.0.170...1.0.171) - 15 February 2023
8
21
 
9
22
  #### :rocket: New Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-clms-theme",
3
- "version": "1.0.171",
3
+ "version": "1.0.172",
4
4
  "description": "volto-clms-theme: Volto theme for CLMS site",
5
5
  "main": "src/index.js",
6
6
  "author": "CodeSyntax for the European Environment Agency",
@@ -11,7 +11,13 @@ import config from '@plone/volto/registry';
11
11
  import { useFilteredPagination } from '../../CclUtils/useFilteredPagination';
12
12
 
13
13
  const CclRelatedListingView = (props) => {
14
- const { data, id, properties, metadata } = props;
14
+ const {
15
+ data,
16
+ id,
17
+ properties,
18
+ metadata,
19
+ associated_elements = 'products',
20
+ } = props;
15
21
  const use_pagination = useFilteredPagination([]);
16
22
  const p_functions = use_pagination.functions;
17
23
  const p_data = use_pagination.data;
@@ -19,9 +25,13 @@ const CclRelatedListingView = (props) => {
19
25
 
20
26
  const dispatch = useDispatch();
21
27
  const searchSubrequests = useSelector(
22
- (state) => state.search.subrequests?.[props.id],
28
+ (state) => state.search.subrequests?.[id],
23
29
  );
24
30
  const uid = metadata ? metadata['UID'] : properties['UID'];
31
+ const associated =
32
+ associated_elements === 'products'
33
+ ? { associated_products: uid }
34
+ : { associated_datasets: uid };
25
35
  let libraries = searchSubrequests?.items || [];
26
36
  const variationsConfig =
27
37
  config.blocks.blocksConfig['relatedListing'].variations;
@@ -83,7 +93,7 @@ const CclRelatedListingView = (props) => {
83
93
  '/',
84
94
  {
85
95
  portal_type: data.content_type || 'News Item',
86
- associated_products: uid,
96
+ ...associated,
87
97
  metadata_fields: '_all',
88
98
  sort_on: sort_on,
89
99
  sort_order: sort_order,
@@ -104,7 +114,7 @@ const CclRelatedListingView = (props) => {
104
114
  <div className="search-wrapper">
105
115
  <div className="search-input">
106
116
  <Input
107
- id={`${props.id}-searchtext`}
117
+ id={`${id}-searchtext`}
108
118
  placeholder={'Search in the following items'}
109
119
  fluid
110
120
  onChange={(event, value) => {
@@ -6,14 +6,16 @@ import { compose } from 'redux';
6
6
 
7
7
  import { RenderBlocks } from '@plone/volto/components';
8
8
  import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
9
+ import { useLocation } from 'react-router-dom';
9
10
 
10
11
  import { slugify } from '../../utils';
11
12
  import './fontawesome';
12
13
 
13
14
  import cx from 'classnames';
14
15
 
15
- const handleClick = (e, tab, activeTab, setActiveTab) => {
16
+ const handleClick = (e, tab, activeTab, setActiveTab, location, tabHash) => {
16
17
  if (activeTab !== tab) {
18
+ location.hash = `#${tabHash}`;
17
19
  setActiveTab(tab);
18
20
  }
19
21
  };
@@ -32,6 +34,7 @@ const TabsComponent = (props) => {
32
34
  tabs = {},
33
35
  setActiveTab,
34
36
  } = props;
37
+ const location = useLocation();
35
38
  return (
36
39
  <div className="left-content cont-w-25">
37
40
  {<ExtraComponent />}
@@ -60,10 +63,24 @@ const TabsComponent = (props) => {
60
63
  to={'#' + tabHash}
61
64
  className="collapsed"
62
65
  onClick={(e) => {
63
- handleClick(e, tab, activeTab, setActiveTab);
66
+ handleClick(
67
+ e,
68
+ tab,
69
+ activeTab,
70
+ setActiveTab,
71
+ location,
72
+ tabHash,
73
+ );
64
74
  }}
65
75
  onKeyDown={(e) => {
66
- handleClick(e, tab, activeTab, setActiveTab);
76
+ handleClick(
77
+ e,
78
+ tab,
79
+ activeTab,
80
+ setActiveTab,
81
+ location,
82
+ tabHash,
83
+ );
67
84
  }}
68
85
  >
69
86
  {title || defaultTitle}
@@ -2,34 +2,27 @@ import React from 'react';
2
2
  import { slugify } from '../../utils';
3
3
  import { useSelector } from 'react-redux';
4
4
 
5
+ const decideTabSubtab = (tabs, option1, option2) => {
6
+ if (!option2) {
7
+ return option1;
8
+ }
9
+ if (!tabs[option1]?.subTab?.subtab && tabs[option2]?.subTab?.subtab) {
10
+ return option2;
11
+ } else if (!tabs[option2]?.subTab?.subtab) {
12
+ return option1;
13
+ }
14
+ return option1;
15
+ };
16
+
5
17
  const RoutingHOC = (TabView) =>
6
18
  function Component(props) {
7
19
  const { tabsList = [], tabs, activeTabIndex = 0, setActiveTab } = props;
8
20
  const location = useSelector((state) => state.router.location);
9
21
 
10
22
  function reloadTab(window, rTabs, rTabsList) {
11
- if (
12
- window.location.hash.length === 0 &&
13
- rTabs[rTabsList[1]]?.subTab?.subtab &&
14
- !rTabs[rTabsList[0]]?.subTab?.subtab
15
- ) {
16
- return rTabsList[1];
17
- } else if (
18
- window.location.hash.length === 0 &&
19
- !rTabs[rTabsList[1]]?.subTab?.subtab
20
- ) {
21
- return rTabsList[0];
22
- }
23
23
  const tabsDict = Object.entries(rTabs).map((t) => {
24
24
  return { title: t[1].title, id: t[0] };
25
25
  });
26
- // Deprecated, now we use tab title to set the hash
27
- // if (
28
- // window.location.hash.match(/.*&?#?tab=(.*)/) &&
29
- // window.location.hash.match(/.*&?#?tab=(.*)/).length > 1
30
- // ) {
31
- // return rTabsList[window.location.hash.match(/.*&?#?tab=(.*)/)[1] - 1];
32
- // }
33
26
  if (
34
27
  window.location.hash.match(/.*([&|#]tab=.*)/) &&
35
28
  window.location.hash.match(/.*([&|#]tab=.*)/).length > 1
@@ -41,8 +34,8 @@ const RoutingHOC = (TabView) =>
41
34
  if (result.length > 0) {
42
35
  return result[0].id;
43
36
  }
44
- return '';
45
37
  }
38
+ return decideTabSubtab(rTabs, rTabsList[0], rTabsList[1]);
46
39
  }
47
40
 
48
41
  React.useEffect(() => {
@@ -13,12 +13,9 @@ import {
13
13
  DownloadDataSetContent,
14
14
  } from '@eeacms/volto-clms-theme/components/CLMSDatasetDetailView';
15
15
 
16
- import {
17
- postImportGeonetwork,
18
- postImportWMSLayers,
19
- postImportWMSFields,
20
- } from '../../actions';
16
+ import { postImportWMSLayers, postImportWMSFields } from '../../actions';
21
17
  import { useSchema } from '../Widgets/SchemaCreatorWidget';
18
+ import { GeonetworkImporterButtons } from './GeonetworkImporterButtons';
22
19
 
23
20
  import jwtDecode from 'jwt-decode';
24
21
  import PropTypes from 'prop-types';
@@ -27,7 +24,6 @@ import PropTypes from 'prop-types';
27
24
  * Full view component.
28
25
  * @module components/theme/View/CLMSDatasetDetailView
29
26
  */
30
-
31
27
  /**
32
28
  * Full view component class.
33
29
  * @function CLMSDatasetDetailView
@@ -38,22 +34,17 @@ import PropTypes from 'prop-types';
38
34
  const CLMSDatasetDetailView = ({ content, token }) => {
39
35
  const location = useLocation();
40
36
  const dispatch = useDispatch();
41
- const geonetwork_importation = useSelector(
42
- (state) => state.geonetwork_importation,
43
- );
37
+
44
38
  const wms_layers_importation = useSelector((state) => state.importWMSLayers);
45
39
  const wms_fields_importation = useSelector((state) => state.importWMSFields);
46
40
  const user = useSelector((state) => state.users?.user);
41
+
47
42
  React.useEffect(() => {
48
43
  if (token) {
49
44
  dispatch(getUser(token));
50
45
  }
51
46
  }, [dispatch, token]);
52
47
 
53
- function handleImport(id, type) {
54
- dispatch(postImportGeonetwork(location.pathname, id, type));
55
- }
56
-
57
48
  function handleWMSImport() {
58
49
  dispatch(postImportWMSLayers(location.pathname));
59
50
  }
@@ -104,322 +95,203 @@ const CLMSDatasetDetailView = ({ content, token }) => {
104
95
  return (
105
96
  <div className="ccl-container ">
106
97
  <h1 className="page-title">{content.title}</h1>
107
- {content.geonetwork_identifiers?.items?.length > 0 &&
108
- user?.roles &&
109
- user.roles.includes('Manager') && (
98
+ {user?.roles && user.roles.includes('Manager') && (
99
+ <GeonetworkImporterButtons
100
+ geonetwork_identifiers_items={content.geonetwork_identifiers.items}
101
+ open={open}
102
+ setOpen={setOpen}
103
+ />
104
+ )}
105
+
106
+ {user?.roles && user.roles.includes('Manager') && (
107
+ <>
108
+ <h2>MapLayers importation options:</h2>
110
109
  <Segment.Group compact horizontal>
111
- {content.geonetwork_identifiers?.items.map((item) => {
112
- return (
113
- <Segment
114
- padded={'very'}
115
- color={'olive'}
116
- key={item.id}
117
- loading={geonetwork_importation.loading}
118
- circular
119
- style={{ width: '50%' }}
120
- >
121
- <strong>
122
- {item.title} (from {item.type}):{' '}
123
- </strong>
124
- <br />
125
- <br />
126
- <Modal
127
- onClose={() => {
128
- setOpen({ ...open, [item.id]: false });
129
- }}
130
- onOpen={() => {
131
- setOpen({ ...open, [item.id]: true });
132
- }}
133
- open={open[item.id]}
134
- trigger={
135
- <CclButton>
110
+ <Segment
111
+ padded={'very'}
112
+ color={'olive'}
113
+ key={'wms-layers-import'}
114
+ loading={wms_layers_importation?.loading}
115
+ circular
116
+ style={{ width: '50%' }}
117
+ >
118
+ <Modal
119
+ onClose={() => {
120
+ setOpen({ ...open, 'wms-layers-import': false });
121
+ }}
122
+ onOpen={() => {
123
+ setOpen({ ...open, 'wms-layers-import': true });
124
+ }}
125
+ open={open['wms-layers-import']}
126
+ trigger={
127
+ <CclButton>
128
+ <FormattedMessage
129
+ id="Import WMS Layers"
130
+ defaultMessage="Import WMS Layers"
131
+ />
132
+ </CclButton>
133
+ }
134
+ className={'modal-clms'}
135
+ >
136
+ <div className={'modal-clms-background'}>
137
+ <div className={'modal-clms-container'}>
138
+ <div className={'modal-close modal-clms-close'}>
139
+ <span
140
+ className="ccl-icon-close"
141
+ aria-label="Close"
142
+ onClick={() => {
143
+ setOpen({ ...open, 'wms-layers-import': false });
144
+ }}
145
+ onKeyDown={() => {
146
+ setOpen({ ...open, 'wms-layers-import': false });
147
+ }}
148
+ tabIndex="0"
149
+ role="button"
150
+ ></span>
151
+ </div>
152
+ <div className="modal-login-text">
153
+ <h1>
136
154
  <FormattedMessage
137
- id="Import data"
138
- defaultMessage="Import data"
155
+ id="Import WMS Layers"
156
+ defaultMessage="Import WMS Layers"
139
157
  />
140
- </CclButton>
141
- }
142
- className={'modal-clms'}
143
- >
144
- <div className={'modal-clms-background'}>
145
- <div className={'modal-clms-container'}>
146
- <div className={'modal-close modal-clms-close'}>
147
- <span
148
- className="ccl-icon-close"
149
- aria-label="Close"
150
- onClick={() => {
151
- setOpen({ ...open, [item.id]: false });
152
- }}
153
- onKeyDown={() => {
154
- setOpen({ ...open, [item.id]: false });
155
- }}
156
- tabIndex="0"
157
- role="button"
158
- ></span>
159
- </div>
160
- <div className="modal-login-text">
161
- <h1>
162
- <FormattedMessage
163
- id="Import from GeoNetwork"
164
- defaultMessage="Import from GeoNetwork"
165
- />
166
- </h1>
167
- This action will import the data from{' '}
168
- <strong>{item.title}</strong> (from {item.type}) into
169
- this dataset.
170
- <br />
171
- <br />
172
- <a
173
- target="_blank"
174
- rel="noreferrer"
175
- href={
176
- item.type === 'EEA'
177
- ? 'https://sdi.eea.europa.eu/catalogue/srv/eng/catalog.search#/metadata/' +
178
- item.id
179
- : 'https://land.copernicus.vgt.vito.be/geonetwork/srv/eng/catalog.search#/metadata/' +
180
- item.id
181
- }
182
- >
183
- {item.type === 'EEA' && (
184
- <FormattedMessage
185
- id="EEA Geonetwork element"
186
- defaultMessage="EEA Geonetwork element"
187
- />
188
- )}
189
- {item.type === 'VITO' && (
190
- <FormattedMessage
191
- id="VITO Geonetwork element"
192
- defaultMessage="VITO Geonetwork element"
193
- />
194
- )}
195
- </a>
196
- </div>
197
- <CclButton
198
- onClick={() => {
199
- handleImport(item.id, item.type);
200
- setOpen({ ...open, [item.id]: false });
201
- }}
202
- mode="filled"
203
- >
204
- <FormattedMessage
205
- id="Import data"
206
- defaultMessage="Import data"
207
- />
208
- </CclButton>
209
- </div>
158
+ </h1>
159
+ This action will import the WMS Layers from the view
160
+ service defined in the dataset or from GeoNetwork if the
161
+ view service is not defined and a linked geonetwork record
162
+ has a valid WMS service link
163
+ <br />
164
+ <br />
210
165
  </div>
211
- </Modal>
212
- {geonetwork_importation.imported_data
213
- ?.requested_geonetwork_id === item.id && (
214
- <p>
215
- {geonetwork_importation.loaded &&
216
- geonetwork_importation.error === null && (
217
- <strong>
218
- {' '}
219
- The data has been successfully imported
220
- </strong>
221
- )}
222
- </p>
223
- )}
224
- {geonetwork_importation.imported_data?.status === 'error' && (
225
- <p>
226
- <strong>
227
- {' '}
228
- {geonetwork_importation.imported_data?.message}
229
- </strong>
230
- </p>
231
- )}
232
- </Segment>
233
- );
234
- })}
235
- </Segment.Group>
236
- )}
237
-
238
- {user?.roles && user.roles.includes('Manager') && (
239
- <Segment.Group compact horizontal>
240
- <Segment
241
- padded={'very'}
242
- color={'olive'}
243
- key={'wms-layers-import'}
244
- loading={wms_layers_importation?.loading}
245
- circular
246
- style={{ width: '50%' }}
247
- >
248
- <Modal
249
- onClose={() => {
250
- setOpen({ ...open, 'wms-layers-import': false });
251
- }}
252
- onOpen={() => {
253
- setOpen({ ...open, 'wms-layers-import': true });
254
- }}
255
- open={open['wms-layers-import']}
256
- trigger={
257
- <CclButton>
258
- <FormattedMessage
259
- id="Import WMS Layers"
260
- defaultMessage="Import WMS Layers"
261
- />
262
- </CclButton>
263
- }
264
- className={'modal-clms'}
265
- >
266
- <div className={'modal-clms-background'}>
267
- <div className={'modal-clms-container'}>
268
- <div className={'modal-close modal-clms-close'}>
269
- <span
270
- className="ccl-icon-close"
271
- aria-label="Close"
166
+ <CclButton
272
167
  onClick={() => {
168
+ handleWMSImport();
273
169
  setOpen({ ...open, 'wms-layers-import': false });
274
170
  }}
275
- onKeyDown={() => {
276
- setOpen({ ...open, 'wms-layers-import': false });
277
- }}
278
- tabIndex="0"
279
- role="button"
280
- ></span>
281
- </div>
282
- <div className="modal-login-text">
283
- <h1>
171
+ mode="filled"
172
+ >
284
173
  <FormattedMessage
285
- id="Import WMS Layers"
286
- defaultMessage="Import WMS Layers"
174
+ id="Import data"
175
+ defaultMessage="Import data"
287
176
  />
288
- </h1>
289
- This action will import the WMS Layers from the view service
290
- defined in the dataset or from GeoNetwork if the view
291
- service is not defined and a linked geonetwork record has a
292
- valid WMS service link
293
- <br />
294
- <br />
177
+ </CclButton>
295
178
  </div>
296
- <CclButton
297
- onClick={() => {
298
- handleWMSImport();
299
- setOpen({ ...open, 'wms-layers-import': false });
300
- }}
301
- mode="filled"
302
- >
179
+ </div>
180
+ </Modal>
181
+ {wms_layers_importation?.imported_wms_layers?.status && (
182
+ <p>
183
+ {wms_layers_importation?.loaded &&
184
+ wms_layers_importation?.error === null && (
185
+ <strong>
186
+ {' '}
187
+ {wms_layers_importation?.imported_wms_layers?.message}
188
+ </strong>
189
+ )}
190
+ </p>
191
+ )}
192
+ {wms_layers_importation?.imported_wms_layers?.status ===
193
+ 'error' && (
194
+ <p>
195
+ <strong>
196
+ {' '}
197
+ {wms_layers_importation?.imported_wms_layers?.message}
198
+ </strong>
199
+ </p>
200
+ )}
201
+ </Segment>
202
+ <Segment
203
+ padded={'very'}
204
+ color={'olive'}
205
+ key={'wms-fields-import'}
206
+ loading={wms_fields_importation?.loading}
207
+ circular
208
+ style={{ width: '50%' }}
209
+ >
210
+ <Modal
211
+ onClose={() => {
212
+ setOpen({ ...open, 'wms-fields-import': false });
213
+ }}
214
+ onOpen={() => {
215
+ setOpen({ ...open, 'wms-fields-import': true });
216
+ }}
217
+ open={open['wms-fields-import']}
218
+ trigger={
219
+ <CclButton>
303
220
  <FormattedMessage
304
- id="Import data"
305
- defaultMessage="Import data"
221
+ id="Import WMS Fields"
222
+ defaultMessage="Import WMS Fields"
306
223
  />
307
224
  </CclButton>
308
- </div>
309
- </div>
310
- </Modal>
311
- {wms_layers_importation?.imported_wms_layers?.status && (
312
- <p>
313
- {wms_layers_importation?.loaded &&
314
- wms_layers_importation?.error === null && (
315
- <strong>
316
- {' '}
317
- {wms_layers_importation?.imported_wms_layers?.message}
318
- </strong>
319
- )}
320
- </p>
321
- )}
322
- {wms_layers_importation?.imported_wms_layers?.status ===
323
- 'error' && (
324
- <p>
325
- <strong>
326
- {' '}
327
- {wms_layers_importation?.imported_wms_layers?.message}
328
- </strong>
329
- </p>
330
- )}
331
- </Segment>
332
- <Segment
333
- padded={'very'}
334
- color={'olive'}
335
- key={'wms-fields-import'}
336
- loading={wms_fields_importation?.loading}
337
- circular
338
- style={{ width: '50%' }}
339
- >
340
- <Modal
341
- onClose={() => {
342
- setOpen({ ...open, 'wms-fields-import': false });
343
- }}
344
- onOpen={() => {
345
- setOpen({ ...open, 'wms-fields-import': true });
346
- }}
347
- open={open['wms-fields-import']}
348
- trigger={
349
- <CclButton>
350
- <FormattedMessage
351
- id="Import WMS Fields"
352
- defaultMessage="Import WMS Fields"
353
- />
354
- </CclButton>
355
- }
356
- className={'modal-clms'}
357
- >
358
- <div className={'modal-clms-background'}>
359
- <div className={'modal-clms-container'}>
360
- <div className={'modal-close modal-clms-close'}>
361
- <span
362
- className="ccl-icon-close"
363
- aria-label="Close"
225
+ }
226
+ className={'modal-clms'}
227
+ >
228
+ <div className={'modal-clms-background'}>
229
+ <div className={'modal-clms-container'}>
230
+ <div className={'modal-close modal-clms-close'}>
231
+ <span
232
+ className="ccl-icon-close"
233
+ aria-label="Close"
234
+ onClick={() => {
235
+ setOpen({ ...open, 'wms-fields-import': false });
236
+ }}
237
+ onKeyDown={() => {
238
+ setOpen({ ...open, 'wms-fields-import': false });
239
+ }}
240
+ tabIndex="0"
241
+ role="button"
242
+ ></span>
243
+ </div>
244
+ <div className="modal-login-text">
245
+ <h1>
246
+ <FormattedMessage
247
+ id="Import WMS Fields"
248
+ defaultMessage="Import WMS Fields"
249
+ />
250
+ </h1>
251
+ This action will import the WMS Fields from the view
252
+ service defined in the dataset if this WMS service is
253
+ Arcgis based
254
+ <br />
255
+ <br />
256
+ </div>
257
+ <CclButton
364
258
  onClick={() => {
259
+ handleWMSFieldimport();
365
260
  setOpen({ ...open, 'wms-fields-import': false });
366
261
  }}
367
- onKeyDown={() => {
368
- setOpen({ ...open, 'wms-fields-import': false });
369
- }}
370
- tabIndex="0"
371
- role="button"
372
- ></span>
373
- </div>
374
- <div className="modal-login-text">
375
- <h1>
262
+ mode="filled"
263
+ >
376
264
  <FormattedMessage
377
- id="Import WMS Fields"
378
- defaultMessage="Import WMS Fields"
265
+ id="Import data"
266
+ defaultMessage="Import data"
379
267
  />
380
- </h1>
381
- This action will import the WMS Fields from the view service
382
- defined in the dataset if this WMS service is Arcgis based
383
- <br />
384
- <br />
268
+ </CclButton>
385
269
  </div>
386
- <CclButton
387
- onClick={() => {
388
- handleWMSFieldimport();
389
- setOpen({ ...open, 'wms-fields-import': false });
390
- }}
391
- mode="filled"
392
- >
393
- <FormattedMessage
394
- id="Import data"
395
- defaultMessage="Import data"
396
- />
397
- </CclButton>
398
270
  </div>
399
- </div>
400
- </Modal>
401
- {wms_fields_importation?.imported_wms_fields?.status && (
402
- <p>
403
- {wms_fields_importation?.loaded &&
404
- wms_fields_importation?.error === null && (
405
- <strong>
406
- {' '}
407
- {wms_fields_importation?.imported_wms_fields?.message}
408
- </strong>
409
- )}
410
- </p>
411
- )}
412
- {wms_fields_importation?.imported_wms_fields?.status ===
413
- 'error' && (
414
- <p>
415
- <strong>
416
- {' '}
417
- {wms_fields_importation?.imported_wms_fields?.message}
418
- </strong>
419
- </p>
420
- )}
421
- </Segment>
422
- </Segment.Group>
271
+ </Modal>
272
+ {wms_fields_importation?.imported_wms_fields?.status && (
273
+ <p>
274
+ {wms_fields_importation?.loaded &&
275
+ wms_fields_importation?.error === null && (
276
+ <strong>
277
+ {' '}
278
+ {wms_fields_importation?.imported_wms_fields?.message}
279
+ </strong>
280
+ )}
281
+ </p>
282
+ )}
283
+ {wms_fields_importation?.imported_wms_fields?.status ===
284
+ 'error' && (
285
+ <p>
286
+ <strong>
287
+ {' '}
288
+ {wms_fields_importation?.imported_wms_fields?.message}
289
+ </strong>
290
+ </p>
291
+ )}
292
+ </Segment>
293
+ </Segment.Group>
294
+ </>
423
295
  )}
424
296
 
425
297
  <CclTabs routing={true}>
@@ -1,17 +1,17 @@
1
- import { Accordion, Loader, Segment } from 'semantic-ui-react';
2
- import { CclInfoContainer, CclInfoDescription } from '../CclInfoDescription';
1
+ import React from 'react';
2
+ import AnimateHeight from 'react-animate-height';
3
3
  import { useDispatch, useSelector } from 'react-redux';
4
+ import { useLocation } from 'react-router-dom';
5
+ import { Accordion, Loader, Segment } from 'semantic-ui-react';
4
6
 
5
- import AnimateHeight from 'react-animate-height';
6
- import CclCard from '@eeacms/volto-clms-theme/components/CclCard/CclCard';
7
- import CclCitation from '@eeacms/volto-clms-theme/components/CclCitation/CclCitation';
7
+ import { searchContent } from '@plone/volto/actions';
8
8
  import { Icon } from '@plone/volto/components';
9
- import React from 'react';
10
- import { StringToHTML } from '@eeacms/volto-clms-theme/components/CclUtils';
11
9
  import config from '@plone/volto/registry';
12
- import { searchContent } from '@plone/volto/actions';
13
- import { useLocation } from 'react-router-dom';
14
- import { formatFileSize } from '../Blocks/utils';
10
+ import CclCitation from '@eeacms/volto-clms-theme/components/CclCitation/CclCitation';
11
+ import { StringToHTML } from '@eeacms/volto-clms-theme/components/CclUtils';
12
+ import CclRelatedListingView from '@eeacms/volto-clms-theme/components/Blocks/CclRelatedListingBlock/CclRelatedListingView';
13
+
14
+ import { CclInfoContainer, CclInfoDescription } from '../CclInfoDescription';
15
15
 
16
16
  const DataSetInfoContent = (props) => {
17
17
  const dispatch = useDispatch();
@@ -20,19 +20,15 @@ const DataSetInfoContent = (props) => {
20
20
  const searchSubrequests = useSelector((state) => state.search.subrequests);
21
21
  let libraries = searchSubrequests?.[id]?.items || [];
22
22
  let librariesPending = searchSubrequests?.[id]?.loading;
23
- const user = useSelector((state) => state.users.user);
24
23
  React.useEffect(() => {
25
24
  if (UID) {
26
25
  dispatch(
27
26
  searchContent(
28
27
  '',
29
28
  {
30
- fullobjects: 1,
31
29
  portal_type: 'TechnicalLibrary',
32
30
  path: '/',
33
31
  associated_datasets: UID,
34
- sort_on: ['documentation_sorting', 'sortable_title'],
35
- sort_order: ['ascending', 'ascending'],
36
32
  sort_limit: 99999,
37
33
  },
38
34
  id,
@@ -178,19 +174,15 @@ const DataSetInfoContent = (props) => {
178
174
  duration={500}
179
175
  height={'auto'}
180
176
  >
181
- {libraries.map((item, index) => (
182
- <CclCard
183
- key={index}
184
- Type="TechnicalLibrary"
185
- type="doc"
186
- card={{
187
- Type: item['@type'],
188
- getObjSize: formatFileSize(item.file.size),
189
- ...item,
190
- }}
191
- showEditor={user?.roles?.includes('Manager')}
192
- />
193
- ))}
177
+ <CclRelatedListingView
178
+ id={'dataset-info-technicals'}
179
+ properties={{ ...props }}
180
+ data={{
181
+ variation: 'CclCardsdoc',
182
+ content_type: 'TechnicalLibrary',
183
+ }}
184
+ associated_elements="dataset"
185
+ />
194
186
  </AnimateHeight>
195
187
  </Accordion.Content>
196
188
  </Accordion>
@@ -0,0 +1,209 @@
1
+ import React from 'react';
2
+ import { FormattedMessage } from 'react-intl';
3
+ import { useDispatch, useSelector } from 'react-redux';
4
+ import { useLocation } from 'react-router-dom';
5
+ import { Modal, Segment, Grid, Input, Pagination } from 'semantic-ui-react';
6
+
7
+ import { Icon } from '@plone/volto/components';
8
+ import paginationLeftSVG from '@plone/volto/icons/left-key.svg';
9
+ import paginationRightSVG from '@plone/volto/icons/right-key.svg';
10
+ import CclButton from '@eeacms/volto-clms-theme/components/CclButton/CclButton';
11
+
12
+ import { postImportGeonetwork } from '../../actions';
13
+ import { useFilteredPagination } from '../CclUtils/useFilteredPagination';
14
+
15
+ export const GeonetworkImporterButtons = (props) => {
16
+ const { geonetwork_identifiers_items, open, setOpen } = props;
17
+ const location = useLocation();
18
+ const dispatch = useDispatch();
19
+ const geonetwork_importation = useSelector(
20
+ (state) => state.geonetwork_importation,
21
+ );
22
+ const use_pagination = useFilteredPagination(geonetwork_identifiers_items, 3);
23
+ const p_functions = use_pagination.functions;
24
+ const p_data = use_pagination.data;
25
+ const { pagination, currentPage, paginationSize, dataList } = p_data;
26
+
27
+ const handleImport = (id, type) => {
28
+ dispatch(postImportGeonetwork(location.pathname, id, type));
29
+ };
30
+
31
+ return (
32
+ <Segment basic>
33
+ <h2>Geonetwork importation options:</h2>
34
+ {paginationSize < geonetwork_identifiers_items.length && (
35
+ <div className="block search">
36
+ <div className="search-wrapper">
37
+ <div className="search-input">
38
+ <Input
39
+ id={`geonetwork-searchtext`}
40
+ placeholder={'Search in the following items'}
41
+ fluid
42
+ onChange={(event, value) => {
43
+ p_functions.applySearch(event, value, 'title');
44
+ p_functions.setCurrentPage(1);
45
+ }}
46
+ />
47
+ </div>
48
+ </div>
49
+ </div>
50
+ )}
51
+ {pagination?.length > 0 && (
52
+ <Grid columns={3} compact horizontal>
53
+ {pagination.map((item) => {
54
+ return (
55
+ <Grid.Column key={item.id}>
56
+ <Segment
57
+ padded={'very'}
58
+ color={'olive'}
59
+ loading={geonetwork_importation.loading}
60
+ >
61
+ <strong>
62
+ {item.title} (from {item.type}):{' '}
63
+ </strong>
64
+ <br />
65
+ <br />
66
+ <Modal
67
+ onClose={() => {
68
+ setOpen({ ...open, [item.id]: false });
69
+ }}
70
+ onOpen={() => {
71
+ setOpen({ ...open, [item.id]: true });
72
+ }}
73
+ open={open[item.id]}
74
+ trigger={
75
+ <CclButton>
76
+ <FormattedMessage
77
+ id="Import data"
78
+ defaultMessage="Import data"
79
+ />
80
+ </CclButton>
81
+ }
82
+ className={'modal-clms'}
83
+ >
84
+ <div className={'modal-clms-background'}>
85
+ <div className={'modal-clms-container'}>
86
+ <div className={'modal-close modal-clms-close'}>
87
+ <span
88
+ className="ccl-icon-close"
89
+ aria-label="Close"
90
+ onClick={() => {
91
+ setOpen({ ...open, [item.id]: false });
92
+ }}
93
+ onKeyDown={() => {
94
+ setOpen({ ...open, [item.id]: false });
95
+ }}
96
+ tabIndex="0"
97
+ role="button"
98
+ ></span>
99
+ </div>
100
+ <div className="modal-login-text">
101
+ <h1>
102
+ <FormattedMessage
103
+ id="Import from GeoNetwork"
104
+ defaultMessage="Import from GeoNetwork"
105
+ />
106
+ </h1>
107
+ This action will import the data from{' '}
108
+ <strong>{item.title}</strong> (from {item.type}) into
109
+ this dataset.
110
+ <br />
111
+ <br />
112
+ <a
113
+ target="_blank"
114
+ rel="noreferrer"
115
+ href={
116
+ item.type === 'EEA'
117
+ ? 'https://sdi.eea.europa.eu/catalogue/srv/eng/catalog.search#/metadata/' +
118
+ item.id
119
+ : 'https://land.copernicus.vgt.vito.be/geonetwork/srv/eng/catalog.search#/metadata/' +
120
+ item.id
121
+ }
122
+ >
123
+ {item.type === 'EEA' && (
124
+ <FormattedMessage
125
+ id="EEA Geonetwork element"
126
+ defaultMessage="EEA Geonetwork element"
127
+ />
128
+ )}
129
+ {item.type === 'VITO' && (
130
+ <FormattedMessage
131
+ id="VITO Geonetwork element"
132
+ defaultMessage="VITO Geonetwork element"
133
+ />
134
+ )}
135
+ </a>
136
+ </div>
137
+ <CclButton
138
+ onClick={() => {
139
+ handleImport(item.id, item.type);
140
+ setOpen({ ...open, [item.id]: false });
141
+ }}
142
+ mode="filled"
143
+ >
144
+ <FormattedMessage
145
+ id="Import data"
146
+ defaultMessage="Import data"
147
+ />
148
+ </CclButton>
149
+ </div>
150
+ </div>
151
+ </Modal>
152
+ {geonetwork_importation.imported_data
153
+ ?.requested_geonetwork_id === item.id && (
154
+ <p>
155
+ {geonetwork_importation.loaded &&
156
+ geonetwork_importation.error === null && (
157
+ <strong>
158
+ {' '}
159
+ The data has been successfully imported
160
+ </strong>
161
+ )}
162
+ </p>
163
+ )}
164
+ {geonetwork_importation.imported_data?.status === 'error' && (
165
+ <p>
166
+ <strong>
167
+ {' '}
168
+ {geonetwork_importation.imported_data?.message}
169
+ </strong>
170
+ </p>
171
+ )}
172
+ </Segment>
173
+ </Grid.Column>
174
+ );
175
+ })}
176
+ </Grid>
177
+ )}
178
+ {dataList.length / paginationSize > 1 && (
179
+ <div className="pagination-wrapper">
180
+ <Pagination
181
+ activePage={currentPage}
182
+ totalPages={Math.ceil(dataList.length / paginationSize)}
183
+ onPageChange={(e, { activePage }) => {
184
+ p_functions.setCurrentPage(activePage);
185
+ }}
186
+ firstItem={null}
187
+ lastItem={null}
188
+ prevItem={{
189
+ content: <Icon name={paginationLeftSVG} size="18px" />,
190
+ icon: true,
191
+ 'aria-disabled': currentPage === 1,
192
+ className: currentPage === 1 ? 'disabled' : null,
193
+ }}
194
+ nextItem={{
195
+ content: <Icon name={paginationRightSVG} size="18px" />,
196
+ icon: true,
197
+ 'aria-disabled':
198
+ currentPage === Math.ceil(dataList.length / paginationSize),
199
+ className:
200
+ currentPage === Math.ceil(dataList.length / paginationSize)
201
+ ? 'disabled'
202
+ : null,
203
+ }}
204
+ ></Pagination>
205
+ </div>
206
+ )}
207
+ </Segment>
208
+ );
209
+ };
@@ -1,9 +1,12 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import { dynamicSort } from './dynamicSort';
3
- export const useFilteredPagination = (original_data) => {
3
+ export const useFilteredPagination = (
4
+ original_data,
5
+ defaultPaginationSize = 10,
6
+ ) => {
4
7
  const [originalDataList, setOriginalDataList] = useState(original_data);
5
8
  const [dataList, setDataList] = useState(original_data);
6
- const [paginationSize, setPaginationSize] = useState(10);
9
+ const [paginationSize, setPaginationSize] = useState(defaultPaginationSize);
7
10
  const [currentPage, setCurrentPage] = useState(1);
8
11
  const [pagination, setPagination] = useState(
9
12
  original_data.slice(