@eeacms/volto-clms-theme 1.0.47 → 1.0.48

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,8 +4,21 @@ 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.48](https://github.com/eea/volto-clms-theme/compare/1.0.47...1.0.48)
8
+
9
+ - dataset view [`38faa9d`](https://github.com/eea/volto-clms-theme/commit/38faa9d291e22c92a1c9049c7241555b2300f830)
10
+ - tab editor [`cfbcf74`](https://github.com/eea/volto-clms-theme/commit/cfbcf742b370cc665c689a2480a09d3b640dc318)
11
+ - remove required to description in proptypes [`9f6da1d`](https://github.com/eea/volto-clms-theme/commit/9f6da1d9c2125865c329a263d0a7b3e771baa287)
12
+ - map keys [`6be4246`](https://github.com/eea/volto-clms-theme/commit/6be424624a61f867f85b6d914811111405ebeb98)
13
+ - add resolutions to package.json volto-slate and react-slick [`54460ad`](https://github.com/eea/volto-clms-theme/commit/54460addb4c4644a03e6af2f94e5c75ee5154bf3)
14
+ - check if items is not null [`26b4399`](https://github.com/eea/volto-clms-theme/commit/26b439981ca354b0f372bdf09a112a58482f2d4b)
15
+ - fix subtab functionality and show subtab in editor [`ece4408`](https://github.com/eea/volto-clms-theme/commit/ece4408bd557a1d2f2868733e1560e2853da1822)
16
+
7
17
  #### [1.0.47](https://github.com/eea/volto-clms-theme/compare/1.0.46...1.0.47)
8
18
 
19
+ > 16 December 2021
20
+
21
+ - Develop [`#155`](https://github.com/eea/volto-clms-theme/pull/155)
9
22
  - use smaller images in Cards [`#147`](https://github.com/eea/volto-clms-theme/pull/147)
10
23
  - Demo modifications [`#154`](https://github.com/eea/volto-clms-theme/pull/154)
11
24
  - Geonetwork fields [`#153`](https://github.com/eea/volto-clms-theme/pull/153)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-clms-theme",
3
- "version": "1.0.47",
3
+ "version": "1.0.48",
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",
@@ -29,6 +29,10 @@
29
29
  "volto-form-block",
30
30
  "@eeacms/volto-taxonomy"
31
31
  ],
32
+ "resolutions": {
33
+ "volto-slate": "4.2.1",
34
+ "react-slick": "0.28.1"
35
+ },
32
36
  "dependencies": {
33
37
  "@eeacms/volto-tabs-block": "1.2.7",
34
38
  "@eeacms/volto-accordion-block": "3.4.7",
@@ -1,12 +1,14 @@
1
+ import './fontawesome';
2
+
3
+ import { NavLink, Route } from 'react-router-dom';
4
+
1
5
  import React from 'react';
2
- import { connect } from 'react-redux';
6
+ import { RenderBlocks } from '@plone/volto/components';
3
7
  import { compose } from 'redux';
8
+ import { connect } from 'react-redux';
9
+ import cx from 'classnames';
4
10
  import { withRouter } from 'react-router';
5
- import { RenderBlocks } from '@plone/volto/components';
6
11
  import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
7
- import './fontawesome';
8
- import cx from 'classnames';
9
- import { Route, NavLink } from 'react-router-dom';
10
12
 
11
13
  const CclVerticalTabsView = (props) => {
12
14
  const { metadata = {}, tabsList = [], ExtraComponent = null } = props;
@@ -47,10 +49,11 @@ const CclVerticalTabsView = (props) => {
47
49
  setActiveTab = () => {},
48
50
  } = props;
49
51
  const title = tabs[tab].title;
50
- const subTab = tabs[tab]?.subTab || false;
52
+ const subTab = tabs[tab]?.subTab?.subtab || false;
51
53
  const tabIndex = index + 1;
52
54
  const nextTabIndex = index + 2;
53
- const nextSubTab = tabs[tabsList[tabIndex]]?.subTab || false;
55
+ const nextSubTab =
56
+ tabs[tabsList[tabIndex]]?.subTab?.subtab || false;
54
57
  const defaultTitle = `Tab ${tabIndex}`;
55
58
  return (
56
59
  <div
@@ -62,41 +65,26 @@ const CclVerticalTabsView = (props) => {
62
65
  subTab && 'subcard',
63
66
  )}
64
67
  >
65
- {subTab === false && nextSubTab !== false ? (
66
- <NavLink
67
- to={'#tab' + nextTabIndex}
68
- className="collapsed"
69
- onClick={(e) => {
70
- if (activeTab !== tab) {
71
- setActiveTab(tab);
72
- }
73
- }}
74
- onKeyDown={() => {
75
- if (activeTab !== tab) {
76
- setActiveTab(tab);
77
- }
78
- }}
79
- >
80
- {title || defaultTitle}
81
- </NavLink>
82
- ) : (
83
- <NavLink
84
- to={'#tab' + tabIndex}
85
- className="collapsed"
86
- onClick={(e) => {
87
- if (activeTab !== tab) {
88
- setActiveTab(tab);
89
- }
90
- }}
91
- onKeyDown={() => {
92
- if (activeTab !== tab) {
93
- setActiveTab(tab);
94
- }
95
- }}
96
- >
97
- {title || defaultTitle}
98
- </NavLink>
99
- )}
68
+ <NavLink
69
+ to={
70
+ subTab === false && nextSubTab !== false
71
+ ? '#tab' + nextTabIndex
72
+ : '#tab' + tabIndex
73
+ }
74
+ className="collapsed"
75
+ onClick={(e) => {
76
+ if (activeTab !== tab) {
77
+ setActiveTab(tab);
78
+ }
79
+ }}
80
+ onKeyDown={() => {
81
+ if (activeTab !== tab) {
82
+ setActiveTab(tab);
83
+ }
84
+ }}
85
+ >
86
+ {title || defaultTitle}
87
+ </NavLink>
100
88
  </div>
101
89
  );
102
90
  })}
@@ -1,25 +1,28 @@
1
- import React from 'react';
2
- import { v4 as uuid } from 'uuid';
1
+ import './fontawesome';
2
+
3
+ import { FormFieldWrapper, Icon } from '@plone/volto/components';
4
+ import { Grid, Header } from 'semantic-ui-react';
5
+ import { faExternalLinkAlt, faIcons } from '@fortawesome/free-solid-svg-icons';
3
6
  import { omit, without } from 'lodash';
4
- import move from 'lodash-move';
5
- import { Icon, FormFieldWrapper } from '@plone/volto/components';
7
+
6
8
  import { DragDropList } from '@plone/volto/components';
7
- import { emptyTab } from '@eeacms/volto-tabs-block/helpers';
8
- import { StyleWrapperEdit } from '@eeacms/volto-block-style/StyleWrapper';
9
- import dragSVG from '@plone/volto/icons/drag.svg';
10
- import themeSVG from '@plone/volto/icons/theme.svg';
11
9
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
12
- import { faIcons, faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';
13
- import trashSVG from '@plone/volto/icons/delete.svg';
14
- import plusSVG from '@plone/volto/icons/circle-plus.svg';
15
- import leftMenuSVG from '@plone/volto/icons/nav.svg';
10
+ import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
11
+ import React from 'react';
16
12
  import { SidebarPopup } from '@plone/volto/components';
13
+ import { StyleWrapperEdit } from '@eeacms/volto-block-style/StyleWrapper';
14
+ import clearSVG from '@plone/volto/icons/clear.svg';
15
+ import dragSVG from '@plone/volto/icons/drag.svg';
16
+ import { emptyTab } from '@eeacms/volto-tabs-block/helpers';
17
17
  import { fontAwesomeSchema } from './fontAwesomeSchema';
18
+ import leftMenuSVG from '@plone/volto/icons/nav.svg';
19
+ import move from 'lodash-move';
20
+ import plusSVG from '@plone/volto/icons/circle-plus.svg';
21
+ import rightSVG from '@plone/volto/icons/right-key.svg';
18
22
  import { subTabSchema } from './subTabSchema';
19
- import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
20
- import clearSVG from '@plone/volto/icons/clear.svg';
21
- import './fontawesome';
22
- import { Header, Grid } from 'semantic-ui-react';
23
+ import themeSVG from '@plone/volto/icons/theme.svg';
24
+ import trashSVG from '@plone/volto/icons/delete.svg';
25
+ import { v4 as uuid } from 'uuid';
23
26
 
24
27
  export function moveColumn(formData, source, destination) {
25
28
  return {
@@ -47,7 +50,6 @@ const TabsWidget = (props) => {
47
50
  blocks[id],
48
51
  ]);
49
52
  const activeTabData = blocks[activeTabId] || {};
50
-
51
53
  return (
52
54
  <FormFieldWrapper
53
55
  {...props}
@@ -87,7 +89,18 @@ const TabsWidget = (props) => {
87
89
  <Icon name={dragSVG} size="18px" />
88
90
  </div>
89
91
  <div className="tab-area">
90
- <div className="label">
92
+ <div
93
+ className="label"
94
+ style={{
95
+ textOverflow: 'ellipsis',
96
+ whiteSpace: 'nowrap',
97
+ overflow: 'hidden',
98
+ maxWidth: '65%',
99
+ }}
100
+ >
101
+ {child.subTab?.subtab === true && (
102
+ <Icon name={rightSVG} size="18px" />
103
+ )}
91
104
  {child.title || `Tab ${index + 1}`}
92
105
  </div>
93
106
  <button
@@ -76,3 +76,8 @@ p.styled-slate {
76
76
  margin-top: -4rem;
77
77
  }
78
78
  }
79
+
80
+ div.tabs-block.edit a.item.active p.menu-item-text {
81
+ border-style: none none solid none;
82
+ font-weight: bold;
83
+ }
@@ -125,36 +125,30 @@ const CLMSDatasetDetailView = ({ content, token }) => {
125
125
  this dataset.
126
126
  <br />
127
127
  <br />
128
- {item.type === 'EEA' && (
129
- <a
130
- target="_blank"
131
- rel="noreferrer"
132
- href={
133
- 'https://sdi.eea.europa.eu/catalogue/srv/eng/catalog.search#/metadata/' +
134
- item.id
135
- }
136
- >
128
+ <a
129
+ target="_blank"
130
+ rel="noreferrer"
131
+ href={
132
+ item.type === 'EEA'
133
+ ? 'https://sdi.eea.europa.eu/catalogue/srv/eng/catalog.search#/metadata/' +
134
+ item.id
135
+ : 'https://land.copernicus.vgt.vito.be/geonetwork/srv/eng/catalog.search#/metadata/' +
136
+ item.id
137
+ }
138
+ >
139
+ {item.type === 'EEA' && (
137
140
  <FormattedMessage
138
141
  id="EEA Geonetwork element"
139
142
  defaultMessage="EEA Geonetwork element"
140
143
  />
141
- </a>
142
- )}
143
- {item.type === 'VITO' && (
144
- <a
145
- target="_blank"
146
- rel="noreferrer"
147
- href={
148
- 'https://land.copernicus.vgt.vito.be/geonetwork/srv/eng/catalog.search#/metadata/' +
149
- item.id
150
- }
151
- >
144
+ )}
145
+ {item.type === 'VITO' && (
152
146
  <FormattedMessage
153
147
  id="VITO Geonetwork element"
154
148
  defaultMessage="VITO Geonetwork element"
155
149
  />
156
- </a>
157
- )}
150
+ )}
151
+ </a>
158
152
  </div>
159
153
  <CclButton
160
154
  onClick={() => {
@@ -4,30 +4,24 @@ import BoundingBoxComponent from './BoundingBoxComponent';
4
4
  import CclButton from '@eeacms/volto-clms-theme/components/CclButton/CclButton';
5
5
  import ContactComponent from './ContactComponent';
6
6
  import DistributionInfoComponent from './DistributionInfoComponent';
7
+ import { Label } from 'semantic-ui-react';
7
8
  import React from 'react';
8
9
  import { StringToHTML } from '@eeacms/volto-clms-theme/components/CclUtils';
9
10
 
10
11
  const MetadataContent = (data) => {
11
12
  return (
12
13
  <>
13
- {data.geonetwork_identifiers?.items.map((item) => {
14
- return item.type === 'EEA' ? (
14
+ {data?.geonetwork_identifiers?.items.map((item, key) => {
15
+ return (
15
16
  <CclButton
17
+ key={key}
16
18
  className="ccl-button ccl-button--default download-dataset-metadata"
17
19
  url={
18
- 'https://sdi.eea.europa.eu/catalogue/srv/eng/catalog.search#/metadata/' +
19
- item.id
20
- }
21
- download={true}
22
- >
23
- Download metadata: {item.title}
24
- </CclButton>
25
- ) : (
26
- <CclButton
27
- className="ccl-button ccl-button--default download-dataset-metadata"
28
- url={
29
- 'https://land.copernicus.vgt.vito.be/geonetwork/srv/eng/catalog.search#/metadata/' +
30
- item.id
20
+ item.type === 'EEA'
21
+ ? 'https://sdi.eea.europa.eu/catalogue/srv/eng/catalog.search#/metadata/' +
22
+ item.id
23
+ : 'https://land.copernicus.vgt.vito.be/geonetwork/srv/eng/catalog.search#/metadata/' +
24
+ item.id
31
25
  }
32
26
  download={true}
33
27
  >
@@ -38,170 +32,183 @@ const MetadataContent = (data) => {
38
32
 
39
33
  <CclInfoContainer>
40
34
  <h2>Data identification</h2>
41
- {data.dataResourceTitle && (
35
+ {data?.dataResourceTitle && (
42
36
  <CclInfoDescription
43
37
  title="Resource title"
44
38
  tooltip="Name by which the cited resource is known"
45
- description={data.dataResourceTitle}
39
+ description={data?.dataResourceTitle}
46
40
  />
47
41
  )}
48
- {data.resourceEffective && (
42
+ {data?.resourceEffective && (
49
43
  <CclInfoDescription
50
44
  title="Date of publication"
51
45
  tooltip=""
52
- description={data.resourceEffective}
46
+ description={new Date(data?.resourceEffective).toLocaleDateString()}
53
47
  />
54
48
  )}
55
- {data.resourceModified && (
49
+ {data?.resourceModified && (
56
50
  <CclInfoDescription
57
51
  title="Revision date"
58
52
  tooltip=""
59
- description={data.resourceModified}
53
+ description={new Date(data?.resourceModified).toLocaleDateString()}
60
54
  />
61
55
  )}
62
56
  <CclInfoDescription
63
57
  title="Resource abstract"
64
58
  tooltip="Brief narrative summary of the content of the resource(s) with coverage, main attributes, data sources, important of the work, etc."
65
59
  description={
66
- <StringToHTML string={data.dataResourceAbstract?.data || ''} />
60
+ <StringToHTML string={data?.dataResourceAbstract?.data || ''} />
67
61
  }
68
62
  />
69
- {data.keywords?.length > 0 && (
63
+ {data?.keywords && data?.keywords?.length > 0 && (
70
64
  <CclInfoDescription
71
65
  title="Keywords"
72
66
  tooltip=""
73
- description={data.keywords.map((keyword) => keyword).join(', ')}
67
+ description={data?.keywords.map((keyword) => {
68
+ return <Label color="olive">{keyword}</Label>;
69
+ })}
74
70
  />
75
71
  )}
76
- {data.geographicCoverage && (
72
+ {data?.geographicCoverage && (
77
73
  <CclInfoDescription
78
74
  title="Geographic coverage"
79
75
  tooltip=""
80
- description={JSON.stringify(data.geographicCoverage)}
76
+ description={JSON.stringify(data?.geographicCoverage)}
81
77
  />
82
78
  )}
83
- {data.accessAndUseLimitationPublic_line && (
79
+ {data?.accessAndUseLimitationPublic_line && (
84
80
  <CclInfoDescription
85
81
  title="Limitation of public access"
86
82
  tooltip=""
87
- description={data.accessAndUseLimitationPublic_line}
83
+ description={data?.accessAndUseLimitationPublic_line}
88
84
  />
89
85
  )}
90
86
  <CclInfoDescription
91
87
  title="Conditions applying to access and use"
92
88
  tooltip=""
93
89
  description={
94
- <StringToHTML string={data.accessAndUseConstraints?.data || ''} />
90
+ <StringToHTML string={data?.accessAndUseConstraints?.data || ''} />
95
91
  }
96
92
  />
97
93
  <CclInfoDescription
98
94
  title="Spatial Resolution"
99
95
  tooltip=""
100
- description={
101
- <StringToHTML string={data.qualitySpatialResolution?.data || ''} />
102
- }
96
+ description={data?.qualitySpatialResolution_line}
103
97
  />
104
- {data.classificationTopicCategory && (
98
+ {data?.classificationTopicCategory && (
105
99
  <CclInfoDescription
106
100
  title="Topic of Category"
107
101
  tooltip=""
108
102
  description={
109
- data.classificationTopicCategory &&
110
- data.classificationTopicCategory.map((topic) => topic).join(', ')
103
+ data?.classificationTopicCategory &&
104
+ data?.classificationTopicCategory.map((topic) => {
105
+ return <Label color="olive">{topic.title}</Label>;
106
+ })
111
107
  }
112
108
  />
113
109
  )}
114
- {data.geographicBoundingBox?.items?.length > 0 && (
110
+ {data?.geographicBoundingBox?.items?.length > 0 && (
115
111
  <CclInfoDescription
116
112
  title="Bounding Boxes"
117
113
  tooltip=""
118
- description={data.geographicBoundingBox?.items.map((bbox) => {
119
- return <BoundingBoxComponent bbox={bbox} />;
114
+ description={data?.geographicBoundingBox?.items.map((bbox, key) => {
115
+ return <BoundingBoxComponent key={key} bbox={bbox} />;
120
116
  })}
121
117
  />
122
118
  )}
123
- {data.temporalCoverage && (
119
+ {data?.temporalCoverage && (
124
120
  <CclInfoDescription
125
121
  title="Temporal Extent"
126
122
  tooltip=""
127
123
  description={
128
- data.temporalCoverage &&
129
- data.temporalCoverage.map((year) => year).join(', ')
124
+ data?.temporalCoverage &&
125
+ data?.temporalCoverage.map((year) => {
126
+ return <Label color="olive">{year}</Label>;
127
+ })
130
128
  }
131
129
  />
132
130
  )}
133
131
  </CclInfoContainer>
134
- {data.dataResourceType && (
132
+ {data?.dataResourceType && (
135
133
  <CclInfoContainer>
136
134
  <h2>Hierarchy Level</h2>
137
135
  <CclInfoDescription
138
136
  title="Resource Type"
139
137
  tooltip=""
140
- description={data.dataResourceType}
141
- />
142
- </CclInfoContainer>
143
- )}
144
- {data.responsiblePartyWithRole?.items?.length > 0 && (
145
- <CclInfoContainer>
146
- <h2>Contacts</h2>
147
- <CclInfoDescription
148
- title="Responsible Party with Role"
149
- tooltip=""
150
- description={data.responsiblePartyWithRole?.items.map((item) => {
151
- return <ContactComponent contact={item} />;
152
- })}
153
- />
154
- </CclInfoContainer>
155
- )}
156
- {data.coordinateReferenceSystemList.length > 0 && (
157
- <CclInfoContainer>
158
- <h2>Reference system info</h2>
159
- <CclInfoDescription
160
- title="Coordinate Reference System"
161
- tooltip="CRS of the resource"
162
- description={
163
- data.coordinateReferenceSystemList &&
164
- data.coordinateReferenceSystemList
165
- .map((reference) => reference)
166
- .join(', ')
167
- }
138
+ description={data?.dataResourceType}
168
139
  />
169
140
  </CclInfoContainer>
170
141
  )}
142
+ {data?.responsiblePartyWithRole?.items &&
143
+ data?.responsiblePartyWithRole?.items?.length > 0 && (
144
+ <CclInfoContainer>
145
+ <h2>Contacts</h2>
146
+ <CclInfoDescription
147
+ title="Responsible Party with Role"
148
+ tooltip=""
149
+ description={data?.responsiblePartyWithRole?.items.map(
150
+ (item, key) => {
151
+ return <ContactComponent key={key} contact={item} />;
152
+ },
153
+ )}
154
+ />
155
+ </CclInfoContainer>
156
+ )}
157
+ {data?.coordinateReferenceSystemList &&
158
+ data?.coordinateReferenceSystemList.length > 0 && (
159
+ <CclInfoContainer>
160
+ <h2>Reference system info</h2>
161
+ <CclInfoDescription
162
+ title="Coordinate Reference System"
163
+ tooltip="CRS of the resource"
164
+ description={
165
+ data?.coordinateReferenceSystemList &&
166
+ data?.coordinateReferenceSystemList.map((reference) => {
167
+ return <Label color="olive">{reference}</Label>;
168
+ })
169
+ }
170
+ />
171
+ </CclInfoContainer>
172
+ )}
171
173
  <CclInfoContainer>
172
174
  <h2>Data quality info</h2>
173
175
  <CclInfoDescription
174
176
  title="Specification"
175
177
  tooltip="A citation of the implementing rules adopted under Article 7(1) of Directive 2007/2/EC or other specification to which a particular resource conforms"
176
178
  description={
177
- <StringToHTML string={data.conformitySpecification?.data} />
179
+ <StringToHTML string={data?.conformitySpecification?.data} />
178
180
  }
179
181
  />
180
- {data.conformityPass && (
182
+ {data?.conformityPass && (
181
183
  <CclInfoDescription
182
184
  title="Pass"
183
185
  tooltip=""
184
- description={data.conformityPass}
186
+ description={data?.conformityPass}
185
187
  />
186
188
  )}
187
189
  <CclInfoDescription
188
190
  title="Lineage"
189
191
  tooltip="General explanation of the data produce knowledge's about the lineage of a dataset"
190
- description={<StringToHTML string={data.qualityLineage?.data} />}
192
+ description={<StringToHTML string={data?.qualityLineage?.data} />}
191
193
  />
192
194
  </CclInfoContainer>
193
- {data.distributionInfo?.items?.length > 0 && (
194
- <CclInfoContainer>
195
- <h2>Distribution info</h2>
196
- <CclInfoDescription
197
- title="Resource Locator and Services"
198
- tooltip=""
199
- description={data.distributionInfo?.items.map((resource) => {
200
- return <DistributionInfoComponent resource={resource} />;
201
- })}
202
- />
203
- </CclInfoContainer>
204
- )}
195
+ {data?.distributionInfo?.items &&
196
+ data?.distributionInfo?.items?.length > 0 && (
197
+ <CclInfoContainer>
198
+ <h2>Distribution info</h2>
199
+ <CclInfoDescription
200
+ title="Resource Locator and Services"
201
+ tooltip=""
202
+ description={data?.distributionInfo?.items.map(
203
+ (resource, key) => {
204
+ return (
205
+ <DistributionInfoComponent key={key} resource={resource} />
206
+ );
207
+ },
208
+ )}
209
+ />
210
+ </CclInfoContainer>
211
+ )}
205
212
  </>
206
213
  );
207
214
  };
@@ -34,7 +34,6 @@ function CclInfoDescription({ title, description, tooltip }) {
34
34
 
35
35
  CclInfoDescription.propTypes = {
36
36
  title: PropTypes.string.isRequired,
37
- description: PropTypes.oneOfType([PropTypes.string, PropTypes.node])
38
- .isRequired,
37
+ description: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
39
38
  };
40
39
  export default CclInfoDescription;
@@ -1,28 +1,25 @@
1
- import React from 'react';
1
+ import { NavLink } from 'react-router-dom';
2
2
  import PropTypes from 'prop-types';
3
+ import React from 'react';
4
+ import cx from 'classnames';
3
5
 
4
6
  function CclTab(props) {
5
- let { activeTab, tabTitle, onClick } = props;
7
+ let { activeTab, tabTitle, onClick, tabId } = props;
6
8
 
7
9
  function onTabClick() {
8
- onClick(tabTitle);
9
- }
10
-
11
- let className = 'card';
12
-
13
- if (activeTab === tabTitle) {
14
- className += ' active';
10
+ onClick(tabId);
15
11
  }
16
12
 
17
13
  return (
18
14
  <div
19
- className={className}
15
+ className={cx('card', activeTab === tabId && 'active')}
20
16
  onClick={onTabClick}
21
17
  onKeyDown={onTabClick}
22
18
  tabIndex="0"
23
19
  role="button"
20
+ id={tabId}
24
21
  >
25
- <li className="collapsed">{tabTitle}</li>
22
+ <NavLink to={'#' + tabId}>{tabTitle}</NavLink>
26
23
  </div>
27
24
  );
28
25
  }
@@ -1,7 +1,9 @@
1
+ import './CclTabs.less';
2
+
1
3
  import React, { useState } from 'react';
2
- import PropTypes from 'prop-types';
4
+
3
5
  import CclTab from './CclTab';
4
- import './CclTabs.less';
6
+ import PropTypes from 'prop-types';
5
7
 
6
8
  /**
7
9
  * Tabs component documentation.
@@ -20,30 +22,43 @@ import './CclTabs.less';
20
22
  */
21
23
  const CclTabs = (props) => {
22
24
  let { children } = props;
23
- let [activeTab, setActiveTab] = useState(props.children[0].props.tabTitle);
25
+ let [activeTab, setActiveTab] = useState(props.children[0].props.tabId || '');
24
26
 
25
27
  function onClickTabItem(tab) {
26
28
  setActiveTab(tab);
27
29
  }
30
+ React.useEffect(() => {
31
+ const hash = window.location.hash.substring(1) || '';
32
+ if (hash) {
33
+ setActiveTab(hash);
34
+ } else {
35
+ setActiveTab(
36
+ children
37
+ .filter((item) => !!item.props.tabTitle)[0]
38
+ .props?.tabTitle?.replace(' ', ''),
39
+ );
40
+ }
41
+ }, [children]);
28
42
 
29
43
  return (
30
44
  <div className="ccl-container-flex">
31
45
  <div className="left-content cont-w-25">
32
- <ul className="left-menu">
46
+ <nav className="left-menu">
33
47
  {children
34
48
  .filter((item) => !!item.props.tabTitle)
35
- .map((child) => {
49
+ .map((child, key) => {
36
50
  const { tabTitle } = child.props;
37
51
  return (
38
52
  <CclTab
39
53
  activeTab={activeTab}
40
- key={tabTitle}
54
+ key={key}
55
+ tabId={tabTitle.replace(' ', '')}
41
56
  tabTitle={tabTitle}
42
57
  onClick={onClickTabItem}
43
58
  />
44
59
  );
45
60
  })}
46
- </ul>
61
+ </nav>
47
62
 
48
63
  {/* Check if underPanel element exist and render */}
49
64
  {children
@@ -59,7 +74,7 @@ const CclTabs = (props) => {
59
74
  {children
60
75
  .filter((item) => !!item.props.tabTitle)
61
76
  .map((child, index) => {
62
- return child.props.tabTitle !== activeTab ? (
77
+ return child.props.tabTitle.replace(' ', '') !== activeTab ? (
63
78
  <div key={index} className="deactivate-content">
64
79
  {child.props.children}
65
80
  </div>