@atlaskit/link-datasource 1.19.46 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/hooks/useDatasourceTableState.js +91 -88
  3. package/dist/cjs/ui/common/error-state/messages.js +20 -0
  4. package/dist/cjs/ui/common/error-state/provider-auth-required-svg.js +449 -0
  5. package/dist/cjs/ui/common/error-state/provider-auth-required.js +96 -0
  6. package/dist/cjs/ui/datasource-table-view/datasourceTableView.js +16 -7
  7. package/dist/cjs/ui/issue-like-table/index.js +4 -7
  8. package/dist/cjs/ui/issue-like-table/render-type/index.js +51 -28
  9. package/dist/cjs/ui/issue-like-table/render-type/user/index.js +85 -19
  10. package/dist/es2019/hooks/useDatasourceTableState.js +26 -24
  11. package/dist/es2019/ui/common/error-state/messages.js +20 -0
  12. package/dist/es2019/ui/common/error-state/provider-auth-required-svg.js +442 -0
  13. package/dist/es2019/ui/common/error-state/provider-auth-required.js +62 -0
  14. package/dist/es2019/ui/datasource-table-view/datasourceTableView.js +16 -7
  15. package/dist/es2019/ui/issue-like-table/index.js +4 -5
  16. package/dist/es2019/ui/issue-like-table/render-type/index.js +34 -33
  17. package/dist/es2019/ui/issue-like-table/render-type/user/index.js +81 -21
  18. package/dist/esm/hooks/useDatasourceTableState.js +91 -88
  19. package/dist/esm/ui/common/error-state/messages.js +20 -0
  20. package/dist/esm/ui/common/error-state/provider-auth-required-svg.js +442 -0
  21. package/dist/esm/ui/common/error-state/provider-auth-required.js +85 -0
  22. package/dist/esm/ui/datasource-table-view/datasourceTableView.js +16 -7
  23. package/dist/esm/ui/issue-like-table/index.js +4 -7
  24. package/dist/esm/ui/issue-like-table/render-type/index.js +51 -28
  25. package/dist/esm/ui/issue-like-table/render-type/user/index.js +82 -19
  26. package/dist/types/hooks/useDatasourceTableState.d.ts +3 -1
  27. package/dist/types/ui/common/error-state/messages.d.ts +20 -0
  28. package/dist/types/ui/common/error-state/provider-auth-required-svg.d.ts +3 -0
  29. package/dist/types/ui/common/error-state/provider-auth-required.d.ts +9 -0
  30. package/dist/types/ui/issue-like-table/render-type/user/index.d.ts +6 -2
  31. package/dist/types/ui/issue-like-table/types.d.ts +9 -1
  32. package/dist/types/ui/jira-issues-modal/types.d.ts +5 -2
  33. package/dist/types-ts4.5/hooks/useDatasourceTableState.d.ts +3 -1
  34. package/dist/types-ts4.5/ui/common/error-state/messages.d.ts +20 -0
  35. package/dist/types-ts4.5/ui/common/error-state/provider-auth-required-svg.d.ts +3 -0
  36. package/dist/types-ts4.5/ui/common/error-state/provider-auth-required.d.ts +9 -0
  37. package/dist/types-ts4.5/ui/issue-like-table/render-type/user/index.d.ts +6 -2
  38. package/dist/types-ts4.5/ui/issue-like-table/types.d.ts +9 -1
  39. package/dist/types-ts4.5/ui/jira-issues-modal/types.d.ts +5 -2
  40. package/examples-helpers/buildJiraIssuesTable.tsx +37 -7
  41. package/package.json +6 -3
