@plone/volto 14.6.0 → 14.8.1
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 +49 -0
- package/cypress.json +2 -1
- package/package.json +6 -4
- package/pyvenv.cfg +3 -0
- package/src/components/index.js +2 -0
- package/src/components/manage/Add/Add.jsx +39 -36
- package/src/components/manage/Contents/Contents.test.jsx +0 -7
- package/src/components/manage/Contents/ContentsItem.jsx +9 -14
- package/src/components/manage/Contents/ContentsUploadModal.jsx +2 -4
- package/src/components/manage/Controlpanels/ModerateComments.jsx +7 -5
- package/src/components/manage/Diff/Diff.jsx +13 -5
- package/src/components/manage/Diff/Diff.test.jsx +0 -6
- package/src/components/manage/Diff/DiffField.jsx +12 -3
- package/src/components/manage/Diff/DiffField.test.jsx +0 -6
- package/src/components/manage/History/History.jsx +6 -5
- package/src/components/manage/History/History.test.jsx +12 -7
- package/src/components/manage/Widgets/DatetimeWidget.jsx +10 -3
- package/src/components/manage/Widgets/DatetimeWidget.test.jsx +2 -2
- package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +4 -3
- package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +10 -3
- package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +8 -4
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +21 -13
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +6 -0
- package/src/components/manage/Widgets/RecurrenceWidget/Utils.js +1 -2
- package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +5 -3
- package/src/components/manage/Widgets/UrlWidget.jsx +2 -0
- package/src/components/theme/App/App.jsx +4 -1
- package/src/components/theme/Comments/Comments.jsx +3 -1
- package/src/components/theme/Comments/Comments.test.jsx +6 -0
- package/src/components/theme/Component/Component.jsx +19 -0
- package/src/components/theme/Component/Component.test.jsx +31 -0
- package/src/components/theme/FormattedDate/FormattedDate.jsx +42 -0
- package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +91 -0
- package/src/components/theme/FormattedDate/FormattedRelativeDate.jsx +57 -0
- package/src/components/theme/FormattedDate/FormattedRelativeDate.stories.jsx +122 -0
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +28 -1
- package/src/components/theme/View/EventDatesInfo.jsx +12 -6
- package/src/components/theme/View/EventDatesInfo.test.jsx +6 -0
- package/src/components/theme/View/EventView.test.jsx +6 -0
- package/src/config/index.js +1 -0
- package/src/helpers/Utils/Date.js +97 -0
- package/src/helpers/Utils/Date.test.js +197 -0
- package/src/helpers/Utils/Utils.js +1 -2
- package/src/helpers/Utils/Utils.test.js +25 -0
- package/src/registry.js +16 -0
- package/src/registry.test.js +28 -0
- package/theme/themes/pastanaga/extras/widgets.less +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 14.8.1 (2022-02-04)
|
|
4
|
+
|
|
5
|
+
### Bugfix
|
|
6
|
+
|
|
7
|
+
- Fix wrong CSS in language independent class selector @sneridagh
|
|
8
|
+
|
|
9
|
+
### Internal
|
|
10
|
+
|
|
11
|
+
- Cleanup redundant buildout install run.
|
|
12
|
+
|
|
13
|
+
## 14.8.0 (2022-02-03)
|
|
14
|
+
|
|
15
|
+
### Feature
|
|
16
|
+
|
|
17
|
+
- Enable `components` property in Volto's config registry. Does not expose any direct feature but this will open the door to be able to override registered components using the config registry and avoid using shadowing explicitly. @sneridagh
|
|
18
|
+
- Add `resolve` and `register` helper methods for the Volto config. They retrieve and register new components in the registry. @tiberiuichim @sneridagh
|
|
19
|
+
- Add `Component` component, given a `name` of a component registered in the registry, it renders it, passing down the props. @tiberiuichim
|
|
20
|
+
- Syncronize the content language with the UI language in multilingual sites. So when you are accessing a content in a given language the rest of the interface literals follow along (it updates the language cookie). So the UI remains consistent. @sneridagh
|
|
21
|
+
|
|
22
|
+
### Bugfix
|
|
23
|
+
|
|
24
|
+
- Fix the a11y violation of UrlWidget @iRohitSingh
|
|
25
|
+
|
|
26
|
+
### Internal
|
|
27
|
+
|
|
28
|
+
- Update volta pins in package.json @fredvd
|
|
29
|
+
|
|
30
|
+
## 14.7.1 (2022-02-02)
|
|
31
|
+
|
|
32
|
+
### Internal
|
|
33
|
+
|
|
34
|
+
- Add CSS body class in Babel view. Improve marker for language independent fields in Babel view too. @sneridagh
|
|
35
|
+
|
|
36
|
+
### Docs
|
|
37
|
+
|
|
38
|
+
Update documentation for internal proxy & other smaller reorganisation for quicker onboarding of
|
|
39
|
+
new users/evaluators. @fredvd
|
|
40
|
+
|
|
41
|
+
## 14.7.0 (2022-01-28)
|
|
42
|
+
|
|
43
|
+
### Feature
|
|
44
|
+
|
|
45
|
+
- Add `<FormattedDate>` and `<FormattedRelativeDate>` components. Check their Storybook stories for details. This is part of ongoing work to minimize the use of 'deprecated' momentjs. @sneridagh @tiberiuichim
|
|
46
|
+
|
|
47
|
+
### Internal
|
|
48
|
+
|
|
49
|
+
- Upgrade jest to latest release, 27 major. @tiberiuichim
|
|
50
|
+
- Lazyload momentjs. `parseDateTime` helper now requires passing the momentjs library @tiberiuichim
|
|
51
|
+
|
|
3
52
|
## 14.6.0 (2022-01-27)
|
|
4
53
|
|
|
5
54
|
### Feature
|
package/cypress.json
CHANGED
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
}
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "14.
|
|
12
|
+
"version": "14.8.1",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git@github.com:plone/volto.git"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"build": "razzle build",
|
|
36
36
|
"build-spa": "razzle build --type=spa",
|
|
37
37
|
"test": "razzle test --env=jest-environment-jsdom-sixteen --maxWorkers=50%",
|
|
38
|
-
"test:ci": "CI=true razzle test --env=jest-environment-jsdom-sixteen",
|
|
38
|
+
"test:ci": "CI=true NODE_ICU_DATA=node_modules/full-icu razzle test --env=jest-environment-jsdom-sixteen",
|
|
39
39
|
"test:husky": "CI=true yarn test --bail --findRelatedTests",
|
|
40
40
|
"test:debug": "node --inspect node_modules/.bin/jest --runInBand",
|
|
41
41
|
"start:prod": "NODE_ENV=production node build/server.js",
|
|
@@ -414,7 +414,9 @@
|
|
|
414
414
|
"@storybook/react": "^6.3.0",
|
|
415
415
|
"babel-loader": "^8.1.0",
|
|
416
416
|
"crypto-random-string": "3.2.0",
|
|
417
|
+
"full-icu": "1.4.0",
|
|
417
418
|
"identity-obj-proxy": "3.0.0",
|
|
419
|
+
"jest": "27.4.5",
|
|
418
420
|
"jest-environment-jsdom-sixteen": "1.0.3",
|
|
419
421
|
"react-is": "^16.13.1",
|
|
420
422
|
"tmp": "0.2.1",
|
|
@@ -432,7 +434,7 @@
|
|
|
432
434
|
"ua-parser-js": "0.7.28"
|
|
433
435
|
},
|
|
434
436
|
"volta": {
|
|
435
|
-
"node": "
|
|
436
|
-
"yarn": "1.
|
|
437
|
+
"node": "16.13.2",
|
|
438
|
+
"yarn": "1.22.17"
|
|
437
439
|
}
|
|
438
440
|
}
|
package/pyvenv.cfg
ADDED
package/src/components/index.js
CHANGED
|
@@ -198,5 +198,7 @@ export ToCSettingsSchema from '@plone/volto/components/manage/Blocks/ToC/Schema'
|
|
|
198
198
|
|
|
199
199
|
export MaybeWrap from '@plone/volto/components/manage/MaybeWrap/MaybeWrap';
|
|
200
200
|
export ContentMetadataTags from '@plone/volto/components/theme/ContentMetadataTags/ContentMetadataTags';
|
|
201
|
+
export FormattedDate from '@plone/volto/components/theme/FormattedDate/FormattedDate';
|
|
202
|
+
export FormattedRelativeDate from '@plone/volto/components/theme/FormattedDate/FormattedRelativeDate';
|
|
201
203
|
|
|
202
204
|
export App from '@plone/volto/components/theme/App/App';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { Component } from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { Helmet } from '@plone/volto/helpers';
|
|
8
|
+
import { BodyClass, Helmet } from '@plone/volto/helpers';
|
|
9
9
|
import { connect } from 'react-redux';
|
|
10
10
|
import { compose } from 'redux';
|
|
11
11
|
import { keys, isEmpty } from 'lodash';
|
|
@@ -400,41 +400,44 @@ class Add extends Component {
|
|
|
400
400
|
);
|
|
401
401
|
|
|
402
402
|
return translationObject ? (
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
403
|
+
<>
|
|
404
|
+
<BodyClass className="babel-view" />
|
|
405
|
+
<Grid
|
|
406
|
+
celled="internally"
|
|
407
|
+
stackable
|
|
408
|
+
columns={2}
|
|
409
|
+
id="page-add-translation"
|
|
410
|
+
>
|
|
411
|
+
<Grid.Column className="source-object">
|
|
412
|
+
<TranslationObject
|
|
413
|
+
translationObject={translationObject}
|
|
414
|
+
schema={this.props.schema}
|
|
415
|
+
pathname={this.props.pathname}
|
|
416
|
+
visual={visual}
|
|
417
|
+
isFormSelected={
|
|
418
|
+
this.state.formSelected === 'translationObjectForm'
|
|
419
|
+
}
|
|
420
|
+
onSelectForm={() => {
|
|
421
|
+
this.setState({
|
|
422
|
+
formSelected: 'translationObjectForm',
|
|
423
|
+
});
|
|
424
|
+
}}
|
|
425
|
+
/>
|
|
426
|
+
</Grid.Column>
|
|
427
|
+
<Grid.Column>
|
|
428
|
+
<div className="new-translation">
|
|
429
|
+
<Menu pointing secondary attached tabular>
|
|
430
|
+
<Menu.Item name={translateTo.toUpperCase()} active={true}>
|
|
431
|
+
{`${this.props.intl.formatMessage(messages.translateTo, {
|
|
432
|
+
lang: translateTo,
|
|
433
|
+
})}`}
|
|
434
|
+
</Menu.Item>
|
|
435
|
+
</Menu>
|
|
436
|
+
{pageAdd}
|
|
437
|
+
</div>
|
|
438
|
+
</Grid.Column>
|
|
439
|
+
</Grid>
|
|
440
|
+
</>
|
|
438
441
|
) : (
|
|
439
442
|
pageAdd
|
|
440
443
|
);
|
|
@@ -24,13 +24,6 @@ jest.mock('./ContentsUploadModal', () =>
|
|
|
24
24
|
jest.fn(() => <div className="UploadModal" />),
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
-
jest.mock('moment', () =>
|
|
28
|
-
jest.fn(() => ({
|
|
29
|
-
format: jest.fn(() => 'Sunday, April 23, 2017 3:38 AM'),
|
|
30
|
-
fromNow: jest.fn(() => 'a few seconds ago'),
|
|
31
|
-
})),
|
|
32
|
-
);
|
|
33
|
-
|
|
34
27
|
describe('Contents', () => {
|
|
35
28
|
it('renders a folder contents view component', () => {
|
|
36
29
|
const store = mockStore({
|
|
@@ -8,9 +8,8 @@ import { Button, Dropdown, Table } from 'semantic-ui-react';
|
|
|
8
8
|
import { Link } from 'react-router-dom';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
10
|
import { map } from 'lodash';
|
|
11
|
-
import moment from 'moment';
|
|
12
11
|
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
|
13
|
-
import {
|
|
12
|
+
import { Circle, FormattedDate, Icon } from '@plone/volto/components';
|
|
14
13
|
import { getContentIcon } from '@plone/volto/helpers';
|
|
15
14
|
import moreSVG from '@plone/volto/icons/more.svg';
|
|
16
15
|
import checkboxUncheckedSVG from '@plone/volto/icons/checkbox-unchecked.svg';
|
|
@@ -48,6 +47,10 @@ const messages = defineMessages({
|
|
|
48
47
|
id: 'no workflow state',
|
|
49
48
|
defaultMessage: 'No workflow state',
|
|
50
49
|
},
|
|
50
|
+
none: {
|
|
51
|
+
id: 'None',
|
|
52
|
+
defaultMessage: 'None',
|
|
53
|
+
},
|
|
51
54
|
});
|
|
52
55
|
|
|
53
56
|
function getColor(string) {
|
|
@@ -187,21 +190,13 @@ export const ContentsItemComponent = ({
|
|
|
187
190
|
</div>
|
|
188
191
|
)}
|
|
189
192
|
{index.type === 'date' && (
|
|
190
|
-
|
|
191
|
-
title={
|
|
192
|
-
item[index.id] !== 'None' ? (
|
|
193
|
-
moment(item[index.id]).format('LLLL')
|
|
194
|
-
) : (
|
|
195
|
-
<FormattedMessage id="None" defaultMessage="None" />
|
|
196
|
-
)
|
|
197
|
-
}
|
|
198
|
-
>
|
|
193
|
+
<>
|
|
199
194
|
{item[index.id] !== 'None' ? (
|
|
200
|
-
|
|
195
|
+
<FormattedDate date={item[index.id]} />
|
|
201
196
|
) : (
|
|
202
|
-
|
|
197
|
+
intl.formatMessage(messages.none)
|
|
203
198
|
)}
|
|
204
|
-
|
|
199
|
+
</>
|
|
205
200
|
)}
|
|
206
201
|
{index.type === 'array' && (
|
|
207
202
|
<span>{item[index.id]?.join(', ')}</span>
|
|
@@ -20,10 +20,10 @@ import {
|
|
|
20
20
|
} from 'semantic-ui-react';
|
|
21
21
|
import loadable from '@loadable/component';
|
|
22
22
|
import { concat, filter, map } from 'lodash';
|
|
23
|
-
import moment from 'moment';
|
|
24
23
|
import filesize from 'filesize';
|
|
25
24
|
import { readAsDataURL } from 'promise-file-reader';
|
|
26
25
|
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|
26
|
+
import { FormattedRelativeDate } from '@plone/volto/components';
|
|
27
27
|
import { createContent } from '@plone/volto/actions';
|
|
28
28
|
|
|
29
29
|
const Dropzone = loadable(() => import('react-dropzone'));
|
|
@@ -180,8 +180,6 @@ class ContentsUploadModal extends Component {
|
|
|
180
180
|
* @returns {string} Markup for the component.
|
|
181
181
|
*/
|
|
182
182
|
render() {
|
|
183
|
-
moment.locale(this.props.intl.locale);
|
|
184
|
-
|
|
185
183
|
return (
|
|
186
184
|
this.props.open && (
|
|
187
185
|
<Modal open={this.props.open}>
|
|
@@ -269,7 +267,7 @@ class ContentsUploadModal extends Component {
|
|
|
269
267
|
<Table.Row className="upload-row" key={file.name}>
|
|
270
268
|
<Table.Cell>{file.name}</Table.Cell>
|
|
271
269
|
<Table.Cell>
|
|
272
|
-
{
|
|
270
|
+
<FormattedRelativeDate date={file.lastModifiedDate} />
|
|
273
271
|
</Table.Cell>
|
|
274
272
|
<Table.Cell>
|
|
275
273
|
{filesize(file.size, { round: 0 })}
|
|
@@ -11,11 +11,15 @@ import { Link } from 'react-router-dom';
|
|
|
11
11
|
import { getParentUrl, Helmet } from '@plone/volto/helpers';
|
|
12
12
|
import { Portal } from 'react-portal';
|
|
13
13
|
import { Container, Button, Table } from 'semantic-ui-react';
|
|
14
|
-
import moment from 'moment';
|
|
15
14
|
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|
16
15
|
|
|
17
16
|
import { deleteComment, searchContent } from '@plone/volto/actions';
|
|
18
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
CommentEditModal,
|
|
19
|
+
FormattedRelativeDate,
|
|
20
|
+
Icon,
|
|
21
|
+
Toolbar,
|
|
22
|
+
} from '@plone/volto/components';
|
|
19
23
|
|
|
20
24
|
import backSVG from '@plone/volto/icons/back.svg';
|
|
21
25
|
|
|
@@ -230,9 +234,7 @@ class ModerateComments extends Component {
|
|
|
230
234
|
<Table.Row key={item['@id']}>
|
|
231
235
|
<Table.Cell>{item.author_name}</Table.Cell>
|
|
232
236
|
<Table.Cell>
|
|
233
|
-
<
|
|
234
|
-
{moment(item.creation_date).fromNow()}
|
|
235
|
-
</span>
|
|
237
|
+
<FormattedRelativeDate date={item.creation_date} />
|
|
236
238
|
</Table.Cell>
|
|
237
239
|
<Table.Cell>{item.text.data}</Table.Cell>
|
|
238
240
|
<Table.Cell>
|
|
@@ -12,7 +12,6 @@ import { filter, isEqual, map } from 'lodash';
|
|
|
12
12
|
import { Container, Button, Dropdown, Grid, Table } from 'semantic-ui-react';
|
|
13
13
|
import { Link, withRouter } from 'react-router-dom';
|
|
14
14
|
import { Portal } from 'react-portal';
|
|
15
|
-
import moment from 'moment';
|
|
16
15
|
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|
17
16
|
import qs from 'query-string';
|
|
18
17
|
|
|
@@ -23,7 +22,12 @@ import {
|
|
|
23
22
|
getBlocksLayoutFieldname,
|
|
24
23
|
hasBlocksData,
|
|
25
24
|
} from '@plone/volto/helpers';
|
|
26
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
DiffField,
|
|
27
|
+
FormattedDate,
|
|
28
|
+
Icon,
|
|
29
|
+
Toolbar,
|
|
30
|
+
} from '@plone/volto/components';
|
|
27
31
|
|
|
28
32
|
import backSVG from '@plone/volto/icons/back.svg';
|
|
29
33
|
|
|
@@ -189,9 +193,13 @@ class Diff extends Component {
|
|
|
189
193
|
const versions = map(
|
|
190
194
|
filter(this.props.historyEntries, (entry) => 'version' in entry),
|
|
191
195
|
(entry, index) => ({
|
|
192
|
-
text:
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
text: (
|
|
197
|
+
<>
|
|
198
|
+
{index === 0 ? 'Current' : entry.version} (
|
|
199
|
+
<FormattedDate date={entry.time} long className="text" />,
|
|
200
|
+
{entry.actor.fullname})
|
|
201
|
+
</>
|
|
202
|
+
),
|
|
195
203
|
value: `${entry.version}`,
|
|
196
204
|
key: `${entry.version}`,
|
|
197
205
|
}),
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
// import renderer from 'react-test-renderer';
|
|
3
2
|
import configureStore from 'redux-mock-store';
|
|
4
3
|
import { Provider } from 'react-intl-redux';
|
|
5
4
|
import { MemoryRouter } from 'react-router-dom';
|
|
@@ -12,11 +11,6 @@ const mockStore = configureStore();
|
|
|
12
11
|
jest.mock('react-portal', () => ({
|
|
13
12
|
Portal: jest.fn(() => <div id="Portal" />),
|
|
14
13
|
}));
|
|
15
|
-
jest.mock('moment', () =>
|
|
16
|
-
jest.fn(() => ({
|
|
17
|
-
format: jest.fn(() => 'Sunday, April 23, 2017 3:38 AM'),
|
|
18
|
-
})),
|
|
19
|
-
);
|
|
20
14
|
|
|
21
15
|
jest.mock('@plone/volto/helpers/Loadable/Loadable');
|
|
22
16
|
beforeAll(
|
|
@@ -8,11 +8,11 @@ import React from 'react';
|
|
|
8
8
|
import { join, map } from 'lodash';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
10
|
import { Table } from 'semantic-ui-react';
|
|
11
|
-
import moment from 'moment';
|
|
12
11
|
import ReactDOMServer from 'react-dom/server';
|
|
13
12
|
import { Provider } from 'react-intl-redux';
|
|
14
13
|
import { createBrowserHistory } from 'history';
|
|
15
14
|
import { ConnectedRouter } from 'connected-react-router';
|
|
15
|
+
import { useSelector } from 'react-redux';
|
|
16
16
|
|
|
17
17
|
import { Api } from '@plone/volto/helpers';
|
|
18
18
|
import configureStore from '@plone/volto/store';
|
|
@@ -44,6 +44,11 @@ const DiffField = ({
|
|
|
44
44
|
schema,
|
|
45
45
|
diffLib,
|
|
46
46
|
}) => {
|
|
47
|
+
const language = useSelector((state) => state.intl.locale);
|
|
48
|
+
const readable_date_format = {
|
|
49
|
+
dateStyle: 'full',
|
|
50
|
+
timeStyle: 'short',
|
|
51
|
+
};
|
|
47
52
|
const diffWords = (oneStr, twoStr) => {
|
|
48
53
|
return diffLib.diffWords(String(oneStr), String(twoStr));
|
|
49
54
|
};
|
|
@@ -56,8 +61,12 @@ const DiffField = ({
|
|
|
56
61
|
break;
|
|
57
62
|
case 'datetime':
|
|
58
63
|
parts = diffWords(
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
new Intl.DateTimeFormat(language, readable_date_format).format(
|
|
65
|
+
new Date(one),
|
|
66
|
+
),
|
|
67
|
+
new Intl.DateTimeFormat(language, readable_date_format).format(
|
|
68
|
+
new Date(two),
|
|
69
|
+
),
|
|
61
70
|
);
|
|
62
71
|
break;
|
|
63
72
|
case 'json':
|
|
@@ -5,12 +5,6 @@ import { waitFor, render, screen } from '@testing-library/react';
|
|
|
5
5
|
|
|
6
6
|
import DiffField from './DiffField';
|
|
7
7
|
|
|
8
|
-
jest.mock('moment', () =>
|
|
9
|
-
jest.fn(() => ({
|
|
10
|
-
format: jest.fn(() => 'Sunday, April 23, 2017 3:38 AM'),
|
|
11
|
-
})),
|
|
12
|
-
);
|
|
13
|
-
|
|
14
8
|
jest.mock('@plone/volto/helpers/Loadable/Loadable');
|
|
15
9
|
beforeAll(
|
|
16
10
|
async () =>
|
|
@@ -12,10 +12,13 @@ import { compose } from 'redux';
|
|
|
12
12
|
import { Container, Dropdown, Icon, Segment, Table } from 'semantic-ui-react';
|
|
13
13
|
import { concat, map, reverse } from 'lodash';
|
|
14
14
|
import { Portal } from 'react-portal';
|
|
15
|
-
import moment from 'moment';
|
|
16
15
|
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|
17
16
|
|
|
18
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
FormattedRelativeDate,
|
|
19
|
+
Icon as IconNext,
|
|
20
|
+
Toolbar,
|
|
21
|
+
} from '@plone/volto/components';
|
|
19
22
|
import { getHistory, revertHistory } from '@plone/volto/actions';
|
|
20
23
|
import { getBaseUrl } from '@plone/volto/helpers';
|
|
21
24
|
|
|
@@ -206,9 +209,7 @@ class History extends Component {
|
|
|
206
209
|
</Table.Cell>
|
|
207
210
|
<Table.Cell>{entry.actor.fullname}</Table.Cell>
|
|
208
211
|
<Table.Cell>
|
|
209
|
-
<
|
|
210
|
-
{moment(entry.time).fromNow()}
|
|
211
|
-
</span>
|
|
212
|
+
<FormattedRelativeDate date={entry.time} />
|
|
212
213
|
</Table.Cell>
|
|
213
214
|
<Table.Cell>{entry.comments}</Table.Cell>
|
|
214
215
|
<Table.Cell>
|
|
@@ -3,21 +3,26 @@ import renderer from 'react-test-renderer';
|
|
|
3
3
|
import configureStore from 'redux-mock-store';
|
|
4
4
|
import { Provider } from 'react-intl-redux';
|
|
5
5
|
|
|
6
|
+
import FakeTimers from '@sinonjs/fake-timers';
|
|
7
|
+
|
|
6
8
|
import History from './History';
|
|
7
9
|
|
|
8
10
|
const mockStore = configureStore();
|
|
9
|
-
|
|
10
11
|
jest.mock('react-portal', () => ({
|
|
11
12
|
Portal: jest.fn(() => <div id="Portal" />),
|
|
12
13
|
}));
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
format: jest.fn(() => 'Sunday, April 23, 2017 3:38 AM'),
|
|
16
|
-
fromNow: jest.fn(() => 'a few seconds ago'),
|
|
17
|
-
})),
|
|
18
|
-
);
|
|
14
|
+
|
|
15
|
+
const FIXED_SYSTEM_TIME = '2017-04-23T15:38:00.000Z';
|
|
19
16
|
|
|
20
17
|
describe('History', () => {
|
|
18
|
+
let clock;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
clock = FakeTimers.install({ now: Date.parse(FIXED_SYSTEM_TIME) });
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
clock.uninstall();
|
|
24
|
+
});
|
|
25
|
+
|
|
21
26
|
it('renders a history component', () => {
|
|
22
27
|
const store = mockStore({
|
|
23
28
|
history: {
|
|
@@ -93,7 +93,7 @@ export class DatetimeWidgetComponent extends Component {
|
|
|
93
93
|
*/
|
|
94
94
|
constructor(props) {
|
|
95
95
|
super(props);
|
|
96
|
-
|
|
96
|
+
this.moment = props.moment.default;
|
|
97
97
|
|
|
98
98
|
this.state = {
|
|
99
99
|
focused: false,
|
|
@@ -102,12 +102,19 @@ export class DatetimeWidgetComponent extends Component {
|
|
|
102
102
|
parseDateTime(
|
|
103
103
|
this.props.intl.locale,
|
|
104
104
|
this.props.value,
|
|
105
|
-
|
|
105
|
+
undefined,
|
|
106
|
+
this.moment,
|
|
107
|
+
)?.toISOString() === this.moment().utc().toISOString(),
|
|
106
108
|
};
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
getInternalValue() {
|
|
110
|
-
return parseDateTime(
|
|
112
|
+
return parseDateTime(
|
|
113
|
+
this.props.intl.locale,
|
|
114
|
+
this.props.value,
|
|
115
|
+
undefined,
|
|
116
|
+
this.moment,
|
|
117
|
+
);
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
getDateOnly() {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import moment from 'moment';
|
|
2
1
|
import React from 'react';
|
|
3
2
|
import { Provider } from 'react-intl-redux';
|
|
4
3
|
import configureStore from 'redux-mock-store';
|
|
@@ -20,6 +19,7 @@ test('renders a datetime widget component', async () => {
|
|
|
20
19
|
messages: {},
|
|
21
20
|
},
|
|
22
21
|
});
|
|
22
|
+
const isoDate = new Date('2019-10-21').toISOString();
|
|
23
23
|
const { container } = render(
|
|
24
24
|
<Provider store={store}>
|
|
25
25
|
<DatetimeWidget
|
|
@@ -27,7 +27,7 @@ test('renders a datetime widget component', async () => {
|
|
|
27
27
|
title="My field"
|
|
28
28
|
fieldSet="default"
|
|
29
29
|
onChange={() => {}}
|
|
30
|
-
value={
|
|
30
|
+
value={isoDate}
|
|
31
31
|
/>
|
|
32
32
|
</Provider>,
|
|
33
33
|
);
|
|
@@ -6,17 +6,18 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { Form, Grid, Button } from 'semantic-ui-react';
|
|
9
|
-
import moment from 'moment';
|
|
10
9
|
import { Days } from './Utils';
|
|
11
10
|
import { useIntl } from 'react-intl';
|
|
11
|
+
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* ByDayField component class.
|
|
15
15
|
* @function ByDayField
|
|
16
16
|
* @returns {string} Markup of the component.
|
|
17
17
|
*/
|
|
18
|
-
const ByDayField = ({ label, value, onChange }) => {
|
|
18
|
+
const ByDayField = ({ label, value, onChange, moment: momentlib }) => {
|
|
19
19
|
const intl = useIntl();
|
|
20
|
+
const moment = momentlib.default;
|
|
20
21
|
moment.locale(intl.locale);
|
|
21
22
|
|
|
22
23
|
const toggleWeekDay = (dayName) => {
|
|
@@ -84,4 +85,4 @@ ByDayField.defaultProps = {
|
|
|
84
85
|
onChange: null,
|
|
85
86
|
};
|
|
86
87
|
|
|
87
|
-
export default ByDayField;
|
|
88
|
+
export default injectLazyLibs(['moment'])(ByDayField);
|
|
@@ -6,17 +6,24 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { map } from 'lodash';
|
|
9
|
-
import moment from 'moment';
|
|
10
9
|
import { useIntl } from 'react-intl';
|
|
11
10
|
import { Form } from 'semantic-ui-react';
|
|
12
11
|
import SelectInput from './SelectInput';
|
|
12
|
+
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* MonthOfTheYearField component class.
|
|
16
16
|
* @function MonthOfTheYearField
|
|
17
17
|
* @returns {string} Markup of the component.
|
|
18
18
|
*/
|
|
19
|
-
const MonthOfTheYearField = ({
|
|
19
|
+
const MonthOfTheYearField = ({
|
|
20
|
+
value,
|
|
21
|
+
disabled,
|
|
22
|
+
inline,
|
|
23
|
+
onChange,
|
|
24
|
+
moment: momentlib,
|
|
25
|
+
}) => {
|
|
26
|
+
const moment = momentlib.default;
|
|
20
27
|
const intl = useIntl();
|
|
21
28
|
moment.locale(intl.locale);
|
|
22
29
|
const monthList = [
|
|
@@ -63,4 +70,4 @@ MonthOfTheYearField.defaultProps = {
|
|
|
63
70
|
onChange: null,
|
|
64
71
|
};
|
|
65
72
|
|
|
66
|
-
export default MonthOfTheYearField;
|
|
73
|
+
export default injectLazyLibs(['moment'])(MonthOfTheYearField);
|