@atlaskit/link-datasource 1.15.3 → 1.16.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 (59) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/hooks/useAssetsClient.js +71 -27
  4. package/dist/cjs/services/cmdbService.js +128 -28
  5. package/dist/cjs/services/cmdbService.utils.js +64 -0
  6. package/dist/cjs/ui/assets-modal/modal/index.js +73 -9
  7. package/dist/cjs/ui/assets-modal/modal/render-assets-content/index.js +25 -12
  8. package/dist/cjs/ui/assets-modal/search-container/index.js +2 -1
  9. package/dist/cjs/ui/assets-modal/search-container/object-schema-select/index.js +21 -63
  10. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +14 -14
  11. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +18 -3
  12. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
  13. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.js +22 -0
  14. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +21 -4
  15. package/dist/es2019/analytics/constants.js +1 -1
  16. package/dist/es2019/hooks/useAssetsClient.js +39 -15
  17. package/dist/es2019/services/cmdbService.js +60 -14
  18. package/dist/es2019/services/cmdbService.utils.js +39 -0
  19. package/dist/es2019/ui/assets-modal/modal/index.js +70 -9
  20. package/dist/es2019/ui/assets-modal/modal/render-assets-content/index.js +24 -9
  21. package/dist/es2019/ui/assets-modal/search-container/index.js +2 -1
  22. package/dist/es2019/ui/assets-modal/search-container/object-schema-select/index.js +2 -25
  23. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +2 -2
  24. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +18 -3
  25. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
  26. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.js +17 -0
  27. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +18 -3
  28. package/dist/esm/analytics/constants.js +1 -1
  29. package/dist/esm/hooks/useAssetsClient.js +72 -28
  30. package/dist/esm/services/cmdbService.js +128 -28
  31. package/dist/esm/services/cmdbService.utils.js +57 -0
  32. package/dist/esm/ui/assets-modal/modal/index.js +73 -9
  33. package/dist/esm/ui/assets-modal/modal/render-assets-content/index.js +24 -9
  34. package/dist/esm/ui/assets-modal/search-container/index.js +2 -1
  35. package/dist/esm/ui/assets-modal/search-container/object-schema-select/index.js +18 -60
  36. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +14 -14
  37. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +18 -3
  38. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
  39. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.js +15 -0
  40. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +21 -4
  41. package/dist/types/hooks/useAssetsClient.d.ts +5 -1
  42. package/dist/types/services/cmdbService.utils.d.ts +9 -0
  43. package/dist/types/ui/assets-modal/modal/render-assets-content/index.d.ts +3 -2
  44. package/dist/types/ui/assets-modal/search-container/index.d.ts +1 -0
  45. package/dist/types/ui/assets-modal/search-container/object-schema-select/index.d.ts +2 -1
  46. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +1 -1
  47. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.d.ts +5 -0
  48. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.d.ts +6 -0
  49. package/dist/types/ui/jira-issues-modal/basic-filters/ui/menu-list/index.d.ts +4 -1
  50. package/dist/types-ts4.5/hooks/useAssetsClient.d.ts +5 -1
  51. package/dist/types-ts4.5/services/cmdbService.utils.d.ts +9 -0
  52. package/dist/types-ts4.5/ui/assets-modal/modal/render-assets-content/index.d.ts +3 -2
  53. package/dist/types-ts4.5/ui/assets-modal/search-container/index.d.ts +1 -0
  54. package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/index.d.ts +2 -1
  55. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +1 -1
  56. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.d.ts +5 -0
  57. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.d.ts +6 -0
  58. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/menu-list/index.d.ts +4 -1
  59. package/package.json +1 -1
