@eeacms/volto-clms-theme 1.1.175 → 1.1.177
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,10 @@ 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.177](https://github.com/eea/volto-clms-theme/compare/1.1.176...1.1.177) - 8 August 2024
|
|
8
|
+
|
|
9
|
+
### [1.1.176](https://github.com/eea/volto-clms-theme/compare/1.1.175...1.1.176) - 8 August 2024
|
|
10
|
+
|
|
7
11
|
### [1.1.175](https://github.com/eea/volto-clms-theme/compare/1.1.174...1.1.175) - 8 August 2024
|
|
8
12
|
|
|
9
13
|
#### :hammer_and_wrench: Others
|
package/package.json
CHANGED
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contents item component.
|
|
3
|
+
* @module components/manage/Contents/ContentsItem
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { Button, Table, Menu, Divider } from 'semantic-ui-react';
|
|
8
|
+
import { Link } from 'react-router-dom';
|
|
9
|
+
import PropTypes from 'prop-types';
|
|
10
|
+
import { map } from 'lodash';
|
|
11
|
+
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
|
12
|
+
import { Circle, FormattedDate, Icon, Popup } from '@plone/volto/components';
|
|
13
|
+
import { getContentIcon } from '@plone/volto/helpers';
|
|
14
|
+
import moreSVG from '@plone/volto/icons/more.svg';
|
|
15
|
+
import checkboxUncheckedSVG from '@plone/volto/icons/checkbox-unchecked.svg';
|
|
16
|
+
import checkboxCheckedSVG from '@plone/volto/icons/checkbox-checked.svg';
|
|
17
|
+
import cutSVG from '@plone/volto/icons/cut.svg';
|
|
18
|
+
import deleteSVG from '@plone/volto/icons/delete.svg';
|
|
19
|
+
import copySVG from '@plone/volto/icons/copy.svg';
|
|
20
|
+
import showSVG from '@plone/volto/icons/show.svg';
|
|
21
|
+
import moveUpSVG from '@plone/volto/icons/move-up.svg';
|
|
22
|
+
import moveDownSVG from '@plone/volto/icons/move-down.svg';
|
|
23
|
+
import editingSVG from '@plone/volto/icons/editing.svg';
|
|
24
|
+
import dragSVG from '@plone/volto/icons/drag.svg';
|
|
25
|
+
import cx from 'classnames';
|
|
26
|
+
|
|
27
|
+
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
28
|
+
|
|
29
|
+
const messages = defineMessages({
|
|
30
|
+
private: {
|
|
31
|
+
id: 'private',
|
|
32
|
+
defaultMessage: 'Private',
|
|
33
|
+
},
|
|
34
|
+
pending: {
|
|
35
|
+
id: 'pending',
|
|
36
|
+
defaultMessage: 'Pending',
|
|
37
|
+
},
|
|
38
|
+
published: {
|
|
39
|
+
id: 'published',
|
|
40
|
+
defaultMessage: 'Published',
|
|
41
|
+
},
|
|
42
|
+
intranet: {
|
|
43
|
+
id: 'intranet',
|
|
44
|
+
defaultMessage: 'Intranet',
|
|
45
|
+
},
|
|
46
|
+
draft: {
|
|
47
|
+
id: 'draft',
|
|
48
|
+
defaultMessage: 'Draft',
|
|
49
|
+
},
|
|
50
|
+
no_workflow_state: {
|
|
51
|
+
id: 'no workflow state',
|
|
52
|
+
defaultMessage: 'No workflow state',
|
|
53
|
+
},
|
|
54
|
+
none: {
|
|
55
|
+
id: 'None',
|
|
56
|
+
defaultMessage: 'None',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
function getColor(string) {
|
|
61
|
+
switch (string) {
|
|
62
|
+
case 'private':
|
|
63
|
+
return '#ed4033';
|
|
64
|
+
case 'published':
|
|
65
|
+
return '#007bc1';
|
|
66
|
+
case 'intranet':
|
|
67
|
+
return '#51aa55';
|
|
68
|
+
case 'draft':
|
|
69
|
+
return '#f6a808';
|
|
70
|
+
default:
|
|
71
|
+
return 'grey';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Contents item component class.
|
|
77
|
+
* @function ContentsItemComponent
|
|
78
|
+
* @returns {string} Markup of the component.
|
|
79
|
+
*/
|
|
80
|
+
export const ContentsItemComponent = ({
|
|
81
|
+
item,
|
|
82
|
+
selected,
|
|
83
|
+
onClick,
|
|
84
|
+
indexes,
|
|
85
|
+
onCut,
|
|
86
|
+
onCopy,
|
|
87
|
+
onDelete,
|
|
88
|
+
onMoveToTop,
|
|
89
|
+
onMoveToBottom,
|
|
90
|
+
connectDragPreview,
|
|
91
|
+
connectDragSource,
|
|
92
|
+
connectDropTarget,
|
|
93
|
+
isDragging,
|
|
94
|
+
order,
|
|
95
|
+
}) => {
|
|
96
|
+
const intl = useIntl();
|
|
97
|
+
|
|
98
|
+
return connectDropTarget(
|
|
99
|
+
connectDragPreview(
|
|
100
|
+
<tr
|
|
101
|
+
key={item['@id']}
|
|
102
|
+
className={cx('', { 'dragging-row': isDragging })}
|
|
103
|
+
aria-label={item['@id']}
|
|
104
|
+
>
|
|
105
|
+
<Table.Cell className={cx('', { 'dragging-cell': isDragging })}>
|
|
106
|
+
{connectDragSource(
|
|
107
|
+
<div style={{ display: 'inline-block' }}>
|
|
108
|
+
<Button icon basic>
|
|
109
|
+
<Icon
|
|
110
|
+
name={dragSVG}
|
|
111
|
+
size="20px"
|
|
112
|
+
color="#878f93"
|
|
113
|
+
className="content drag handle"
|
|
114
|
+
/>
|
|
115
|
+
</Button>
|
|
116
|
+
</div>,
|
|
117
|
+
)}
|
|
118
|
+
</Table.Cell>
|
|
119
|
+
<Table.Cell className={cx('', { 'dragging-cell': isDragging })}>
|
|
120
|
+
{selected ? (
|
|
121
|
+
<Button
|
|
122
|
+
icon
|
|
123
|
+
basic
|
|
124
|
+
aria-label="Unchecked"
|
|
125
|
+
onClick={(e) => onClick(e, item['@id'])}
|
|
126
|
+
>
|
|
127
|
+
<Icon
|
|
128
|
+
name={checkboxCheckedSVG}
|
|
129
|
+
color="#007eb1"
|
|
130
|
+
size="24px"
|
|
131
|
+
className="checked"
|
|
132
|
+
/>
|
|
133
|
+
</Button>
|
|
134
|
+
) : (
|
|
135
|
+
<Button
|
|
136
|
+
icon
|
|
137
|
+
basic
|
|
138
|
+
aria-label="Checked"
|
|
139
|
+
onClick={(e) => onClick(e, item['@id'])}
|
|
140
|
+
>
|
|
141
|
+
<Icon
|
|
142
|
+
name={checkboxUncheckedSVG}
|
|
143
|
+
color="#826a6a"
|
|
144
|
+
size="24px"
|
|
145
|
+
className="unchecked"
|
|
146
|
+
/>
|
|
147
|
+
</Button>
|
|
148
|
+
)}
|
|
149
|
+
</Table.Cell>
|
|
150
|
+
<Table.Cell className={cx('', { 'dragging-cell': isDragging })}>
|
|
151
|
+
<Link
|
|
152
|
+
className="icon-align-name"
|
|
153
|
+
to={`${item['@id']}${item.is_folderish ? '/contents' : ''}`}
|
|
154
|
+
>
|
|
155
|
+
<div className="expire-align">
|
|
156
|
+
<Icon
|
|
157
|
+
name={getContentIcon(item['@type'], item.is_folderish)}
|
|
158
|
+
size="20px"
|
|
159
|
+
className="icon-margin"
|
|
160
|
+
color="#878f93"
|
|
161
|
+
title={item['Type'] || item['@type']}
|
|
162
|
+
/>
|
|
163
|
+
<span title={item.title} className="content-title-force-one-line">
|
|
164
|
+
{item.title}
|
|
165
|
+
</span>
|
|
166
|
+
</div>
|
|
167
|
+
{item.ExpirationDate !== 'None' &&
|
|
168
|
+
new Date(item.ExpirationDate).getTime() <
|
|
169
|
+
new Date().getTime() && (
|
|
170
|
+
<Button className="button-margin" size="mini">
|
|
171
|
+
<FormattedMessage id="Expired" defaultMessage="Expired" />
|
|
172
|
+
</Button>
|
|
173
|
+
)}
|
|
174
|
+
{item.EffectiveDate !== 'None' &&
|
|
175
|
+
new Date(item.EffectiveDate).getTime() > new Date().getTime() && (
|
|
176
|
+
<Button className="button-margin effective-future" size="mini">
|
|
177
|
+
<FormattedMessage id="Scheduled" defaultMessage="Scheduled" />
|
|
178
|
+
</Button>
|
|
179
|
+
)}
|
|
180
|
+
</Link>
|
|
181
|
+
</Table.Cell>
|
|
182
|
+
{map(indexes, (index) => (
|
|
183
|
+
<Table.Cell
|
|
184
|
+
className={cx('', { 'dragging-cell': isDragging })}
|
|
185
|
+
key={index.id}
|
|
186
|
+
>
|
|
187
|
+
{index.type === 'boolean' &&
|
|
188
|
+
(item[index.id] ? (
|
|
189
|
+
<FormattedMessage id="Yes" defaultMessage="Yes" />
|
|
190
|
+
) : (
|
|
191
|
+
<FormattedMessage id="No" defaultMessage="No" />
|
|
192
|
+
))}
|
|
193
|
+
{index.type === 'string' &&
|
|
194
|
+
index.id !== 'review_state' &&
|
|
195
|
+
item[index.id]}
|
|
196
|
+
{index.id === 'review_state' && (
|
|
197
|
+
<div>
|
|
198
|
+
<span>
|
|
199
|
+
<Circle color={getColor(item[index.id])} size="15px" />
|
|
200
|
+
</span>
|
|
201
|
+
{messages[item[index.id]]
|
|
202
|
+
? intl.formatMessage(messages[item[index.id]])
|
|
203
|
+
: item['review_title'] ||
|
|
204
|
+
item['review_state'] ||
|
|
205
|
+
intl.formatMessage(messages.no_workflow_state)}
|
|
206
|
+
</div>
|
|
207
|
+
)}
|
|
208
|
+
{index.type === 'date' && (
|
|
209
|
+
<>
|
|
210
|
+
{item[index?.id] && item[index.id] !== 'None' ? (
|
|
211
|
+
<FormattedDate date={item[index.id]} />
|
|
212
|
+
) : (
|
|
213
|
+
intl.formatMessage(messages.none)
|
|
214
|
+
)}
|
|
215
|
+
</>
|
|
216
|
+
)}
|
|
217
|
+
{index.type === 'array' && (
|
|
218
|
+
<span>{item[index.id]?.join(', ')}</span>
|
|
219
|
+
)}
|
|
220
|
+
</Table.Cell>
|
|
221
|
+
))}
|
|
222
|
+
<Table.Cell
|
|
223
|
+
className={cx('', { 'dragging-cell': isDragging })}
|
|
224
|
+
textAlign="right"
|
|
225
|
+
>
|
|
226
|
+
<Popup
|
|
227
|
+
menu={true}
|
|
228
|
+
position="bottom right"
|
|
229
|
+
flowing={true}
|
|
230
|
+
basic={true}
|
|
231
|
+
on="click"
|
|
232
|
+
popper={{
|
|
233
|
+
className: 'dropdown-popup',
|
|
234
|
+
}}
|
|
235
|
+
trigger={
|
|
236
|
+
<Icon
|
|
237
|
+
name={moreSVG}
|
|
238
|
+
className="dropdown-popup-trigger"
|
|
239
|
+
size="24px"
|
|
240
|
+
color="#007eb1"
|
|
241
|
+
/>
|
|
242
|
+
}
|
|
243
|
+
>
|
|
244
|
+
<Menu vertical borderless fluid>
|
|
245
|
+
<Link className="item icon-align" to={`${item['@id']}/edit`}>
|
|
246
|
+
<Icon name={editingSVG} color="#007eb1" size="24px" />{' '}
|
|
247
|
+
<FormattedMessage id="Edit" defaultMessage="Edit" />
|
|
248
|
+
</Link>
|
|
249
|
+
<Link className="item right-dropdown icon-align" to={item['@id']}>
|
|
250
|
+
<Icon name={showSVG} color="#007eb1" size="24px" />{' '}
|
|
251
|
+
<FormattedMessage id="View" defaultMessage="View" />
|
|
252
|
+
</Link>
|
|
253
|
+
<Divider />
|
|
254
|
+
<Menu.Item
|
|
255
|
+
onClick={onCut}
|
|
256
|
+
value={item['@id']}
|
|
257
|
+
className="right-dropdown icon-align"
|
|
258
|
+
>
|
|
259
|
+
<Icon name={cutSVG} color="#007eb1" size="24px" />{' '}
|
|
260
|
+
<FormattedMessage id="Cut" defaultMessage="Cut" />
|
|
261
|
+
</Menu.Item>
|
|
262
|
+
<Menu.Item
|
|
263
|
+
onClick={onCopy}
|
|
264
|
+
value={item['@id']}
|
|
265
|
+
className="right-dropdown icon-align"
|
|
266
|
+
>
|
|
267
|
+
<Icon name={copySVG} color="#007eb1" size="24px" />{' '}
|
|
268
|
+
<FormattedMessage id="Copy" defaultMessage="Copy" />
|
|
269
|
+
</Menu.Item>
|
|
270
|
+
<Menu.Item
|
|
271
|
+
onClick={onDelete}
|
|
272
|
+
value={item['@id']}
|
|
273
|
+
className="right-dropdown icon-align"
|
|
274
|
+
>
|
|
275
|
+
<Icon name={deleteSVG} color="#e40166" size="24px" />{' '}
|
|
276
|
+
<FormattedMessage id="Delete" defaultMessage="Delete" />
|
|
277
|
+
</Menu.Item>
|
|
278
|
+
<Divider />
|
|
279
|
+
<Menu.Item
|
|
280
|
+
onClick={onMoveToTop}
|
|
281
|
+
value={order}
|
|
282
|
+
className="right-dropdown icon-align"
|
|
283
|
+
>
|
|
284
|
+
<Icon name={moveUpSVG} color="#007eb1" size="24px" />{' '}
|
|
285
|
+
<FormattedMessage
|
|
286
|
+
id="Move to top of folder"
|
|
287
|
+
defaultMessage="Move to top of folder"
|
|
288
|
+
/>
|
|
289
|
+
</Menu.Item>
|
|
290
|
+
<Menu.Item
|
|
291
|
+
onClick={onMoveToBottom}
|
|
292
|
+
value={order}
|
|
293
|
+
className="right-dropdown icon-align"
|
|
294
|
+
>
|
|
295
|
+
<Icon name={moveDownSVG} color="#007eb1" size="24px" />{' '}
|
|
296
|
+
<FormattedMessage
|
|
297
|
+
id="Move to bottom of folder"
|
|
298
|
+
defaultMessage="Move to bottom of folder"
|
|
299
|
+
/>
|
|
300
|
+
</Menu.Item>
|
|
301
|
+
</Menu>
|
|
302
|
+
</Popup>
|
|
303
|
+
</Table.Cell>
|
|
304
|
+
</tr>,
|
|
305
|
+
),
|
|
306
|
+
);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Property types.
|
|
311
|
+
* @property {Object} propTypes Property types.
|
|
312
|
+
* @static
|
|
313
|
+
*/
|
|
314
|
+
ContentsItemComponent.propTypes = {
|
|
315
|
+
item: PropTypes.shape({
|
|
316
|
+
'@id': PropTypes.string,
|
|
317
|
+
title: PropTypes.string,
|
|
318
|
+
is_folderish: PropTypes.bool,
|
|
319
|
+
'@type': PropTypes.string,
|
|
320
|
+
}).isRequired,
|
|
321
|
+
selected: PropTypes.bool.isRequired,
|
|
322
|
+
onClick: PropTypes.func.isRequired,
|
|
323
|
+
indexes: PropTypes.arrayOf(
|
|
324
|
+
PropTypes.shape({
|
|
325
|
+
id: PropTypes.string,
|
|
326
|
+
type: PropTypes.string,
|
|
327
|
+
}),
|
|
328
|
+
).isRequired,
|
|
329
|
+
onCut: PropTypes.func.isRequired,
|
|
330
|
+
onCopy: PropTypes.func.isRequired,
|
|
331
|
+
onDelete: PropTypes.func.isRequired,
|
|
332
|
+
onMoveToTop: PropTypes.func.isRequired,
|
|
333
|
+
onMoveToBottom: PropTypes.func.isRequired,
|
|
334
|
+
connectDragPreview: PropTypes.func.isRequired,
|
|
335
|
+
connectDragSource: PropTypes.func.isRequired,
|
|
336
|
+
connectDropTarget: PropTypes.func.isRequired,
|
|
337
|
+
isDragging: PropTypes.bool.isRequired,
|
|
338
|
+
order: PropTypes.number.isRequired,
|
|
339
|
+
onOrderItem: PropTypes.func.isRequired,
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const DragDropConnector = (props) => {
|
|
343
|
+
const { DropTarget, DragSource } = props.reactDnd;
|
|
344
|
+
|
|
345
|
+
const DndConnectedContentsItem = React.useMemo(
|
|
346
|
+
() =>
|
|
347
|
+
DropTarget(
|
|
348
|
+
'item',
|
|
349
|
+
{
|
|
350
|
+
hover(props, monitor) {
|
|
351
|
+
const id = monitor.getItem().id;
|
|
352
|
+
const dragOrder = monitor.getItem().order;
|
|
353
|
+
const hoverOrder = props.order;
|
|
354
|
+
|
|
355
|
+
if (dragOrder === hoverOrder) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
props.onOrderItem(id, dragOrder, hoverOrder - dragOrder, false);
|
|
360
|
+
|
|
361
|
+
monitor.getItem().order = hoverOrder;
|
|
362
|
+
},
|
|
363
|
+
drop(props, monitor) {
|
|
364
|
+
const id = monitor.getItem().id;
|
|
365
|
+
const dragOrder = monitor.getItem().startOrder;
|
|
366
|
+
const dropOrder = props.order;
|
|
367
|
+
|
|
368
|
+
if (dragOrder === dropOrder) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
props.onOrderItem(id, dragOrder, dropOrder - dragOrder, true);
|
|
373
|
+
|
|
374
|
+
monitor.getItem().order = dropOrder;
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
(connect) => ({
|
|
378
|
+
connectDropTarget: connect.dropTarget(),
|
|
379
|
+
}),
|
|
380
|
+
)(
|
|
381
|
+
DragSource(
|
|
382
|
+
'item',
|
|
383
|
+
{
|
|
384
|
+
beginDrag(props) {
|
|
385
|
+
return {
|
|
386
|
+
id: props.item['@id'],
|
|
387
|
+
order: props.order,
|
|
388
|
+
startOrder: props.order,
|
|
389
|
+
};
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
(connect, monitor) => ({
|
|
393
|
+
connectDragSource: connect.dragSource(),
|
|
394
|
+
connectDragPreview: connect.dragPreview(),
|
|
395
|
+
isDragging: monitor.isDragging(),
|
|
396
|
+
}),
|
|
397
|
+
)(ContentsItemComponent),
|
|
398
|
+
),
|
|
399
|
+
[DragSource, DropTarget],
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
return <DndConnectedContentsItem {...props} />;
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
export default injectLazyLibs('reactDnd')(DragDropConnector);
|
package/src/index.js
CHANGED