@atlaskit/link-datasource 4.29.4 → 4.30.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 +20 -0
- package/dist/cjs/hooks/useLoadOptions.js +1 -1
- package/dist/cjs/ui/assets-modal/modal/index.js +1 -1
- package/dist/cjs/ui/assets-modal/search-container/object-schema-select/index.js +1 -1
- package/dist/cjs/ui/common/modal/insert-button/index.js +1 -1
- package/dist/cjs/ui/issue-like-table/render-type/date-range/index.js +181 -0
- package/dist/cjs/ui/issue-like-table/render-type/date-range/messages.js +24 -0
- package/dist/cjs/ui/issue-like-table/render-type/index.js +19 -0
- package/dist/cjs/ui/issue-like-table/render-type/user/index.js +1 -1
- package/dist/es2019/hooks/useLoadOptions.js +1 -1
- package/dist/es2019/ui/assets-modal/modal/index.js +1 -1
- package/dist/es2019/ui/assets-modal/search-container/object-schema-select/index.js +1 -1
- package/dist/es2019/ui/common/modal/insert-button/index.js +1 -1
- package/dist/es2019/ui/issue-like-table/render-type/date-range/index.js +177 -0
- package/dist/es2019/ui/issue-like-table/render-type/date-range/messages.js +18 -0
- package/dist/es2019/ui/issue-like-table/render-type/index.js +17 -0
- package/dist/es2019/ui/issue-like-table/render-type/user/index.js +1 -1
- package/dist/esm/hooks/useLoadOptions.js +1 -1
- package/dist/esm/ui/assets-modal/modal/index.js +1 -1
- package/dist/esm/ui/assets-modal/search-container/object-schema-select/index.js +1 -1
- package/dist/esm/ui/common/modal/insert-button/index.js +1 -1
- package/dist/esm/ui/issue-like-table/render-type/date-range/index.js +173 -0
- package/dist/esm/ui/issue-like-table/render-type/date-range/messages.js +18 -0
- package/dist/esm/ui/issue-like-table/render-type/index.js +19 -0
- package/dist/esm/ui/issue-like-table/render-type/user/index.js +1 -1
- package/dist/types/hooks/useErrorLogger.d.ts +1 -1
- package/dist/types/ui/assets-modal/search-container/object-schema-select/index.d.ts +1 -1
- package/dist/types/ui/common/modal/insert-button/index.d.ts +1 -1
- package/dist/types/ui/issue-like-table/render-type/date-range/index.d.ts +11 -0
- package/dist/types/ui/issue-like-table/render-type/date-range/messages.d.ts +17 -0
- package/dist/types-ts4.5/hooks/useErrorLogger.d.ts +1 -1
- package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/index.d.ts +1 -1
- package/dist/types-ts4.5/ui/common/modal/insert-button/index.d.ts +1 -1
- package/dist/types-ts4.5/ui/issue-like-table/render-type/date-range/index.d.ts +11 -0
- package/dist/types-ts4.5/ui/issue-like-table/render-type/date-range/messages.d.ts +17 -0
- package/package.json +13 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atlaskit/link-datasource
|
|
2
2
|
|
|
3
|
+
## 4.30.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`c60de47015108`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c60de47015108) -
|
|
8
|
+
Fix types for editor related dependencies
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 4.30.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [`a477f1382d9c3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a477f1382d9c3) -
|
|
16
|
+
[ux] Add support for daterange data type in link-datasource to better represents data ranges like
|
|
17
|
+
day, month or quarter
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
|
|
3
23
|
## 4.29.4
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -226,7 +226,7 @@ var PlainAssetsConfigModal = function PlainAssetsConfigModal(props) {
|
|
|
226
226
|
// agreement with BE that we will use `key` for rendering smartlink
|
|
227
227
|
return data === null || data === void 0 || (_data$key = data.key) === null || _data$key === void 0 || (_data$key = _data$key.data) === null || _data$key === void 0 ? void 0 : _data$key.url;
|
|
228
228
|
}, [responseItems]);
|
|
229
|
-
var onInsertPressed = (0, _react.useCallback)(function (
|
|
229
|
+
var onInsertPressed = (0, _react.useCallback)(function (_e, analyticsEvent) {
|
|
230
230
|
var _insertButtonClickedE;
|
|
231
231
|
if (!aql || !schemaId || !workspaceId) {
|
|
232
232
|
return;
|
|
@@ -75,7 +75,7 @@ var AssetsObjectSchemaSelect = exports.AssetsObjectSchemaSelect = function Asset
|
|
|
75
75
|
workspaceId = _ref2.workspaceId,
|
|
76
76
|
initialObjectSchemas = _ref2.initialObjectSchemas,
|
|
77
77
|
_ref2$classNamePrefix = _ref2.classNamePrefix,
|
|
78
|
-
|
|
78
|
+
_classNamePrefix = _ref2$classNamePrefix === void 0 ? 'assets-datasource-modal--object-schema-select' : _ref2$classNamePrefix,
|
|
79
79
|
_ref2$testId = _ref2.testId,
|
|
80
80
|
testId = _ref2$testId === void 0 ? 'assets-datasource-modal--object-schema-select' : _ref2$testId;
|
|
81
81
|
var _useIntl = (0, _reactIntlNext.useIntl)(),
|
|
@@ -39,7 +39,7 @@ var InsertButton = exports.InsertButton = function InsertButton(_ref) {
|
|
|
39
39
|
var _useViewModeContext = (0, _useViewModeContext2.useViewModeContext)(),
|
|
40
40
|
currentViewMode = _useViewModeContext.currentViewMode;
|
|
41
41
|
var isInsertDisabled = !isValidParameters(parameters) || status === 'rejected' || status === 'unauthorized' || status === 'loading';
|
|
42
|
-
var onInsertPressed = (0, _react.useCallback)(function (
|
|
42
|
+
var onInsertPressed = (0, _react.useCallback)(function (_e, analyticsEvent) {
|
|
43
43
|
var _insertButtonClickedE;
|
|
44
44
|
if (!parameters || !isValidParameters(parameters) || !url) {
|
|
45
45
|
return;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = exports.DATERANGE_TYPE_TEST_ID = void 0;
|
|
8
|
+
exports.getFormattedDateRange = getFormattedDateRange;
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
|
11
|
+
var _addMonths = _interopRequireDefault(require("date-fns/addMonths"));
|
|
12
|
+
var _differenceInDays = _interopRequireDefault(require("date-fns/differenceInDays"));
|
|
13
|
+
var _endOfDay = _interopRequireDefault(require("date-fns/endOfDay"));
|
|
14
|
+
var _getDaysInMonth = _interopRequireDefault(require("date-fns/getDaysInMonth"));
|
|
15
|
+
var _isFirstDayOfMonth = _interopRequireDefault(require("date-fns/isFirstDayOfMonth"));
|
|
16
|
+
var _isLastDayOfMonth = _interopRequireDefault(require("date-fns/isLastDayOfMonth"));
|
|
17
|
+
var _isSameDay = _interopRequireDefault(require("date-fns/isSameDay"));
|
|
18
|
+
var _isSameMonth = _interopRequireDefault(require("date-fns/isSameMonth"));
|
|
19
|
+
var _isSameYear = _interopRequireDefault(require("date-fns/isSameYear"));
|
|
20
|
+
var _startOfDay = _interopRequireDefault(require("date-fns/startOfDay"));
|
|
21
|
+
var _reactIntlNext = require("react-intl-next");
|
|
22
|
+
var _compiled = require("@atlaskit/primitives/compiled");
|
|
23
|
+
var _messages = require("./messages");
|
|
24
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
25
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
26
|
+
var DATERANGE_TYPE_TEST_ID = exports.DATERANGE_TYPE_TEST_ID = 'link-datasource-render-type--daterange';
|
|
27
|
+
var dateOptions = {
|
|
28
|
+
month: 'short',
|
|
29
|
+
day: 'numeric',
|
|
30
|
+
year: 'numeric'
|
|
31
|
+
};
|
|
32
|
+
var timeOptions = {
|
|
33
|
+
hour12: false,
|
|
34
|
+
hour: '2-digit',
|
|
35
|
+
minute: '2-digit'
|
|
36
|
+
};
|
|
37
|
+
var isDayRange = function isDayRange(startDate, endDate) {
|
|
38
|
+
// Naivly, we could just check
|
|
39
|
+
// return startDate.getTime() === endDate.getTime();
|
|
40
|
+
return (0, _isSameYear.default)(startDate, endDate) && (0, _isSameMonth.default)(startDate, endDate) && (0, _isSameDay.default)(startDate, endDate);
|
|
41
|
+
};
|
|
42
|
+
var isMonthRange = function isMonthRange(startDate, endDate) {
|
|
43
|
+
return (0, _isSameYear.default)(startDate, endDate) && (0, _isSameMonth.default)(startDate, endDate) && (0, _isFirstDayOfMonth.default)(startDate) && (0, _isLastDayOfMonth.default)(endDate);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Checks if the date range is a quarter range.
|
|
48
|
+
* A quarter range is a range of 3 months.
|
|
49
|
+
* The start date must be the first day of the month.
|
|
50
|
+
* The end date must be the last day of the month.
|
|
51
|
+
* Quarters can span across multiple years.
|
|
52
|
+
*/
|
|
53
|
+
var isQuarterRange = function isQuarterRange(startDate, endDate) {
|
|
54
|
+
// We need to add 1 to the difference in days
|
|
55
|
+
// because the differenceInDays method returns the number of full days between the two dates
|
|
56
|
+
// and we want to include the start and end dates
|
|
57
|
+
var diffDays = Math.abs((0, _differenceInDays.default)(startDate, endDate)) + 1;
|
|
58
|
+
var firstMonthDays = (0, _getDaysInMonth.default)(startDate);
|
|
59
|
+
var secondMonthDays = (0, _getDaysInMonth.default)((0, _addMonths.default)(startDate, 1));
|
|
60
|
+
var thirdMonthDays = (0, _getDaysInMonth.default)(endDate);
|
|
61
|
+
return diffDays === firstMonthDays + secondMonthDays + thirdMonthDays && (0, _isFirstDayOfMonth.default)(startDate) && (0, _isLastDayOfMonth.default)(endDate);
|
|
62
|
+
};
|
|
63
|
+
var getDateScale = function getDateScale(startDate, endDate) {
|
|
64
|
+
if (isDayRange(startDate, endDate)) {
|
|
65
|
+
// start: 2025-11-01
|
|
66
|
+
// end: 2025-11-01
|
|
67
|
+
return 'day';
|
|
68
|
+
}
|
|
69
|
+
if (isMonthRange(startDate, endDate)) {
|
|
70
|
+
// start: 2025-11-01
|
|
71
|
+
// end: 2025-11-30
|
|
72
|
+
return 'month';
|
|
73
|
+
}
|
|
74
|
+
if (isQuarterRange(startDate, endDate)) {
|
|
75
|
+
// start: 2025-11-01
|
|
76
|
+
// end: 2026-01-31
|
|
77
|
+
return 'quarter';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// start: 2025-11-02
|
|
81
|
+
// end: 2026-05-19
|
|
82
|
+
return 'full';
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// I decided to reuse the same logic as we use currently in the date-time render type
|
|
86
|
+
// Alternatively, we could also use here `parseISO` from `date-fns`
|
|
87
|
+
var shiftUtcToLocal = function shiftUtcToLocal(dateString) {
|
|
88
|
+
// In some cases we get a value of `2023-12-20` which when parsed by JS assumes meantime timezone, causing the date
|
|
89
|
+
// to be one day off in some timezones. We want it to display the date without converting timezones and a solution
|
|
90
|
+
// is to replace the hyphens with slashes. So it should be 20th Dec regardless of the timezone in this case.
|
|
91
|
+
// See https://stackoverflow.com/a/31732581
|
|
92
|
+
var dateValue = /^\d{4}-\d{2}-\d{2}$/.exec(dateString) ? dateString.replace(/-/g, '/') : dateString;
|
|
93
|
+
return new Date(dateValue);
|
|
94
|
+
};
|
|
95
|
+
var isDateTimeString = function isDateTimeString(dateString) {
|
|
96
|
+
return dateString.match(/^\d{4}-\d{2}-\d{2}/) !== null && dateString.includes('T');
|
|
97
|
+
};
|
|
98
|
+
function getFormattedDateRange(startValue, endValue, formatDate, formatMessage) {
|
|
99
|
+
if (!startValue || !endValue) {
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
102
|
+
var isDateTime = isDateTimeString(startValue) && isDateTimeString(endValue);
|
|
103
|
+
var startDate = isDateTime ? new Date(startValue) : (0, _startOfDay.default)(shiftUtcToLocal(startValue));
|
|
104
|
+
var endDate = isDateTime ? new Date(endValue) : (0, _endOfDay.default)(shiftUtcToLocal(endValue));
|
|
105
|
+
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
|
106
|
+
return '';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// If startValue and endValue are valid ISO date strings, we consider it a full range
|
|
110
|
+
var dateScale = isDateTime ? 'full' : getDateScale(startDate, endDate);
|
|
111
|
+
switch (dateScale) {
|
|
112
|
+
case 'day':
|
|
113
|
+
// Nov 1, 2025
|
|
114
|
+
return formatDate(startDate, {
|
|
115
|
+
month: 'short',
|
|
116
|
+
day: 'numeric',
|
|
117
|
+
year: 'numeric'
|
|
118
|
+
});
|
|
119
|
+
case 'month':
|
|
120
|
+
// Nov 2025
|
|
121
|
+
return formatDate(startDate, {
|
|
122
|
+
month: 'short',
|
|
123
|
+
year: 'numeric'
|
|
124
|
+
});
|
|
125
|
+
case 'quarter':
|
|
126
|
+
{
|
|
127
|
+
// Jan-Mar, 2025
|
|
128
|
+
if ((0, _isSameYear.default)(startDate, endDate)) {
|
|
129
|
+
return formatMessage(_messages.messages.quarterRange, {
|
|
130
|
+
startMonth: formatDate(startDate, {
|
|
131
|
+
month: 'short'
|
|
132
|
+
}),
|
|
133
|
+
endMonth: formatDate(endDate, {
|
|
134
|
+
month: 'short'
|
|
135
|
+
}),
|
|
136
|
+
year: formatDate(startDate, {
|
|
137
|
+
year: 'numeric'
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// Dec-Feb, 2025-2026
|
|
142
|
+
return formatMessage(_messages.messages.quarterRangeOverYears, {
|
|
143
|
+
startMonth: formatDate(startDate, {
|
|
144
|
+
month: 'short'
|
|
145
|
+
}),
|
|
146
|
+
endMonth: formatDate(endDate, {
|
|
147
|
+
month: 'short'
|
|
148
|
+
}),
|
|
149
|
+
startYear: formatDate(startDate, {
|
|
150
|
+
year: 'numeric'
|
|
151
|
+
}),
|
|
152
|
+
endYear: formatDate(endDate, {
|
|
153
|
+
year: 'numeric'
|
|
154
|
+
})
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
case 'full':
|
|
158
|
+
// Nov 1, 2025 - May 19, 2026
|
|
159
|
+
// Jan 1, 2025, 00:00 - Mar 31, 2025, 23:59
|
|
160
|
+
return formatMessage(_messages.messages.fullRange, {
|
|
161
|
+
start: formatDate(startDate, _objectSpread(_objectSpread({}, dateOptions), timeOptions)),
|
|
162
|
+
end: formatDate(endDate, _objectSpread(_objectSpread({}, dateOptions), timeOptions))
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
var DateRangeRenderType = function DateRangeRenderType(_ref) {
|
|
167
|
+
var value = _ref.value,
|
|
168
|
+
_ref$testId = _ref.testId,
|
|
169
|
+
testId = _ref$testId === void 0 ? DATERANGE_TYPE_TEST_ID : _ref$testId;
|
|
170
|
+
var _useIntl = (0, _reactIntlNext.useIntl)(),
|
|
171
|
+
formatDate = _useIntl.formatDate,
|
|
172
|
+
formatMessage = _useIntl.formatMessage;
|
|
173
|
+
var formattedString = getFormattedDateRange(value.start, value.end, formatDate, formatMessage);
|
|
174
|
+
if (formattedString === '') {
|
|
175
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null);
|
|
176
|
+
}
|
|
177
|
+
return /*#__PURE__*/_react.default.createElement(_compiled.Text, {
|
|
178
|
+
testId: testId
|
|
179
|
+
}, formattedString);
|
|
180
|
+
};
|
|
181
|
+
var _default = exports.default = DateRangeRenderType;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.messages = void 0;
|
|
7
|
+
var _reactIntlNext = require("react-intl-next");
|
|
8
|
+
var messages = exports.messages = (0, _reactIntlNext.defineMessages)({
|
|
9
|
+
quarterRange: {
|
|
10
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.quarterRange',
|
|
11
|
+
description: 'The formatted date range for a quarter range',
|
|
12
|
+
defaultMessage: '{startMonth}-{endMonth}, {year}'
|
|
13
|
+
},
|
|
14
|
+
quarterRangeOverYears: {
|
|
15
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.quarterRangeOverYears',
|
|
16
|
+
description: 'The formatted date range for a quarter range that spans across multiple years',
|
|
17
|
+
defaultMessage: '{startMonth}-{endMonth}, {startYear}-{endYear}'
|
|
18
|
+
},
|
|
19
|
+
fullRange: {
|
|
20
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.fullRange',
|
|
21
|
+
description: 'The formatted date range for a full range (day, month, quarter, or full)',
|
|
22
|
+
defaultMessage: '{start} - {end}'
|
|
23
|
+
}
|
|
24
|
+
});
|
|
@@ -10,6 +10,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
|
|
|
10
10
|
var _react = _interopRequireDefault(require("react"));
|
|
11
11
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
12
12
|
var _boolean = _interopRequireDefault(require("./boolean"));
|
|
13
|
+
var _dateRange = _interopRequireWildcard(require("./date-range"));
|
|
13
14
|
var _dateTime = _interopRequireWildcard(require("./date-time"));
|
|
14
15
|
var _icon = _interopRequireDefault(require("./icon"));
|
|
15
16
|
var _link = _interopRequireDefault(require("./link"));
|
|
@@ -32,6 +33,13 @@ var stringifyType = exports.stringifyType = function stringifyType(_ref, formatM
|
|
|
32
33
|
return (0, _dateTime.getFormattedDate)(value, 'date', formatDate);
|
|
33
34
|
case 'datetime':
|
|
34
35
|
return (0, _dateTime.getFormattedDate)(value, 'datetime', formatDate);
|
|
36
|
+
case 'daterange':
|
|
37
|
+
{
|
|
38
|
+
if ((0, _platformFeatureFlags.fg)('jpd_confluence_date_fields_improvements')) {
|
|
39
|
+
return (0, _dateRange.getFormattedDateRange)(value.start, value.end, formatDate, formatMessage);
|
|
40
|
+
}
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
35
43
|
case 'time':
|
|
36
44
|
return (0, _dateTime.getFormattedDate)(value, 'time', formatDate);
|
|
37
45
|
case 'icon':
|
|
@@ -78,6 +86,17 @@ var renderType = exports.renderType = function renderType(item) {
|
|
|
78
86
|
display: "datetime"
|
|
79
87
|
});
|
|
80
88
|
});
|
|
89
|
+
case 'daterange':
|
|
90
|
+
{
|
|
91
|
+
if ((0, _platformFeatureFlags.fg)('jpd_confluence_date_fields_improvements')) {
|
|
92
|
+
return item.values.map(function (dateRangeValue) {
|
|
93
|
+
return /*#__PURE__*/_react.default.createElement(_dateRange.default, {
|
|
94
|
+
value: dateRangeValue
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null);
|
|
99
|
+
}
|
|
81
100
|
case 'icon':
|
|
82
101
|
return item.values.map(function (iconValue) {
|
|
83
102
|
return /*#__PURE__*/_react.default.createElement(_icon.default, iconValue);
|
|
@@ -43,7 +43,7 @@ var AvatarGroupWrapperStyles = (0, _react.forwardRef)(function (_ref, __cmplr) {
|
|
|
43
43
|
if (process.env.NODE_ENV !== 'production') {
|
|
44
44
|
AvatarGroupWrapperStyles.displayName = 'AvatarGroupWrapperStyles';
|
|
45
45
|
}
|
|
46
|
-
var getMaxUserCount = function getMaxUserCount(
|
|
46
|
+
var getMaxUserCount = function getMaxUserCount(_userCount, availableWidth) {
|
|
47
47
|
if (availableWidth <= 28) {
|
|
48
48
|
// If width is less than or equal to 28px, we should only display the user count
|
|
49
49
|
return 1;
|
|
@@ -200,7 +200,7 @@ const PlainAssetsConfigModal = props => {
|
|
|
200
200
|
// agreement with BE that we will use `key` for rendering smartlink
|
|
201
201
|
return data === null || data === void 0 ? void 0 : (_data$key = data.key) === null || _data$key === void 0 ? void 0 : (_data$key$data = _data$key.data) === null || _data$key$data === void 0 ? void 0 : _data$key$data.url;
|
|
202
202
|
}, [responseItems]);
|
|
203
|
-
const onInsertPressed = useCallback((
|
|
203
|
+
const onInsertPressed = useCallback((_e, analyticsEvent) => {
|
|
204
204
|
var _insertButtonClickedE;
|
|
205
205
|
if (!aql || !schemaId || !workspaceId) {
|
|
206
206
|
return;
|
|
@@ -54,7 +54,7 @@ export const AssetsObjectSchemaSelect = ({
|
|
|
54
54
|
value,
|
|
55
55
|
workspaceId,
|
|
56
56
|
initialObjectSchemas,
|
|
57
|
-
classNamePrefix = 'assets-datasource-modal--object-schema-select',
|
|
57
|
+
classNamePrefix: _classNamePrefix = 'assets-datasource-modal--object-schema-select',
|
|
58
58
|
testId = 'assets-datasource-modal--object-schema-select'
|
|
59
59
|
}) => {
|
|
60
60
|
const {
|
|
@@ -31,7 +31,7 @@ export const InsertButton = ({
|
|
|
31
31
|
currentViewMode
|
|
32
32
|
} = useViewModeContext();
|
|
33
33
|
const isInsertDisabled = !isValidParameters(parameters) || status === 'rejected' || status === 'unauthorized' || status === 'loading';
|
|
34
|
-
const onInsertPressed = useCallback((
|
|
34
|
+
const onInsertPressed = useCallback((_e, analyticsEvent) => {
|
|
35
35
|
var _insertButtonClickedE;
|
|
36
36
|
if (!parameters || !isValidParameters(parameters) || !url) {
|
|
37
37
|
return;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import addMonths from 'date-fns/addMonths';
|
|
3
|
+
import differenceInDays from 'date-fns/differenceInDays';
|
|
4
|
+
import endOfDay from 'date-fns/endOfDay';
|
|
5
|
+
import getDaysInMonth from 'date-fns/getDaysInMonth';
|
|
6
|
+
import isFirstDayOfMonth from 'date-fns/isFirstDayOfMonth';
|
|
7
|
+
import isLastDayOfMonth from 'date-fns/isLastDayOfMonth';
|
|
8
|
+
import isSameDay from 'date-fns/isSameDay';
|
|
9
|
+
import isSameMonth from 'date-fns/isSameMonth';
|
|
10
|
+
import isSameYear from 'date-fns/isSameYear';
|
|
11
|
+
import startOfDay from 'date-fns/startOfDay';
|
|
12
|
+
import { useIntl } from 'react-intl-next';
|
|
13
|
+
import { Text } from '@atlaskit/primitives/compiled';
|
|
14
|
+
import { messages } from './messages';
|
|
15
|
+
export const DATERANGE_TYPE_TEST_ID = 'link-datasource-render-type--daterange';
|
|
16
|
+
const dateOptions = {
|
|
17
|
+
month: 'short',
|
|
18
|
+
day: 'numeric',
|
|
19
|
+
year: 'numeric'
|
|
20
|
+
};
|
|
21
|
+
const timeOptions = {
|
|
22
|
+
hour12: false,
|
|
23
|
+
hour: '2-digit',
|
|
24
|
+
minute: '2-digit'
|
|
25
|
+
};
|
|
26
|
+
const isDayRange = (startDate, endDate) => {
|
|
27
|
+
// Naivly, we could just check
|
|
28
|
+
// return startDate.getTime() === endDate.getTime();
|
|
29
|
+
return isSameYear(startDate, endDate) && isSameMonth(startDate, endDate) && isSameDay(startDate, endDate);
|
|
30
|
+
};
|
|
31
|
+
const isMonthRange = (startDate, endDate) => {
|
|
32
|
+
return isSameYear(startDate, endDate) && isSameMonth(startDate, endDate) && isFirstDayOfMonth(startDate) && isLastDayOfMonth(endDate);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Checks if the date range is a quarter range.
|
|
37
|
+
* A quarter range is a range of 3 months.
|
|
38
|
+
* The start date must be the first day of the month.
|
|
39
|
+
* The end date must be the last day of the month.
|
|
40
|
+
* Quarters can span across multiple years.
|
|
41
|
+
*/
|
|
42
|
+
const isQuarterRange = (startDate, endDate) => {
|
|
43
|
+
// We need to add 1 to the difference in days
|
|
44
|
+
// because the differenceInDays method returns the number of full days between the two dates
|
|
45
|
+
// and we want to include the start and end dates
|
|
46
|
+
const diffDays = Math.abs(differenceInDays(startDate, endDate)) + 1;
|
|
47
|
+
const firstMonthDays = getDaysInMonth(startDate);
|
|
48
|
+
const secondMonthDays = getDaysInMonth(addMonths(startDate, 1));
|
|
49
|
+
const thirdMonthDays = getDaysInMonth(endDate);
|
|
50
|
+
return diffDays === firstMonthDays + secondMonthDays + thirdMonthDays && isFirstDayOfMonth(startDate) && isLastDayOfMonth(endDate);
|
|
51
|
+
};
|
|
52
|
+
const getDateScale = (startDate, endDate) => {
|
|
53
|
+
if (isDayRange(startDate, endDate)) {
|
|
54
|
+
// start: 2025-11-01
|
|
55
|
+
// end: 2025-11-01
|
|
56
|
+
return 'day';
|
|
57
|
+
}
|
|
58
|
+
if (isMonthRange(startDate, endDate)) {
|
|
59
|
+
// start: 2025-11-01
|
|
60
|
+
// end: 2025-11-30
|
|
61
|
+
return 'month';
|
|
62
|
+
}
|
|
63
|
+
if (isQuarterRange(startDate, endDate)) {
|
|
64
|
+
// start: 2025-11-01
|
|
65
|
+
// end: 2026-01-31
|
|
66
|
+
return 'quarter';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// start: 2025-11-02
|
|
70
|
+
// end: 2026-05-19
|
|
71
|
+
return 'full';
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// I decided to reuse the same logic as we use currently in the date-time render type
|
|
75
|
+
// Alternatively, we could also use here `parseISO` from `date-fns`
|
|
76
|
+
const shiftUtcToLocal = dateString => {
|
|
77
|
+
// In some cases we get a value of `2023-12-20` which when parsed by JS assumes meantime timezone, causing the date
|
|
78
|
+
// to be one day off in some timezones. We want it to display the date without converting timezones and a solution
|
|
79
|
+
// is to replace the hyphens with slashes. So it should be 20th Dec regardless of the timezone in this case.
|
|
80
|
+
// See https://stackoverflow.com/a/31732581
|
|
81
|
+
const dateValue = /^\d{4}-\d{2}-\d{2}$/.exec(dateString) ? dateString.replace(/-/g, '/') : dateString;
|
|
82
|
+
return new Date(dateValue);
|
|
83
|
+
};
|
|
84
|
+
const isDateTimeString = dateString => {
|
|
85
|
+
return dateString.match(/^\d{4}-\d{2}-\d{2}/) !== null && dateString.includes('T');
|
|
86
|
+
};
|
|
87
|
+
export function getFormattedDateRange(startValue, endValue, formatDate, formatMessage) {
|
|
88
|
+
if (!startValue || !endValue) {
|
|
89
|
+
return '';
|
|
90
|
+
}
|
|
91
|
+
const isDateTime = isDateTimeString(startValue) && isDateTimeString(endValue);
|
|
92
|
+
const startDate = isDateTime ? new Date(startValue) : startOfDay(shiftUtcToLocal(startValue));
|
|
93
|
+
const endDate = isDateTime ? new Date(endValue) : endOfDay(shiftUtcToLocal(endValue));
|
|
94
|
+
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
|
95
|
+
return '';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// If startValue and endValue are valid ISO date strings, we consider it a full range
|
|
99
|
+
const dateScale = isDateTime ? 'full' : getDateScale(startDate, endDate);
|
|
100
|
+
switch (dateScale) {
|
|
101
|
+
case 'day':
|
|
102
|
+
// Nov 1, 2025
|
|
103
|
+
return formatDate(startDate, {
|
|
104
|
+
month: 'short',
|
|
105
|
+
day: 'numeric',
|
|
106
|
+
year: 'numeric'
|
|
107
|
+
});
|
|
108
|
+
case 'month':
|
|
109
|
+
// Nov 2025
|
|
110
|
+
return formatDate(startDate, {
|
|
111
|
+
month: 'short',
|
|
112
|
+
year: 'numeric'
|
|
113
|
+
});
|
|
114
|
+
case 'quarter':
|
|
115
|
+
{
|
|
116
|
+
// Jan-Mar, 2025
|
|
117
|
+
if (isSameYear(startDate, endDate)) {
|
|
118
|
+
return formatMessage(messages.quarterRange, {
|
|
119
|
+
startMonth: formatDate(startDate, {
|
|
120
|
+
month: 'short'
|
|
121
|
+
}),
|
|
122
|
+
endMonth: formatDate(endDate, {
|
|
123
|
+
month: 'short'
|
|
124
|
+
}),
|
|
125
|
+
year: formatDate(startDate, {
|
|
126
|
+
year: 'numeric'
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// Dec-Feb, 2025-2026
|
|
131
|
+
return formatMessage(messages.quarterRangeOverYears, {
|
|
132
|
+
startMonth: formatDate(startDate, {
|
|
133
|
+
month: 'short'
|
|
134
|
+
}),
|
|
135
|
+
endMonth: formatDate(endDate, {
|
|
136
|
+
month: 'short'
|
|
137
|
+
}),
|
|
138
|
+
startYear: formatDate(startDate, {
|
|
139
|
+
year: 'numeric'
|
|
140
|
+
}),
|
|
141
|
+
endYear: formatDate(endDate, {
|
|
142
|
+
year: 'numeric'
|
|
143
|
+
})
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
case 'full':
|
|
147
|
+
// Nov 1, 2025 - May 19, 2026
|
|
148
|
+
// Jan 1, 2025, 00:00 - Mar 31, 2025, 23:59
|
|
149
|
+
return formatMessage(messages.fullRange, {
|
|
150
|
+
start: formatDate(startDate, {
|
|
151
|
+
...dateOptions,
|
|
152
|
+
...timeOptions
|
|
153
|
+
}),
|
|
154
|
+
end: formatDate(endDate, {
|
|
155
|
+
...dateOptions,
|
|
156
|
+
...timeOptions
|
|
157
|
+
})
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const DateRangeRenderType = ({
|
|
162
|
+
value,
|
|
163
|
+
testId = DATERANGE_TYPE_TEST_ID
|
|
164
|
+
}) => {
|
|
165
|
+
const {
|
|
166
|
+
formatDate,
|
|
167
|
+
formatMessage
|
|
168
|
+
} = useIntl();
|
|
169
|
+
const formattedString = getFormattedDateRange(value.start, value.end, formatDate, formatMessage);
|
|
170
|
+
if (formattedString === '') {
|
|
171
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
|
172
|
+
}
|
|
173
|
+
return /*#__PURE__*/React.createElement(Text, {
|
|
174
|
+
testId: testId
|
|
175
|
+
}, formattedString);
|
|
176
|
+
};
|
|
177
|
+
export default DateRangeRenderType;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export const messages = defineMessages({
|
|
3
|
+
quarterRange: {
|
|
4
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.quarterRange',
|
|
5
|
+
description: 'The formatted date range for a quarter range',
|
|
6
|
+
defaultMessage: '{startMonth}-{endMonth}, {year}'
|
|
7
|
+
},
|
|
8
|
+
quarterRangeOverYears: {
|
|
9
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.quarterRangeOverYears',
|
|
10
|
+
description: 'The formatted date range for a quarter range that spans across multiple years',
|
|
11
|
+
defaultMessage: '{startMonth}-{endMonth}, {startYear}-{endYear}'
|
|
12
|
+
},
|
|
13
|
+
fullRange: {
|
|
14
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.fullRange',
|
|
15
|
+
description: 'The formatted date range for a full range (day, month, quarter, or full)',
|
|
16
|
+
defaultMessage: '{start} - {end}'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
@@ -2,6 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
4
|
import BooleanRenderType from './boolean';
|
|
5
|
+
import DateRangeRenderType, { getFormattedDateRange } from './date-range';
|
|
5
6
|
import DateTimeRenderType, { getFormattedDate } from './date-time';
|
|
6
7
|
import IconRenderType from './icon';
|
|
7
8
|
import LinkRenderType from './link';
|
|
@@ -24,6 +25,13 @@ export const stringifyType = ({
|
|
|
24
25
|
return getFormattedDate(value, 'date', formatDate);
|
|
25
26
|
case 'datetime':
|
|
26
27
|
return getFormattedDate(value, 'datetime', formatDate);
|
|
28
|
+
case 'daterange':
|
|
29
|
+
{
|
|
30
|
+
if (fg('jpd_confluence_date_fields_improvements')) {
|
|
31
|
+
return getFormattedDateRange(value.start, value.end, formatDate, formatMessage);
|
|
32
|
+
}
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
27
35
|
case 'time':
|
|
28
36
|
return getFormattedDate(value, 'time', formatDate);
|
|
29
37
|
case 'icon':
|
|
@@ -64,6 +72,15 @@ export const renderType = item => {
|
|
|
64
72
|
value: datTimeValue,
|
|
65
73
|
display: "datetime"
|
|
66
74
|
}));
|
|
75
|
+
case 'daterange':
|
|
76
|
+
{
|
|
77
|
+
if (fg('jpd_confluence_date_fields_improvements')) {
|
|
78
|
+
return item.values.map(dateRangeValue => /*#__PURE__*/React.createElement(DateRangeRenderType, {
|
|
79
|
+
value: dateRangeValue
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
|
83
|
+
}
|
|
67
84
|
case 'icon':
|
|
68
85
|
return item.values.map(iconValue => /*#__PURE__*/React.createElement(IconRenderType, iconValue));
|
|
69
86
|
case 'link':
|
|
@@ -32,7 +32,7 @@ const AvatarGroupWrapperStyles = forwardRef(({
|
|
|
32
32
|
if (process.env.NODE_ENV !== 'production') {
|
|
33
33
|
AvatarGroupWrapperStyles.displayName = 'AvatarGroupWrapperStyles';
|
|
34
34
|
}
|
|
35
|
-
const getMaxUserCount = (
|
|
35
|
+
const getMaxUserCount = (_userCount, availableWidth) => {
|
|
36
36
|
if (availableWidth <= 28) {
|
|
37
37
|
// If width is less than or equal to 28px, we should only display the user count
|
|
38
38
|
return 1;
|
|
@@ -217,7 +217,7 @@ var PlainAssetsConfigModal = function PlainAssetsConfigModal(props) {
|
|
|
217
217
|
// agreement with BE that we will use `key` for rendering smartlink
|
|
218
218
|
return data === null || data === void 0 || (_data$key = data.key) === null || _data$key === void 0 || (_data$key = _data$key.data) === null || _data$key === void 0 ? void 0 : _data$key.url;
|
|
219
219
|
}, [responseItems]);
|
|
220
|
-
var onInsertPressed = useCallback(function (
|
|
220
|
+
var onInsertPressed = useCallback(function (_e, analyticsEvent) {
|
|
221
221
|
var _insertButtonClickedE;
|
|
222
222
|
if (!aql || !schemaId || !workspaceId) {
|
|
223
223
|
return;
|
|
@@ -68,7 +68,7 @@ export var AssetsObjectSchemaSelect = function AssetsObjectSchemaSelect(_ref2) {
|
|
|
68
68
|
workspaceId = _ref2.workspaceId,
|
|
69
69
|
initialObjectSchemas = _ref2.initialObjectSchemas,
|
|
70
70
|
_ref2$classNamePrefix = _ref2.classNamePrefix,
|
|
71
|
-
|
|
71
|
+
_classNamePrefix = _ref2$classNamePrefix === void 0 ? 'assets-datasource-modal--object-schema-select' : _ref2$classNamePrefix,
|
|
72
72
|
_ref2$testId = _ref2.testId,
|
|
73
73
|
testId = _ref2$testId === void 0 ? 'assets-datasource-modal--object-schema-select' : _ref2$testId;
|
|
74
74
|
var _useIntl = useIntl(),
|
|
@@ -30,7 +30,7 @@ export var InsertButton = function InsertButton(_ref) {
|
|
|
30
30
|
var _useViewModeContext = useViewModeContext(),
|
|
31
31
|
currentViewMode = _useViewModeContext.currentViewMode;
|
|
32
32
|
var isInsertDisabled = !isValidParameters(parameters) || status === 'rejected' || status === 'unauthorized' || status === 'loading';
|
|
33
|
-
var onInsertPressed = useCallback(function (
|
|
33
|
+
var onInsertPressed = useCallback(function (_e, analyticsEvent) {
|
|
34
34
|
var _insertButtonClickedE;
|
|
35
35
|
if (!parameters || !isValidParameters(parameters) || !url) {
|
|
36
36
|
return;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import addMonths from 'date-fns/addMonths';
|
|
6
|
+
import differenceInDays from 'date-fns/differenceInDays';
|
|
7
|
+
import endOfDay from 'date-fns/endOfDay';
|
|
8
|
+
import getDaysInMonth from 'date-fns/getDaysInMonth';
|
|
9
|
+
import isFirstDayOfMonth from 'date-fns/isFirstDayOfMonth';
|
|
10
|
+
import isLastDayOfMonth from 'date-fns/isLastDayOfMonth';
|
|
11
|
+
import isSameDay from 'date-fns/isSameDay';
|
|
12
|
+
import isSameMonth from 'date-fns/isSameMonth';
|
|
13
|
+
import isSameYear from 'date-fns/isSameYear';
|
|
14
|
+
import startOfDay from 'date-fns/startOfDay';
|
|
15
|
+
import { useIntl } from 'react-intl-next';
|
|
16
|
+
import { Text } from '@atlaskit/primitives/compiled';
|
|
17
|
+
import { messages } from './messages';
|
|
18
|
+
export var DATERANGE_TYPE_TEST_ID = 'link-datasource-render-type--daterange';
|
|
19
|
+
var dateOptions = {
|
|
20
|
+
month: 'short',
|
|
21
|
+
day: 'numeric',
|
|
22
|
+
year: 'numeric'
|
|
23
|
+
};
|
|
24
|
+
var timeOptions = {
|
|
25
|
+
hour12: false,
|
|
26
|
+
hour: '2-digit',
|
|
27
|
+
minute: '2-digit'
|
|
28
|
+
};
|
|
29
|
+
var isDayRange = function isDayRange(startDate, endDate) {
|
|
30
|
+
// Naivly, we could just check
|
|
31
|
+
// return startDate.getTime() === endDate.getTime();
|
|
32
|
+
return isSameYear(startDate, endDate) && isSameMonth(startDate, endDate) && isSameDay(startDate, endDate);
|
|
33
|
+
};
|
|
34
|
+
var isMonthRange = function isMonthRange(startDate, endDate) {
|
|
35
|
+
return isSameYear(startDate, endDate) && isSameMonth(startDate, endDate) && isFirstDayOfMonth(startDate) && isLastDayOfMonth(endDate);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Checks if the date range is a quarter range.
|
|
40
|
+
* A quarter range is a range of 3 months.
|
|
41
|
+
* The start date must be the first day of the month.
|
|
42
|
+
* The end date must be the last day of the month.
|
|
43
|
+
* Quarters can span across multiple years.
|
|
44
|
+
*/
|
|
45
|
+
var isQuarterRange = function isQuarterRange(startDate, endDate) {
|
|
46
|
+
// We need to add 1 to the difference in days
|
|
47
|
+
// because the differenceInDays method returns the number of full days between the two dates
|
|
48
|
+
// and we want to include the start and end dates
|
|
49
|
+
var diffDays = Math.abs(differenceInDays(startDate, endDate)) + 1;
|
|
50
|
+
var firstMonthDays = getDaysInMonth(startDate);
|
|
51
|
+
var secondMonthDays = getDaysInMonth(addMonths(startDate, 1));
|
|
52
|
+
var thirdMonthDays = getDaysInMonth(endDate);
|
|
53
|
+
return diffDays === firstMonthDays + secondMonthDays + thirdMonthDays && isFirstDayOfMonth(startDate) && isLastDayOfMonth(endDate);
|
|
54
|
+
};
|
|
55
|
+
var getDateScale = function getDateScale(startDate, endDate) {
|
|
56
|
+
if (isDayRange(startDate, endDate)) {
|
|
57
|
+
// start: 2025-11-01
|
|
58
|
+
// end: 2025-11-01
|
|
59
|
+
return 'day';
|
|
60
|
+
}
|
|
61
|
+
if (isMonthRange(startDate, endDate)) {
|
|
62
|
+
// start: 2025-11-01
|
|
63
|
+
// end: 2025-11-30
|
|
64
|
+
return 'month';
|
|
65
|
+
}
|
|
66
|
+
if (isQuarterRange(startDate, endDate)) {
|
|
67
|
+
// start: 2025-11-01
|
|
68
|
+
// end: 2026-01-31
|
|
69
|
+
return 'quarter';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// start: 2025-11-02
|
|
73
|
+
// end: 2026-05-19
|
|
74
|
+
return 'full';
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// I decided to reuse the same logic as we use currently in the date-time render type
|
|
78
|
+
// Alternatively, we could also use here `parseISO` from `date-fns`
|
|
79
|
+
var shiftUtcToLocal = function shiftUtcToLocal(dateString) {
|
|
80
|
+
// In some cases we get a value of `2023-12-20` which when parsed by JS assumes meantime timezone, causing the date
|
|
81
|
+
// to be one day off in some timezones. We want it to display the date without converting timezones and a solution
|
|
82
|
+
// is to replace the hyphens with slashes. So it should be 20th Dec regardless of the timezone in this case.
|
|
83
|
+
// See https://stackoverflow.com/a/31732581
|
|
84
|
+
var dateValue = /^\d{4}-\d{2}-\d{2}$/.exec(dateString) ? dateString.replace(/-/g, '/') : dateString;
|
|
85
|
+
return new Date(dateValue);
|
|
86
|
+
};
|
|
87
|
+
var isDateTimeString = function isDateTimeString(dateString) {
|
|
88
|
+
return dateString.match(/^\d{4}-\d{2}-\d{2}/) !== null && dateString.includes('T');
|
|
89
|
+
};
|
|
90
|
+
export function getFormattedDateRange(startValue, endValue, formatDate, formatMessage) {
|
|
91
|
+
if (!startValue || !endValue) {
|
|
92
|
+
return '';
|
|
93
|
+
}
|
|
94
|
+
var isDateTime = isDateTimeString(startValue) && isDateTimeString(endValue);
|
|
95
|
+
var startDate = isDateTime ? new Date(startValue) : startOfDay(shiftUtcToLocal(startValue));
|
|
96
|
+
var endDate = isDateTime ? new Date(endValue) : endOfDay(shiftUtcToLocal(endValue));
|
|
97
|
+
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
|
98
|
+
return '';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// If startValue and endValue are valid ISO date strings, we consider it a full range
|
|
102
|
+
var dateScale = isDateTime ? 'full' : getDateScale(startDate, endDate);
|
|
103
|
+
switch (dateScale) {
|
|
104
|
+
case 'day':
|
|
105
|
+
// Nov 1, 2025
|
|
106
|
+
return formatDate(startDate, {
|
|
107
|
+
month: 'short',
|
|
108
|
+
day: 'numeric',
|
|
109
|
+
year: 'numeric'
|
|
110
|
+
});
|
|
111
|
+
case 'month':
|
|
112
|
+
// Nov 2025
|
|
113
|
+
return formatDate(startDate, {
|
|
114
|
+
month: 'short',
|
|
115
|
+
year: 'numeric'
|
|
116
|
+
});
|
|
117
|
+
case 'quarter':
|
|
118
|
+
{
|
|
119
|
+
// Jan-Mar, 2025
|
|
120
|
+
if (isSameYear(startDate, endDate)) {
|
|
121
|
+
return formatMessage(messages.quarterRange, {
|
|
122
|
+
startMonth: formatDate(startDate, {
|
|
123
|
+
month: 'short'
|
|
124
|
+
}),
|
|
125
|
+
endMonth: formatDate(endDate, {
|
|
126
|
+
month: 'short'
|
|
127
|
+
}),
|
|
128
|
+
year: formatDate(startDate, {
|
|
129
|
+
year: 'numeric'
|
|
130
|
+
})
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// Dec-Feb, 2025-2026
|
|
134
|
+
return formatMessage(messages.quarterRangeOverYears, {
|
|
135
|
+
startMonth: formatDate(startDate, {
|
|
136
|
+
month: 'short'
|
|
137
|
+
}),
|
|
138
|
+
endMonth: formatDate(endDate, {
|
|
139
|
+
month: 'short'
|
|
140
|
+
}),
|
|
141
|
+
startYear: formatDate(startDate, {
|
|
142
|
+
year: 'numeric'
|
|
143
|
+
}),
|
|
144
|
+
endYear: formatDate(endDate, {
|
|
145
|
+
year: 'numeric'
|
|
146
|
+
})
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
case 'full':
|
|
150
|
+
// Nov 1, 2025 - May 19, 2026
|
|
151
|
+
// Jan 1, 2025, 00:00 - Mar 31, 2025, 23:59
|
|
152
|
+
return formatMessage(messages.fullRange, {
|
|
153
|
+
start: formatDate(startDate, _objectSpread(_objectSpread({}, dateOptions), timeOptions)),
|
|
154
|
+
end: formatDate(endDate, _objectSpread(_objectSpread({}, dateOptions), timeOptions))
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
var DateRangeRenderType = function DateRangeRenderType(_ref) {
|
|
159
|
+
var value = _ref.value,
|
|
160
|
+
_ref$testId = _ref.testId,
|
|
161
|
+
testId = _ref$testId === void 0 ? DATERANGE_TYPE_TEST_ID : _ref$testId;
|
|
162
|
+
var _useIntl = useIntl(),
|
|
163
|
+
formatDate = _useIntl.formatDate,
|
|
164
|
+
formatMessage = _useIntl.formatMessage;
|
|
165
|
+
var formattedString = getFormattedDateRange(value.start, value.end, formatDate, formatMessage);
|
|
166
|
+
if (formattedString === '') {
|
|
167
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
|
168
|
+
}
|
|
169
|
+
return /*#__PURE__*/React.createElement(Text, {
|
|
170
|
+
testId: testId
|
|
171
|
+
}, formattedString);
|
|
172
|
+
};
|
|
173
|
+
export default DateRangeRenderType;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export var messages = defineMessages({
|
|
3
|
+
quarterRange: {
|
|
4
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.quarterRange',
|
|
5
|
+
description: 'The formatted date range for a quarter range',
|
|
6
|
+
defaultMessage: '{startMonth}-{endMonth}, {year}'
|
|
7
|
+
},
|
|
8
|
+
quarterRangeOverYears: {
|
|
9
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.quarterRangeOverYears',
|
|
10
|
+
description: 'The formatted date range for a quarter range that spans across multiple years',
|
|
11
|
+
defaultMessage: '{startMonth}-{endMonth}, {startYear}-{endYear}'
|
|
12
|
+
},
|
|
13
|
+
fullRange: {
|
|
14
|
+
id: 'linkDataSource.issueLikeTable.renderType.dateRange.fullRange',
|
|
15
|
+
description: 'The formatted date range for a full range (day, month, quarter, or full)',
|
|
16
|
+
defaultMessage: '{start} - {end}'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
@@ -2,6 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
4
|
import BooleanRenderType from './boolean';
|
|
5
|
+
import DateRangeRenderType, { getFormattedDateRange } from './date-range';
|
|
5
6
|
import DateTimeRenderType, { getFormattedDate } from './date-time';
|
|
6
7
|
import IconRenderType from './icon';
|
|
7
8
|
import LinkRenderType from './link';
|
|
@@ -23,6 +24,13 @@ export var stringifyType = function stringifyType(_ref, formatMessage, formatDat
|
|
|
23
24
|
return getFormattedDate(value, 'date', formatDate);
|
|
24
25
|
case 'datetime':
|
|
25
26
|
return getFormattedDate(value, 'datetime', formatDate);
|
|
27
|
+
case 'daterange':
|
|
28
|
+
{
|
|
29
|
+
if (fg('jpd_confluence_date_fields_improvements')) {
|
|
30
|
+
return getFormattedDateRange(value.start, value.end, formatDate, formatMessage);
|
|
31
|
+
}
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
26
34
|
case 'time':
|
|
27
35
|
return getFormattedDate(value, 'time', formatDate);
|
|
28
36
|
case 'icon':
|
|
@@ -69,6 +77,17 @@ export var renderType = function renderType(item) {
|
|
|
69
77
|
display: "datetime"
|
|
70
78
|
});
|
|
71
79
|
});
|
|
80
|
+
case 'daterange':
|
|
81
|
+
{
|
|
82
|
+
if (fg('jpd_confluence_date_fields_improvements')) {
|
|
83
|
+
return item.values.map(function (dateRangeValue) {
|
|
84
|
+
return /*#__PURE__*/React.createElement(DateRangeRenderType, {
|
|
85
|
+
value: dateRangeValue
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
|
90
|
+
}
|
|
72
91
|
case 'icon':
|
|
73
92
|
return item.values.map(function (iconValue) {
|
|
74
93
|
return /*#__PURE__*/React.createElement(IconRenderType, iconValue);
|
|
@@ -35,7 +35,7 @@ var AvatarGroupWrapperStyles = forwardRef(function (_ref, __cmplr) {
|
|
|
35
35
|
if (process.env.NODE_ENV !== 'production') {
|
|
36
36
|
AvatarGroupWrapperStyles.displayName = 'AvatarGroupWrapperStyles';
|
|
37
37
|
}
|
|
38
|
-
var getMaxUserCount = function getMaxUserCount(
|
|
38
|
+
var getMaxUserCount = function getMaxUserCount(_userCount, availableWidth) {
|
|
39
39
|
if (availableWidth <= 28) {
|
|
40
40
|
// If width is less than or equal to 28px, we should only display the user count
|
|
41
41
|
return 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { captureException } from '@atlaskit/linking-common/sentry';
|
|
2
2
|
import { type DatasourceOperationFailedAttributesType } from '../analytics/generated/analytics.types';
|
|
3
|
-
type Tail<T extends any[]> = T extends [infer
|
|
3
|
+
type Tail<T extends any[]> = T extends [infer _A, ...infer R] ? R : never;
|
|
4
4
|
/**
|
|
5
5
|
* This function is just a wrapper around captureException that checks if the enable-sentry-client FF is enabled
|
|
6
6
|
* and error is instanceof Error. We have to override the type of error from captureException to unknown so we use
|
|
@@ -21,5 +21,5 @@ export declare const selectInAModalStyleFixProps: {
|
|
|
21
21
|
};
|
|
22
22
|
menuPortalTarget: HTMLElement;
|
|
23
23
|
};
|
|
24
|
-
export declare const AssetsObjectSchemaSelect: ({ value, workspaceId, initialObjectSchemas, classNamePrefix, testId, }: AssetsObjectSchemaSelectProps) => JSX.Element;
|
|
24
|
+
export declare const AssetsObjectSchemaSelect: ({ value, workspaceId, initialObjectSchemas, classNamePrefix: _classNamePrefix, testId, }: AssetsObjectSchemaSelectProps) => JSX.Element;
|
|
25
25
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type PropsWithChildren } from 'react';
|
|
2
2
|
import { type DatasourceParameters } from '@atlaskit/linking-types';
|
|
3
|
-
export type InsertButtonProps<
|
|
3
|
+
export type InsertButtonProps<_Parameters extends DatasourceParameters> = PropsWithChildren<{
|
|
4
4
|
getAnalyticsPayload: () => Record<string, any>;
|
|
5
5
|
testId?: string;
|
|
6
6
|
url: string | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type IntlShape } from 'react-intl-next';
|
|
3
|
+
import { type DateRangeType } from '@atlaskit/linking-types';
|
|
4
|
+
export interface DateRangeProps {
|
|
5
|
+
testId?: string;
|
|
6
|
+
value: DateRangeType['value'];
|
|
7
|
+
}
|
|
8
|
+
export declare const DATERANGE_TYPE_TEST_ID = "link-datasource-render-type--daterange";
|
|
9
|
+
export declare function getFormattedDateRange(startValue: string, endValue: string, formatDate: IntlShape['formatDate'], formatMessage: IntlShape['formatMessage']): string;
|
|
10
|
+
declare const DateRangeRenderType: ({ value, testId }: DateRangeProps) => React.JSX.Element;
|
|
11
|
+
export default DateRangeRenderType;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const messages: {
|
|
2
|
+
quarterRange: {
|
|
3
|
+
id: string;
|
|
4
|
+
description: string;
|
|
5
|
+
defaultMessage: string;
|
|
6
|
+
};
|
|
7
|
+
quarterRangeOverYears: {
|
|
8
|
+
id: string;
|
|
9
|
+
description: string;
|
|
10
|
+
defaultMessage: string;
|
|
11
|
+
};
|
|
12
|
+
fullRange: {
|
|
13
|
+
id: string;
|
|
14
|
+
description: string;
|
|
15
|
+
defaultMessage: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { captureException } from '@atlaskit/linking-common/sentry';
|
|
2
2
|
import { type DatasourceOperationFailedAttributesType } from '../analytics/generated/analytics.types';
|
|
3
3
|
type Tail<T extends any[]> = T extends [
|
|
4
|
-
infer
|
|
4
|
+
infer _A,
|
|
5
5
|
...infer R
|
|
6
6
|
] ? R : never;
|
|
7
7
|
/**
|
|
@@ -21,5 +21,5 @@ export declare const selectInAModalStyleFixProps: {
|
|
|
21
21
|
};
|
|
22
22
|
menuPortalTarget: HTMLElement;
|
|
23
23
|
};
|
|
24
|
-
export declare const AssetsObjectSchemaSelect: ({ value, workspaceId, initialObjectSchemas, classNamePrefix, testId, }: AssetsObjectSchemaSelectProps) => JSX.Element;
|
|
24
|
+
export declare const AssetsObjectSchemaSelect: ({ value, workspaceId, initialObjectSchemas, classNamePrefix: _classNamePrefix, testId, }: AssetsObjectSchemaSelectProps) => JSX.Element;
|
|
25
25
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type PropsWithChildren } from 'react';
|
|
2
2
|
import { type DatasourceParameters } from '@atlaskit/linking-types';
|
|
3
|
-
export type InsertButtonProps<
|
|
3
|
+
export type InsertButtonProps<_Parameters extends DatasourceParameters> = PropsWithChildren<{
|
|
4
4
|
getAnalyticsPayload: () => Record<string, any>;
|
|
5
5
|
testId?: string;
|
|
6
6
|
url: string | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type IntlShape } from 'react-intl-next';
|
|
3
|
+
import { type DateRangeType } from '@atlaskit/linking-types';
|
|
4
|
+
export interface DateRangeProps {
|
|
5
|
+
testId?: string;
|
|
6
|
+
value: DateRangeType['value'];
|
|
7
|
+
}
|
|
8
|
+
export declare const DATERANGE_TYPE_TEST_ID = "link-datasource-render-type--daterange";
|
|
9
|
+
export declare function getFormattedDateRange(startValue: string, endValue: string, formatDate: IntlShape['formatDate'], formatMessage: IntlShape['formatMessage']): string;
|
|
10
|
+
declare const DateRangeRenderType: ({ value, testId }: DateRangeProps) => React.JSX.Element;
|
|
11
|
+
export default DateRangeRenderType;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const messages: {
|
|
2
|
+
quarterRange: {
|
|
3
|
+
id: string;
|
|
4
|
+
description: string;
|
|
5
|
+
defaultMessage: string;
|
|
6
|
+
};
|
|
7
|
+
quarterRangeOverYears: {
|
|
8
|
+
id: string;
|
|
9
|
+
description: string;
|
|
10
|
+
defaultMessage: string;
|
|
11
|
+
};
|
|
12
|
+
fullRange: {
|
|
13
|
+
id: string;
|
|
14
|
+
description: string;
|
|
15
|
+
defaultMessage: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/link-datasource",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.30.1",
|
|
4
4
|
"description": "UI Components to support linking platform dataset feature",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -61,14 +61,14 @@
|
|
|
61
61
|
"@atlaskit/jql-ast": "^3.3.0",
|
|
62
62
|
"@atlaskit/jql-editor": "^5.8.0",
|
|
63
63
|
"@atlaskit/jql-editor-autocomplete-rest": "^3.0.0",
|
|
64
|
-
"@atlaskit/layering": "^3.
|
|
64
|
+
"@atlaskit/layering": "^3.3.0",
|
|
65
65
|
"@atlaskit/link": "^3.2.0",
|
|
66
66
|
"@atlaskit/link-client-extension": "^6.0.0",
|
|
67
67
|
"@atlaskit/linking-common": "^9.8.0",
|
|
68
|
-
"@atlaskit/linking-types": "^14.
|
|
68
|
+
"@atlaskit/linking-types": "^14.2.0",
|
|
69
69
|
"@atlaskit/logo": "^19.9.0",
|
|
70
70
|
"@atlaskit/lozenge": "^13.1.0",
|
|
71
|
-
"@atlaskit/modal-dialog": "^14.
|
|
71
|
+
"@atlaskit/modal-dialog": "^14.7.0",
|
|
72
72
|
"@atlaskit/outbound-auth-flow-client": "^3.4.0",
|
|
73
73
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
74
74
|
"@atlaskit/popup": "^4.6.0",
|
|
@@ -77,13 +77,13 @@
|
|
|
77
77
|
"@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll": "^2.0.0",
|
|
78
78
|
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
|
|
79
79
|
"@atlaskit/primitives": "^16.1.0",
|
|
80
|
-
"@atlaskit/react-select": "^3.
|
|
81
|
-
"@atlaskit/select": "^21.
|
|
82
|
-
"@atlaskit/smart-card": "^43.
|
|
80
|
+
"@atlaskit/react-select": "^3.9.0",
|
|
81
|
+
"@atlaskit/select": "^21.4.0",
|
|
82
|
+
"@atlaskit/smart-card": "^43.7.0",
|
|
83
83
|
"@atlaskit/smart-user-picker": "^8.4.0",
|
|
84
84
|
"@atlaskit/spinner": "^19.0.0",
|
|
85
85
|
"@atlaskit/tag": "^14.1.0",
|
|
86
|
-
"@atlaskit/textfield": "^8.
|
|
86
|
+
"@atlaskit/textfield": "^8.1.0",
|
|
87
87
|
"@atlaskit/theme": "^21.0.0",
|
|
88
88
|
"@atlaskit/tokens": "^8.0.0",
|
|
89
89
|
"@atlaskit/tooltip": "^20.8.0",
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
"@babel/runtime": "^7.0.0",
|
|
93
93
|
"@compiled/react": "^0.18.6",
|
|
94
94
|
"@types/dompurify": "^2.2.3",
|
|
95
|
+
"date-fns": "^2.17.0",
|
|
95
96
|
"debounce-promise": "^3.1.2",
|
|
96
97
|
"dompurify": "^2.5.6",
|
|
97
98
|
"lodash": "^4.17.21",
|
|
@@ -110,7 +111,7 @@
|
|
|
110
111
|
"@af/visual-regression": "workspace:^",
|
|
111
112
|
"@atlaskit/json-ld-types": "^1.4.0",
|
|
112
113
|
"@atlaskit/link-provider": "^4.0.0",
|
|
113
|
-
"@atlaskit/link-test-helpers": "^8.
|
|
114
|
+
"@atlaskit/link-test-helpers": "^8.5.0",
|
|
114
115
|
"@atlaskit/ssr": "workspace:^",
|
|
115
116
|
"@atlassian/feature-flags-test-utils": "^1.0.0",
|
|
116
117
|
"@faker-js/faker": "^7.5.0",
|
|
@@ -189,6 +190,9 @@
|
|
|
189
190
|
},
|
|
190
191
|
"platform_navx_jira_sllv_rich_text_gate": {
|
|
191
192
|
"type": "boolean"
|
|
193
|
+
},
|
|
194
|
+
"jpd_confluence_date_fields_improvements": {
|
|
195
|
+
"type": "boolean"
|
|
192
196
|
}
|
|
193
197
|
},
|
|
194
198
|
"compassUnitTestMetricSourceId": "ari:cloud:compass:a436116f-02ce-4520-8fbb-7301462a1674:metric-source/c5751cc6-3513-4070-9deb-af31e86aed34/9c893299-a527-4457-9b46-f3bc4c828766"
|