@@ -36,7 +36,7 @@ var AssetsSearchContainer = exports.AssetsSearchContainer = function AssetsSearc
36
36
  return (0, _react.jsx)(_form.default, {
37
37
  onSubmit: onFormSubmit
38
38
  }, function (_ref) {
39
- var _initialSearchData$ob, _initialSearchData$aq;
39
+ var _initialSearchData$ob, _initialSearchData$ob2, _initialSearchData$aq;
40
40
  var formProps = _ref.formProps;
41
41
  return (0, _react.jsx)(_styled.FormContainer, (0, _extends2.default)({}, formProps, {
42
42
  id: SEARCH_FORM_ID
@@ -45,6 +45,7 @@ var AssetsSearchContainer = exports.AssetsSearchContainer = function AssetsSearc
45
45
  }, modalTitle, (0, _react.jsx)(_styled.SchemaSelectContainer, null, (0, _react.jsx)(_objectSchemaSelect.AssetsObjectSchemaSelect, {
46
46
  value: (_initialSearchData$ob = initialSearchData.objectSchema) !== null && _initialSearchData$ob !== void 0 ? _initialSearchData$ob : undefined,
47
47
  workspaceId: workspaceId,
48
+ initialObjectSchemas: (_initialSearchData$ob2 = initialSearchData.objectSchemas) !== null && _initialSearchData$ob2 !== void 0 ? _initialSearchData$ob2 : undefined,
48
49
  classNamePrefix: "assets-datasource-modal--object-schema-select"
49
50
  }))), (0, _react.jsx)(_styled.FormRowContainer, null, (0, _react.jsx)(_aqlSearchInput.AqlSearchInput, {
50
51
  value: (_initialSearchData$aq = initialSearchData.aql) !== null && _initialSearchData$aq !== void 0 ? _initialSearchData$aq : DEFAULT_AQL_QUERY,
@@ -9,16 +9,13 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
9
9
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
12
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
- var _react = require("react");
15
- var _react2 = require("@emotion/react");
13
+ var _react = require("@emotion/react");
16
14
  var _debouncePromise = _interopRequireDefault(require("debounce-promise"));
17
15
  var _reactIntlNext = require("react-intl-next");
18
16
  var _form = require("@atlaskit/form");
19
17
  var _select = require("@atlaskit/select");
20
18
  var _constants = require("@atlaskit/theme/constants");
21
- var _analytics = require("../../../../analytics");
22
19
  var _useObjectSchemas2 = require("../../../../hooks/useObjectSchemas");
23
20
  var _types = require("../../../../types/assets/types");
24
21
  var _styled = require("../styled");
@@ -51,74 +48,35 @@ var selectInAModalStyleFixProps = exports.selectInAModalStyleFixProps = {
51
48
  var AssetsObjectSchemaSelect = exports.AssetsObjectSchemaSelect = function AssetsObjectSchemaSelect(_ref) {
52
49
  var value = _ref.value,
53
50
  workspaceId = _ref.workspaceId,
51
+ initialObjectSchemas = _ref.initialObjectSchemas,
54
52
  _ref$classNamePrefix = _ref.classNamePrefix,
55
53
  classNamePrefix = _ref$classNamePrefix === void 0 ? 'assets-datasource-modal--object-schema-select' : _ref$classNamePrefix;
56
- var _useState = (0, _react.useState)(null),
57
- _useState2 = (0, _slicedToArray2.default)(_useState, 2),
58
- defaultOptions = _useState2[0],
59
- setDefaultOptions = _useState2[1];
60
- var _useDatasourceAnalyti = (0, _analytics.useDatasourceAnalyticsEvents)(),
61
- fireEvent = _useDatasourceAnalyti.fireEvent;
62
54
  var _useIntl = (0, _reactIntlNext.useIntl)(),
63
55
  formatMessage = _useIntl.formatMessage;
64
56
  var _useObjectSchemas = (0, _useObjectSchemas2.useObjectSchemas)(workspaceId),
65
57
  fetchObjectSchemas = _useObjectSchemas.fetchObjectSchemas,
66
58
  objectSchemasLoading = _useObjectSchemas.objectSchemasLoading;
67
59
  var selectedObjectSchema = value ? (0, _utils.objectSchemaToSelectOption)(value) : undefined;
68
- (0, _react.useEffect)(function () {
69
- var fetchInitialData = /*#__PURE__*/function () {
70
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
71
- var _yield$fetchObjectSch, objectSchemas, totalObjectSchemas;
72
- return _regenerator.default.wrap(function _callee$(_context) {
73
- while (1) switch (_context.prev = _context.next) {
74
- case 0:
75
- _context.next = 2;
76
- return fetchObjectSchemas('');
77
- case 2:
78
- _yield$fetchObjectSch = _context.sent;
79
- objectSchemas = _yield$fetchObjectSch.objectSchemas;
80
- totalObjectSchemas = _yield$fetchObjectSch.totalObjectSchemas;
81
- // We only want to send modal ready event once after we've fetched the schema count
82
- fireEvent('ui.modal.ready.datasource', {
83
- schemasCount: totalObjectSchemas !== null && totalObjectSchemas !== void 0 ? totalObjectSchemas : 0,
84
- instancesCount: null
85
- });
86
- setDefaultOptions(mapObjectSchemasToOptions(objectSchemas));
87
- case 7:
88
- case "end":
89
- return _context.stop();
90
- }
91
- }, _callee);
92
- }));
93
- return function fetchInitialData() {
94
- return _ref2.apply(this, arguments);
95
- };
96
- }();
97
- if (defaultOptions === null) {
98
- fetchInitialData();
99
- }
100
- // eslint-disable-next-line react-hooks/exhaustive-deps
101
- }, []);
102
60
  var loadOptions = /*#__PURE__*/function () {
103
- var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(inputValue) {
104
- var _yield$fetchObjectSch2, objectSchemas;
105
- return _regenerator.default.wrap(function _callee2$(_context2) {
106
- while (1) switch (_context2.prev = _context2.next) {
61
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(inputValue) {
62
+ var _yield$fetchObjectSch, objectSchemas;
63
+ return _regenerator.default.wrap(function _callee$(_context) {
64
+ while (1) switch (_context.prev = _context.next) {
107
65
  case 0:
108
- _context2.next = 2;
66
+ _context.next = 2;
109
67
  return fetchObjectSchemas(inputValue);
110
68
  case 2:
111
- _yield$fetchObjectSch2 = _context2.sent;
112
- objectSchemas = _yield$fetchObjectSch2.objectSchemas;
113
- return _context2.abrupt("return", mapObjectSchemasToOptions(objectSchemas));
69
+ _yield$fetchObjectSch = _context.sent;
70
+ objectSchemas = _yield$fetchObjectSch.objectSchemas;
71
+ return _context.abrupt("return", mapObjectSchemasToOptions(objectSchemas));
114
72
  case 5:
115
73
  case "end":
116
- return _context2.stop();
74
+ return _context.stop();
117
75
  }
118
- }, _callee2);
76
+ }, _callee);
119
77
  }));
120
78
  return function loadOptions(_x) {
121
- return _ref3.apply(this, arguments);
79
+ return _ref2.apply(this, arguments);
122
80
  };
123
81
  }();
124
82
  var debouncedLoadOptions = (0, _debouncePromise.default)(loadOptions, SEARCH_DEBOUNCE_MS);
@@ -128,22 +86,22 @@ var AssetsObjectSchemaSelect = exports.AssetsObjectSchemaSelect = function Asset
128
86
  }
129
87
  return undefined;
130
88
  };
131
- return (0, _react2.jsx)(_styled.FieldContainer, null, (0, _react2.jsx)(_form.Field, {
89
+ return (0, _react.jsx)(_styled.FieldContainer, null, (0, _react.jsx)(_form.Field, {
132
90
  name: _types.objectSchemaKey,
133
91
  defaultValue: selectedObjectSchema,
134
92
  validate: function validate(value) {
135
93
  return validateSchema(value);
136
94
  }
137
- }, function (_ref4) {
138
- var _ref4$fieldProps = _ref4.fieldProps,
139
- _onChange = _ref4$fieldProps.onChange,
140
- onFocus = _ref4$fieldProps.onFocus,
141
- restFieldProps = (0, _objectWithoutProperties2.default)(_ref4$fieldProps, _excluded);
142
- return (0, _react2.jsx)(_select.AsyncSelect, (0, _extends2.default)({
95
+ }, function (_ref3) {
96
+ var _ref3$fieldProps = _ref3.fieldProps,
97
+ _onChange = _ref3$fieldProps.onChange,
98
+ onFocus = _ref3$fieldProps.onFocus,
99
+ restFieldProps = (0, _objectWithoutProperties2.default)(_ref3$fieldProps, _excluded);
100
+ return (0, _react.jsx)(_select.AsyncSelect, (0, _extends2.default)({
143
101
  autoFocus: true,
144
102
  classNamePrefix: classNamePrefix,
145
103
  isLoading: objectSchemasLoading,
146
- defaultOptions: defaultOptions !== null && defaultOptions !== void 0 ? defaultOptions : [],
104
+ defaultOptions: mapObjectSchemasToOptions(initialObjectSchemas),
147
105
  isSearchable: true,
148
106
  loadOptions: debouncedLoadOptions,
149
107
  placeholder: formatMessage(_messages.objectSchemaSelectMessages.placeholder),
@@ -38,28 +38,29 @@ var useFilterOptions = exports.useFilterOptions = function useFilterOptions(_ref
38
38
  var _ref3,
39
39
  pageCursor,
40
40
  searchString,
41
+ isNewSearch,
41
42
  isRequestLikeInitialSearch,
42
43
  initialResponseData,
43
44
  response,
44
- isNewSearch,
45
45
  _args = arguments;
46
46
  return _regenerator.default.wrap(function _callee$(_context) {
47
47
  while (1) switch (_context.prev = _context.next) {
48
48
  case 0:
49
49
  _ref3 = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, pageCursor = _ref3.pageCursor, searchString = _ref3.searchString;
50
- setStatus('loading');
50
+ isNewSearch = !pageCursor;
51
+ isNewSearch ? setStatus('loading') : setStatus('loadingMore');
51
52
  isRequestLikeInitialSearch = !pageCursor && !searchString;
52
53
  initialResponseData = initialData.current;
53
- _context.prev = 4;
54
+ _context.prev = 5;
54
55
  if (!(isRequestLikeInitialSearch && initialResponseData)) {
55
- _context.next = 9;
56
+ _context.next = 10;
56
57
  break;
57
58
  }
58
59
  _context.t0 = initialResponseData;
59
- _context.next = 12;
60
+ _context.next = 13;
60
61
  break;
61
- case 9:
62
- _context.next = 11;
62
+ case 10:
63
+ _context.next = 12;
63
64
  return getFieldValues({
64
65
  cloudId: cloudId,
65
66
  jql: '',
@@ -67,18 +68,17 @@ var useFilterOptions = exports.useFilterOptions = function useFilterOptions(_ref
67
68
  searchString: searchString,
68
69
  pageCursor: pageCursor
69
70
  });
70
- case 11:
71
- _context.t0 = _context.sent;
72
71
  case 12:
72
+ _context.t0 = _context.sent;
73
+ case 13:
73
74
  response = _context.t0;
74
75
  if (!(response.errors && response.errors.length > 0)) {
75
- _context.next = 16;
76
+ _context.next = 17;
76
77
  break;
77
78
  }
78
79
  setStatus('rejected');
79
80
  return _context.abrupt("return");
80
- case 16:
81
- isNewSearch = !pageCursor;
81
+ case 17:
82
82
  if (isNewSearch) {
83
83
  setFilterOptions((0, _transformers.mapFieldValuesToFilterOptions)(response));
84
84
  if (isRequestLikeInitialSearch) {
@@ -98,13 +98,13 @@ var useFilterOptions = exports.useFilterOptions = function useFilterOptions(_ref
98
98
  break;
99
99
  case 23:
100
100
  _context.prev = 23;
101
- _context.t1 = _context["catch"](4);
101
+ _context.t1 = _context["catch"](5);
102
102
  setStatus('rejected');
103
103
  case 26:
104
104
  case "end":
105
105
  return _context.stop();
106
106
  }
107
- }, _callee, null, [[4, 23]]);
107
+ }, _callee, null, [[5, 23]]);
108
108
  })), [cloudId, filterOptions, filterType, getFieldValues]);
109
109
  return {
110
110
  filterOptions: filterOptions,
@@ -57,7 +57,8 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
57
57
  filterOptions = _useFilterOptions.filterOptions,
58
58
  fetchFilterOptions = _useFilterOptions.fetchFilterOptions,
59
59
  totalCount = _useFilterOptions.totalCount,
60
- status = _useFilterOptions.status;
60
+ status = _useFilterOptions.status,
61
+ pageCursor = _useFilterOptions.pageCursor;
61
62
  var _useDebouncedCallback = (0, _useDebounce.useDebouncedCallback)(function (searchString) {
62
63
  fetchFilterOptions({
63
64
  searchString: searchString
@@ -96,6 +97,14 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
96
97
  });
97
98
  }
98
99
  }, [fetchFilterOptions, searchTerm, status]);
100
+ var handleShowMore = (0, _react.useCallback)(function () {
101
+ if (pageCursor) {
102
+ fetchFilterOptions({
103
+ pageCursor: pageCursor,
104
+ searchString: searchTerm
105
+ });
106
+ }
107
+ }, [fetchFilterOptions, pageCursor, searchTerm]);
99
108
  (0, _react.useEffect)(function () {
100
109
  if (status === 'resolved') {
101
110
  var _pickerRef$current;
@@ -106,8 +115,11 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
106
115
  var filterOptionsLength = filterOptions.length;
107
116
  var isError = status === 'rejected';
108
117
  var isLoading = status === 'loading' || status === 'empty';
118
+ var isLoadingMore = status === 'loadingMore';
109
119
  var isEmpty = status === 'resolved' && filterOptionsLength === 0;
110
- var shouldShowFooter = status === 'resolved' && filterOptionsLength > 0;
120
+ var areAllResultsLoaded = filterOptions.length === totalCount;
121
+ var shouldShowFooter = (status === 'resolved' || isLoadingMore) && filterOptions.length > 0; // footer should not disappear when there is an inline spinner for loading more data
122
+ var shouldDisplayShowMoreButton = status === 'resolved' && !!pageCursor && !areAllResultsLoaded;
111
123
  var options = isLoading || isError ? [] : filterOptions; // if not set to [], for eg: on loading, no loading UI will be shown
112
124
 
113
125
  return /*#__PURE__*/_react.default.createElement(_select.PopupSelect, {
@@ -136,7 +148,10 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
136
148
  return /*#__PURE__*/_react.default.createElement(_menuList.default, (0, _extends2.default)({}, props, {
137
149
  isError: isError,
138
150
  isEmpty: isEmpty,
139
- isLoading: isLoading
151
+ isLoading: isLoading,
152
+ isLoadingMore: isLoadingMore,
153
+ showMore: shouldDisplayShowMoreButton,
154
+ handleShowMore: handleShowMore
140
155
  }));
141
156
  },
142
157
  DropdownIndicator: _dropdownIndicator.default,
@@ -34,5 +34,10 @@ var asyncPopupSelectMessages = exports.asyncPopupSelectMessages = {
34
34
  id: 'linkDataSource.basic-filter.assignee.label',
35
35
  description: 'Label to be displayed for assignee filter dropdown button.',
36
36
  defaultMessage: 'Assignee'
37
+ },
38
+ showMoreMessage: {
39
+ id: 'linkDataSource.basic-filter.showMoreButton',
40
+ defaultMessage: 'Show more',
41
+ description: 'The text to show more options in dropdown'
37
42
  }
38
43
  };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _reactIntlNext = require("react-intl-next");
10
+ var _button = _interopRequireDefault(require("@atlaskit/button"));
11
+ var _messages = require("./messages");
12
+ var ShowMoreButton = function ShowMoreButton(_ref) {
13
+ var onShowMore = _ref.onShowMore;
14
+ var _useIntl = (0, _reactIntlNext.useIntl)(),
15
+ formatMessage = _useIntl.formatMessage;
16
+ return /*#__PURE__*/_react.default.createElement(_button.default, {
17
+ onClick: onShowMore,
18
+ appearance: "link",
19
+ testId: "jlol-basic-filter-popup-select--show-more-button"
20
+ }, formatMessage(_messages.asyncPopupSelectMessages.showMoreMessage));
21
+ };
22
+ var _default = exports.default = ShowMoreButton;
@@ -7,18 +7,33 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
9
9
  var _react = _interopRequireDefault(require("react"));
10
+ var _primitives = require("@atlaskit/primitives");
10
11
  var _select = require("@atlaskit/select");
12
+ var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
13
+ var _showMoreButton = _interopRequireDefault(require("../async-popup-select/showMoreButton"));
11
14
  var _errorMessage = _interopRequireDefault(require("./errorMessage"));
12
15
  var _loadingMessage = _interopRequireDefault(require("./loadingMessage"));
13
16
  var _noOptionsMessage = _interopRequireDefault(require("./noOptionsMessage"));
14
- var _excluded = ["isLoading", "isError", "isEmpty", "children"];
17
+ var _excluded = ["isLoading", "isLoadingMore", "isError", "isEmpty", "showMore", "handleShowMore", "children"];
15
18
  var CustomMenuList = function CustomMenuList(_ref) {
16
19
  var isLoading = _ref.isLoading,
20
+ isLoadingMore = _ref.isLoadingMore,
17
21
  isError = _ref.isError,
18
22
  isEmpty = _ref.isEmpty,
23
+ showMore = _ref.showMore,
24
+ handleShowMore = _ref.handleShowMore,
19
25
  children = _ref.children,
20
26
  props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
21
- var getChildComponent = function getChildComponent() {
27
+ var shouldDisplayShowMore = showMore && !isLoadingMore;
28
+ var isLoadingMoreData = !shouldDisplayShowMore && isLoadingMore;
29
+ var InlineSpinner = function InlineSpinner() {
30
+ return /*#__PURE__*/_react.default.createElement(_primitives.Flex, {
31
+ justifyContent: "center"
32
+ }, /*#__PURE__*/_react.default.createElement(_spinner.default, {
33
+ size: "medium"
34
+ }));
35
+ };
36
+ var renderChildren = function renderChildren() {
22
37
  if (isLoading) {
23
38
  return /*#__PURE__*/_react.default.createElement(_loadingMessage.default, null);
24
39
  }
@@ -28,8 +43,10 @@ var CustomMenuList = function CustomMenuList(_ref) {
28
43
  if (isEmpty) {
29
44
  return /*#__PURE__*/_react.default.createElement(_noOptionsMessage.default, null);
30
45
  }
31
- return children;
46
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children, shouldDisplayShowMore && /*#__PURE__*/_react.default.createElement(_showMoreButton.default, {
47
+ onShowMore: handleShowMore
48
+ }), isLoadingMoreData && /*#__PURE__*/_react.default.createElement(InlineSpinner, null));
32
49
  };
33
- return /*#__PURE__*/_react.default.createElement(_select.components.MenuList, props, getChildComponent());
50
+ return /*#__PURE__*/_react.default.createElement(_select.components.MenuList, props, renderChildren());
34
51
  };
35
52
  var _default = exports.default = CustomMenuList;
@@ -1,5 +1,5 @@
1
1
  export const EVENT_CHANNEL = 'media';
2
2
  export const packageMetaData = {
3
3
  packageName: "@atlaskit/link-datasource",
4
- packageVersion: "1.15.3"
4
+ packageVersion: "1.16.0"
5
5
  };
@@ -1,32 +1,52 @@
1
1
  import { useEffect, useState } from 'react';
2
- import { fetchObjectSchema, getWorkspaceId } from '../services/cmdbService';
2
+ import { fetchObjectSchema, fetchObjectSchemas, getWorkspaceId } from '../services/cmdbService';
3
+ const handleAssetsClientErrors = (errorSetter, error) => {
4
+ if (error instanceof Error) {
5
+ errorSetter(error);
6
+ } else {
7
+ errorSetter(new Error('Unexpected error occured'));
8
+ }
9
+ };
3
10
  export const useAssetsClient = initialParameters => {
4
11
  const [loading, setLoading] = useState(false);
5
12
  const [workspaceId, setWorkspaceId] = useState();
6
- const [objectSchema, setObjectSchema] = useState();
7
- const [error, setError] = useState();
13
+ const [workspaceError, setWorkspaceError] = useState();
14
+ const [existingObjectSchema, setExistingObjectSchema] = useState();
15
+ const [existingObjectSchemaError, setExistingObjectSchemaError] = useState();
16
+ const [objectSchemas, setObjectSchemas] = useState();
17
+ const [totalObjectSchemas, setTotalObjectSchemas] = useState();
18
+ const [objectSchemasError, setObjectSchemasError] = useState();
19
+
20
+ /*
21
+ * We wrap this in nested try/catch blocks because we want to handle
22
+ * workspaceError/existingObjectSchemaError/objectSchemasError differently
23
+ * if we need to implement more initial data fetching/errors we should look at a store
24
+ */
8
25
  useEffect(() => {
9
26
  (async () => {
10
27
  setLoading(true);
11
- setError(undefined);
28
+ setWorkspaceError(undefined);
12
29
  try {
13
30
  const workspaceId = await getWorkspaceId();
14
31
  setWorkspaceId(workspaceId);
15
- // Check schema from initial parameters still exists and fetch name for schema select
32
+ // Check schema from initial parameters still exists and fetch name/permissions for schema select
16
33
  if (initialParameters !== null && initialParameters !== void 0 && initialParameters.schemaId) {
17
34
  try {
18
35
  const fetchedObjectSchema = await fetchObjectSchema(workspaceId, initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.schemaId);
19
- setObjectSchema(fetchedObjectSchema);
20
- } catch {
21
- // Could update this to check if status is 404 and set objectSchemaError
36
+ setExistingObjectSchema(fetchedObjectSchema);
37
+ } catch (fetchObjectSchemaError) {
38
+ handleAssetsClientErrors(setExistingObjectSchemaError, fetchObjectSchemaError);
22
39
  }
23
40
  }
24
- } catch (err) {
25
- if (err instanceof Error) {
26
- setError(err);
27
- } else {
28
- setError(new Error('Unexpected error occured'));
41
+ try {
42
+ const fetchedObjectSchemasResponse = await fetchObjectSchemas(workspaceId);
43
+ setObjectSchemas(fetchedObjectSchemasResponse.values);
44
+ setTotalObjectSchemas(fetchedObjectSchemasResponse.total);
45
+ } catch (fetchObjectSchemasError) {
46
+ handleAssetsClientErrors(setObjectSchemasError, fetchObjectSchemasError);
29
47
  }
48
+ } catch (getWorkspaceIdError) {
49
+ handleAssetsClientErrors(setWorkspaceError, getWorkspaceIdError);
30
50
  } finally {
31
51
  setLoading(false);
32
52
  }
@@ -34,8 +54,12 @@ export const useAssetsClient = initialParameters => {
34
54
  }, [initialParameters]);
35
55
  return {
36
56
  workspaceId,
37
- workspaceError: error,
38
- objectSchema,
57
+ workspaceError,
58
+ existingObjectSchema,
59
+ existingObjectSchemaError,
60
+ objectSchemas,
61
+ totalObjectSchemas,
62
+ objectSchemasError,
39
63
  assetsClientLoading: loading
40
64
  };
41
65
  };
@@ -1,29 +1,75 @@
1
1
  import { request } from '@atlaskit/linking-common';
2
+ import { FetchError, getStatusCodeGroup, mapFetchErrors, PermissionError } from './cmdbService.utils';
2
3
  export const getWorkspaceId = async () => {
3
- var _workspaceDetailsResp;
4
4
  const url = '/rest/servicedesk/cmdb/latest/workspace';
5
- const workspaceDetailsResponse = await request('get', url, undefined, undefined, [200, 201, 202, 203, 204]);
6
- if (!((_workspaceDetailsResp = workspaceDetailsResponse.results) !== null && _workspaceDetailsResp !== void 0 && _workspaceDetailsResp.length)) {
7
- throw new Error('No workspace results found');
5
+ try {
6
+ var _workspaceDetailsResp;
7
+ const workspaceDetailsResponse = await request('get', url, undefined, undefined, [200, 201, 202, 203, 204]);
8
+ if (!((_workspaceDetailsResp = workspaceDetailsResponse.results) !== null && _workspaceDetailsResp !== void 0 && _workspaceDetailsResp.length)) {
9
+ throw new PermissionError('No workspace results found');
10
+ }
11
+ return workspaceDetailsResponse.results[0].id;
12
+ } catch (err) {
13
+ let error = mapFetchErrors(err);
14
+ if (error instanceof FetchError) {
15
+ // TODO Fire error operational event for workspace here before remapping to PermissionError
16
+ // Only 429 and 5xx errors will be treated as FetchErrors otherwise PermissionError
17
+ if (getStatusCodeGroup(error) !== '5xx' && error.statusCode !== 429) {
18
+ error = new PermissionError('Failed to fetch workspace');
19
+ }
20
+ }
21
+ throw error;
8
22
  }
9
- return workspaceDetailsResponse.results[0].id;
10
23
  };
11
- export const validateAql = (workspaceId, data) => {
24
+ export const validateAql = async (workspaceId, data) => {
12
25
  const url = `/gateway/api/jsm/assets/workspace/${workspaceId}/v1/aql/validate`;
13
- return request('post', url, {
14
- qlQuery: data.qlQuery,
15
- context: 'SMART_LINKS'
16
- }, undefined, [200, 201, 202, 203, 204]);
26
+ try {
27
+ return await request('post', url, {
28
+ qlQuery: data.qlQuery,
29
+ context: 'SMART_LINKS'
30
+ }, undefined, [200, 201, 202, 203, 204]);
31
+ } catch (err) {
32
+ let error = mapFetchErrors(err);
33
+ if (error instanceof FetchError) {
34
+ // TODO Fire error operational event for aql here before remapping to PermissionError
35
+ if (error.statusCode === 401 || error.statusCode === 403) {
36
+ error = new PermissionError('Failed to fetch object schemas');
37
+ }
38
+ }
39
+ throw error;
40
+ }
17
41
  };
18
- export const fetchObjectSchema = (workspaceId, schemaId) => {
42
+ export const fetchObjectSchema = async (workspaceId, schemaId) => {
19
43
  const url = `/gateway/api/jsm/assets/workspace/${workspaceId}/v1/objectschema/${schemaId}`;
20
- return request('get', url, undefined, undefined, [200, 201, 202, 203, 204]);
44
+ try {
45
+ return await request('get', url, undefined, undefined, [200, 201, 202, 203, 204]);
46
+ } catch (err) {
47
+ let error = mapFetchErrors(err);
48
+ if (error instanceof FetchError) {
49
+ // TODO Fire error operational event for object schema here before remapping to PermissionError
50
+ if (error.statusCode === 401 || error.statusCode === 403) {
51
+ error = new PermissionError('Failed to fetch object schemas');
52
+ }
53
+ }
54
+ throw error;
55
+ }
21
56
  };
22
- export const fetchObjectSchemas = (workspaceId, query) => {
57
+ export const fetchObjectSchemas = async (workspaceId, query) => {
23
58
  const queryParams = new URLSearchParams();
24
59
  queryParams.set('maxResults', '20');
25
60
  queryParams.set('includeCounts', 'false');
26
61
  query && queryParams.set('query', query);
27
62
  const url = `/gateway/api/jsm/assets/workspace/${workspaceId}/v1/objectschema/list?${queryParams}`;
28
- return request('get', url, undefined, undefined, [200, 201, 202, 203, 204]);
63
+ try {
64
+ return await request('get', url, undefined, undefined, [200, 201, 202, 203, 204]);
65
+ } catch (err) {
66
+ let error = mapFetchErrors(err);
67
+ if (error instanceof FetchError) {
68
+ // TODO Fire error operational event for object schemas here before remapping to PermissionError
69
+ if (error.statusCode === 401 || error.statusCode === 403) {
70
+ error = new PermissionError('Failed to fetch object schemas');
71
+ }
72
+ }
73
+ throw error;
74
+ }
29
75
  };
@@ -0,0 +1,39 @@
1
+ export const mapFetchErrors = error => {
2
+ if (error instanceof Response && !error.ok) {
3
+ return new FetchError(error.status, `Error server response: ${error.status}`);
4
+ }
5
+ return error;
6
+ };
7
+ export const getStatusCodeGroup = error => {
8
+ if (error instanceof FetchError) {
9
+ const {
10
+ statusCode
11
+ } = error;
12
+ if (statusCode >= 100 && statusCode < 200) {
13
+ return '1xx';
14
+ }
15
+ if (statusCode >= 300 && statusCode < 400) {
16
+ return '3xx';
17
+ }
18
+ if (statusCode >= 400 && statusCode < 500) {
19
+ return '4xx';
20
+ }
21
+ if (statusCode >= 500 && statusCode < 600) {
22
+ return '5xx';
23
+ }
24
+ }
25
+ return 'unknown';
26
+ };
27
+ export class PermissionError extends Error {
28
+ constructor(message) {
29
+ super(message);
30
+ this.name = 'PermissionError';
31
+ }
32
+ }
33
+ export class FetchError extends Error {
34
+ constructor(statusCode, message) {
35
+ super(message || `Fetch call failed with status code: ${statusCode}`);
36
+ this.name = 'FetchError';
37
+ this.statusCode = statusCode;
38
+ }
39
+ }