@eeacms/volto-clms-theme 1.1.208 → 1.1.210
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 +18 -0
- package/package.json +1 -1
- package/src/components/Blocks/CclRelatedListingBlock/CclRelatedListingEdit.jsx +1 -1
- package/src/components/CLMSDownloadCartView/Fields/TimeseriesPicker.jsx +71 -16
- package/src/components/CLMSDownloadCartView/cart-table.less +47 -0
- package/src/components/Widgets/OrderDocumentsWidget.jsx +43 -27
- package/src/components/Widgets/OrderDocumentsWidget.test.jsx +36 -5
- package/theme/site/extras/order-documents-widget.less +24 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ 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.1.210](https://github.com/eea/volto-clms-theme/compare/1.1.209...1.1.210) - 10 February 2025
|
|
8
|
+
|
|
9
|
+
#### :hammer_and_wrench: Others
|
|
10
|
+
|
|
11
|
+
- CLMS-279774 (feat): Improved calendar selection [Urkorue - [`ab4c043`](https://github.com/eea/volto-clms-theme/commit/ab4c043e4a81c90bdcbdbdd0bf707da17037c34e)]
|
|
12
|
+
### [1.1.209](https://github.com/eea/volto-clms-theme/compare/1.1.208...1.1.209) - 30 January 2025
|
|
13
|
+
|
|
14
|
+
#### :rocket: New Features
|
|
15
|
+
|
|
16
|
+
- feat: Improve the order of documents in the technical library of the product/product group - refs #283044 [ana-oprea - [`6feba8a`](https://github.com/eea/volto-clms-theme/commit/6feba8a82ec84a6186cee3da719de7b10a356947)]
|
|
17
|
+
|
|
18
|
+
#### :bug: Bug Fixes
|
|
19
|
+
|
|
20
|
+
- fix(test): modify widget tests for dataset and add test for product content type [ana-oprea - [`d7534cc`](https://github.com/eea/volto-clms-theme/commit/d7534cc4f26e77bcfcc91d3988f4f974ec3116f4)]
|
|
21
|
+
|
|
22
|
+
#### :hammer_and_wrench: Others
|
|
23
|
+
|
|
24
|
+
- fix eslint [ana-oprea - [`785ccf8`](https://github.com/eea/volto-clms-theme/commit/785ccf86f60e3275b7f392fb3b47f0eb6845f7b2)]
|
|
7
25
|
### [1.1.208](https://github.com/eea/volto-clms-theme/compare/1.1.207...1.1.208) - 13 January 2025
|
|
8
26
|
|
|
9
27
|
#### :hammer_and_wrench: Others
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@ const CclRelatedListingEdit = (props) => {
|
|
|
27
27
|
(variation) => variation.id === data.variation,
|
|
28
28
|
);
|
|
29
29
|
TemplateView = theVariation?.template;
|
|
30
|
-
template_id = theVariation.
|
|
30
|
+
template_id = theVariation.templateID;
|
|
31
31
|
} else {
|
|
32
32
|
TemplateView = defaultVariation.template;
|
|
33
33
|
template_id = defaultVariation.id;
|
|
@@ -79,7 +79,7 @@ export const TimeseriesPicker = (props) => {
|
|
|
79
79
|
<DatePicker
|
|
80
80
|
id="start_date"
|
|
81
81
|
inline
|
|
82
|
-
selectsRange
|
|
82
|
+
selectsRange={download_limit_temporal_extent < 360 ? true : false}
|
|
83
83
|
className="datepicker"
|
|
84
84
|
minDate={new Date(start)}
|
|
85
85
|
maxDate={new Date(end)}
|
|
@@ -87,14 +87,38 @@ export const TimeseriesPicker = (props) => {
|
|
|
87
87
|
endDate={item?.TemporalFilter?.EndDate}
|
|
88
88
|
// selectsStart
|
|
89
89
|
onChange={(e) => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
if (download_limit_temporal_extent < 360) {
|
|
91
|
+
if (download_limit_temporal_extent > 180 && e[1]) {
|
|
92
|
+
e[1].setMonth(e[1].getMonth() + 1);
|
|
93
|
+
e[1].setDate(e[1].getDate() - 1);
|
|
94
|
+
}
|
|
95
|
+
item.TemporalFilter = {
|
|
96
|
+
StartDate: e[0],
|
|
97
|
+
EndDate: e[1],
|
|
98
|
+
};
|
|
99
|
+
setStartValue(e[0]);
|
|
100
|
+
setEndValue(e[1]);
|
|
101
|
+
} else {
|
|
102
|
+
let e2 = new Date(e);
|
|
103
|
+
e2.setDate(e2.getDate() + 364);
|
|
104
|
+
item.TemporalFilter = {
|
|
105
|
+
StartDate: e,
|
|
106
|
+
EndDate: e2,
|
|
107
|
+
};
|
|
108
|
+
setStartValue(e);
|
|
109
|
+
setEndValue(e2);
|
|
110
|
+
}
|
|
96
111
|
}}
|
|
97
112
|
dateFormat="dd.MM.yyyy"
|
|
113
|
+
showMonthYearPicker={
|
|
114
|
+
download_limit_temporal_extent > 180 &&
|
|
115
|
+
download_limit_temporal_extent < 360
|
|
116
|
+
? true
|
|
117
|
+
: false
|
|
118
|
+
}
|
|
119
|
+
showYearPicker={
|
|
120
|
+
download_limit_temporal_extent >= 360 ? true : false
|
|
121
|
+
}
|
|
98
122
|
calendarStartDay={1}
|
|
99
123
|
popperPlacement="top"
|
|
100
124
|
dropdownMode="select"
|
|
@@ -114,21 +138,52 @@ export const TimeseriesPicker = (props) => {
|
|
|
114
138
|
</span>
|
|
115
139
|
)}
|
|
116
140
|
<br />
|
|
117
|
-
|
|
141
|
+
{download_limit_temporal_extent < 180 && (
|
|
142
|
+
<span>Click the start and end dates, and then apply.</span>
|
|
143
|
+
)}
|
|
144
|
+
{download_limit_temporal_extent > 180 &&
|
|
145
|
+
download_limit_temporal_extent < 360 && (
|
|
146
|
+
<span>Click the start and end months, and then apply.</span>
|
|
147
|
+
)}
|
|
148
|
+
{download_limit_temporal_extent > 360 && (
|
|
149
|
+
<span>Click the year, and then apply.</span>
|
|
150
|
+
)}
|
|
118
151
|
{(!startValue ||
|
|
119
152
|
!endValue ||
|
|
120
153
|
!isValidDateRange({
|
|
121
154
|
start: startValue,
|
|
122
155
|
end: endValue,
|
|
123
156
|
limit: download_limit_temporal_extent,
|
|
124
|
-
})) &&
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
157
|
+
})) &&
|
|
158
|
+
download_limit_temporal_extent < 180 && (
|
|
159
|
+
<span>
|
|
160
|
+
{' '}
|
|
161
|
+
Allowed time range of {
|
|
162
|
+
download_limit_temporal_extent
|
|
163
|
+
} days.{' '}
|
|
164
|
+
</span>
|
|
165
|
+
)}
|
|
166
|
+
{(!startValue ||
|
|
167
|
+
!endValue ||
|
|
168
|
+
!isValidDateRange({
|
|
169
|
+
start: startValue,
|
|
170
|
+
end: endValue,
|
|
171
|
+
limit: download_limit_temporal_extent,
|
|
172
|
+
})) &&
|
|
173
|
+
download_limit_temporal_extent > 180 &&
|
|
174
|
+
download_limit_temporal_extent < 360 && (
|
|
175
|
+
<span> Allowed time range of 6 months. </span>
|
|
176
|
+
)}
|
|
177
|
+
{(!startValue ||
|
|
178
|
+
!endValue ||
|
|
179
|
+
!isValidDateRange({
|
|
180
|
+
start: startValue,
|
|
181
|
+
end: endValue,
|
|
182
|
+
limit: download_limit_temporal_extent,
|
|
183
|
+
})) &&
|
|
184
|
+
download_limit_temporal_extent > 360 && (
|
|
185
|
+
<span> Allowed time range of 1 year. </span>
|
|
186
|
+
)}
|
|
132
187
|
<CclButton
|
|
133
188
|
isButton={true}
|
|
134
189
|
mode={'filled'}
|
|
@@ -121,3 +121,50 @@ div.mb-2 {
|
|
|
121
121
|
margin-bottom: 1rem !important;
|
|
122
122
|
margin-inline: 2rem !important;
|
|
123
123
|
}
|
|
124
|
+
|
|
125
|
+
// .react-datepicker__month{
|
|
126
|
+
// display: none;
|
|
127
|
+
// }
|
|
128
|
+
|
|
129
|
+
// .react-datepicker__day-names{
|
|
130
|
+
// display: none;
|
|
131
|
+
// }
|
|
132
|
+
|
|
133
|
+
// .react-datepicker__month-container{
|
|
134
|
+
// width: 100%;
|
|
135
|
+
// }
|
|
136
|
+
|
|
137
|
+
.react-datepicker__month-text--in-range {
|
|
138
|
+
background-color: #7c8921 !important;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.react-datepicker__month-text--in-selecting-range {
|
|
142
|
+
background-color: #7c8921 !important;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.react-datepicker__month-text--range-start {
|
|
146
|
+
background-color: rgba(160, 177, 40, 0.2) !important;
|
|
147
|
+
color: black;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.react-datepicker__month-text--range-end {
|
|
151
|
+
background-color: rgba(160, 177, 40, 0.2) !important;
|
|
152
|
+
color: black;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.react-datepicker__year-text--in-range {
|
|
156
|
+
background-color: #7c8921 !important;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.react-datepicker-year-header {
|
|
160
|
+
width: 100%;
|
|
161
|
+
color: white;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.react-datepicker__year-wrapper {
|
|
165
|
+
max-width: 260px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.react-datepicker__month-container {
|
|
169
|
+
width: 100%;
|
|
170
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useCallback, useMemo } from 'react';
|
|
1
|
+
import React, { useEffect, useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { useLocation } from 'react-router-dom';
|
|
4
4
|
import { useDispatch, useSelector } from 'react-redux';
|
|
@@ -41,34 +41,39 @@ const DocumentItem = React.memo(({ item, provided }) => (
|
|
|
41
41
|
const OrderDocumentsWidget = (props) => {
|
|
42
42
|
const { id, formData, onChange, value } = props;
|
|
43
43
|
const UID = formData?.UID;
|
|
44
|
+
const contentType = formData?.['@type'] || undefined;
|
|
44
45
|
const location = useLocation();
|
|
45
46
|
const dispatch = useDispatch();
|
|
46
47
|
const searchSubrequests = useSelector((state) => state.search.subrequests);
|
|
47
|
-
const [documentsList, setDocumentsList] =
|
|
48
|
-
const [isLoading, setIsLoading] =
|
|
48
|
+
const [documentsList, setDocumentsList] = useState([]);
|
|
49
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
50
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
49
51
|
|
|
50
52
|
const fetchDocuments = useCallback(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const sort_order = ['ascending', 'ascending'];
|
|
53
|
+
const sort_on = ['documentation_sorting', 'sortable_title'];
|
|
54
|
+
const sort_order = ['ascending', 'ascending'];
|
|
54
55
|
|
|
56
|
+
if (UID) {
|
|
55
57
|
setIsLoading(true);
|
|
58
|
+
const searchParams = {
|
|
59
|
+
portal_type: 'TechnicalLibrary',
|
|
60
|
+
path: 'en/technical-library',
|
|
61
|
+
sort_on: sort_on,
|
|
62
|
+
sort_order: sort_order,
|
|
63
|
+
b_size: 99999,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
if (contentType === 'DataSet') {
|
|
67
|
+
searchParams.associated_datasets = UID;
|
|
68
|
+
} else if (contentType === 'Product') {
|
|
69
|
+
searchParams.associated_products = UID;
|
|
70
|
+
}
|
|
71
|
+
|
|
56
72
|
dispatch(
|
|
57
|
-
searchContent(
|
|
58
|
-
'en/technical-library',
|
|
59
|
-
{
|
|
60
|
-
portal_type: 'TechnicalLibrary',
|
|
61
|
-
path: 'en/technical-library',
|
|
62
|
-
associated_datasets: UID,
|
|
63
|
-
sort_on: sort_on,
|
|
64
|
-
sort_order: sort_order,
|
|
65
|
-
b_size: 99999,
|
|
66
|
-
},
|
|
67
|
-
id,
|
|
68
|
-
),
|
|
73
|
+
searchContent('en/technical-library', searchParams, id),
|
|
69
74
|
).finally(() => setIsLoading(false));
|
|
70
75
|
}
|
|
71
|
-
}, [id, UID, dispatch]);
|
|
76
|
+
}, [id, UID, contentType, dispatch]);
|
|
72
77
|
|
|
73
78
|
const handleDragEnd = useCallback(
|
|
74
79
|
(result) => {
|
|
@@ -86,8 +91,8 @@ const OrderDocumentsWidget = (props) => {
|
|
|
86
91
|
[documentsList, onChange, id],
|
|
87
92
|
);
|
|
88
93
|
|
|
89
|
-
const memoizedList = useMemo(
|
|
90
|
-
|
|
94
|
+
const memoizedList = useMemo(() => {
|
|
95
|
+
return (
|
|
91
96
|
<DragDropContext onDragEnd={handleDragEnd}>
|
|
92
97
|
<Droppable droppableId="documents">
|
|
93
98
|
{(provided) => (
|
|
@@ -110,9 +115,8 @@ const OrderDocumentsWidget = (props) => {
|
|
|
110
115
|
)}
|
|
111
116
|
</Droppable>
|
|
112
117
|
</DragDropContext>
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
);
|
|
118
|
+
);
|
|
119
|
+
}, [documentsList, handleDragEnd]);
|
|
116
120
|
|
|
117
121
|
useEffect(() => {
|
|
118
122
|
fetchDocuments();
|
|
@@ -130,9 +134,9 @@ const OrderDocumentsWidget = (props) => {
|
|
|
130
134
|
const newItems = receivedDocumentsList.filter(
|
|
131
135
|
(item) => !value.items.some((item2) => item2.id === item.id),
|
|
132
136
|
);
|
|
133
|
-
setDocumentsList([...value
|
|
137
|
+
setDocumentsList([...value?.items, ...newItems]);
|
|
134
138
|
} else {
|
|
135
|
-
setDocumentsList(value
|
|
139
|
+
setDocumentsList(value?.items);
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
}, [searchSubrequests, id, value]);
|
|
@@ -143,6 +147,18 @@ const OrderDocumentsWidget = (props) => {
|
|
|
143
147
|
draggable={true}
|
|
144
148
|
className="drag-drop-list-widget"
|
|
145
149
|
>
|
|
150
|
+
{contentType === 'Product' && (
|
|
151
|
+
<Button
|
|
152
|
+
basic
|
|
153
|
+
size="small"
|
|
154
|
+
type="button"
|
|
155
|
+
onClick={() => setIsVisible((prev) => !prev)}
|
|
156
|
+
aria-label="Toggle document list visibility"
|
|
157
|
+
className="order-docs-button"
|
|
158
|
+
>
|
|
159
|
+
{isVisible ? 'Hide' : 'Show'}
|
|
160
|
+
</Button>
|
|
161
|
+
)}
|
|
146
162
|
<div className="order-documents-area">
|
|
147
163
|
<div className="documents-list-header">
|
|
148
164
|
<div>Technical Document Title</div>
|
|
@@ -150,7 +166,7 @@ const OrderDocumentsWidget = (props) => {
|
|
|
150
166
|
{isLoading ? (
|
|
151
167
|
<div className="loading-documents">Loading documents...</div>
|
|
152
168
|
) : (
|
|
153
|
-
memoizedList
|
|
169
|
+
(contentType === 'DataSet' || isVisible) && memoizedList
|
|
154
170
|
)}
|
|
155
171
|
</div>
|
|
156
172
|
</FormFieldWrapper>
|
|
@@ -55,7 +55,7 @@ describe('OrderDocumentsWidget', () => {
|
|
|
55
55
|
<MemoryRouter>
|
|
56
56
|
<OrderDocumentsWidget
|
|
57
57
|
id="testId"
|
|
58
|
-
formData={{ UID: 'someUID' }}
|
|
58
|
+
formData={{ UID: 'someUID', '@type': 'DataSet' }}
|
|
59
59
|
onChange={mockOnChange}
|
|
60
60
|
value={{ items: [] }}
|
|
61
61
|
/>
|
|
@@ -80,7 +80,7 @@ describe('OrderDocumentsWidget', () => {
|
|
|
80
80
|
id="testId"
|
|
81
81
|
formData={{ UID: 'someUID' }}
|
|
82
82
|
onChange={mockOnChange}
|
|
83
|
-
value={{ items: [] }}
|
|
83
|
+
value={{ items: [], '@type': 'DataSet' }}
|
|
84
84
|
/>
|
|
85
85
|
</MemoryRouter>
|
|
86
86
|
</Provider>,
|
|
@@ -96,7 +96,7 @@ describe('OrderDocumentsWidget', () => {
|
|
|
96
96
|
<MemoryRouter>
|
|
97
97
|
<OrderDocumentsWidget
|
|
98
98
|
id="testId"
|
|
99
|
-
formData={{ UID: 'someUID' }}
|
|
99
|
+
formData={{ UID: 'someUID', '@type': 'DataSet' }}
|
|
100
100
|
onChange={mockOnChange}
|
|
101
101
|
value={{
|
|
102
102
|
items: [
|
|
@@ -151,7 +151,7 @@ describe('OrderDocumentsWidget', () => {
|
|
|
151
151
|
<MemoryRouter>
|
|
152
152
|
<OrderDocumentsWidget
|
|
153
153
|
id="testId"
|
|
154
|
-
formData={{ UID: 'someUID' }}
|
|
154
|
+
formData={{ UID: 'someUID', '@type': 'DataSet' }}
|
|
155
155
|
onChange={mockOnChange}
|
|
156
156
|
value={{ items: [] }}
|
|
157
157
|
/>
|
|
@@ -190,7 +190,7 @@ describe('OrderDocumentsWidget', () => {
|
|
|
190
190
|
<MemoryRouter>
|
|
191
191
|
<OrderDocumentsWidget
|
|
192
192
|
id="testId"
|
|
193
|
-
formData={{ UID: 'someUID' }}
|
|
193
|
+
formData={{ UID: 'someUID', '@type': 'DataSet' }}
|
|
194
194
|
onChange={mockOnChange}
|
|
195
195
|
value={{ items: [] }}
|
|
196
196
|
/>
|
|
@@ -206,4 +206,35 @@ describe('OrderDocumentsWidget', () => {
|
|
|
206
206
|
expect(screen.getByText('Document 3')).toBeInTheDocument();
|
|
207
207
|
expect(screen.getByText('Document 4')).toBeInTheDocument();
|
|
208
208
|
});
|
|
209
|
+
|
|
210
|
+
it('renders the widget with documents', async () => {
|
|
211
|
+
act(() => {
|
|
212
|
+
render(
|
|
213
|
+
<Provider store={store}>
|
|
214
|
+
<MemoryRouter>
|
|
215
|
+
<OrderDocumentsWidget
|
|
216
|
+
id="testId"
|
|
217
|
+
formData={{ UID: 'someUID', '@type': 'Product' }}
|
|
218
|
+
onChange={mockOnChange}
|
|
219
|
+
value={{ items: [] }}
|
|
220
|
+
/>
|
|
221
|
+
</MemoryRouter>
|
|
222
|
+
</Provider>,
|
|
223
|
+
);
|
|
224
|
+
});
|
|
225
|
+
await Promise.resolve();
|
|
226
|
+
|
|
227
|
+
expect(screen.getByText('Show')).toBeInTheDocument();
|
|
228
|
+
fireEvent.click(screen.getByText('Show'));
|
|
229
|
+
|
|
230
|
+
expect(screen.getByText('Technical Document Title')).toBeInTheDocument();
|
|
231
|
+
expect(screen.getByText('Document 1')).toBeInTheDocument();
|
|
232
|
+
expect(screen.getByText('Document 2')).toBeInTheDocument();
|
|
233
|
+
expect(screen.getByText('Document 3')).toBeInTheDocument();
|
|
234
|
+
|
|
235
|
+
expect(screen.getByText('Hide')).toBeInTheDocument();
|
|
236
|
+
fireEvent.click(screen.getByText('Hide'));
|
|
237
|
+
|
|
238
|
+
expect(screen.getByText('Technical Document Title')).toBeInTheDocument();
|
|
239
|
+
});
|
|
209
240
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.order-documents-area {
|
|
2
2
|
width: 100%;
|
|
3
3
|
max-width: 800px;
|
|
4
|
-
margin: 16px
|
|
4
|
+
margin: 16px 0;
|
|
5
5
|
border: 1px solid #e0e0e0;
|
|
6
6
|
border-radius: 8px;
|
|
7
7
|
overflow: hidden;
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
background-color: #ffffff;
|
|
42
42
|
transition: background-color 0.2s ease;
|
|
43
43
|
cursor: grab;
|
|
44
|
+
box-shadow: none;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
.document-item:last-child {
|
|
@@ -64,4 +65,26 @@
|
|
|
64
65
|
background-color: #f0f8ff;
|
|
65
66
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
66
67
|
}
|
|
68
|
+
|
|
69
|
+
.document-item {
|
|
70
|
+
.ui.basic.icon.button[aria-label='Drag handle'] {
|
|
71
|
+
box-shadow: none;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.field-wrapper-technical_documents_order {
|
|
77
|
+
.ui.basic.button.order-docs-button {
|
|
78
|
+
display: inline-block;
|
|
79
|
+
padding: 7px 10px;
|
|
80
|
+
border: 2px solid #007eb1;
|
|
81
|
+
margin-top: 20px;
|
|
82
|
+
border-radius: 10px;
|
|
83
|
+
color: #007eb1 !important;
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
opacity: 0.8;
|
|
86
|
+
box-shadow: none;
|
|
87
|
+
max-width: 200px;
|
|
88
|
+
text-align: center;
|
|
89
|
+
}
|
|
67
90
|
}
|