@plone/volto 14.6.0 → 14.7.0

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +4 -2
  3. package/src/components/index.js +2 -0
  4. package/src/components/manage/Contents/Contents.test.jsx +0 -7
  5. package/src/components/manage/Contents/ContentsItem.jsx +9 -14
  6. package/src/components/manage/Contents/ContentsUploadModal.jsx +2 -4
  7. package/src/components/manage/Controlpanels/ModerateComments.jsx +7 -5
  8. package/src/components/manage/Diff/Diff.jsx +13 -5
  9. package/src/components/manage/Diff/Diff.test.jsx +0 -6
  10. package/src/components/manage/Diff/DiffField.jsx +12 -3
  11. package/src/components/manage/Diff/DiffField.test.jsx +0 -6
  12. package/src/components/manage/History/History.jsx +6 -5
  13. package/src/components/manage/History/History.test.jsx +12 -7
  14. package/src/components/manage/Widgets/DatetimeWidget.jsx +10 -3
  15. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +2 -2
  16. package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +4 -3
  17. package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +10 -3
  18. package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +8 -4
  19. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +21 -13
  20. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +6 -0
  21. package/src/components/manage/Widgets/RecurrenceWidget/Utils.js +1 -2
  22. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +5 -3
  23. package/src/components/theme/Comments/Comments.jsx +3 -1
  24. package/src/components/theme/Comments/Comments.test.jsx +6 -0
  25. package/src/components/theme/FormattedDate/FormattedDate.jsx +42 -0
  26. package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +91 -0
  27. package/src/components/theme/FormattedDate/FormattedRelativeDate.jsx +57 -0
  28. package/src/components/theme/FormattedDate/FormattedRelativeDate.stories.jsx +122 -0
  29. package/src/components/theme/View/EventDatesInfo.jsx +12 -6
  30. package/src/components/theme/View/EventDatesInfo.test.jsx +6 -0
  31. package/src/components/theme/View/EventView.test.jsx +6 -0
  32. package/src/helpers/Utils/Date.js +97 -0
  33. package/src/helpers/Utils/Date.test.js +197 -0
  34. package/src/helpers/Utils/Utils.js +1 -2
  35. package/src/helpers/Utils/Utils.test.js +25 -0
