@atlaskit/link-datasource 1.14.1 → 1.15.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 (38) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +26 -27
  4. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
  5. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/menu-list/errorMessage.js +24 -0
  6. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +35 -0
  7. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/loadingMessage.js +3 -3
  8. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/noOptionsMessage.js +3 -3
  9. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/{custom-select-message/index.js → menu-list/selectMessage.js} +9 -1
  10. package/dist/es2019/analytics/constants.js +1 -1
  11. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +19 -11
  12. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
  13. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/menu-list/errorMessage.js +17 -0
  14. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +27 -0
  15. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/loadingMessage.js +2 -2
  16. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/noOptionsMessage.js +2 -2
  17. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/{custom-select-message/index.js → menu-list/selectMessage.js} +9 -1
  18. package/dist/esm/analytics/constants.js +1 -1
  19. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +26 -27
  20. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
  21. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/menu-list/errorMessage.js +17 -0
  22. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +28 -0
  23. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/loadingMessage.js +2 -2
  24. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/noOptionsMessage.js +2 -2
  25. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/{custom-select-message/index.js → menu-list/selectMessage.js} +9 -1
  26. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.d.ts +5 -0
  27. package/dist/types/ui/jira-issues-modal/basic-filters/ui/menu-list/errorMessage.d.ts +3 -0
  28. package/dist/types/ui/jira-issues-modal/basic-filters/ui/menu-list/index.d.ts +10 -0
  29. package/dist/types/ui/jira-issues-modal/basic-filters/ui/{custom-select-message/index.d.ts → menu-list/selectMessage.d.ts} +2 -1
  30. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.d.ts +5 -0
  31. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/menu-list/errorMessage.d.ts +3 -0
  32. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/menu-list/index.d.ts +10 -0
  33. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/{custom-select-message/index.d.ts → menu-list/selectMessage.d.ts} +2 -1
  34. package/package.json +2 -2
  35. /package/dist/types/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/loadingMessage.d.ts +0 -0
  36. /package/dist/types/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/noOptionsMessage.d.ts +0 -0
  37. /package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/loadingMessage.d.ts +0 -0
  38. /package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/{async-popup-select → menu-list}/noOptionsMessage.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @atlaskit/link-datasource
2
2
 
3
+ ## 1.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#42867](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42867) [`39f66ca6aec`](https://bitbucket.org/atlassian/atlassian-frontend/commits/39f66ca6aec) - Add error state UI to basic filter dropdown.
8
+
3
9
  ## 1.14.1
4
10
 
5
11
  ### Patch Changes
@@ -7,5 +7,5 @@ exports.packageMetaData = exports.EVENT_CHANNEL = void 0;
7
7
  var EVENT_CHANNEL = exports.EVENT_CHANNEL = 'media';
8
8
  var packageMetaData = exports.packageMetaData = {
9
9
  packageName: "@atlaskit/link-datasource",
10
- packageVersion: "1.14.1"
10
+ packageVersion: "1.15.0"
11
11
  };
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.default = void 0;
9
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
9
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
12
12
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
13
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
14
  var _react = _interopRequireWildcard(require("react"));
@@ -16,13 +16,12 @@ var _reactIntlNext = require("react-intl-next");
16
16
  var _useDebounce = require("use-debounce");
17
17
  var _select = require("@atlaskit/select");
18
18
  var _useFilterOptions2 = require("../../hooks/useFilterOptions");
19
+ var _menuList = _interopRequireDefault(require("../menu-list"));
19
20
  var _control = _interopRequireDefault(require("./control"));
20
21
  var _dropdownIndicator = _interopRequireDefault(require("./dropdownIndicator"));
21
22
  var _footer = _interopRequireDefault(require("./footer"));
22
23
  var _formatOptionLabel = _interopRequireDefault(require("./formatOptionLabel"));
23
- var _loadingMessage = _interopRequireDefault(require("./loadingMessage"));
24
24
  var _messages = require("./messages");
25
- var _noOptionsMessage = _interopRequireDefault(require("./noOptionsMessage"));
26
25
  var _trigger = _interopRequireDefault(require("./trigger"));
27
26
  var _excluded = ["isOpen"];
28
27
  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); }
@@ -89,22 +88,14 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
89
88
  setSelectedOptions(newValue);
90
89
  onSelectionChange(newValue);
91
90
  };
