@eeacms/volto-clms-theme 1.0.73 → 1.0.76

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,9 +4,44 @@ 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.76](https://github.com/eea/volto-clms-theme/compare/1.0.75...1.0.76)
8
+
9
+ - add modal when download requests are both standard downloads or prepackaged files [`#219`](https://github.com/eea/volto-clms-theme/pull/219)
10
+ - upgrade volto-accordion-block [`cf8a7a6`](https://github.com/eea/volto-clms-theme/commit/cf8a7a6909b1d38f855ef01f0642add7e882e804)
11
+ - add modal when downloading files are prepackaged and mapviewer [`c974d37`](https://github.com/eea/volto-clms-theme/commit/c974d37f42fd13d0de53416c36ed4b8f8a8ba2c0)
12
+
13
+ #### [1.0.75](https://github.com/eea/volto-clms-theme/compare/1.0.74...1.0.75)
14
+
15
+ > 1 March 2022
16
+
17
+ - New release [`#218`](https://github.com/eea/volto-clms-theme/pull/218)
18
+ - add elvis operator [`#217`](https://github.com/eea/volto-clms-theme/pull/217)
19
+ - no need to tinker with dates, we configure the listing in Volto [`#215`](https://github.com/eea/volto-clms-theme/pull/215)
20
+ - use new placeholder image [`#216`](https://github.com/eea/volto-clms-theme/pull/216)
21
+ - add sorting to related item listing [`#214`](https://github.com/eea/volto-clms-theme/pull/214)
22
+ - change no related item message [`#213`](https://github.com/eea/volto-clms-theme/pull/213)
23
+ - test [`2863dbd`](https://github.com/eea/volto-clms-theme/commit/2863dbd060043419ee6bfd8f9ba709df1b82811d)
24
+ - use new placeholder [`875b97b`](https://github.com/eea/volto-clms-theme/commit/875b97b75311cf0f2722ddb8f1e2e62d0fcdb8f4)
25
+ - no longer needed VariationHOC for WorkOpportunities [`5148f5a`](https://github.com/eea/volto-clms-theme/commit/5148f5a3b7906a78108480a172ad541aec7d98de)
26
+
27
+ #### [1.0.74](https://github.com/eea/volto-clms-theme/compare/1.0.73...1.0.74)
28
+
29
+ > 25 February 2022
30
+
31
+ - Remove fullobjects from listings and demo feedback [`#212`](https://github.com/eea/volto-clms-theme/pull/212)
32
+ - fix [`3d683f2`](https://github.com/eea/volto-clms-theme/commit/3d683f241799aaeb9034652f1839b34bc8662003)
33
+ - add husky installer script to package.json [`071706f`](https://github.com/eea/volto-clms-theme/commit/071706f2c65333aba82c0ec9b545095479bb5348)
34
+ - remove fullobjects and show images with generated url [`0bfbc00`](https://github.com/eea/volto-clms-theme/commit/0bfbc0080a6a9be4b63bfd3eb7ed8f65856382a2)
35
+ - stop re-requesting on re-rendering of relatedListing view [`27bd33c`](https://github.com/eea/volto-clms-theme/commit/27bd33cdbb65686a37b0591e8a023aa155f2539d)
36
+ - date format [`e61e6f1`](https://github.com/eea/volto-clms-theme/commit/e61e6f1a655914d5ecadc7b8cfe51cfa6d19a7cb)
37
+ - fix related Listing block portal_type selector [`02228f9`](https://github.com/eea/volto-clms-theme/commit/02228f98e3032a9af436dedc6e5e6a5ac7d863fa)
38
+ - feedback received on demo fixed [`52530c0`](https://github.com/eea/volto-clms-theme/commit/52530c0deea9ba855816350041cb285adde03035)
39
+
7
40
  #### [1.0.73](https://github.com/eea/volto-clms-theme/compare/1.0.72...1.0.73)
8
41
 
9
- - fix import [`9d7f118`](https://github.com/eea/volto-clms-theme/commit/9d7f1189984066d9f53b46ead0b32c232bd73463)
42
+ > 23 February 2022
43
+
44
+ - fix import [`#211`](https://github.com/eea/volto-clms-theme/pull/211)
10
45
 
11
46
  #### [1.0.72](https://github.com/eea/volto-clms-theme/compare/1.0.71...1.0.72)
12
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-clms-theme",
3
- "version": "1.0.73",
3
+ "version": "1.0.76",
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",
@@ -30,7 +30,7 @@
30
30
  "@eeacms/volto-taxonomy"
31
31
  ],
32
32
  "dependencies": {
33
- "@eeacms/volto-accordion-block": "3.4.7",
33
+ "@eeacms/volto-accordion-block": "3.4.13",
34
34
  "@eeacms/volto-arcgis-block": "*",
35
35
  "@eeacms/volto-clms-utils": "0.1.6",
36
36
  "@eeacms/volto-columns-block": "4.4.3",
@@ -121,6 +121,7 @@
121
121
  "cypress:run": "NODE_ENV=production CYPRESS_API=plone ../../../node_modules/cypress/bin/cypress run",
122
122
  "cypress:open": "NODE_ENV=production CYPRESS_API=plone ../../../node_modules/cypress/bin/cypress open",
123
123
  "precommit": "yarn stylelint && yarn prettier && yarn lint",
124
+ "husky": "husky install",
124
125
  "test": "docker run -it --rm -v $(pwd):/opt/frontend/my-volto-project/src/addons/volto-clms-theme -e GIT_NAME=volto-clms-theme -e NAMESPACE=@eeacms plone/volto-addon-ci"
125
126
  }
126
127
  }
@@ -18,7 +18,7 @@ Array [
18
18
  >
19
19
  <img
20
20
  alt="Placeholder"
21
- src="https://eu-copernicus.github.io/copernicus-component-library/assets/images/image_placeholder.jpg"
21
+ src="ccl-thumbnail-placeholder.jpg"
22
22
  />
23
23
  </div>
24
24
  <div
@@ -9,7 +9,10 @@ const CclRelatedListingEdit = (props) => {
9
9
  const schema = config.blocks.blocksConfig['relatedListing'].blockSchema;
10
10
  const searchSubrequests = useSelector((state) => state.search.subrequests);
11
11
  const types = useSelector((state) => state.types.types);
12
- const types_schema = types.map((type) => [type.title, type.title]);
12
+ const types_schema = types.map((type) => [
13
+ type['@id'].split('/').pop(),
14
+ type.title,
15
+ ]);
13
16
  let libraries = searchSubrequests?.[props.id]?.items || [];
14
17
  const variationsConfig =
15
18
  config.blocks.blocksConfig['relatedListing'].variations;
@@ -3,13 +3,16 @@ import { useDispatch, useSelector } from 'react-redux';
3
3
  import React from 'react';
4
4
  import config from '@plone/volto/registry';
5
5
  import { searchContent } from '@plone/volto/actions';
6
+ import { Segment } from 'semantic-ui-react';
6
7
 
7
8
  const CclRelatedListingView = (props) => {
8
9
  const { data, id, properties, metadata } = props;
9
10
  const dispatch = useDispatch();
10
- const searchSubrequests = useSelector((state) => state.search.subrequests);
11
+ const searchSubrequests = useSelector(
12
+ (state) => state.search.subrequests?.[props.id],
13
+ );
11
14
  const uid = metadata ? metadata['UID'] : properties['UID'];
12
- let libraries = searchSubrequests?.[props.id]?.items || [];
15
+ let libraries = searchSubrequests?.items || [];
13
16
  const variationsConfig =
14
17
  config.blocks.blocksConfig['relatedListing'].variations;
15
18
  let TemplateView = '';
@@ -36,34 +39,50 @@ const CclRelatedListingView = (props) => {
36
39
  template_id = defaultVariation.id;
37
40
  data.variation = template_id;
38
41
  }
39
-
40
42
  if (!data.content_type) {
41
43
  data.content_type = 'News Item';
42
44
  }
43
45
 
46
+ // Configure sorting for the related items
47
+ let sort_on = 'effective';
48
+ let sort_order = 'descending';
49
+ if (data.content_type === 'eea.meeting') {
50
+ sort_on = 'start';
51
+ sort_order = 'descending';
52
+ } else if (data.content_type === 'TechnicalLibrary') {
53
+ sort_on = 'documentation_sorting';
54
+ sort_order = 'ascending';
55
+ }
56
+
44
57
  React.useEffect(() => {
45
58
  uid &&
59
+ !searchSubrequests?.loading &&
60
+ !searchSubrequests?.loaded &&
61
+ !searchSubrequests?.error &&
46
62
  dispatch(
47
63
  searchContent(
48
- '',
64
+ '/',
49
65
  {
50
- fullobjects: 1,
51
66
  portal_type: data.content_type || 'News Item',
52
- path: '/',
53
67
  associated_products: uid,
68
+ metadata_fields: '_all',
69
+ sort_on: sort_on,
70
+ sort_order: sort_order,
54
71
  },
55
72
  id,
56
73
  ),
57
74
  );
58
- }, [data, id, uid, dispatch]);
75
+ // eslint-disable-next-line react-hooks/exhaustive-deps
76
+ }, [data, id, uid, dispatch, searchSubrequests]);
59
77
 
60
78
  return (
61
79
  <>
62
- {libraries.length > 0 ? (
80
+ {searchSubrequests?.loaded && libraries.length > 0 ? (
63
81
  <TemplateView items={libraries} variation={template_id} />
64
82
  ) : (
65
- <p>There are no related {data.content_type} items.</p>
83
+ <p>There are no related items.</p>
66
84
  )}
85
+ {searchSubrequests?.loading && <Segment loading></Segment>}
67
86
  </>
68
87
  );
69
88
  };
@@ -0,0 +1,37 @@
1
+ import { SubscriptionView } from '@eeacms/volto-clms-theme/components/CLMSSubscriptionView';
2
+ import { SidebarPortal } from '@plone/volto/components';
3
+ import { SubscriptionSchema } from './schema';
4
+ import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
5
+
6
+ const SubscriptionBlockEdit = (props) => {
7
+ const { block, data, onChangeBlock, selected } = props;
8
+
9
+ return (
10
+ <>
11
+ <div className="ccl-block-editor-header">
12
+ <legend
13
+ onClick={() => {
14
+ props.setSidebarTab(1);
15
+ }}
16
+ aria-hidden="true"
17
+ />
18
+ </div>
19
+ <SubscriptionView type={data.type || 'events'} />
20
+ <SidebarPortal selected={selected}>
21
+ <InlineForm
22
+ schema={SubscriptionSchema()}
23
+ title="Product card block"
24
+ onChangeField={(id, value) => {
25
+ onChangeBlock(block, {
26
+ ...data,
27
+ [id]: value,
28
+ });
29
+ }}
30
+ formData={data}
31
+ />
32
+ </SidebarPortal>
33
+ </>
34
+ );
35
+ };
36
+
37
+ export default SubscriptionBlockEdit;
@@ -0,0 +1,9 @@
1
+ import { SubscriptionView } from '@eeacms/volto-clms-theme/components/CLMSSubscriptionView';
2
+
3
+ const SubscriptionBlockView = (props) => {
4
+ const { data } = props;
5
+
6
+ return <SubscriptionView type={data.type || 'events'} />;
7
+ };
8
+
9
+ export default SubscriptionBlockView;
@@ -0,0 +1,21 @@
1
+ export const SubscriptionSchema = () => ({
2
+ title: 'Subscription block',
3
+ fieldsets: [
4
+ {
5
+ id: 'default',
6
+ title: 'Default',
7
+ fields: ['type'],
8
+ },
9
+ ],
10
+ properties: {
11
+ type: {
12
+ title: 'Subscription type',
13
+ choices: [
14
+ ['news', 'news'],
15
+ ['events', 'events'],
16
+ ['newsletter', 'newsletter'],
17
+ ],
18
+ },
19
+ },
20
+ required: ['product'],
21
+ });
@@ -7,15 +7,15 @@ import { Link } from 'react-router-dom';
7
7
  const messages = defineMessages({
8
8
  ProcurementNo: {
9
9
  id: 'ProcurementNo',
10
- defaultMessage: 'Procurement No:',
10
+ defaultMessage: 'Procurement No: ',
11
11
  },
12
12
  ReferenceNo: {
13
13
  id: 'ReferenceNo',
14
- defaultMessage: 'Reference No:',
14
+ defaultMessage: 'Reference No: ',
15
15
  },
16
16
  SubmissionDeadline: {
17
17
  id: 'SubmissionDeadline',
18
- defaultMessage: 'Submission deadline:',
18
+ defaultMessage: 'Submission deadline: ',
19
19
  },
20
20
  });
21
21
 
@@ -50,48 +50,26 @@ const CclWorkOpportunity = (props) => {
50
50
  <span className="card-work-deadline-title">
51
51
  {intl.formatMessage(messages.SubmissionDeadline)}
52
52
  </span>
53
- {new Date(item.submission_deadline).toLocaleDateString()}
53
+ {new Date(item.submission_deadline).toLocaleString()}
54
54
  </div>
55
55
  </div>
56
56
  );
57
57
  };
58
58
 
59
- var Today = new Date();
60
-
61
59
  const CclListingWorkOpportunities = (props) => {
62
- const { items, variation } = props;
60
+ const { items } = props;
63
61
  const intl = useIntl();
64
62
  const user = useSelector((state) => state.users?.user);
65
63
  return (
66
64
  <>
67
- {items
68
- .filter(
69
- (item) =>
70
- new Date(item.submission_deadline) < Today &&
71
- variation === 'CloseTenders',
72
- )
73
- .map((item, index) => (
74
- <CclWorkOpportunity
75
- key={index}
76
- item={item}
77
- intl={intl}
78
- user={user}
79
- ></CclWorkOpportunity>
80
- ))}
81
- {items
82
- .filter(
83
- (item) =>
84
- new Date(item.submission_deadline) > Today &&
85
- variation === 'OpenTenders',
86
- )
87
- .map((item, index) => (
88
- <CclWorkOpportunity
89
- key={index}
90
- item={item}
91
- intl={intl}
92
- user={user}
93
- ></CclWorkOpportunity>
94
- ))}
65
+ {items.map((item, index) => (
66
+ <CclWorkOpportunity
67
+ key={index}
68
+ item={item}
69
+ intl={intl}
70
+ user={user}
71
+ ></CclWorkOpportunity>
72
+ ))}
95
73
  </>
96
74
  );
97
75
  };
@@ -56,6 +56,8 @@ import RelatedListingSchema from '@eeacms/volto-clms-theme/components/Blocks/Ccl
56
56
  import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
57
57
  import TextLinkCarouselEdit from '@eeacms/volto-clms-theme/components/Blocks/CclTextLinkCarouselBlock/CclTextLinkCarouselEdit';
58
58
  import TextLinkCarouselView from '@eeacms/volto-clms-theme/components/Blocks/CclTextLinkCarouselBlock/CclTextLinkCarouselView';
59
+ import SubscriptionBlockView from '@eeacms/volto-clms-theme/components/Blocks/CclSubscriptionBlock/SubscriptionView';
60
+ import SubscriptionBlockEdit from '@eeacms/volto-clms-theme/components/Blocks/CclSubscriptionBlock/SubscriptionEdit';
59
61
  import cardSVG from '@plone/volto/icons/indent.svg';
60
62
  import containerSVG from '@plone/volto/icons/apps.svg';
61
63
  import customIdFieldSchema from '@eeacms/volto-clms-theme/components/Blocks/CustomTemplates/VoltoFormBlock/customIdFieldSchema';
@@ -81,11 +83,9 @@ function listingVariation(id, isDefault, title, template, isWO = false) {
81
83
  id: id,
82
84
  isDefault: isDefault,
83
85
  title: title,
84
- template: VariationHOC(
85
- isWO ? CclListingWorkOpportunities : CclListingCards,
86
- template,
87
- ),
88
- fullobjects: true,
86
+ template: isWO
87
+ ? CclListingWorkOpportunities
88
+ : VariationHOC(CclListingCards, template),
89
89
  };
90
90
  }
91
91
 
@@ -443,6 +443,22 @@ const customBlocks = (config) => ({
443
443
  view: [], // Future proof (not implemented yet) view user role(s)
444
444
  },
445
445
  },
446
+ subscriptionBlock: {
447
+ id: 'subscriptionBlock', // The name (id) of the block
448
+ title: 'Subscription Block', // The display name of the block
449
+ icon: homeBand, // The icon used in the block chooser
450
+ group: 'ccl_blocks', // The group (blocks can be grouped, displayed in the chooser)
451
+ view: SubscriptionBlockView, // The view mode component
452
+ edit: SubscriptionBlockEdit, // The edit mode component
453
+ restricted: false, // If the block is restricted, it won't show in the chooser
454
+ mostUsed: false, // A meta group `most used`, appearing at the top of the chooser
455
+ blockHasOwnFocusManagement: false, // Set this to true if the block manages its own focus
456
+ sidebarTab: 1, // The sidebar tab you want to be selected when selecting the block
457
+ security: {
458
+ addPermission: [], // Future proof (not implemented yet) add user permission role(s)
459
+ view: [], // Future proof (not implemented yet) view user role(s)
460
+ },
461
+ },
446
462
  form: {
447
463
  ...config.blocks.blocksConfig.form,
448
464
  fieldSchema: customIdFieldSchema,
@@ -4,7 +4,7 @@
4
4
  * @module components/CLMSDownloadCartView/CLMSCartContent
5
5
  */
6
6
 
7
- import { Checkbox, Segment, Select } from 'semantic-ui-react';
7
+ import { Checkbox, Grid, Modal, Segment, Select } from 'semantic-ui-react';
8
8
  import React, { useEffect, useState } from 'react';
9
9
  import {
10
10
  getCartObjectFromMapviewer,
@@ -30,10 +30,16 @@ import useCartState from '@eeacms/volto-clms-utils/cart/useCartState';
30
30
  const CLMSCartContent = (props) => {
31
31
  const { localSessionCart } = props;
32
32
  const dispatch = useDispatch();
33
- const cart = useSelector((state) => state.cart_items.items);
34
33
  const { removeCartItem, removeCartItems } = useCartState();
34
+
35
+ // component states
36
+ const [openedModal, setOpenedModal] = useState(false);
35
37
  const [cartSelection, setCartSelection] = useState([]);
36
38
  const [loadingTable, setLoadingTable] = useState(false);
39
+ const [cartItems, setCartItems] = useState([]);
40
+
41
+ // state connections
42
+ const cart = useSelector((state) => state.cart_items.items);
37
43
  const post_download_in_progress = useSelector(
38
44
  (state) => state.downloadtool.post_download_in_progress,
39
45
  );
@@ -46,8 +52,6 @@ const CLMSCartContent = (props) => {
46
52
  );
47
53
  const nutsnames = useSelector((state) => state.nutsnames.nutsnames);
48
54
 
49
- const [cartItems, setCartItems] = useState([]);
50
-
51
55
  useEffect(() => {
52
56
  dispatch(getProjections());
53
57
  dispatch(getFormatConversionTable());
@@ -139,7 +143,7 @@ const CLMSCartContent = (props) => {
139
143
  dispatch(getDownloadtool());
140
144
  };
141
145
 
142
- function startDownloading() {
146
+ const startDownloading = () => {
143
147
  setLoadingTable(true);
144
148
  window.scrollTo(0, 0);
145
149
 
@@ -161,7 +165,21 @@ const CLMSCartContent = (props) => {
161
165
  setLoadingTable(false);
162
166
  toast.error(<Toast autoClose={5000} title={'Something went wrong.'} />);
163
167
  });
164
- }
168
+ };
169
+
170
+ const downloadModal = () => {
171
+ let selectedItems = getSelectedCartItems();
172
+ const hasPrepackaged =
173
+ selectedItems.filter((item) => item.file_id).length > 0;
174
+ const hasMapSelection =
175
+ selectedItems.filter((item) => item.area).length > 0;
176
+ if (!(hasMapSelection && hasPrepackaged)) {
177
+ startDownloading();
178
+ } else {
179
+ setOpenedModal(true);
180
+ }
181
+ };
182
+
165
183
  const setProjectionValue = (unique_id, value) => {
166
184
  const objIndex = cartItems.findIndex((obj) => obj.unique_id === unique_id);
167
185
  cartItems[objIndex].projection = value;
@@ -346,12 +364,70 @@ const CLMSCartContent = (props) => {
346
364
  )}
347
365
  {cartItems?.length !== 0 && (
348
366
  <CclButton
349
- onClick={() => startDownloading()}
367
+ onClick={() => downloadModal()}
350
368
  disabled={cartSelection.length === 0}
351
369
  >
352
370
  Start downloading
353
371
  </CclButton>
354
372
  )}
373
+ <Modal
374
+ // onClose={() => closeModal()}
375
+ // onOpen={() => openModal()}
376
+ open={openedModal}
377
+ // trigger={trigger}
378
+ className={'modal-clms'}
379
+ size={'fullscreen'}
380
+ >
381
+ <Modal.Header>Download processing</Modal.Header>
382
+ <Modal.Content>
383
+ <div className={'modal-clms-background'}>
384
+ <div className={'modal-clms-container'}>
385
+ {'The download is going to be processed in two different files.'}
386
+ <br />
387
+ <br />
388
+ <strong>Prepackaged files:</strong>
389
+ <ul>
390
+ {getSelectedCartItems()
391
+ .filter((item) => item.file_id)
392
+ .map((item, key) => (
393
+ <li key={key}>{item.name}</li>
394
+ ))}
395
+ </ul>
396
+ <br />
397
+ <strong>Map viewer selection:</strong>
398
+ <ul>
399
+ {getSelectedCartItems()
400
+ .filter((item) => item.area)
401
+ .map((item, key) => (
402
+ <li key={key}>{item.name}</li>
403
+ ))}
404
+ </ul>
405
+ </div>
406
+ </div>
407
+ </Modal.Content>
408
+ <Modal.Actions>
409
+ <Grid columns={2} stackable textAlign="center">
410
+ <Grid.Row verticalAlign="middle">
411
+ <Grid.Column>
412
+ <CclButton onClick={() => setOpenedModal(false)}>
413
+ Cancel
414
+ </CclButton>
415
+ </Grid.Column>
416
+ <Grid.Column>
417
+ <CclButton
418
+ mode={'filled'}
419
+ onClick={() => {
420
+ setOpenedModal(false);
421
+ startDownloading();
422
+ }}
423
+ >
424
+ Accept
425
+ </CclButton>
426
+ </Grid.Column>
427
+ </Grid.Row>
428
+ </Grid>
429
+ </Modal.Actions>
430
+ </Modal>
355
431
  </>
356
432
  );
357
433
  };
@@ -73,10 +73,6 @@ export const CLMSMeetingView = (props) => {
73
73
  id: 'meetingtype',
74
74
  defaultMessage: 'Type',
75
75
  },
76
- meetinglevel: {
77
- id: 'meetinglevel',
78
- defaultMessage: 'Level',
79
- },
80
76
  hosting_organisation: {
81
77
  id: 'hosting_organisation',
82
78
  defaultMessage: 'Hosting organisation',
@@ -330,19 +326,6 @@ export const CLMSMeetingView = (props) => {
330
326
  </>
331
327
  )}
332
328
 
333
- {content.meeting_level && (
334
- <>
335
- <div className="dataset-info-field">
336
- <div className="dataset-field-title">
337
- <Header>{intl.formatMessage(messages.meetinglevel)}</Header>
338
- </div>
339
- <div className="dataset-field-description">
340
- {content.meeting_level.title}
341
- </div>
342
- </div>
343
- </>
344
- )}
345
-
346
329
  {content.hosting_organisation && (
347
330
  <>
348
331
  <div className="dataset-info-field">
@@ -8,7 +8,7 @@ const CLMSNewsItemView = (props) => {
8
8
  <h1 className="page-title">{content.title}</h1>
9
9
  <div className="news-detail">
10
10
  <div className="news-detail-date">
11
- {new Date(content?.effective).toLocaleDateString()}
11
+ {new Date(content?.effective).toLocaleString()}
12
12
  </div>
13
13
  {content?.image && (
14
14
  <figure className="news-detail-image">
@@ -1,7 +1,5 @@
1
1
  import './cards.less';
2
2
 
3
- import * as mime from 'react-native-mime-types';
4
-
5
3
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
4
  import { Link } from 'react-router-dom';
7
5
  import PropTypes from 'prop-types';
@@ -12,12 +10,49 @@ import { portal_types_labels } from '../Blocks/CustomTemplates/VoltoSearchBlock'
12
10
  import penSVG from '@plone/volto/icons/pen.svg';
13
11
  import { Icon } from '@plone/volto/components';
14
12
 
15
- function bytesToSize(bytes) {
16
- var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
17
- if (bytes === 0) return '0 Byte';
18
- var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
19
- return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
20
- }
13
+ import PlaceHolder from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-thumbnail-placeholder.jpg';
14
+
15
+ const CardImage = ({ card, size = 'preview' }) => {
16
+ return card?.image_field ? (
17
+ <img
18
+ src={`${card.getURL}/@@images/${card?.image_field}/${size}`}
19
+ alt={card?.image?.alt || 'Placeholder'}
20
+ />
21
+ ) : (
22
+ <img src={PlaceHolder} alt={card?.image?.alt || 'Placeholder'} />
23
+ );
24
+ };
25
+
26
+ const DocCard = ({ card, url, showEditor, children }) => {
27
+ return (
28
+ <>
29
+ <div className="card-doc-title">
30
+ {card?.Type === 'TechnicalLibrary' ? (
31
+ <a href={`${card['@id']}/@@download/file`}>{card?.title}</a>
32
+ ) : (
33
+ <Link to={url}>{card?.title}</Link>
34
+ )}
35
+ {card?.Type === 'TechnicalLibrary' && showEditor && (
36
+ <Link to={`${url}/edit`}>
37
+ <Icon
38
+ name={penSVG}
39
+ size="15px"
40
+ className="circled"
41
+ title={'Edit'}
42
+ />
43
+ </Link>
44
+ )}
45
+ </div>
46
+ <div className="card-doc-text">
47
+ <div className="doc-description">{card?.description}</div>
48
+ {card?.Type === 'TechnicalLibrary' && (
49
+ <div className="card-doc-size">{card.getObjSize || ''}</div>
50
+ )}
51
+ {children}
52
+ </div>
53
+ </>
54
+ );
55
+ };
21
56
  function CclCard(props) {
22
57
  const { type, children, card, showEditor = false } = props;
23
58
  let url = '/';
@@ -40,53 +75,27 @@ function CclCard(props) {
40
75
  >
41
76
  {conditional_types.includes(type) ? (
42
77
  <>
43
- {(type === 'doc' || type === 'globalSearch') && (
78
+ {type === 'doc' && (
44
79
  <>
45
- {type === 'globalSearch' && (
46
- <Label ribbon="right" color="olive">
47
- {content_type}
48
- </Label>
49
- )}
50
- <div className="card-doc-title">
51
- {card?.file?.download ? (
52
- <a href={card.file.download}>{card?.title}</a>
53
- ) : (
54
- <Link to={url}>{card?.title}</Link>
55
- )}
56
- {card?.file?.download && showEditor && (
57
- <Link to={`${url}/edit`}>
58
- <Icon
59
- name={penSVG}
60
- size="15px"
61
- className="circled"
62
- title={'Edit'}
63
- />
64
- </Link>
65
- )}
66
- </div>
67
- <div className="card-doc-text">
68
- <div className="doc-description">{card?.description}</div>
69
- {card?.file && (
70
- <div className="card-doc-size">
71
- {mime.extension(card?.file?.['content-type']).toUpperCase()}{' '}
72
- {bytesToSize(card?.file?.size) || ''}
73
- </div>
74
- )}
80
+ <DocCard card={card} url={url} showEditor={showEditor}>
75
81
  {children}
76
- </div>
82
+ </DocCard>
83
+ </>
84
+ )}
85
+ {type === 'globalSearch' && (
86
+ <>
87
+ <Label ribbon="right" color="olive">
88
+ {content_type}
89
+ </Label>
90
+ <DocCard card={card} url={url} showEditor={showEditor}>
91
+ {children}
92
+ </DocCard>
77
93
  </>
78
94
  )}
79
95
  {(type === 'block' || type === 'threeColumns') && (
80
96
  <>
81
97
  <div className={`card-${type}-image`}>
82
- <img
83
- src={
84
- card?.image?.scales?.preview?.download ||
85
- card?.image?.download ||
86
- 'https://eu-copernicus.github.io/copernicus-component-library/assets/images/image_placeholder.jpg'
87
- }
88
- alt={card?.image?.alt || 'Placeholder'}
89
- />
98
+ <CardImage card={card} size={'preview'} />
90
99
  </div>
91
100
  <div className="card-text">
92
101
  <div className="card-title">
@@ -100,21 +109,14 @@ function CclCard(props) {
100
109
  {type === 'news' && (
101
110
  <>
102
111
  <div className="card-news-image">
103
- <img
104
- src={
105
- card?.image?.scales?.mini?.download ||
106
- card?.image?.download ||
107
- 'https://eu-copernicus.github.io/copernicus-component-library/assets/images/image_placeholder.jpg'
108
- }
109
- alt={card?.image?.alt || 'Placeholder'}
110
- />
112
+ <CardImage card={card} size={'mini'} />
111
113
  </div>
112
114
  <div className="card-news-text">
113
115
  <div className="card-news-title">
114
116
  <Link to={url}>{card?.title || 'Card default title'}</Link>
115
117
  </div>
116
118
  <div className="card-news-date">
117
- {new Date(card?.effective).toLocaleDateString()}
119
+ {new Date(card?.effective).toLocaleString()}
118
120
  </div>
119
121
  <p className="card-news-description">{card?.description}</p>
120
122
  </div>
@@ -129,19 +131,11 @@ function CclCard(props) {
129
131
  <div className="card-event-when">
130
132
  <FontAwesomeIcon icon={['far', 'calendar-alt']} />
131
133
  <div className="card-event-when-text">
132
- {card.whole_day ? (
133
- <When
134
- start={card.start}
135
- end={card.start}
136
- whole_day={card.whole_day}
137
- />
138
- ) : (
139
- <When
140
- start={card.start}
141
- end={card.end}
142
- whole_day={card.whole_day}
143
- />
144
- )}
134
+ <When
135
+ start={card.start}
136
+ end={card.whole_day ? card.start : card.end}
137
+ whole_day={card.whole_day}
138
+ />
145
139
  </div>
146
140
  </div>
147
141
  {card?.location ? (
@@ -164,14 +158,7 @@ function CclCard(props) {
164
158
  ) : (
165
159
  <>
166
160
  <div className="card-image">
167
- <img
168
- src={
169
- card?.image?.scales?.mini?.download ||
170
- card?.image?.download ||
171
- 'https://eu-copernicus.github.io/copernicus-component-library/assets/images/image_placeholder.jpg'
172
- }
173
- alt={card?.image?.alt || 'Placeholder'}
174
- />
161
+ <CardImage card={card} size={'mini'} />
175
162
  </div>
176
163
  <div className={'card-text'}>
177
164
  <div className="card-title">
@@ -55,7 +55,7 @@ function CclDownloadTable(props) {
55
55
 
56
56
  React.useEffect(() => {
57
57
  let fItems = prePackagedCollection.filter((item) =>
58
- item.resolution.toLowerCase().includes(filterText.toLocaleLowerCase()),
58
+ item?.resolution?.toLowerCase().includes(filterText.toLocaleLowerCase()),
59
59
  );
60
60
  if (filterText) {
61
61
  setCurrentPageItems(fItems.slice(0, 10));
@@ -231,7 +231,7 @@ function CclDownloadTable(props) {
231
231
  <span
232
232
  className={
233
233
  'tag tag-' +
234
- (dataset_file?.type.toLowerCase() || 'raster')
234
+ (dataset_file?.type?.toLowerCase() || 'raster')
235
235
  }
236
236
  >
237
237
  {dataset_file?.type || 'Raster'}
package/src/index.js CHANGED
@@ -40,7 +40,6 @@ const applyConfig = (config) => {
40
40
  ...config.contentTypesViews,
41
41
  DataSet: CLMSDatasetDetailView,
42
42
  'News Item': CLMSNewsItemView,
43
- TechnicalLibrary: CLMSDownloadableFileView,
44
43
  File: CLMSDownloadableFileView,
45
44
  'eea.meeting': CLMSMeetingView,
46
45
  'eea.meeting.subscribers': CLMSMeetingSubscribersView,