@@ -0,0 +1,197 @@
1
+ import { formatDate, formatRelativeDate } from './Date';
2
+
3
+ const d = '2022-01-03T19:26:08.999Z';
4
+ const date = new Date(d);
5
+
6
+ const SECOND = 1000;
7
+ const MINUTE = SECOND * 60;
8
+ const HOUR = MINUTE * 60;
9
+ const DAY = HOUR * 24;
10
+ const MONTH = DAY * 30;
11
+ const YEAR = DAY * 365; // ? is this safe or should it be more accurate
12
+
13
+ describe('formatDate helper', () => {
14
+ it('accepts an iso date string', () => {
15
+ expect(formatDate({ date: d })).toBe('1/3/2022');
16
+ });
17
+
18
+ it('accepts a date object', () => {
19
+ expect(formatDate({ date })).toBe('1/3/2022');
20
+ });
21
+
22
+ it('formats a date object in other language', () => {
23
+ expect(formatDate({ date, locale: 'de' })).toBe('3.1.2022');
24
+ });
25
+
26
+ it('formats a date object with time in default en locale', () => {
27
+ expect(formatDate({ date, includeTime: true })).toBe('1/3/22, 7:26 PM');
28
+ });
29
+
30
+ it('formats a date object with time in other language', () => {
31
+ expect(formatDate({ date, locale: 'de', includeTime: true })).toBe(
32
+ '03.01.22, 19:26',
33
+ );
34
+ });
35
+
36
+ it('formats a date as long', () => {
37
+ expect(formatDate({ date, long: true })).toBe(
38
+ 'Monday, January 3, 2022 at 7:26 PM',
39
+ );
40
+ });
41
+
42
+ it('formats a date as long in other language', () => {
43
+ expect(formatDate({ date, long: true, locale: 'de' })).toBe(
44
+ 'Montag, 3. Januar 2022 um 19:26',
45
+ );
46
+ });
47
+
48
+ it('includeTime takes precedence over long', () => {
49
+ expect(formatDate({ date, long: true, includeTime: true })).toBe(
50
+ '1/3/22, 7:26 PM',
51
+ );
52
+ });
53
+
54
+ it('accepts custom format', () => {
55
+ expect(
56
+ formatDate({
57
+ date,
58
+ format: {
59
+ year: 'numeric',
60
+ month: 'narrow',
61
+ day: '2-digit',
62
+ },
63
+ }),
64
+ ).toBe('J 03, 2022');
65
+ });
66
+
67
+ it('custom format takes precedence over long and includeTime', () => {
68
+ expect(
69
+ formatDate({
70
+ date,
71
+ long: true,
72
+ includeTime: true,
73
+ format: {
74
+ year: 'numeric',
75
+ month: 'narrow',
76
+ day: '2-digit',
77
+ // dayPeriod: 'long',
78
+ },
79
+ }),
80
+ ).toBe('J 03, 2022');
81
+ });
82
+ });
83
+
84
+ describe('formatRelativeDate helper', () => {
85
+ it('accepts an iso date string', () => {
86
+ expect(formatRelativeDate({ date: d })).toBeTruthy();
87
+ });
88
+
89
+ it('accepts date object', () => {
90
+ expect(formatRelativeDate({ date })).toBeTruthy();
91
+ });
92
+
93
+ it('uses auto numeric to format close past days', () => {
94
+ const now = Date.now();
95
+ const d = new Date(now - 1 * DAY);
96
+ expect(formatRelativeDate({ date: d })).toBe('yesterday');
97
+ });
98
+
99
+ it('uses auto numeric to format close future days', () => {
100
+ const now = Date.now();
101
+ const d = new Date(now + 1 * DAY);
102
+ expect(formatRelativeDate({ date: d })).toBe('tomorrow');
103
+ });
104
+
105
+ it('uses auto numeric to format close future years', () => {
106
+ const now = Date.now();
107
+ const d = new Date(now + 1 * YEAR);
108
+ expect(formatRelativeDate({ date: d })).toBe('next year');
109
+ });
110
+
111
+ it('uses auto numeric to format close last years', () => {
112
+ const now = Date.now();
113
+ const d = new Date(now - 1 * YEAR);
114
+ expect(formatRelativeDate({ date: d })).toBe('last year');
115
+ });
116
+
117
+ it('accepts a relativeTo date', () => {
118
+ const relativeTo = new Date(date.getTime() + 4 * DAY);
119
+ expect(formatRelativeDate({ date, relativeTo })).toBe('4 days ago');
120
+ });
121
+
122
+ it('can format past seconds', () => {
123
+ const relativeTo = new Date(date.getTime() + 4 * SECOND);
124
+ expect(formatRelativeDate({ date, relativeTo })).toBe('4 seconds ago');
125
+ });
126
+
127
+ it('can format future seconds', () => {
128
+ const relativeTo = new Date(date.getTime() - 4 * SECOND);
129
+ expect(formatRelativeDate({ date, relativeTo })).toBe('in 4 seconds');
130
+ });
131
+
132
+ it('can format past minutes', () => {
133
+ const relativeTo = new Date(date.getTime() + 4 * MINUTE);
134
+ expect(formatRelativeDate({ date, relativeTo })).toBe('4 minutes ago');
135
+ });
136
+
137
+ it('can format future minutes', () => {
138
+ const relativeTo = new Date(date.getTime() - 4 * MINUTE);
139
+ expect(formatRelativeDate({ date, relativeTo })).toBe('in 4 minutes');
140
+ });
141
+
142
+ it('can format past hours', () => {
143
+ const relativeTo = new Date(date.getTime() + 4 * HOUR);
144
+ expect(formatRelativeDate({ date, relativeTo })).toBe('4 hours ago');
145
+ });
146
+
147
+ it('can format future hours', () => {
148
+ const relativeTo = new Date(date.getTime() - 4 * HOUR);
149
+ expect(formatRelativeDate({ date, relativeTo })).toBe('in 4 hours');
150
+ });
151
+
152
+ it('can format past days', () => {
153
+ const relativeTo = new Date(date.getTime() + 4 * DAY);
154
+ expect(formatRelativeDate({ date, relativeTo })).toBe('4 days ago');
155
+ });
156
+
157
+ it('can format future days', () => {
158
+ const relativeTo = new Date(date.getTime() - 4 * DAY);
159
+ expect(formatRelativeDate({ date, relativeTo })).toBe('in 4 days');
160
+ });
161
+
162
+ it('can format past months', () => {
163
+ const relativeTo = new Date(date.getTime() + 4 * MONTH);
164
+ expect(formatRelativeDate({ date, relativeTo })).toBe('4 months ago');
165
+ });
166
+
167
+ it('can format future months', () => {
168
+ const relativeTo = new Date(date.getTime() - 4 * MONTH);
169
+ expect(formatRelativeDate({ date, relativeTo })).toBe('in 4 months');
170
+ });
171
+
172
+ it('can format past years', () => {
173
+ const relativeTo = new Date(
174
+ date.getTime() + 4 * YEAR + 4 * MONTH + 4 * DAY,
175
+ );
176
+ expect(formatRelativeDate({ date, relativeTo })).toBe('4 years ago');
177
+ });
178
+
179
+ it('can format future years', () => {
180
+ const relativeTo = new Date(
181
+ date.getTime() - 4 * YEAR - +4 * MONTH - 4 * DAY,
182
+ );
183
+ expect(formatRelativeDate({ date, relativeTo })).toBe('in 4 years');
184
+ });
185
+
186
+ it('can use alternate style short', () => {
187
+ const now = Date.now();
188
+ const d = new Date(now + 3 * MONTH);
189
+ expect(formatRelativeDate({ date: d, style: 'short' })).toBe('in 3 mo.');
190
+ });
191
+
192
+ it('can use alternate style narrow', () => {
193
+ const now = Date.now();
194
+ const d = new Date(now + 3 * MONTH);
195
+ expect(formatRelativeDate({ date: d, style: 'narrow' })).toBe('in 3 mo.');
196
+ });
197
+ });
@@ -1,7 +1,6 @@
1
1
  import { flatten, isEqual, isObject, transform } from 'lodash';