92
- var handleOpenPopup = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
93
- return _regenerator.default.wrap(function _callee2$(_context2) {
94
- while (1) switch (_context2.prev = _context2.next) {
95
- case 0:
96
- if (!(status === 'empty')) {
97
- _context2.next = 3;
98
- break;
99
- }
100
- _context2.next = 3;
101
- return fetchFilterOptions();
102
- case 3:
103
- case "end":
104
- return _context2.stop();
105
- }
106
- }, _callee2);
107
- })), [fetchFilterOptions, status]);
91
+ var handleOpenPopup = (0, _react.useCallback)(function () {
92
+ if (status === 'empty' || status === 'rejected') {
93
+ // if user searches and gets status as rejected, we want the dropdown to try load the request with searchString when the user reopens the dropdown
94
+ fetchFilterOptions({
95
+ searchString: searchTerm
96
+ });
97
+ }
98
+ }, [fetchFilterOptions, searchTerm, status]);
108
99
  (0, _react.useEffect)(function () {
109
100
  if (status === 'resolved') {
110
101
  var _pickerRef$current;
@@ -112,9 +103,12 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
112
103
  pickerRef === null || pickerRef === void 0 || (_pickerRef$current = pickerRef.current) === null || _pickerRef$current === void 0 || (_pickerRef$current = _pickerRef$current.selectRef) === null || _pickerRef$current === void 0 || (_pickerRef$current = _pickerRef$current.inputRef) === null || _pickerRef$current === void 0 || _pickerRef$current.focus();
113
104
  }
114
105
  }, [status]);
106
+ var filterOptionsLength = filterOptions.length;
107
+ var isError = status === 'rejected';
115
108
  var isLoading = status === 'loading' || status === 'empty';
116
- var shouldShowFooter = status === 'resolved' && filterOptions.length > 0;
117
- var options = isLoading ? [] : filterOptions; // if not set to [], then on loading, no loading UI will be shown
109
+ var isEmpty = status === 'resolved' && filterOptionsLength === 0;
110
+ var shouldShowFooter = status === 'resolved' && filterOptionsLength > 0;
111
+ var options = isLoading || isError ? [] : filterOptions; // if not set to [], for eg: on loading, no loading UI will be shown
118
112
 