@@ -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;
@@ -16,12 +16,14 @@ export const useDatasourceTableState = ({
16
16
  } = useErrorLogger();
17
17
  const idFieldCount = 1;
18
18
  const keyFieldCount = 1;
19
+ const [initialEmptyArray] = useState([]);
19
20
  const [defaultVisibleColumnKeys, setDefaultVisibleColumnKeys] = useState([]);
20
21
  const [lastRequestedFieldKeys, setLastRequestedFieldKeys] = useState([]);
21
22
  const [fullSchema, setFullSchema] = useState({
22
23
  properties: []
23
24
  });
24
25
  const [status, setStatus] = useState('empty');
26
+ const [authDetails, setAuthDetails] = useState([]);
25
27
  const [responseItems, setResponseItems] = useState([]);
26
28
  const [hasNextPage, setHasNextPage] = useState(true);
27
29
  const [nextCursor, setNextCursor] = useState(undefined);
@@ -41,7 +43,8 @@ export const useDatasourceTableState = ({
41
43
  try {
42
44
  const {
43
45
  meta: {
44
- access
46
+ access,
47
+ auth
45
48
  },
46
49
  data: {
47
50
  schema
@@ -49,12 +52,9 @@ export const useDatasourceTableState = ({
49
52
  } = await getDatasourceDetails(datasourceId, {
50
53
  parameters
51
54
  });
52
- if (access === 'unauthorized') {
53
- setStatus('unauthorized');
54
- return;
55
- }
56
- if (access === 'forbidden') {
57
- setStatus('forbidden');
55
+ if (access === 'unauthorized' || access === 'forbidden') {
56
+ setStatus(access);
57
+ setAuthDetails(auth || initialEmptyArray);
58
58
  return;
59
59
  }
60
60
  const isColumnNotPresentInCurrentColumnsList = col => !columns.find(column => column.key === col.key);
@@ -73,7 +73,7 @@ export const useDatasourceTableState = ({
73
73
  }
74
74
  setStatus('rejected');
75
75
  }
76
- }, [captureError, columns, datasourceId, getDatasourceDetails, parameters]);
76
+ }, [captureError, columns, datasourceId, getDatasourceDetails, parameters, initialEmptyArray]);
77
77
  const applySchemaProperties = useCallback((schema, fieldKeys) => {
78
78
  let {
79
79
  properties,
@@ -131,7 +131,8 @@ export const useDatasourceTableState = ({
131
131
  meta: {
132
132
  access,
133
133
  destinationObjectTypes,
134
- extensionKey
134
+ extensionKey,
135
+ auth
135
136
  },
136
137
  data: {
137
138
  items,
@@ -140,12 +141,9 @@ export const useDatasourceTableState = ({
140
141
  schema
141
142
  }
142
143
  } = await getDatasourceData(datasourceId, datasourceDataRequest, shouldForceRequest);
143
- if (access === 'unauthorized') {
144
- setStatus('unauthorized');
145
- return;
146
- }
147
- if (access === 'forbidden') {
148
- setStatus('forbidden');
144
+ if (access === 'unauthorized' || access === 'forbidden') {
145
+ setStatus(access);
146
+ setAuthDetails(auth || initialEmptyArray);
149
147
  return;
150
148
  }
151
149
  setExtensionKey(extensionKey);
@@ -192,23 +190,26 @@ export const useDatasourceTableState = ({
192
190
  }
193
191
  setStatus('rejected');
194
192
  }
195
- }, [captureError, parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems, applySchemaProperties, fireEvent, fullSchema]);
193
+ }, [captureError, parameters, fieldKeys, nextCursor, getDatasourceData, datasourceId, responseItems, applySchemaProperties, fireEvent, fullSchema, initialEmptyArray]);
196
194
  const reset = useCallback(options => {
197
- setStatus('empty');
198
- setResponseItems([]);
195
+ setResponseItems(initialEmptyArray);
199
196
  setHasNextPage(true);
200
197
  setNextCursor(undefined);
201
198
  setTotalCount(undefined);
202
- setLastRequestedFieldKeys([]);
199
+ setLastRequestedFieldKeys(initialEmptyArray);
200
+ setAuthDetails(initialEmptyArray);
203
201
  setFullSchema({
204
- properties: []
202
+ properties: initialEmptyArray
205
203
  });
206
204
  setShouldForceRequest((options === null || options === void 0 ? void 0 : options.shouldForceRequest) || false);
207
205
  if (options !== null && options !== void 0 && options.shouldResetColumns) {
208
- setColumns([]);
209
- setDefaultVisibleColumnKeys([]);
206
+ setColumns(initialEmptyArray);
207
+ setDefaultVisibleColumnKeys(initialEmptyArray);
210
208
  }
211
- }, []);
209
+
210
+ // setting the status earlier is triggering useEffects without all reset state values, hence placing this as the last state reset item
211
+ setStatus('empty');
212
+ }, [initialEmptyArray]);
212
213
 
213
214
  // this takes care of requesting /data initially
214
215
  useEffect(() => {
@@ -255,6 +256,7 @@ export const useDatasourceTableState = ({
255
256
  defaultVisibleColumnKeys,
256
257
  totalCount,
257
258
  extensionKey,
258
- destinationObjectTypes
259
+ destinationObjectTypes,
260
+ authDetails
259
261
  };
260
262
  };
@@ -54,5 +54,25 @@ export const loadingErrorMessages = defineMessages({
54
54
  id: 'linkDataSource.jira-issues.no.jira.sites.access.description',
55
55
  description: 'Description that shows in the modal when user has no access to any Jira sites',
56
56
  defaultMessage: 'To request access, contact your admin.'
57
+ },
58
+ authScreenHeaderText: {
59
+ id: 'linkDataSource.datasource.table.authScreenHeaderText',
60
+ defaultMessage: 'Connect your account',
61
+ description: 'Header text to be displayed in the auth screen UI.'
62
+ },
63
+ authScreenDescriptionText: {
64
+ id: 'linkDataSource.datasource.table.authScreenDescriptionText',
65
+ defaultMessage: 'Connect your account to collaborate on work across Atlassian products.',
66
+ description: 'Description text to be displayed in the auth screen UI.'
67
+ },
68
+ learnMoreAboutSmartLinks: {
69
+ id: 'linkDataSource.datasource.table.learnMoreAboutSmartLinks',
70
+ defaultMessage: 'Learn more about Smart Links.',
71
+ description: 'An anchor link to redirect user to a page about Smart Links.'
72
+ },
73
+ authConnectButtonText: {
74
+ id: 'linkDataSource.datasource.table.authConnectButtonText',
75
+ defaultMessage: 'Connect',
76
+ description: 'Label for the authentication button.'
57
77
  }
58
78
  });