2
2
  import React from 'react';
3
3
  import { matchPath } from 'react-router';
4
- import moment from 'moment';
5
4
  import config from '@plone/volto/registry';
6
5
 
7
6
  /**
@@ -152,7 +151,7 @@ export const getColor = (name) => {
152
151
  * @param {string} format Date format of choice
153
152
  * @returns {Object|string} Moment object or string if format is set
154
153
  */
155
- export const parseDateTime = (locale, value, format) => {
154
+ export const parseDateTime = (locale, value, format, moment) => {
156
155
  // Used to set a server timezone or UTC as default
157
156
  moment.defineLocale(locale, moment.localeData(locale)._config); // copy locale to moment-timezone
158
157
  let datetime = null;
@@ -7,7 +7,9 @@ import {
7
7
  safeWrapper,
8
8
  normalizeLanguageName,
9
9
  hasApiExpander,
10
+ parseDateTime,
10
11
  } from './Utils';
12
+ import moment from 'moment';
11
13
 
12
14
  describe('Utils tests', () => {
13
15
  describe('difference', () => {
@@ -320,4 +322,27 @@ describe('Utils tests', () => {
320
322
  );
321
323
  });
322
324
  });
325
+
326
+ describe('parseDateTime', () => {
327
+ it('Parses iso date strings in en locale', () => {
328
+ const isoDate = '2022-01-16T07:40:04.331Z';
329
+ expect(
330
+ parseDateTime('en', isoDate, undefined, moment).toISOString(),
331
+ ).toBe(isoDate);
332
+ });
333
+
334
+ it('Parses iso date strings in de locale', () => {
335
+ const isoDate = '2022-01-16T07:40:04.331Z';
336
+ expect(
337
+ parseDateTime('de', isoDate, undefined, moment).toISOString(),
338
+ ).toBe(isoDate);
339
+ });
340
+
341
+ it('Parses iso date strings in de locale with Z marker', () => {
342
+ const isoDate = '2022-01-16T07:40:04.331';
343
+ expect(
344
+ parseDateTime('de', isoDate, undefined, moment).toISOString(),
345
+ ).toBe(`${isoDate}Z`);
346
+ });
347
+ });
323
348
  });