119
113
  return /*#__PURE__*/_react.default.createElement(_select.PopupSelect, {
120
114
  isMulti: true,
@@ -133,13 +127,18 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
133
127
  closeMenuOnSelect: false,
134
128
  hideSelectedOptions: false,
135
129
  isLoading: isLoading,
136
- loadingMessage: _loadingMessage.default,
137
- noOptionsMessage: _noOptionsMessage.default,
138
130
  placeholder: formatMessage(_messages.asyncPopupSelectMessages.selectPlaceholder),
139
131
  components: {
140
132
  /* @ts-expect-error - This component has stricter OptionType, hence a temp setup untill its made generic */
141
133
  Option: _select.CheckboxOption,
142
134
  Control: _control.default,
135
+ MenuList: function MenuList(props) {
136
+ return /*#__PURE__*/_react.default.createElement(_menuList.default, (0, _extends2.default)({}, props, {
137
+ isError: isError,
138
+ isEmpty: isEmpty,
139
+ isLoading: isLoading
140
+ }));
141
+ },
143
142
  DropdownIndicator: _dropdownIndicator.default,
144
143
  LoadingIndicator: undefined,
145
144
  // disables the three ... indicator in the searchbox when picker is loading
@@ -152,9 +151,9 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
152
151
  formatOptionLabel: _formatOptionLabel.default,
153
152
  onChange: handleOptionSelection,
154
153
  onInputChange: handleInputChange,
155
- target: function target(_ref4) {
156
- var isOpen = _ref4.isOpen,
157
- triggerProps = (0, _objectWithoutProperties2.default)(_ref4, _excluded);
154
+ target: function target(_ref3) {
155
+ var isOpen = _ref3.isOpen,
156
+ triggerProps = (0, _objectWithoutProperties2.default)(_ref3, _excluded);
158
157
  return /*#__PURE__*/_react.default.createElement(_trigger.default, (0, _extends2.default)({}, triggerProps, {
159
158
  filterType: filterType,
160
159
  isSelected: isOpen,
@@ -163,7 +162,7 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
163
162
  }));
164
163
  },
165
164
  footer: shouldShowFooter && /*#__PURE__*/_react.default.createElement(_footer.default, {
166
- currentDisplayCount: filterOptions.length,
165
+ currentDisplayCount: filterOptionsLength,
167
166
  totalCount: totalCount
168
167
  })
169
168
  });
@@ -44,5 +44,10 @@ var asyncPopupSelectMessages = exports.asyncPopupSelectMessages = {
44
44
  id: 'linkDataSource.basic-filter.no-options-message',
45
45
  defaultMessage: 'No matches found',
46
46
  description: 'The text for when no matches are found in dropdown'
47
+ },
48
+ errorMessage: {
49
+ id: 'linkDataSource.basic-filter.error-message',
50
+ defaultMessage: "Couldn't retrieve data",
51
+ description: 'The text for when an error occurs when loading options'
47
52
  }
48
53
  };
@@ -0,0 +1,24 @@
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 _error = _interopRequireDefault(require("@atlaskit/icon/glyph/error"));
10
+ var _colors = require("@atlaskit/theme/colors");
11
+ var _messages = require("../async-popup-select/messages");
12
+ var _selectMessage = _interopRequireDefault(require("./selectMessage"));
13
+ var CustomErrorMessage = function CustomErrorMessage() {
14
+ return /*#__PURE__*/_react.default.createElement(_selectMessage.default, {
15
+ icon: /*#__PURE__*/_react.default.createElement(_error.default, {
16
+ primaryColor: "var(--ds-icon, ".concat(_colors.N500, ")"),
17
+ label: "",
18
+ size: "xlarge"
19
+ }),
20
+ message: _messages.asyncPopupSelectMessages.errorMessage,
21
+ testId: "jlol-basic-filter-popup-select--error-message"
22
+ });
23
+ };
24
+ var _default = exports.default = CustomErrorMessage;
@@ -0,0 +1,35 @@
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 _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _select = require("@atlaskit/select");
11
+ var _errorMessage = _interopRequireDefault(require("./errorMessage"));
12
+ var _loadingMessage = _interopRequireDefault(require("./loadingMessage"));
13
+ var _noOptionsMessage = _interopRequireDefault(require("./noOptionsMessage"));
14
+ var _excluded = ["isLoading", "isError", "isEmpty", "children"];
15
+ var CustomMenuList = function CustomMenuList(_ref) {
16
+ var isLoading = _ref.isLoading,
17
+ isError = _ref.isError,
18
+ isEmpty = _ref.isEmpty,
19
+ children = _ref.children,
20
+ props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
21
+ var getChildComponent = function getChildComponent() {
22
+ if (isLoading) {
23
+ return /*#__PURE__*/_react.default.createElement(_loadingMessage.default, null);
24
+ }
25
+ if (isError) {
26
+ return /*#__PURE__*/_react.default.createElement(_errorMessage.default, null);
27
+ }
28
+ if (isEmpty) {
29
+ return /*#__PURE__*/_react.default.createElement(_noOptionsMessage.default, null);
30
+ }
31
+ return children;
32
+ };
33
+ return /*#__PURE__*/_react.default.createElement(_select.components.MenuList, props, getChildComponent());
34
+ };
35
+ var _default = exports.default = CustomMenuList;
@@ -7,10 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
10
- var _customSelectMessage = _interopRequireDefault(require("../custom-select-message"));
11
- var _messages = require("./messages");
10
+ var _messages = require("../async-popup-select/messages");
11
+ var _selectMessage = _interopRequireDefault(require("./selectMessage"));
12
12
  var CustomDropdownLoadingMessage = function CustomDropdownLoadingMessage() {
13
- return /*#__PURE__*/_react.default.createElement(_customSelectMessage.default, {
13
+ return /*#__PURE__*/_react.default.createElement(_selectMessage.default, {
14
14
  icon: /*#__PURE__*/_react.default.createElement(_spinner.default, {
15
15
  size: "large"
16
16
  }),
@@ -8,10 +8,10 @@ exports.default = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _questionCircle = _interopRequireDefault(require("@atlaskit/icon/glyph/question-circle"));
10
10
  var _colors = require("@atlaskit/theme/colors");
11
- var _customSelectMessage = _interopRequireDefault(require("../custom-select-message"));
12
- var _messages = require("./messages");
11
+ var _messages = require("../async-popup-select/messages");
12
+ var _selectMessage = _interopRequireDefault(require("./selectMessage"));
13
13
  var CustomNoOptionsMessage = function CustomNoOptionsMessage() {
14
- return /*#__PURE__*/_react.default.createElement(_customSelectMessage.default, {
14
+ return /*#__PURE__*/_react.default.createElement(_selectMessage.default, {
15
15
  icon: /*#__PURE__*/_react.default.createElement(_questionCircle.default, {
16
16
  primaryColor: "var(--ds-icon, ".concat(_colors.N500, ")"),
17
17
  size: "xlarge",
@@ -13,12 +13,20 @@ var boxStyles = (0, _primitives.xcss)({
13
13
  height: "var(--ds-space-800, 64px)",
14
14
  marginBottom: "var(--ds-space-200, 16px)"
15
15
  });
16
+ var stackStyles = (0, _primitives.xcss)({
17
+ paddingTop: 'space.100',
18
+ paddingBottom: 'space.100',
19
+ paddingLeft: 'space.150',
20
+ paddingRight: 'space.150'
21
+ });
16
22
  var CustomSelectMessage = function CustomSelectMessage(_ref) {
17
23
  var icon = _ref.icon,
18
24
  message = _ref.message,
19
25
  testId = _ref.testId;
20
26
  return /*#__PURE__*/_react.default.createElement(_primitives.Stack, {
21
- testId: testId
27
+ xcss: stackStyles,
28
+ testId: testId,
29
+ alignInline: "center"
22
30
  }, /*#__PURE__*/_react.default.createElement(_primitives.Flex, {
23
31
  xcss: boxStyles,
24
32
  alignItems: "center",
@@ -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.14.1"
4
+ packageVersion: "1.15.0"
5
5
  };
@@ -4,13 +4,12 @@ import { useIntl } from 'react-intl-next';
4
4
  import { useDebouncedCallback } from 'use-debounce';
5
5
  import { CheckboxOption, PopupSelect } from '@atlaskit/select';
6
6
  import { useFilterOptions } from '../../hooks/useFilterOptions';
7
+ import CustomMenuList from '../menu-list';
7
8
  import CustomControl from './control';
8
9
  import CustomDropdownIndicator from './dropdownIndicator';
9
10
  import PopupFooter from './footer';
10
11
  import formatOptionLabel from './formatOptionLabel';
11
- import CustomDropdownLoadingMessage from './loadingMessage';
12
12
  import { asyncPopupSelectMessages } from './messages';
13
- import CustomNoOptionsMessage from './noOptionsMessage';
14
13
  import PopupTrigger from './trigger';
15
14
  // Needed to disable filtering from react-select
16
15
  const noFilterOptions = () => true;
@@ -52,11 +51,14 @@ const AsyncPopupSelect = ({
52
51
  setSelectedOptions(newValue);
53
52
  onSelectionChange(newValue);
54
53
  };
55
- const handleOpenPopup = useCallback(async () => {
56
- if (status === 'empty') {
57
- await fetchFilterOptions();
54
+ const handleOpenPopup = useCallback(() => {
55
+ if (status === 'empty' || status === 'rejected') {
56
+ // if user searches and gets status as rejected, we want the dropdown to try load the request with searchString when the user reopens the dropdown
57
+ fetchFilterOptions({
58
+ searchString: searchTerm
59
+ });
58
60
  }
59
- }, [fetchFilterOptions, status]);
61
+ }, [fetchFilterOptions, searchTerm, status]);
60
62
  useEffect(() => {
61
63
  if (status === 'resolved') {
62
64
  var _pickerRef$current, _pickerRef$current$se, _pickerRef$current$se2;
@@ -64,9 +66,12 @@ const AsyncPopupSelect = ({
64
66
  pickerRef === null || pickerRef === void 0 ? void 0 : (_pickerRef$current = pickerRef.current) === null || _pickerRef$current === void 0 ? void 0 : (_pickerRef$current$se = _pickerRef$current.selectRef) === null || _pickerRef$current$se === void 0 ? void 0 : (_pickerRef$current$se2 = _pickerRef$current$se.inputRef) === null || _pickerRef$current$se2 === void 0 ? void 0 : _pickerRef$current$se2.focus();
65
67
  }
66
68
  }, [status]);
69
+ const filterOptionsLength = filterOptions.length;
70
+ const isError = status === 'rejected';
67
71
  const isLoading = status === 'loading' || status === 'empty';
68
- const shouldShowFooter = status === 'resolved' && filterOptions.length > 0;
69
- const options = isLoading ? [] : filterOptions; // if not set to [], then on loading, no loading UI will be shown
72
+ const isEmpty = status === 'resolved' && filterOptionsLength === 0;
73
+ const shouldShowFooter = status === 'resolved' && filterOptionsLength > 0;
74
+ const options = isLoading || isError ? [] : filterOptions; // if not set to [], for eg: on loading, no loading UI will be shown
70
75
 
71
76
  return /*#__PURE__*/React.createElement(PopupSelect, {
72
77
  isMulti: true,
@@ -85,13 +90,16 @@ const AsyncPopupSelect = ({
85
90
  closeMenuOnSelect: false,
86
91
  hideSelectedOptions: false,
87
92
  isLoading: isLoading,
88
- loadingMessage: CustomDropdownLoadingMessage,
89
- noOptionsMessage: CustomNoOptionsMessage,
90
93
  placeholder: formatMessage(asyncPopupSelectMessages.selectPlaceholder),
91
94
  components: {
92
95
  /* @ts-expect-error - This component has stricter OptionType, hence a temp setup untill its made generic */
93
96
  Option: CheckboxOption,
94
97
  Control: CustomControl,
98
+ MenuList: props => /*#__PURE__*/React.createElement(CustomMenuList, _extends({}, props, {
99
+ isError: isError,
100
+ isEmpty: isEmpty,
101
+ isLoading: isLoading
102
+ })),
95
103
  DropdownIndicator: CustomDropdownIndicator,
96
104
  LoadingIndicator: undefined,
97
105
  // disables the three ... indicator in the searchbox when picker is loading
@@ -114,7 +122,7 @@ const AsyncPopupSelect = ({
114
122
  isDisabled: isDisabled
115
123
  })),
116
124
  footer: shouldShowFooter && /*#__PURE__*/React.createElement(PopupFooter, {
117
- currentDisplayCount: filterOptions.length,
125
+ currentDisplayCount: filterOptionsLength,
118
126
  totalCount: totalCount
119
127
  })
120
128
  });
@@ -38,5 +38,10 @@ export const asyncPopupSelectMessages = {
38
38
  id: 'linkDataSource.basic-filter.no-options-message',
39
39
  defaultMessage: 'No matches found',
40
40
  description: 'The text for when no matches are found in dropdown'
41
+ },
42
+ errorMessage: {
43
+ id: 'linkDataSource.basic-filter.error-message',
44
+ defaultMessage: "Couldn't retrieve data",
45
+ description: 'The text for when an error occurs when loading options'
41
46
  }
42
47
  };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import ErrorIcon from '@atlaskit/icon/glyph/error';
3
+ import { N500 } from '@atlaskit/theme/colors';
4
+ import { asyncPopupSelectMessages } from '../async-popup-select/messages';
5
+ import CustomSelectMessage from './selectMessage';
6
+ const CustomErrorMessage = () => {
7
+ return /*#__PURE__*/React.createElement(CustomSelectMessage, {
8
+ icon: /*#__PURE__*/React.createElement(ErrorIcon, {
9
+ primaryColor: `var(--ds-icon, ${N500})`,
10
+ label: "",
11
+ size: "xlarge"
12
+ }),
13
+ message: asyncPopupSelectMessages.errorMessage,
14
+ testId: "jlol-basic-filter-popup-select--error-message"
15
+ });
16
+ };
17
+ export default CustomErrorMessage;
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { components } from '@atlaskit/select';
3
+ import CustomErrorMessage from './errorMessage';
4
+ import CustomDropdownLoadingMessage from './loadingMessage';
5
+ import CustomNoOptionsMessage from './noOptionsMessage';
6
+ const CustomMenuList = ({
7
+ isLoading,
8
+ isError,
9
+ isEmpty,
10
+ children,
11
+ ...props
12
+ }) => {
13
+ const getChildComponent = () => {
14
+ if (isLoading) {
15
+ return /*#__PURE__*/React.createElement(CustomDropdownLoadingMessage, null);
16
+ }
17
+ if (isError) {
18
+ return /*#__PURE__*/React.createElement(CustomErrorMessage, null);
19
+ }
20
+ if (isEmpty) {
21
+ return /*#__PURE__*/React.createElement(CustomNoOptionsMessage, null);
22
+ }
23
+ return children;
24
+ };
25
+ return /*#__PURE__*/React.createElement(components.MenuList, props, getChildComponent());
26
+ };
27
+ export default CustomMenuList;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import Spinner from '@atlaskit/spinner';
3
- import CustomSelectMessage from '../custom-select-message';
4
- import { asyncPopupSelectMessages } from './messages';
3
+ import { asyncPopupSelectMessages } from '../async-popup-select/messages';
4
+ import CustomSelectMessage from './selectMessage';
5
5
  const CustomDropdownLoadingMessage = () => {
6
6
  return /*#__PURE__*/React.createElement(CustomSelectMessage, {
7
7
  icon: /*#__PURE__*/React.createElement(Spinner, {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import QuestionCircleIcon from '@atlaskit/icon/glyph/question-circle';
3
3
  import { N500 } from '@atlaskit/theme/colors';
4
- import CustomSelectMessage from '../custom-select-message';
5
- import { asyncPopupSelectMessages } from './messages';
4
+ import { asyncPopupSelectMessages } from '../async-popup-select/messages';
5
+ import CustomSelectMessage from './selectMessage';
6
6
  const CustomNoOptionsMessage = () => {
7
7
  return /*#__PURE__*/React.createElement(CustomSelectMessage, {
8
8
  icon: /*#__PURE__*/React.createElement(QuestionCircleIcon, {
@@ -6,13 +6,21 @@ const boxStyles = xcss({
6
6
  height: "var(--ds-space-800, 64px)",
7
7
  marginBottom: "var(--ds-space-200, 16px)"
8
8
  });
9
+ const stackStyles = xcss({
10
+ paddingTop: 'space.100',
11
+ paddingBottom: 'space.100',
12
+ paddingLeft: 'space.150',
13
+ paddingRight: 'space.150'
14
+ });
9
15
  const CustomSelectMessage = ({
10
16
  icon,
11
17
  message,
12
18
  testId
13
19
  }) => {
14
20
  return /*#__PURE__*/React.createElement(Stack, {
15
- testId: testId
21
+ xcss: stackStyles,
22
+ testId: testId,
23
+ alignInline: "center"
16
24
  }, /*#__PURE__*/React.createElement(Flex, {
17
25
  xcss: boxStyles,
18
26
  alignItems: "center",
@@ -1,5 +1,5 @@
1
1
  export var EVENT_CHANNEL = 'media';
2
2
  export var packageMetaData = {
3
3
  packageName: "@atlaskit/link-datasource",
4
- packageVersion: "1.14.1"
4
+ packageVersion: "1.15.0"
5
5
  };
@@ -1,5 +1,5 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
1
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
2
+ import _extends from "@babel/runtime/helpers/extends";
3
3
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
4
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  var _excluded = ["isOpen"];
@@ -9,13 +9,12 @@ import { useIntl } from 'react-intl-next';
9
9
  import { useDebouncedCallback } from 'use-debounce';
10
10
  import { CheckboxOption, PopupSelect } from '@atlaskit/select';
11
11
  import { useFilterOptions } from '../../hooks/useFilterOptions';
12
+ import CustomMenuList from '../menu-list';
12
13
  import CustomControl from './control';
13
14
  import CustomDropdownIndicator from './dropdownIndicator';
14
15
  import PopupFooter from './footer';
15
16
  import formatOptionLabel from './formatOptionLabel';
16
- import CustomDropdownLoadingMessage from './loadingMessage';
17
17
  import { asyncPopupSelectMessages } from './messages';
18
- import CustomNoOptionsMessage from './noOptionsMessage';
19
18
  import PopupTrigger from './trigger';
20
19
  // Needed to disable filtering from react-select
21
20
  var noFilterOptions = function noFilterOptions() {
@@ -79,22 +78,14 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
79
78
  setSelectedOptions(newValue);
80
79
  onSelectionChange(newValue);
81
80
  };
82
- var handleOpenPopup = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
83
- return _regeneratorRuntime.wrap(function _callee2$(_context2) {
84
- while (1) switch (_context2.prev = _context2.next) {
85
- case 0:
86
- if (!(status === 'empty')) {
87
- _context2.next = 3;
88
- break;
89
- }
90
- _context2.next = 3;
91
- return fetchFilterOptions();
92
- case 3:
93
- case "end":
94
- return _context2.stop();
95
- }
96
- }, _callee2);
97
- })), [fetchFilterOptions, status]);
81
+ var handleOpenPopup = useCallback(function () {
82
+ if (status === 'empty' || status === 'rejected') {
83
+ // if user searches and gets status as rejected, we want the dropdown to try load the request with searchString when the user reopens the dropdown
84
+ fetchFilterOptions({
85
+ searchString: searchTerm
86
+ });
87
+ }
88
+ }, [fetchFilterOptions, searchTerm, status]);
98
89
  useEffect(function () {
99
90
  if (status === 'resolved') {
100
91
  var _pickerRef$current;
@@ -102,9 +93,12 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
102
93
  pickerRef === null || pickerRef === void 0 || (_pickerRef$current = pickerRef.current) === null || _pickerRef$current === void 0 || (_pickerRef$current = _pickerRef$current.selectRef) === null || _pickerRef$current === void 0 || (_pickerRef$current = _pickerRef$current.inputRef) === null || _pickerRef$current === void 0 || _pickerRef$current.focus();
103
94
  }
104
95
  }, [status]);
96
+ var filterOptionsLength = filterOptions.length;
97
+ var isError = status === 'rejected';
105
98
  var isLoading = status === 'loading' || status === 'empty';
106
- var shouldShowFooter = status === 'resolved' && filterOptions.length > 0;
107
- var options = isLoading ? [] : filterOptions; // if not set to [], then on loading, no loading UI will be shown
99
+ var isEmpty = status === 'resolved' && filterOptionsLength === 0;
100
+ var shouldShowFooter = status === 'resolved' && filterOptionsLength > 0;
101
+ var options = isLoading || isError ? [] : filterOptions; // if not set to [], for eg: on loading, no loading UI will be shown
108
102
 
109
103
  return /*#__PURE__*/React.createElement(PopupSelect, {
110
104
  isMulti: true,
@@ -123,13 +117,18 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
123
117
  closeMenuOnSelect: false,
124
118
  hideSelectedOptions: false,
125
119
  isLoading: isLoading,
126
- loadingMessage: CustomDropdownLoadingMessage,
127
- noOptionsMessage: CustomNoOptionsMessage,
128
120
  placeholder: formatMessage(asyncPopupSelectMessages.selectPlaceholder),
129
121
  components: {
130
122
  /* @ts-expect-error - This component has stricter OptionType, hence a temp setup untill its made generic */
131
123
  Option: CheckboxOption,
132
124
  Control: CustomControl,
125
+ MenuList: function MenuList(props) {
126
+ return /*#__PURE__*/React.createElement(CustomMenuList, _extends({}, props, {
127
+ isError: isError,
128
+ isEmpty: isEmpty,
129
+ isLoading: isLoading
130
+ }));
131
+ },
133
132
  DropdownIndicator: CustomDropdownIndicator,
134
133
  LoadingIndicator: undefined,
135
134
  // disables the three ... indicator in the searchbox when picker is loading
@@ -142,9 +141,9 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
142
141
  formatOptionLabel: formatOptionLabel,
143
142
  onChange: handleOptionSelection,
144
143
  onInputChange: handleInputChange,
145
- target: function target(_ref4) {
146
- var isOpen = _ref4.isOpen,
147
- triggerProps = _objectWithoutProperties(_ref4, _excluded);
144
+ target: function target(_ref3) {
145
+ var isOpen = _ref3.isOpen,
146
+ triggerProps = _objectWithoutProperties(_ref3, _excluded);
148
147
  return /*#__PURE__*/React.createElement(PopupTrigger, _extends({}, triggerProps, {
149
148
  filterType: filterType,
150
149
  isSelected: isOpen,
@@ -153,7 +152,7 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
153
152
  }));
154
153
  },
155
154
  footer: shouldShowFooter && /*#__PURE__*/React.createElement(PopupFooter, {
156
- currentDisplayCount: filterOptions.length,
155
+ currentDisplayCount: filterOptionsLength,
157
156
  totalCount: totalCount
158
157
  })
159
158
  });
@@ -38,5 +38,10 @@ export var asyncPopupSelectMessages = {
38
38
  id: 'linkDataSource.basic-filter.no-options-message',
39
39
  defaultMessage: 'No matches found',
40
40
  description: 'The text for when no matches are found in dropdown'
41
+ },
42
+ errorMessage: {
43
+ id: 'linkDataSource.basic-filter.error-message',
44
+ defaultMessage: "Couldn't retrieve data",
45
+ description: 'The text for when an error occurs when loading options'
41
46
  }
42
47
  };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import ErrorIcon from '@atlaskit/icon/glyph/error';
3
+ import { N500 } from '@atlaskit/theme/colors';
4
+ import { asyncPopupSelectMessages } from '../async-popup-select/messages';
5
+ import CustomSelectMessage from './selectMessage';
6
+ var CustomErrorMessage = function CustomErrorMessage() {
7
+ return /*#__PURE__*/React.createElement(CustomSelectMessage, {
8
+ icon: /*#__PURE__*/React.createElement(ErrorIcon, {
9
+ primaryColor: "var(--ds-icon, ".concat(N500, ")"),
10
+ label: "",
11
+ size: "xlarge"
12
+ }),
13
+ message: asyncPopupSelectMessages.errorMessage,
14
+ testId: "jlol-basic-filter-popup-select--error-message"
15
+ });
16
+ };
17
+ export default CustomErrorMessage;
@@ -0,0 +1,28 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
2
+ var _excluded = ["isLoading", "isError", "isEmpty", "children"];
3
+ import React from 'react';
4
+ import { components } from '@atlaskit/select';
5
+ import CustomErrorMessage from './errorMessage';
6
+ import CustomDropdownLoadingMessage from './loadingMessage';
7
+ import CustomNoOptionsMessage from './noOptionsMessage';
8
+ var CustomMenuList = function CustomMenuList(_ref) {
9
+ var isLoading = _ref.isLoading,
10
+ isError = _ref.isError,
11
+ isEmpty = _ref.isEmpty,
12
+ children = _ref.children,
13
+ props = _objectWithoutProperties(_ref, _excluded);
14
+ var getChildComponent = function getChildComponent() {
15
+ if (isLoading) {
16
+ return /*#__PURE__*/React.createElement(CustomDropdownLoadingMessage, null);
17
+ }
18
+ if (isError) {
19
+ return /*#__PURE__*/React.createElement(CustomErrorMessage, null);
20
+ }
21
+ if (isEmpty) {
22
+ return /*#__PURE__*/React.createElement(CustomNoOptionsMessage, null);
23
+ }
24
+ return children;
25
+ };
26
+ return /*#__PURE__*/React.createElement(components.MenuList, props, getChildComponent());
27
+ };
28
+ export default CustomMenuList;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import Spinner from '@atlaskit/spinner';
3
- import CustomSelectMessage from '../custom-select-message';
4
- import { asyncPopupSelectMessages } from './messages';
3
+ import { asyncPopupSelectMessages } from '../async-popup-select/messages';
4
+ import CustomSelectMessage from './selectMessage';
5
5
  var CustomDropdownLoadingMessage = function CustomDropdownLoadingMessage() {
6
6
  return /*#__PURE__*/React.createElement(CustomSelectMessage, {
7
7
  icon: /*#__PURE__*/React.createElement(Spinner, {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import QuestionCircleIcon from '@atlaskit/icon/glyph/question-circle';
3
3
  import { N500 } from '@atlaskit/theme/colors';
4
- import CustomSelectMessage from '../custom-select-message';
5
- import { asyncPopupSelectMessages } from './messages';
4
+ import { asyncPopupSelectMessages } from '../async-popup-select/messages';
5
+ import CustomSelectMessage from './selectMessage';
6
6
  var CustomNoOptionsMessage = function CustomNoOptionsMessage() {
7
7
  return /*#__PURE__*/React.createElement(CustomSelectMessage, {
8
8
  icon: /*#__PURE__*/React.createElement(QuestionCircleIcon, {
@@ -6,12 +6,20 @@ var boxStyles = xcss({
6
6
  height: "var(--ds-space-800, 64px)",
7
7
  marginBottom: "var(--ds-space-200, 16px)"
8
8
  });
9
+ var stackStyles = xcss({
10
+ paddingTop: 'space.100',
11
+ paddingBottom: 'space.100',
12
+ paddingLeft: 'space.150',
13
+ paddingRight: 'space.150'
14
+ });
9
15
  var CustomSelectMessage = function CustomSelectMessage(_ref) {
10
16
  var icon = _ref.icon,
11
17
  message = _ref.message,
12
18
  testId = _ref.testId;
13
19
  return /*#__PURE__*/React.createElement(Stack, {
14
- testId: testId
20
+ xcss: stackStyles,
21
+ testId: testId,
22
+ alignInline: "center"
15
23
  }, /*#__PURE__*/React.createElement(Flex, {
16
24
  xcss: boxStyles,
17
25
  alignItems: "center",
@@ -39,4 +39,9 @@ export declare const asyncPopupSelectMessages: {
39
39
  defaultMessage: string;
40
40
  description: string;
41
41
  };
42
+ errorMessage: {
43
+ id: string;
44
+ defaultMessage: string;
45
+ description: string;
46
+ };
42
47
  };
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ declare const CustomErrorMessage: () => JSX.Element;
3
+ export default CustomErrorMessage;
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { MenuListComponentProps } from '@atlaskit/select';
3
+ import { SelectOption } from '../../types';
4
+ type CustomProps = {
5
+ isError?: boolean;
6
+ isLoading?: boolean;
7
+ isEmpty?: boolean;
8
+ };
9
+ declare const CustomMenuList: ({ isLoading, isError, isEmpty, children, ...props }: MenuListComponentProps<SelectOption, true> & CustomProps) => JSX.Element;
10
+ export default CustomMenuList;
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
+ import { MessageDescriptor } from 'react-intl-next';
2
3
  interface CustomSelectMessageProps {
3
4
  icon: React.ReactNode;
4
- message: object;
5
+ message: MessageDescriptor;
5
6
  testId: string;
6
7
  }
7
8
  declare const CustomSelectMessage: ({ icon, message, testId, }: CustomSelectMessageProps) => JSX.Element;
@@ -39,4 +39,9 @@ export declare const asyncPopupSelectMessages: {
39
39
  defaultMessage: string;
40
40
  description: string;
41
41
  };
42
+ errorMessage: {
43
+ id: string;
44
+ defaultMessage: string;
45
+ description: string;
46
+ };
42
47
  };
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ declare const CustomErrorMessage: () => JSX.Element;
3
+ export default CustomErrorMessage;
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { MenuListComponentProps } from '@atlaskit/select';
3
+ import { SelectOption } from '../../types';
4
+ type CustomProps = {
5
+ isError?: boolean;
6
+ isLoading?: boolean;
7
+ isEmpty?: boolean;
8
+ };
9
+ declare const CustomMenuList: ({ isLoading, isError, isEmpty, children, ...props }: MenuListComponentProps<SelectOption, true> & CustomProps) => JSX.Element;
10
+ export default CustomMenuList;
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
+ import { MessageDescriptor } from 'react-intl-next';
2
3
  interface CustomSelectMessageProps {
3
4
  icon: React.ReactNode;
4
- message: object;
5
+ message: MessageDescriptor;
5
6
  testId: string;
6
7
  }
7
8
  declare const CustomSelectMessage: ({ icon, message, testId, }: CustomSelectMessageProps) => JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "1.14.1",
3
+ "version": "1.15.0",
4
4
  "description": "UI Components to support linking platform dataset feature",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -45,7 +45,7 @@
45
45
  "@atlaskit/jql-ast": "^3.0.0",
46
46
  "@atlaskit/jql-editor-autocomplete-rest": "^2.0.0",
47
47
  "@atlaskit/link-client-extension": "^1.8.0",
48
- "@atlaskit/linking-common": "^4.16.0",
48
+ "@atlaskit/linking-common": "^4.17.0",
49
49
  "@atlaskit/linking-types": "^8.4.0",
50
50
  "@atlaskit/lozenge": "^11.4.0",
51
51
  "@atlaskit/modal-dialog": "^12.8.0",