@atlaskit/link-datasource 1.19.46 → 1.20.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @atlaskit/link-datasource
2
2
 
3
+ ## 1.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#67414](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/67414) [`e1ad52cb07b8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e1ad52cb07b8) - [ux] Change to display multiple avatar images of users in a group component rather than on new lines
8
+
3
9
  ## 1.19.46
4
10
 
5
11
  ### Patch Changes
@@ -400,11 +400,9 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
400
400
  type = _ref11.type;
401
401
  var value = ((_newRowData$key = newRowData[key]) === null || _newRowData$key === void 0 ? void 0 : _newRowData$key.data) || newRowData[key];
402
402
  var values = Array.isArray(value) ? value : [value];
403
- var renderedValues = values.map(function (value) {
404
- return renderItem({
405
- type: type,
406
- value: value
407
- });
403
+ var renderedValues = renderItem({
404
+ type: type,
405
+ values: values
408
406
  });
409
407
  var stringifiedContent = values.map(function (value) {
410
408
  return (0, _renderType.stringifyType)({
@@ -414,12 +412,11 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
414
412
  }).filter(function (value) {
415
413
  return value !== '';
416
414
  }).join(', ');
417
- var content = renderedValues.length === 1 ? renderedValues[0] : renderedValues;
418
415
  var contentComponent = stringifiedContent ? (0, _react2.jsx)(_tooltip.default, {
419
416
  tag: TruncateTextTag,
420
417
  content: stringifiedContent,
421
418
  testId: "issues-table-cell-tooltip"
422
- }, content) : content;
419
+ }, renderedValues) : renderedValues;
423
420
  return {
424
421
  key: key,
425
422
  content: contentComponent,
@@ -53,54 +53,77 @@ var stringifyType = exports.stringifyType = function stringifyType(_ref, formatM
53
53
  }
54
54
  };
55
55
  var fallbackRenderType = exports.fallbackRenderType = function fallbackRenderType(item) {
56
- var _item$value, _item$value2, _item$value3;
57
56
  switch (item.type) {
58
57
  case 'boolean':
59
- return /*#__PURE__*/_react.default.createElement(_boolean.default, {
60
- value: item.value
58
+ return item.values.map(function (booleanValue) {
59
+ return /*#__PURE__*/_react.default.createElement(_boolean.default, {
60
+ value: booleanValue
61
+ });
61
62
  });
62
63
  case 'date':
63
- return /*#__PURE__*/_react.default.createElement(_dateTime.default, {
64
- value: item.value,
65
- display: "date"
64
+ return item.values.map(function (dateValue) {
65
+ return /*#__PURE__*/_react.default.createElement(_dateTime.default, {
66
+ value: dateValue,
67
+ display: "date"
68
+ });
66
69
  });
67
70
  case 'datetime':
68
- return /*#__PURE__*/_react.default.createElement(_dateTime.default, {
69
- value: item.value,
70
- display: "datetime"
71
+ return item.values.map(function (datTimeValue) {
72
+ return /*#__PURE__*/_react.default.createElement(_dateTime.default, {
73
+ value: datTimeValue,
74
+ display: "datetime"
75
+ });
71
76
  });
72
77
  case 'icon':
73
- return /*#__PURE__*/_react.default.createElement(_icon.default, item.value);
78
+ return item.values.map(function (iconValue) {
79
+ return /*#__PURE__*/_react.default.createElement(_icon.default, iconValue);
80
+ });
74
81
  case 'link':
75
- return /*#__PURE__*/_react.default.createElement(_link.default, (0, _extends2.default)({
76
- key: (_item$value = item.value) === null || _item$value === void 0 ? void 0 : _item$value.url
77
- }, item.value));
82
+ return item.values.map(function (linkValue) {
83
+ return /*#__PURE__*/_react.default.createElement(_link.default, (0, _extends2.default)({
84
+ key: linkValue === null || linkValue === void 0 ? void 0 : linkValue.url
85
+ }, linkValue));
86
+ });
78
87
  case 'number':
79
- return /*#__PURE__*/_react.default.createElement(_number.default, {
80
- number: item.value
88
+ return item.values.map(function (numberValue) {
89
+ return /*#__PURE__*/_react.default.createElement(_number.default, {
90
+ number: numberValue
91
+ });
81
92
  });
82
93
  case 'status':
83
- return /*#__PURE__*/_react.default.createElement(_status.default, item.value);
94
+ return item.values.map(function (statusValue) {
95
+ return /*#__PURE__*/_react.default.createElement(_status.default, statusValue);
96
+ });
84
97
  case 'string':
85
- return /*#__PURE__*/_react.default.createElement(_text.default, {
86
- key: item.value,
87
- text: item.value
98
+ return item.values.map(function (stringValue) {
99
+ return /*#__PURE__*/_react.default.createElement(_text.default, {
100
+ key: stringValue,
101
+ text: stringValue
102
+ });
88
103
  });
89
104
  case 'tag':
90
- return /*#__PURE__*/_react.default.createElement(_tag.default, {
91
- key: ((_item$value2 = item.value) === null || _item$value2 === void 0 ? void 0 : _item$value2.id) || ((_item$value3 = item.value) === null || _item$value3 === void 0 ? void 0 : _item$value3.text),
92
- tag: item.value
105
+ return item.values.map(function (tagValue) {
106
+ return /*#__PURE__*/_react.default.createElement(_tag.default, {
107
+ key: (tagValue === null || tagValue === void 0 ? void 0 : tagValue.id) || (tagValue === null || tagValue === void 0 ? void 0 : tagValue.text),
108
+ tag: tagValue
109
+ });
93
110
  });
94
111
  case 'time':
95
- return /*#__PURE__*/_react.default.createElement(_dateTime.default, {
96
- value: item.value,
97
- display: "time"
112
+ return item.values.map(function (timeValue) {
113
+ return /*#__PURE__*/_react.default.createElement(_dateTime.default, {
114
+ value: timeValue,
115
+ display: "time"
116
+ });
98
117
  });
99
118
  case 'user':
100
- return /*#__PURE__*/_react.default.createElement(_user.default, item.value);
119
+ return /*#__PURE__*/_react.default.createElement(_user.default, {
120
+ users: item.values
121
+ });
101
122
  case 'richtext':
102
- return /*#__PURE__*/_react.default.createElement(_richtext.default, {
103
- value: item.value
123
+ return item.values.map(function (richValue) {
124
+ return /*#__PURE__*/_react.default.createElement(_richtext.default, {
125
+ value: richValue
126
+ });
104
127
  });
105
128
  default:
106
129
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null);
@@ -1,36 +1,102 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
7
8
  exports.default = exports.USER_TYPE_TEST_ID = void 0;
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
8
10
  var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
9
- var _react = _interopRequireDefault(require("react"));
11
+ var _react = _interopRequireWildcard(require("react"));
12
+ var _react2 = require("@emotion/react");
10
13
  var _styled = _interopRequireDefault(require("@emotion/styled"));
11
14
  var _reactIntlNext = require("react-intl-next");
12
15
  var _avatar = _interopRequireDefault(require("@atlaskit/avatar"));
16
+ var _avatarGroup = _interopRequireDefault(require("@atlaskit/avatar-group"));
17
+ var _primitives = require("@atlaskit/primitives");
18
+ var _widthDetector = require("@atlaskit/width-detector");
13
19
  var _styled2 = require("../../styled");
14
20
  var _messages = require("./messages");
15
- var _templateObject, _templateObject2;
16
- var UserWrapper = _styled.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n align-items: center;\n font-size: ", ";\n"])), _styled2.FieldTextFontSize);
17
- var AvatarWrapper = _styled.default.div(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n margin-right: 5px;\n"])));
21
+ var _templateObject;
22
+ /** @jsx jsx */
23
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
24
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
+ var userWrapperStyles = (0, _primitives.xcss)({
26
+ display: 'flex',
27
+ alignItems: 'center',
28
+ fontSize: "".concat(_styled2.FieldTextFontSize, "px")
29
+ });
30
+ var avatarWrapperStyles = (0, _primitives.xcss)({
31
+ marginRight: '5px'
32
+ });
33
+ var widthObserverWrapperStyles = (0, _primitives.xcss)({
34
+ position: 'relative'
35
+ });
36
+ var AvatarGroupWrapperStyles = _styled.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n /*\n The css from editor core package affects the padding of the AvatarGroup\n The & refers to the parent selector (.<generated className>),\n so && becomes .<generated className>.<generated className> which increases its specificity\n */\n && ul {\n padding-left: 0px;\n }\n"])));
37
+ var getMaxUserCount = function getMaxUserCount(userCount, availableWidth) {
38
+ if (availableWidth <= 28) {
39
+ // If width is less than or equal to 28px, we should only display the user count
40
+ return 1;
41
+ }
42
+ var defaultMaxCount = 5;
43
+ var usersNumFitToAvailableWidth = Math.ceil((availableWidth - 28) / 20);
44
+ return usersNumFitToAvailableWidth > defaultMaxCount ? defaultMaxCount : usersNumFitToAvailableWidth;
45
+ };
18
46
  var USER_TYPE_TEST_ID = exports.USER_TYPE_TEST_ID = 'link-datasource-render-type--user';
19
47
  var UserType = function UserType(_ref) {
20
- var avatarSource = _ref.avatarSource,
21
- _ref$avatarSize = _ref.avatarSize,
22
- avatarSize = _ref$avatarSize === void 0 ? 'small' : _ref$avatarSize,
23
- displayName = _ref.displayName,
24
- _ref$testId = _ref.testId,
25
- testId = _ref$testId === void 0 ? USER_TYPE_TEST_ID : _ref$testId,
26
- children = _ref.children;
27
- return /*#__PURE__*/_react.default.createElement(UserWrapper, {
28
- "data-testid": testId
29
- }, /*#__PURE__*/_react.default.createElement(AvatarWrapper, null, /*#__PURE__*/_react.default.createElement(_avatar.default, {
30
- appearance: "circle",
31
- size: avatarSize,
32
- src: avatarSource,
33
- testId: "".concat(testId, "--avatar")
34
- })), children || displayName || /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.userTypeMessages.userDefaultdisplayNameValue));
48
+ var users = _ref.users;
49
+ var _useState = (0, _react.useState)(null),
50
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
51
+ width = _useState2[0],
52
+ setWidth = _useState2[1];
53
+ if (users.length <= 1) {
54
+ var _ref2 = users[0] || {},
55
+ avatarSource = _ref2.avatarSource,
56
+ _ref2$avatarSize = _ref2.avatarSize,
57
+ avatarSize = _ref2$avatarSize === void 0 ? 'small' : _ref2$avatarSize,
58
+ displayName = _ref2.displayName,
59
+ _ref2$testId = _ref2.testId,
60
+ testId = _ref2$testId === void 0 ? USER_TYPE_TEST_ID : _ref2$testId,
61
+ children = _ref2.children;
62
+ return (0, _react2.jsx)(_primitives.Box, {
63
+ xcss: userWrapperStyles,
64
+ testId: testId
65
+ }, (0, _react2.jsx)(_primitives.Box, {
66
+ xcss: avatarWrapperStyles
67
+ }, (0, _react2.jsx)(_avatar.default, {
68
+ appearance: "circle",
69
+ size: avatarSize || 'small',
70
+ src: avatarSource,
71
+ testId: "".concat(testId, "--avatar")
72
+ })), children || displayName || (0, _react2.jsx)(_reactIntlNext.FormattedMessage, _messages.userTypeMessages.userDefaultdisplayNameValue));
73
+ } else {
74
+ var maxCount = width !== null ? getMaxUserCount(users.length, width) : 5;
75
+ var data = users.filter(function (user) {
76
+ return !!user.displayName;
77
+ }).map(function (_ref3) {
78
+ var atlassianUserId = _ref3.atlassianUserId,
79
+ displayName = _ref3.displayName,
80
+ avatarSource = _ref3.avatarSource,
81
+ testId = _ref3.testId;
82
+ return {
83
+ key: atlassianUserId,
84
+ name: displayName,
85
+ src: avatarSource,
86
+ testId: "".concat(testId, "--avatar")
87
+ };
88
+ });
89
+ return (0, _react2.jsx)(AvatarGroupWrapperStyles, null, (0, _react2.jsx)(_primitives.Box, {
90
+ xcss: widthObserverWrapperStyles
91
+ }, (0, _react2.jsx)(_widthDetector.WidthObserver, {
92
+ setWidth: setWidth
93
+ })), (0, _react2.jsx)(_avatarGroup.default, {
94
+ data: data,
95
+ maxCount: maxCount,
96
+ size: "small",
97
+ isTooltipDisabled: true,
98
+ testId: USER_TYPE_TEST_ID
99
+ }));
100
+ }
35
101
  };
36
102
  var _default = exports.default = UserType;
@@ -444,20 +444,19 @@ export const IssueLikeDataTableView = ({
444
444
  var _newRowData$key;
445
445
  const value = ((_newRowData$key = newRowData[key]) === null || _newRowData$key === void 0 ? void 0 : _newRowData$key.data) || newRowData[key];
446
446
  const values = Array.isArray(value) ? value : [value];
447
- const renderedValues = values.map(value => renderItem({
447
+ const renderedValues = renderItem({
448
448
  type,
449
- value
450
- }));
449
+ values
450
+ });
451
451
  const stringifiedContent = values.map(value => stringifyType({
452
452
  type,
453
453
  value
454
454
  }, intl.formatMessage, intl.formatDate)).filter(value => value !== '').join(', ');
455
- const content = renderedValues.length === 1 ? renderedValues[0] : renderedValues;
456
455
  const contentComponent = stringifiedContent ? jsx(Tooltip, {
457
456
  tag: TruncateTextTag,
458
457
  content: stringifiedContent,
459
458
  testId: "issues-table-cell-tooltip"
460
- }, content) : content;
459
+ }, renderedValues) : renderedValues;
461
460
  return {
462
461
  key,
463
462
  content: contentComponent,
@@ -44,55 +44,56 @@ export const stringifyType = ({
44
44
  }
45
45
  };
46
46
  export const fallbackRenderType = item => {
47
- var _item$value, _item$value2, _item$value3;
48
47
  switch (item.type) {
49
48
  case 'boolean':
50
- return /*#__PURE__*/React.createElement(BooleanRenderType, {
51
- value: item.value
52
- });
49
+ return item.values.map(booleanValue => /*#__PURE__*/React.createElement(BooleanRenderType, {
50
+ value: booleanValue
51
+ }));
53
52
  case 'date':
54
- return /*#__PURE__*/React.createElement(DateTimeRenderType, {
55
- value: item.value,
53
+ return item.values.map(dateValue => /*#__PURE__*/React.createElement(DateTimeRenderType, {
54
+ value: dateValue,
56
55
  display: "date"
57
- });
56
+ }));
58
57
  case 'datetime':
59
- return /*#__PURE__*/React.createElement(DateTimeRenderType, {
60
- value: item.value,
58
+ return item.values.map(datTimeValue => /*#__PURE__*/React.createElement(DateTimeRenderType, {
59
+ value: datTimeValue,
61
60
  display: "datetime"
62
- });
61
+ }));
63
62
  case 'icon':
64
- return /*#__PURE__*/React.createElement(IconRenderType, item.value);
63
+ return item.values.map(iconValue => /*#__PURE__*/React.createElement(IconRenderType, iconValue));
65
64
  case 'link':
66
- return /*#__PURE__*/React.createElement(LinkRenderType, _extends({
67
- key: (_item$value = item.value) === null || _item$value === void 0 ? void 0 : _item$value.url
68
- }, item.value));
65
+ return item.values.map(linkValue => /*#__PURE__*/React.createElement(LinkRenderType, _extends({
66
+ key: linkValue === null || linkValue === void 0 ? void 0 : linkValue.url
67
+ }, linkValue)));
69
68
  case 'number':
70
- return /*#__PURE__*/React.createElement(NumberRenderType, {
71
- number: item.value
72
- });
69
+ return item.values.map(numberValue => /*#__PURE__*/React.createElement(NumberRenderType, {
70
+ number: numberValue
71
+ }));
73
72
  case 'status':
74
- return /*#__PURE__*/React.createElement(StatusRenderType, item.value);
73
+ return item.values.map(statusValue => /*#__PURE__*/React.createElement(StatusRenderType, statusValue));
75
74
  case 'string':
76
- return /*#__PURE__*/React.createElement(StringRenderType, {
77
- key: item.value,
78
- text: item.value
79
- });
75
+ return item.values.map(stringValue => /*#__PURE__*/React.createElement(StringRenderType, {
76
+ key: stringValue,
77
+ text: stringValue
78
+ }));
80
79
  case 'tag':
81
- return /*#__PURE__*/React.createElement(TagRenderType, {
82
- key: ((_item$value2 = item.value) === null || _item$value2 === void 0 ? void 0 : _item$value2.id) || ((_item$value3 = item.value) === null || _item$value3 === void 0 ? void 0 : _item$value3.text),
83
- tag: item.value
84
- });
80
+ return item.values.map(tagValue => /*#__PURE__*/React.createElement(TagRenderType, {
81
+ key: (tagValue === null || tagValue === void 0 ? void 0 : tagValue.id) || (tagValue === null || tagValue === void 0 ? void 0 : tagValue.text),
82
+ tag: tagValue
83
+ }));
85
84
  case 'time':
86
- return /*#__PURE__*/React.createElement(DateTimeRenderType, {
87
- value: item.value,
85
+ return item.values.map(timeValue => /*#__PURE__*/React.createElement(DateTimeRenderType, {
86
+ value: timeValue,
88
87
  display: "time"
89
- });
88
+ }));
90
89
  case 'user':
91
- return /*#__PURE__*/React.createElement(UserRenderType, item.value);
92
- case 'richtext':
93
- return /*#__PURE__*/React.createElement(RichTextRenderType, {
94
- value: item.value
90
+ return /*#__PURE__*/React.createElement(UserRenderType, {
91
+ users: item.values
95
92
  });
93
+ case 'richtext':
94
+ return item.values.map(richValue => /*#__PURE__*/React.createElement(RichTextRenderType, {
95
+ value: richValue
96
+ }));
96
97
  default:
97
98
  return /*#__PURE__*/React.createElement(React.Fragment, null);
98
99
  }
@@ -1,32 +1,92 @@
1
- import React from 'react';
1
+ /** @jsx jsx */
2
+ import React, { useState } from 'react';
3
+ import { jsx } from '@emotion/react';
2
4
  import styled from '@emotion/styled';
3
5
  import { FormattedMessage } from 'react-intl-next';
4
6
  import Avatar from '@atlaskit/avatar';
7
+ import AvatarGroup from '@atlaskit/avatar-group';
8
+ import { Box, xcss } from '@atlaskit/primitives';
9
+ import { WidthObserver } from '@atlaskit/width-detector';
5
10
  import { FieldTextFontSize } from '../../styled';
6
11
  import { userTypeMessages } from './messages';
7
- const UserWrapper = styled.div`
8
- display: flex;
9
- align-items: center;
10
- font-size: ${FieldTextFontSize};
11
- `;
12
- const AvatarWrapper = styled.div`
13
- margin-right: 5px;
12
+ const userWrapperStyles = xcss({
13
+ display: 'flex',
14
+ alignItems: 'center',
15
+ fontSize: `${FieldTextFontSize}px`
16
+ });
17
+ const avatarWrapperStyles = xcss({
18
+ marginRight: '5px'
19
+ });
20
+ const widthObserverWrapperStyles = xcss({
21
+ position: 'relative'
22
+ });
23
+ const AvatarGroupWrapperStyles = styled.div`
24
+ /*
25
+ The css from editor core package affects the padding of the AvatarGroup
26
+ The & refers to the parent selector (.<generated className>),
27
+ so && becomes .<generated className>.<generated className> which increases its specificity
28
+ */
29
+ && ul {
30
+ padding-left: 0px;
31
+ }
14
32
  `;
33
+ const getMaxUserCount = (userCount, availableWidth) => {
34
+ if (availableWidth <= 28) {
35
+ // If width is less than or equal to 28px, we should only display the user count
36
+ return 1;
37
+ }
38
+ const defaultMaxCount = 5;
39
+ const usersNumFitToAvailableWidth = Math.ceil((availableWidth - 28) / 20);
40
+ return usersNumFitToAvailableWidth > defaultMaxCount ? defaultMaxCount : usersNumFitToAvailableWidth;
41
+ };
15
42
  export const USER_TYPE_TEST_ID = 'link-datasource-render-type--user';
16
43
  const UserType = ({
17
- avatarSource,
18
- avatarSize = 'small',
19
- displayName,
20
- testId = USER_TYPE_TEST_ID,
21
- children
44
+ users
22
45
  }) => {
23
- return /*#__PURE__*/React.createElement(UserWrapper, {
24
- "data-testid": testId
25
- }, /*#__PURE__*/React.createElement(AvatarWrapper, null, /*#__PURE__*/React.createElement(Avatar, {
26
- appearance: "circle",
27
- size: avatarSize,
28
- src: avatarSource,
29
- testId: `${testId}--avatar`
30
- })), children || displayName || /*#__PURE__*/React.createElement(FormattedMessage, userTypeMessages.userDefaultdisplayNameValue));
46
+ const [width, setWidth] = useState(null);
47
+ if (users.length <= 1) {
48
+ const {
49
+ avatarSource,
50
+ avatarSize = 'small',
51
+ displayName,
52
+ testId = USER_TYPE_TEST_ID,
53
+ children
54
+ } = users[0] || {};
55
+ return jsx(Box, {
56
+ xcss: userWrapperStyles,
57
+ testId: testId
58
+ }, jsx(Box, {
59
+ xcss: avatarWrapperStyles
60
+ }, jsx(Avatar, {
61
+ appearance: "circle",
62
+ size: avatarSize || 'small',
63
+ src: avatarSource,
64
+ testId: `${testId}--avatar`
65
+ })), children || displayName || jsx(FormattedMessage, userTypeMessages.userDefaultdisplayNameValue));
66
+ } else {
67
+ const maxCount = width !== null ? getMaxUserCount(users.length, width) : 5;
68
+ const data = users.filter(user => !!user.displayName).map(({
69
+ atlassianUserId,
70
+ displayName,
71
+ avatarSource,
72
+ testId
73
+ }) => ({
74
+ key: atlassianUserId,
75
+ name: displayName,
76
+ src: avatarSource,
77
+ testId: `${testId}--avatar`
78
+ }));
79
+ return jsx(AvatarGroupWrapperStyles, null, jsx(Box, {
80
+ xcss: widthObserverWrapperStyles
81
+ }, jsx(WidthObserver, {
82
+ setWidth: setWidth
83
+ })), jsx(AvatarGroup, {
84
+ data: data,
85
+ maxCount: maxCount,
86
+ size: "small",
87
+ isTooltipDisabled: true,
88
+ testId: USER_TYPE_TEST_ID
89
+ }));
90
+ }
31
91
  };
32
92
  export default UserType;
@@ -393,11 +393,9 @@ export var IssueLikeDataTableView = function IssueLikeDataTableView(_ref5) {
393
393
  type = _ref11.type;
394
394
  var value = ((_newRowData$key = newRowData[key]) === null || _newRowData$key === void 0 ? void 0 : _newRowData$key.data) || newRowData[key];
395
395
  var values = Array.isArray(value) ? value : [value];
396
- var renderedValues = values.map(function (value) {
397
- return renderItem({
398
- type: type,
399
- value: value
400
- });
396
+ var renderedValues = renderItem({
397
+ type: type,
398
+ values: values
401
399
  });
402
400
  var stringifiedContent = values.map(function (value) {
403
401
  return stringifyType({
@@ -407,12 +405,11 @@ export var IssueLikeDataTableView = function IssueLikeDataTableView(_ref5) {
407
405
  }).filter(function (value) {
408
406
  return value !== '';
409
407
  }).join(', ');
410
- var content = renderedValues.length === 1 ? renderedValues[0] : renderedValues;
411
408
  var contentComponent = stringifiedContent ? jsx(Tooltip, {
412
409
  tag: TruncateTextTag,
413
410
  content: stringifiedContent,
414
411
  testId: "issues-table-cell-tooltip"
415
- }, content) : content;
412
+ }, renderedValues) : renderedValues;
416
413
  return {
417
414
  key: key,
418
415
  content: contentComponent,
@@ -43,54 +43,77 @@ export var stringifyType = function stringifyType(_ref, formatMessage, formatDat
43
43
  }
44
44
  };
45
45
  export var fallbackRenderType = function fallbackRenderType(item) {
46
- var _item$value, _item$value2, _item$value3;
47
46
  switch (item.type) {
48
47
  case 'boolean':
49
- return /*#__PURE__*/React.createElement(BooleanRenderType, {
50
- value: item.value
48
+ return item.values.map(function (booleanValue) {
49
+ return /*#__PURE__*/React.createElement(BooleanRenderType, {
50
+ value: booleanValue
51
+ });
51
52
  });
52
53
  case 'date':
53
- return /*#__PURE__*/React.createElement(DateTimeRenderType, {
54
- value: item.value,
55
- display: "date"
54
+ return item.values.map(function (dateValue) {
55
+ return /*#__PURE__*/React.createElement(DateTimeRenderType, {
56
+ value: dateValue,
57
+ display: "date"
58
+ });
56
59
  });
57
60
  case 'datetime':
58
- return /*#__PURE__*/React.createElement(DateTimeRenderType, {
59
- value: item.value,
60
- display: "datetime"
61
+ return item.values.map(function (datTimeValue) {
62
+ return /*#__PURE__*/React.createElement(DateTimeRenderType, {
63
+ value: datTimeValue,
64
+ display: "datetime"
65
+ });
61
66
  });
62
67
  case 'icon':
63
- return /*#__PURE__*/React.createElement(IconRenderType, item.value);
68
+ return item.values.map(function (iconValue) {
69
+ return /*#__PURE__*/React.createElement(IconRenderType, iconValue);
70
+ });
64
71
  case 'link':
65
- return /*#__PURE__*/React.createElement(LinkRenderType, _extends({
66
- key: (_item$value = item.value) === null || _item$value === void 0 ? void 0 : _item$value.url
67
- }, item.value));
72
+ return item.values.map(function (linkValue) {
73
+ return /*#__PURE__*/React.createElement(LinkRenderType, _extends({
74
+ key: linkValue === null || linkValue === void 0 ? void 0 : linkValue.url
75
+ }, linkValue));
76
+ });
68
77
  case 'number':
69
- return /*#__PURE__*/React.createElement(NumberRenderType, {
70
- number: item.value
78
+ return item.values.map(function (numberValue) {
79
+ return /*#__PURE__*/React.createElement(NumberRenderType, {
80
+ number: numberValue
81
+ });
71
82
  });
72
83
  case 'status':
73
- return /*#__PURE__*/React.createElement(StatusRenderType, item.value);
84
+ return item.values.map(function (statusValue) {
85
+ return /*#__PURE__*/React.createElement(StatusRenderType, statusValue);
86
+ });
74
87
  case 'string':
75
- return /*#__PURE__*/React.createElement(StringRenderType, {
76
- key: item.value,
77
- text: item.value
88
+ return item.values.map(function (stringValue) {
89
+ return /*#__PURE__*/React.createElement(StringRenderType, {
90
+ key: stringValue,
91
+ text: stringValue
92
+ });
78
93
  });
79
94
  case 'tag':
80
- return /*#__PURE__*/React.createElement(TagRenderType, {
81
- key: ((_item$value2 = item.value) === null || _item$value2 === void 0 ? void 0 : _item$value2.id) || ((_item$value3 = item.value) === null || _item$value3 === void 0 ? void 0 : _item$value3.text),
82
- tag: item.value
95
+ return item.values.map(function (tagValue) {
96
+ return /*#__PURE__*/React.createElement(TagRenderType, {
97
+ key: (tagValue === null || tagValue === void 0 ? void 0 : tagValue.id) || (tagValue === null || tagValue === void 0 ? void 0 : tagValue.text),
98
+ tag: tagValue
99
+ });
83
100
  });
84
101
  case 'time':
85
- return /*#__PURE__*/React.createElement(DateTimeRenderType, {
86
- value: item.value,
87
- display: "time"
102
+ return item.values.map(function (timeValue) {
103
+ return /*#__PURE__*/React.createElement(DateTimeRenderType, {
104
+ value: timeValue,
105
+ display: "time"
106
+ });
88
107
  });
89
108
  case 'user':
90
- return /*#__PURE__*/React.createElement(UserRenderType, item.value);
109
+ return /*#__PURE__*/React.createElement(UserRenderType, {
110
+ users: item.values
111
+ });
91
112
  case 'richtext':
92
- return /*#__PURE__*/React.createElement(RichTextRenderType, {
93
- value: item.value
113
+ return item.values.map(function (richValue) {
114
+ return /*#__PURE__*/React.createElement(RichTextRenderType, {
115
+ value: richValue
116
+ });
94
117
  });
95
118
  default:
96
119
  return /*#__PURE__*/React.createElement(React.Fragment, null);
@@ -1,29 +1,92 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
1
2
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
- var _templateObject, _templateObject2;
3
- import React from 'react';
3
+ var _templateObject;
4
+ /** @jsx jsx */
5
+ import React, { useState } from 'react';
6
+ import { jsx } from '@emotion/react';
4
7
  import styled from '@emotion/styled';
5
8
  import { FormattedMessage } from 'react-intl-next';
6
9
  import Avatar from '@atlaskit/avatar';
10
+ import AvatarGroup from '@atlaskit/avatar-group';
11
+ import { Box, xcss } from '@atlaskit/primitives';
12
+ import { WidthObserver } from '@atlaskit/width-detector';
7
13
  import { FieldTextFontSize } from '../../styled';
8
14
  import { userTypeMessages } from './messages';
9
- var UserWrapper = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n align-items: center;\n font-size: ", ";\n"])), FieldTextFontSize);
10
- var AvatarWrapper = styled.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n margin-right: 5px;\n"])));
15
+ var userWrapperStyles = xcss({
16
+ display: 'flex',
17
+ alignItems: 'center',
18
+ fontSize: "".concat(FieldTextFontSize, "px")
19
+ });
20
+ var avatarWrapperStyles = xcss({
21
+ marginRight: '5px'
22
+ });
23
+ var widthObserverWrapperStyles = xcss({
24
+ position: 'relative'
25
+ });
26
+ var AvatarGroupWrapperStyles = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n /*\n The css from editor core package affects the padding of the AvatarGroup\n The & refers to the parent selector (.<generated className>),\n so && becomes .<generated className>.<generated className> which increases its specificity\n */\n && ul {\n padding-left: 0px;\n }\n"])));
27
+ var getMaxUserCount = function getMaxUserCount(userCount, availableWidth) {
28
+ if (availableWidth <= 28) {
29
+ // If width is less than or equal to 28px, we should only display the user count
30
+ return 1;
31
+ }
32
+ var defaultMaxCount = 5;
33
+ var usersNumFitToAvailableWidth = Math.ceil((availableWidth - 28) / 20);
34
+ return usersNumFitToAvailableWidth > defaultMaxCount ? defaultMaxCount : usersNumFitToAvailableWidth;
35
+ };
11
36
  export var USER_TYPE_TEST_ID = 'link-datasource-render-type--user';
12
37
  var UserType = function UserType(_ref) {
13
- var avatarSource = _ref.avatarSource,
14
- _ref$avatarSize = _ref.avatarSize,
15
- avatarSize = _ref$avatarSize === void 0 ? 'small' : _ref$avatarSize,
16
- displayName = _ref.displayName,
17
- _ref$testId = _ref.testId,
18
- testId = _ref$testId === void 0 ? USER_TYPE_TEST_ID : _ref$testId,
19
- children = _ref.children;
20
- return /*#__PURE__*/React.createElement(UserWrapper, {
21
- "data-testid": testId
22
- }, /*#__PURE__*/React.createElement(AvatarWrapper, null, /*#__PURE__*/React.createElement(Avatar, {
23
- appearance: "circle",
24
- size: avatarSize,
25
- src: avatarSource,
26
- testId: "".concat(testId, "--avatar")
27
- })), children || displayName || /*#__PURE__*/React.createElement(FormattedMessage, userTypeMessages.userDefaultdisplayNameValue));
38
+ var users = _ref.users;
39
+ var _useState = useState(null),
40
+ _useState2 = _slicedToArray(_useState, 2),
41
+ width = _useState2[0],
42
+ setWidth = _useState2[1];
43
+ if (users.length <= 1) {
44
+ var _ref2 = users[0] || {},
45
+ avatarSource = _ref2.avatarSource,
46
+ _ref2$avatarSize = _ref2.avatarSize,
47
+ avatarSize = _ref2$avatarSize === void 0 ? 'small' : _ref2$avatarSize,
48
+ displayName = _ref2.displayName,
49
+ _ref2$testId = _ref2.testId,
50
+ testId = _ref2$testId === void 0 ? USER_TYPE_TEST_ID : _ref2$testId,
51
+ children = _ref2.children;
52
+ return jsx(Box, {
53
+ xcss: userWrapperStyles,
54
+ testId: testId
55
+ }, jsx(Box, {
56
+ xcss: avatarWrapperStyles
57
+ }, jsx(Avatar, {
58
+ appearance: "circle",
59
+ size: avatarSize || 'small',
60
+ src: avatarSource,
61
+ testId: "".concat(testId, "--avatar")
62
+ })), children || displayName || jsx(FormattedMessage, userTypeMessages.userDefaultdisplayNameValue));
63
+ } else {
64
+ var maxCount = width !== null ? getMaxUserCount(users.length, width) : 5;
65
+ var data = users.filter(function (user) {
66
+ return !!user.displayName;
67
+ }).map(function (_ref3) {
68
+ var atlassianUserId = _ref3.atlassianUserId,
69
+ displayName = _ref3.displayName,
70
+ avatarSource = _ref3.avatarSource,
71
+ testId = _ref3.testId;
72
+ return {
73
+ key: atlassianUserId,
74
+ name: displayName,
75
+ src: avatarSource,
76
+ testId: "".concat(testId, "--avatar")
77
+ };
78
+ });
79
+ return jsx(AvatarGroupWrapperStyles, null, jsx(Box, {
80
+ xcss: widthObserverWrapperStyles
81
+ }, jsx(WidthObserver, {
82
+ setWidth: setWidth
83
+ })), jsx(AvatarGroup, {
84
+ data: data,
85
+ maxCount: maxCount,
86
+ size: "small",
87
+ isTooltipDisabled: true,
88
+ testId: USER_TYPE_TEST_ID
89
+ }));
90
+ }
28
91
  };
29
92
  export default UserType;
@@ -1,11 +1,15 @@
1
+ /** @jsx jsx */
1
2
  import React from 'react';
3
+ import { jsx } from '@emotion/react';
2
4
  import { SizeType } from '@atlaskit/avatar';
3
5
  import { User } from '@atlaskit/linking-types';
4
- interface UserProps extends User {
6
+ export interface UserProps extends User {
5
7
  children?: React.ReactElement;
6
8
  testId?: string;
7
9
  avatarSize?: SizeType;
8
10
  }
9
11
  export declare const USER_TYPE_TEST_ID = "link-datasource-render-type--user";
10
- declare const UserType: ({ avatarSource, avatarSize, displayName, testId, children, }: UserProps) => JSX.Element;
12
+ declare const UserType: ({ users }: {
13
+ users: UserProps[];
14
+ }) => jsx.JSX.Element;
11
15
  export default UserType;
@@ -1,7 +1,15 @@
1
1
  /// <reference types="react" />
2
2
  import { DatasourceDataResponseItem, DatasourceResponseSchemaProperty, DatasourceTableStatusType, DatasourceType } from '@atlaskit/linking-types';
3
3
  import { NextPageType } from '../../hooks/useDatasourceTableState';
4
- export type TableViewPropsRenderType = (item: DatasourceType) => React.ReactNode;
4
+ export type DatasourceTypeWithOnlyValues = {
5
+ [K in DatasourceType['type']]: {
6
+ type: K;
7
+ values: Extract<DatasourceType, {
8
+ type: K;
9
+ }>['value'][];
10
+ };
11
+ }[DatasourceType['type']];
12
+ export type TableViewPropsRenderType = (item: DatasourceTypeWithOnlyValues) => React.ReactNode;
5
13
  export interface ColumnSizesMap {
6
14
  [key: string]: number;
7
15
  }
@@ -56,8 +56,11 @@ export interface JiraIssuesConfigModalProps {
56
56
  /** Callback function to be invoked when the insert issues button is clicked */
57
57
  onInsert: (adf: InlineCardAdf | JiraIssuesDatasourceAdf, analyticsEvent?: UIAnalyticsEvent) => void;
58
58
  /** The view mode that the modal will show on open:
59
- * - issues = list of links table
60
- * - count = smart link showing query results count */
59
+ * - Table = Displays a list of links in table format
60
+ * - Inline link = Presents a smart link that shows the count of query results. However, if there's only one result, it converts to an inline smart link of that issue.
61
+
62
+ * The view modes in 'JiraIssueViewModes' have not been changed from 'count' to 'inline link' and 'issue' to 'table'
63
+ * because it will introduce breaking changes to the public API requiring a major version bump*/
61
64
  viewMode?: JiraIssueViewModes;
62
65
  }
63
66
  export {};
@@ -1,11 +1,15 @@
1
+ /** @jsx jsx */
1
2
  import React from 'react';
3
+ import { jsx } from '@emotion/react';
2
4
  import { SizeType } from '@atlaskit/avatar';
3
5
  import { User } from '@atlaskit/linking-types';
4
- interface UserProps extends User {
6
+ export interface UserProps extends User {
5
7
  children?: React.ReactElement;
6
8
  testId?: string;
7
9
  avatarSize?: SizeType;
8
10
  }
9
11
  export declare const USER_TYPE_TEST_ID = "link-datasource-render-type--user";
10
- declare const UserType: ({ avatarSource, avatarSize, displayName, testId, children, }: UserProps) => JSX.Element;
12
+ declare const UserType: ({ users }: {
13
+ users: UserProps[];
14
+ }) => jsx.JSX.Element;
11
15
  export default UserType;
@@ -1,7 +1,15 @@
1
1
  /// <reference types="react" />
2
2
  import { DatasourceDataResponseItem, DatasourceResponseSchemaProperty, DatasourceTableStatusType, DatasourceType } from '@atlaskit/linking-types';
3
3
  import { NextPageType } from '../../hooks/useDatasourceTableState';
4
- export type TableViewPropsRenderType = (item: DatasourceType) => React.ReactNode;
4
+ export type DatasourceTypeWithOnlyValues = {
5
+ [K in DatasourceType['type']]: {
6
+ type: K;
7
+ values: Extract<DatasourceType, {
8
+ type: K;
9
+ }>['value'][];
10
+ };
11
+ }[DatasourceType['type']];
12
+ export type TableViewPropsRenderType = (item: DatasourceTypeWithOnlyValues) => React.ReactNode;
5
13
  export interface ColumnSizesMap {
6
14
  [key: string]: number;
7
15
  }
@@ -56,8 +56,11 @@ export interface JiraIssuesConfigModalProps {
56
56
  /** Callback function to be invoked when the insert issues button is clicked */
57
57
  onInsert: (adf: InlineCardAdf | JiraIssuesDatasourceAdf, analyticsEvent?: UIAnalyticsEvent) => void;
58
58
  /** The view mode that the modal will show on open:
59
- * - issues = list of links table
60
- * - count = smart link showing query results count */
59
+ * - Table = Displays a list of links in table format
60
+ * - Inline link = Presents a smart link that shows the count of query results. However, if there's only one result, it converts to an inline smart link of that issue.
61
+
62
+ * The view modes in 'JiraIssueViewModes' have not been changed from 'count' to 'inline link' and 'issue' to 'table'
63
+ * because it will introduce breaking changes to the public API requiring a major version bump*/
61
64
  viewMode?: JiraIssueViewModes;
62
65
  }
63
66
  export {};
@@ -28,7 +28,9 @@ export const ExampleJiraIssuesTableView = () => {
28
28
 
29
29
  const [columnCustomSizes, setColumnCustomSizes] = useState<
30
30
  ColumnSizesMap | undefined
31
- >();
31
+ >({
32
+ people: 100,
33
+ });
32
34
 
33
35
  const onColumnResize = useCallback(
34
36
  (key: string, width: number) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "1.19.46",
3
+ "version": "1.20.0",
4
4
  "description": "UI Components to support linking platform dataset feature",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -33,6 +33,7 @@
33
33
  "@atlaskit/adf-schema": "^35.3.0",
34
34
  "@atlaskit/analytics-next": "^9.1.3",
35
35
  "@atlaskit/avatar": "^21.4.0",
36
+ "@atlaskit/avatar-group": "^9.5.0",
36
37
  "@atlaskit/badge": "^15.2.0",
37
38
  "@atlaskit/button": "^17.2.0",
38
39
  "@atlaskit/dropdown-menu": "^12.2.0",
@@ -67,6 +68,7 @@
67
68
  "@atlaskit/tokens": "^1.35.0",
68
69
  "@atlaskit/tooltip": "^18.1.0",
69
70
  "@atlaskit/ufo": "^0.2.4",
71
+ "@atlaskit/width-detector": "^4.1.7",
70
72
  "@babel/runtime": "^7.0.0",
71
73
  "@emotion/react": "^11.7.1",
72
74
  "@emotion/styled": "^11.0.0",