@atlaskit/link-datasource 1.12.4 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +34 -12
  4. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/dropdownIndicator.js +39 -0
  5. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +51 -20
  6. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.js +2 -0
  7. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/index.js +1 -0
  8. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.js +93 -0
  9. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.js +146 -0
  10. package/dist/cjs/ui/jira-issues-modal/jira-search-container/buildJQL.js +3 -2
  11. package/dist/cjs/ui/jira-issues-modal/jira-search-container/index.js +21 -8
  12. package/dist/cjs/ui/jira-issues-modal/jira-search-container/messages.js +5 -0
  13. package/dist/cjs/ui/jira-issues-modal/mode-switcher/index.js +28 -16
  14. package/dist/es2019/analytics/constants.js +1 -1
  15. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +14 -2
  16. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/dropdownIndicator.js +34 -0
  17. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +25 -10
  18. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.js +2 -0
  19. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/index.js +1 -0
  20. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.js +77 -0
  21. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.js +105 -0
  22. package/dist/es2019/ui/jira-issues-modal/jira-search-container/buildJQL.js +2 -1
  23. package/dist/es2019/ui/jira-issues-modal/jira-search-container/index.js +13 -3
  24. package/dist/es2019/ui/jira-issues-modal/jira-search-container/messages.js +5 -0
  25. package/dist/es2019/ui/jira-issues-modal/mode-switcher/index.js +19 -9
  26. package/dist/esm/analytics/constants.js +1 -1
  27. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +35 -13
  28. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/dropdownIndicator.js +32 -0
  29. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +52 -21
  30. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.js +2 -0
  31. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/index.js +1 -0
  32. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.js +86 -0
  33. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.js +140 -0
  34. package/dist/esm/ui/jira-issues-modal/jira-search-container/buildJQL.js +2 -1
  35. package/dist/esm/ui/jira-issues-modal/jira-search-container/index.js +21 -8
  36. package/dist/esm/ui/jira-issues-modal/jira-search-container/messages.js +5 -0
  37. package/dist/esm/ui/jira-issues-modal/mode-switcher/index.js +29 -17
  38. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/dropdownIndicator.d.ts +5 -0
  39. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  40. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.d.ts +1 -0
  41. package/dist/types/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.d.ts +2 -0
  42. package/dist/types/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.d.ts +1 -0
  43. package/dist/types/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +1 -0
  44. package/dist/types/ui/jira-issues-modal/jira-search-container/index.d.ts +1 -0
  45. package/dist/types/ui/jira-issues-modal/jira-search-container/messages.d.ts +5 -0
  46. package/dist/types/ui/jira-issues-modal/mode-switcher/index.d.ts +2 -0
  47. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/dropdownIndicator.d.ts +5 -0
  48. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  49. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.d.ts +1 -0
  50. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.d.ts +2 -0
  51. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.d.ts +1 -0
  52. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +1 -0
  53. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/index.d.ts +1 -0
  54. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/messages.d.ts +5 -0
  55. package/dist/types-ts4.5/ui/jira-issues-modal/mode-switcher/index.d.ts +2 -0
  56. package/package.json +1 -2
  57. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.js +0 -12
  58. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.js +0 -6
  59. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.js +0 -6
  60. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.d.ts +0 -3
  61. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.d.ts +0 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/link-datasource
2
2
 
3
+ ## 1.13.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#42684](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42684) [`3752d98e7fd`](https://bitbucket.org/atlassian/atlassian-frontend/commits/3752d98e7fd) - Add search functionality to basic filter dropdowns.
8
+
9
+ ## 1.13.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#42523](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/42523) [`8cf0628d658`](https://bitbucket.org/atlassian/atlassian-frontend/commits/8cf0628d658) - Add logic to disable switching to Basic mode when the query is complex
14
+
3
15
  ## 1.12.4
4
16
 
5
17
  ### 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.12.4"
10
+ packageVersion: "1.13.1"
11
11
  };
@@ -31,12 +31,15 @@ var useFilterOptions = exports.useFilterOptions = function useFilterOptions(_ref
31
31
  _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
32
32
  nextPageCursor = _useState8[0],
33
33
  setNextPageCursor = _useState8[1];
34
+ var initialData = (0, _react.useRef)();
34
35
  var _useBasicFilterAGG = (0, _useBasicFilterAGG2.useBasicFilterAGG)(),
35
36
  getFieldValues = _useBasicFilterAGG.getFieldValues;
36
37
  var fetchFilterOptions = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
37
38
  var _ref3,
38
39
  pageCursor,
39
40
  searchString,
41
+ isRequestLikeInitialSearch,
42
+ initialResponseData,
40
43
  response,
41
44
  isNewSearch,
42
45
  _args = arguments;
@@ -45,8 +48,18 @@ var useFilterOptions = exports.useFilterOptions = function useFilterOptions(_ref
45
48
  case 0:
46
49
  _ref3 = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, pageCursor = _ref3.pageCursor, searchString = _ref3.searchString;
47
50
  setStatus('loading');
48
- _context.prev = 2;
49
- _context.next = 5;
51
+ isRequestLikeInitialSearch = !pageCursor && !searchString;
52
+ initialResponseData = initialData.current;
53
+ _context.prev = 4;
54
+ if (!(isRequestLikeInitialSearch && initialResponseData)) {
55
+ _context.next = 9;
56
+ break;
57
+ }
58
+ _context.t0 = initialResponseData;
59
+ _context.next = 12;
60
+ break;
61
+ case 9:
62
+ _context.next = 11;
50
63
  return getFieldValues({
51
64
  cloudId: cloudId,
52
65
  jql: '',
@@ -54,35 +67,44 @@ var useFilterOptions = exports.useFilterOptions = function useFilterOptions(_ref
54
67
  searchString: searchString,
55
68
  pageCursor: pageCursor
56
69
  });
57
- case 5:
58
- response = _context.sent;
70
+ case 11:
71
+ _context.t0 = _context.sent;
72
+ case 12:
73
+ response = _context.t0;
59
74
  if (!(response.errors && response.errors.length > 0)) {
60
- _context.next = 9;
75
+ _context.next = 16;
61
76
  break;
62
77
  }
63
78
  setStatus('rejected');
64
79
  return _context.abrupt("return");
65
- case 9:
80
+ case 16:
66
81
  isNewSearch = !pageCursor;
67
82
  if (isNewSearch) {
68
83
  setFilterOptions((0, _transformers.mapFieldValuesToFilterOptions)(response));
84
+ if (isRequestLikeInitialSearch) {
85
+ /**
86
+ * The initial dataset is used in couple of paths, eg: when a user searches and clears the search text.
87
+ * During these times, we dont want to fetch data again and again, hence a mini cache setup to store and provide the initial dataset
88
+ */
89
+ initialData.current = response;
90
+ }
69
91
  } else {
70
92
  setFilterOptions([].concat((0, _toConsumableArray2.default)(filterOptions), (0, _toConsumableArray2.default)((0, _transformers.mapFieldValuesToFilterOptions)(response))));
71
93
  }
72
94
  setTotalCount((0, _transformers.mapFieldValuesToTotalCount)(response));
73
95
  setNextPageCursor((0, _transformers.mapFieldValuesToPageCursor)(response));
74
96
  setStatus('resolved');
75
- _context.next = 19;
97
+ _context.next = 26;
76
98
  break;
77
- case 16:
78
- _context.prev = 16;
79
- _context.t0 = _context["catch"](2);
99
+ case 23:
100
+ _context.prev = 23;
101
+ _context.t1 = _context["catch"](4);
80
102
  setStatus('rejected');
81
- case 19:
103
+ case 26:
82
104
  case "end":
83
105
  return _context.stop();
84
106
  }
85
- }, _callee, null, [[2, 16]]);
107
+ }, _callee, null, [[4, 23]]);
86
108
  })), [cloudId, filterOptions, filterType, getFieldValues]);
87
109
  return {
88
110
  filterOptions: filterOptions,
@@ -0,0 +1,39 @@
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 _crossCircle = _interopRequireDefault(require("@atlaskit/icon/glyph/cross-circle"));
10
+ var _search = _interopRequireDefault(require("@atlaskit/icon/glyph/search"));
11
+ var _primitives = require("@atlaskit/primitives");
12
+ var _select = require("@atlaskit/select");
13
+ var customDropdownIndicatorStyles = (0, _primitives.xcss)({
14
+ display: 'flex',
15
+ cursor: 'pointer',
16
+ justifyContent: 'center',
17
+ width: "var(--ds-space-400, 32px)"
18
+ });
19
+ var CustomDropdownIndicator = function CustomDropdownIndicator(props) {
20
+ var selectProps = props.selectProps;
21
+ return /*#__PURE__*/_react.default.createElement(_select.components.DropdownIndicator, props, /*#__PURE__*/_react.default.createElement(_primitives.Box, {
22
+ xcss: customDropdownIndicatorStyles,
23
+ onClick: function onClick() {
24
+ if (selectProps.inputValue) {
25
+ selectProps.onInputChange && selectProps.onInputChange('', {
26
+ action: 'input-change',
27
+ prevInputValue: selectProps.inputValue
28
+ });
29
+ }
30
+ }
31
+ }, selectProps.inputValue ? /*#__PURE__*/_react.default.createElement(_crossCircle.default, {
32
+ size: "small",
33
+ label: ""
34
+ }) : /*#__PURE__*/_react.default.createElement(_search.default, {
35
+ size: "small",
36
+ label: ""
37
+ })));
38
+ };
39
+ var _default = exports.default = CustomDropdownIndicator;
@@ -12,10 +12,12 @@ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"))
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"));
15
+ var _debounce = _interopRequireDefault(require("lodash/debounce"));
15
16
  var _reactIntlNext = require("react-intl-next");
16
17
  var _select = require("@atlaskit/select");
17
18
  var _useFilterOptions2 = require("../../hooks/useFilterOptions");
18
19
  var _control = _interopRequireDefault(require("./control"));
20
+ var _dropdownIndicator = _interopRequireDefault(require("./dropdownIndicator"));
19
21
  var _footer = _interopRequireDefault(require("./footer"));
20
22
  var _formatOptionLabel = _interopRequireDefault(require("./formatOptionLabel"));
21
23
  var _messages = require("./messages");
@@ -27,12 +29,15 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
27
29
  var noFilterOptions = function noFilterOptions() {
28
30
  return true;
29
31
  };
32
+ var SEARCH_DEBOUNCE_MS = 350;
30
33
  var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
31
34
  var filterType = _ref.filterType,
32
35
  cloudId = _ref.cloudId,
33
36
  selection = _ref.selection,
34
37
  _ref$onSelectionChang = _ref.onSelectionChange,
35
- onSelectionChange = _ref$onSelectionChang === void 0 ? function () {} : _ref$onSelectionChang;
38
+ onSelectionChange = _ref$onSelectionChang === void 0 ? function () {} : _ref$onSelectionChang,
39
+ _ref$isDisabled = _ref.isDisabled,
40
+ isDisabled = _ref$isDisabled === void 0 ? false : _ref$isDisabled;
36
41
  var _useIntl = (0, _reactIntlNext.useIntl)(),
37
42
  formatMessage = _useIntl.formatMessage;
38
43
  var pickerRef = (0, _react.useRef)(null);
@@ -52,30 +57,49 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
52
57
  fetchFilterOptions = _useFilterOptions.fetchFilterOptions,
53
58
  totalCount = _useFilterOptions.totalCount,
54
59
  status = _useFilterOptions.status;
55
- var handleInputChange = (0, _react.useCallback)(function (searchString, actionMeta) {
56
- if (actionMeta.action === 'input-change' && searchString !== searchTerm) {
57
- setSearchTerm(searchString);
58
- }
59
- }, [searchTerm]);
60
+ var handleDebouncedFetchFilterOptions = (0, _react.useMemo)(function () {
61
+ return (0, _debounce.default)(fetchFilterOptions, SEARCH_DEBOUNCE_MS);
62
+ }, [fetchFilterOptions]);
63
+ var handleInputChange = (0, _react.useCallback)( /*#__PURE__*/function () {
64
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(newSearchTerm, actionMeta) {
65
+ return _regenerator.default.wrap(function _callee$(_context) {
66
+ while (1) switch (_context.prev = _context.next) {
67
+ case 0:
68
+ if (actionMeta.action === 'input-change' && newSearchTerm !== searchTerm) {
69
+ setSearchTerm(newSearchTerm);
70
+ handleDebouncedFetchFilterOptions({
71
+ searchString: newSearchTerm
72
+ });
73
+ }
74
+ case 1:
75
+ case "end":
76
+ return _context.stop();
77
+ }
78
+ }, _callee);
79
+ }));
80
+ return function (_x, _x2) {
81
+ return _ref2.apply(this, arguments);
82
+ };
83
+ }(), [handleDebouncedFetchFilterOptions, searchTerm]);
60
84
  var handleOptionSelection = function handleOptionSelection(newValue) {
61
85
  setSelectedOptions(newValue);
62
86
  onSelectionChange(newValue);
63
87
  };
64
- var handleOpenPopup = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
65
- return _regenerator.default.wrap(function _callee$(_context) {
66
- while (1) switch (_context.prev = _context.next) {
88
+ var handleOpenPopup = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
89
+ return _regenerator.default.wrap(function _callee2$(_context2) {
90
+ while (1) switch (_context2.prev = _context2.next) {
67
91
  case 0:
68
92
  if (!(status === 'empty')) {
69
- _context.next = 3;
93
+ _context2.next = 3;
70
94
  break;
71
95
  }
72
- _context.next = 3;
96
+ _context2.next = 3;
73
97
  return fetchFilterOptions();
74
98
  case 3:
75
99
  case "end":
76
- return _context.stop();
100
+ return _context2.stop();
77
101
  }
78
- }, _callee);
102
+ }, _callee2);
79
103
  })), [fetchFilterOptions, status]);
80
104
  (0, _react.useEffect)(function () {
81
105
  if (status === 'resolved') {
@@ -85,6 +109,9 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
85
109
  }
86
110
  }, [status]);
87
111
  var isLoading = status === 'loading' || status === 'empty';
112
+ var shouldShowFooter = status === 'resolved' && filterOptions.length > 0;
113
+ var options = isLoading ? [] : filterOptions; // if not set to [], then on loading, no loading UI will be shown
114
+
88
115
  return /*#__PURE__*/_react.default.createElement(_select.PopupSelect, {
89
116
  isMulti: true,
90
117
  maxMenuWidth: 300,
@@ -106,24 +133,28 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
106
133
  components: {
107
134
  /* @ts-expect-error - This component has stricter OptionType, hence a temp setup untill its made generic */
108
135
  Option: _select.CheckboxOption,
109
- Control: _control.default
136
+ Control: _control.default,
137
+ LoadingIndicator: undefined,
138
+ // disables the three ... indicator in the searchbox when picker is loading
139
+ DropdownIndicator: _dropdownIndicator.default
110
140
  },
111
- options: filterOptions,
141
+ options: options,
112
142
  value: selectedOptions,
113
143
  filterOption: noFilterOptions,
114
144
  formatOptionLabel: _formatOptionLabel.default,
115
145
  onChange: handleOptionSelection,
116
146
  onInputChange: handleInputChange,
117
- target: function target(_ref3) {
118
- var isOpen = _ref3.isOpen,
119
- triggerProps = (0, _objectWithoutProperties2.default)(_ref3, _excluded);
147
+ target: function target(_ref4) {
148
+ var isOpen = _ref4.isOpen,
149
+ triggerProps = (0, _objectWithoutProperties2.default)(_ref4, _excluded);
120
150
  return /*#__PURE__*/_react.default.createElement(_trigger.default, (0, _extends2.default)({}, triggerProps, {
121
151
  filterType: filterType,
122
152
  isSelected: isOpen,
123
- onClick: handleOpenPopup
153
+ onClick: handleOpenPopup,
154
+ isDisabled: isDisabled
124
155
  }));
125
156
  },
126
- footer: /*#__PURE__*/_react.default.createElement(_footer.default, {
157
+ footer: shouldShowFooter && /*#__PURE__*/_react.default.createElement(_footer.default, {
127
158
  currentDisplayCount: filterOptions.length,
128
159
  totalCount: totalCount
129
160
  })
@@ -16,11 +16,13 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
16
16
  var PopupTrigger = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
17
17
  var filterType = _ref.filterType,
18
18
  isSelected = _ref.isSelected,
19
+ isDisabled = _ref.isDisabled,
19
20
  onClick = _ref.onClick;
20
21
  return /*#__PURE__*/_react.default.createElement(_standardButton.default, {
21
22
  ref: ref,
22
23
  appearance: "default",
23
24
  isSelected: isSelected,
25
+ isDisabled: isDisabled,
24
26
  onClick: onClick,
25
27
  testId: "jlol-basic-filter-".concat(filterType, "-trigger"),
26
28
  iconAfter: /*#__PURE__*/_react.default.createElement(_chevronDown.default, {
@@ -35,6 +35,7 @@ var BasicFilterContainer = function BasicFilterContainer(_ref) {
35
35
  filterType: filter,
36
36
  key: filter,
37
37
  selection: selection,
38
+ isDisabled: !cloudId,
38
39
  onSelectionChange: handleSelectionChange
39
40
  });
40
41
  }));
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.isClauseTooComplex = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _jqlAst = require("@atlaskit/jql-ast");
10
+ var _buildJQL = require("../../jira-search-container/buildJQL");
11
+ var removeFuzzyCharacter = function removeFuzzyCharacter(value) {
12
+ if (value !== null && value !== void 0 && value.endsWith(_buildJQL.fuzzyCharacter)) {
13
+ return value.slice(0, -1);
14
+ }
15
+ return value;
16
+ };
17
+ var getValueFromTerminalClause = function getValueFromTerminalClause(clause) {
18
+ var operand = clause.operand;
19
+ return operand !== undefined && operand.operandType === _jqlAst.OPERAND_TYPE_VALUE && removeFuzzyCharacter(operand.value) || undefined;
20
+ };
21
+ var areClauseFieldValuesEqual = function areClauseFieldValuesEqual(clauseA, clauseB, clauseC) {
22
+ var valueA = clauseA && getValueFromTerminalClause(clauseA);
23
+ var valueB = clauseB && getValueFromTerminalClause(clauseB);
24
+ var valueC = clauseC && getValueFromTerminalClause(clauseC);
25
+ var values = [valueA, valueB, valueC].filter(Boolean);
26
+
27
+ // checks if valid fields, text, summary and key have the same value, if not, its a complex query and cannnot be recreated in basic mode
28
+ return values.length > 1 && values.every(function (value) {
29
+ return value === values[0];
30
+ });
31
+ };
32
+ var areClauseFieldKeysAllowed = function areClauseFieldKeysAllowed(clauseA, clauseB, clauseC) {
33
+ var fieldA = clauseA.field.value;
34
+ var fieldB = clauseB.field.value;
35
+ var fieldC = clauseC === null || clauseC === void 0 ? void 0 : clauseC.field.value; // clauseC only if jql with 3 OR clauses, 'text ~ "EDM-6023*" or summary ~ "EDM-6023*" or key = EDM-6023 ORDER BY created DESC',
36
+
37
+ return [fieldA, fieldB, fieldC].filter(Boolean).every(function (field) {
38
+ return ['summary', 'text', 'key'].includes(field);
39
+ });
40
+ };
41
+ var doesCompoundClauseContainAllTerminalClauses = function doesCompoundClauseContainAllTerminalClauses(clauses) {
42
+ return clauses.every(function (clauses) {
43
+ return clauses.clauseType === _jqlAst.CLAUSE_TYPE_TERMINAL;
44
+ });
45
+ };
46
+ var isClauseTooComplex = exports.isClauseTooComplex = function isClauseTooComplex(clauses, key) {
47
+ if (key === 'text') {
48
+ var _clauses = (0, _slicedToArray2.default)(clauses, 1),
49
+ clause = _clauses[0];
50
+ if (clause.clauseType === _jqlAst.CLAUSE_TYPE_COMPOUND) {
51
+ var textClauses = clause.clauses;
52
+
53
+ /**
54
+ * valid: text ~ "test*" or summary ~ "test*" ORDER BY created DESC
55
+ * valid: text ~ "EDM-6023*" or summary ~ "EDM-6023*" or key = EDM-6023 ORDER BY created DESC
56
+ * invalid: assignee = "me" or text ~ "EDM-6023*" or summary ~ "EDM-6023*" or key = EDM-6023 ORDER BY created DESC
57
+ */
58
+ if (textClauses.length !== 2 && textClauses.length !== 3) {
59
+ return true;
60
+ }
61
+
62
+ /**
63
+ * valid: text ~ "test*" or summary ~ "test*"
64
+ * invalid: text ~ "test" or (summary ~ "test" or key = "test")
65
+ */
66
+ if (!doesCompoundClauseContainAllTerminalClauses(textClauses)) {
67
+ return true;
68
+ }
69
+ var _textClauses = (0, _slicedToArray2.default)(textClauses, 3),
70
+ clauseA = _textClauses[0],
71
+ clauseB = _textClauses[1],
72
+ clauseC = _textClauses[2];
73
+
74
+ /**
75
+ * valid: text ~ "EDM-6023*" or summary ~ "EDM-6023*" or key = EDM-6023 ORDER BY created DESC
76
+ * invalid: text ~ "EDM-6023*" or summary ~ "anotherValue" ORDER BY created DESC
77
+ * invalid: text ~ "EDM-6023*" or text ~ "anotherValue" ORDER BY created DESC
78
+ */
79
+ if (!areClauseFieldValuesEqual(clauseA, clauseB, clauseC)) {
80
+ return true;
81
+ }
82
+
83
+ /**
84
+ * valid: text ~ "EDM-6023*" ORDER BY created DESC
85
+ * invalid: resolution = 40134 ORDER BY created DESC
86
+ */
87
+ if (!areClauseFieldKeysAllowed(clauseA, clauseB, clauseC)) {
88
+ return true;
89
+ }
90
+ }
91
+ }
92
+ return clauses.length > 1;
93
+ };
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.isQueryTooComplex = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
12
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
14
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
15
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
16
+ var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
17
+ var _mergeWith = _interopRequireDefault(require("lodash/mergeWith"));
18
+ var _jqlAst = require("@atlaskit/jql-ast");
19
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
20
+ var _jiraSearchContainer = require("../../jira-search-container");
21
+ var _isClauseTooComplex = require("./isClauseTooComplex");
22
+ var _index = require("./index");
23
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
24
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
25
+ // Map of field keys to their respective clauses in the Jast
26
+
27
+ var allowedFields = [
28
+ // basic filter fields
29
+ 'assignee', 'issuetype', 'project', 'status',
30
+ // search input fields
31
+ 'text', 'summary', 'key',
32
+ // orderby field
33
+ 'created'];
34
+ var fallbackOperators = [_jqlAst.OPERATOR_IN];
35
+ var fieldSpecificOperators = {
36
+ text: [_jqlAst.OPERATOR_LIKE, _jqlAst.OPERATOR_EQUALS],
37
+ summary: [_jqlAst.OPERATOR_LIKE, _jqlAst.OPERATOR_EQUALS],
38
+ key: [_jqlAst.OPERATOR_EQUALS],
39
+ created: [_jqlAst.OPERATOR_GT_EQUALS],
40
+ project: [_jqlAst.OPERATOR_IN, _jqlAst.OPERATOR_EQUALS],
41
+ issuetype: [_jqlAst.OPERATOR_IN, _jqlAst.OPERATOR_EQUALS],
42
+ status: [_jqlAst.OPERATOR_IN, _jqlAst.OPERATOR_EQUALS],
43
+ assignee: [_jqlAst.OPERATOR_IN, _jqlAst.OPERATOR_EQUALS]
44
+ };
45
+ var JqlClauseCollectingVisitorError = /*#__PURE__*/function (_Error) {
46
+ (0, _inherits2.default)(JqlClauseCollectingVisitorError, _Error);
47
+ var _super = _createSuper(JqlClauseCollectingVisitorError);
48
+ function JqlClauseCollectingVisitorError() {
49
+ (0, _classCallCheck2.default)(this, JqlClauseCollectingVisitorError);
50
+ return _super.apply(this, arguments);
51
+ }
52
+ return (0, _createClass2.default)(JqlClauseCollectingVisitorError);
53
+ }( /*#__PURE__*/(0, _wrapNativeSuper2.default)(Error));
54
+ /**
55
+ * Rather than having to navigate the entire tree structure ourself, we extend AbstractJastVisitor
56
+ * class and implement visitor functions for node types that we wish to process.
57
+ * A list of available visitor can be viewed in packages/jql/jql-ast/src/types/api/jast-visitor.ts
58
+ * more info - https://atlaskit.atlassian.com/packages/jql/jql-ast/docs/traversing-the-ast
59
+ * */
60
+ var JqlClauseCollectingVisitor = /*#__PURE__*/function (_AbstractJastVisitor) {
61
+ (0, _inherits2.default)(JqlClauseCollectingVisitor, _AbstractJastVisitor);
62
+ var _super2 = _createSuper(JqlClauseCollectingVisitor);
63
+ function JqlClauseCollectingVisitor() {
64
+ var _this;
65
+ (0, _classCallCheck2.default)(this, JqlClauseCollectingVisitor);
66
+ _this = _super2.call(this);
67
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "visitNotClause", function () {
68
+ throw new JqlClauseCollectingVisitorError('Visited an unsupported node while traversing the AST');
69
+ });
70
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "visitOrderByField", function (orderByField) {
71
+ var _orderByField$field$v;
72
+ var fieldValue = (_orderByField$field$v = orderByField.field.value) === null || _orderByField$field$v === void 0 ? void 0 : _orderByField$field$v.toLowerCase();
73
+ if (fieldValue && !_jiraSearchContainer.ALLOWED_ORDER_BY_KEYS.includes(fieldValue)) {
74
+ throw new JqlClauseCollectingVisitorError("query with order by field '".concat(fieldValue, "' is not supported"));
75
+ }
76
+ return {};
77
+ });
78
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "visitCompoundClause", function (compoundClause) {
79
+ var clauseMap = {};
80
+ var operator = compoundClause.operator.value;
81
+ if (operator === _jqlAst.COMPOUND_OPERATOR_AND) {
82
+ return compoundClause.clauses.reduce(function (result, clause) {
83
+ return _this.aggregateResult(clause.accept((0, _assertThisInitialized2.default)(_this)), result);
84
+ }, clauseMap);
85
+ }
86
+ if (operator === _jqlAst.COMPOUND_OPERATOR_OR) {
87
+ // this is delt with in isClauseTooComplex
88
+ return _this.aggregateResult({
89
+ text: [compoundClause]
90
+ }, clauseMap);
91
+ }
92
+ throw new JqlClauseCollectingVisitorError("Compound clauses using the operator '".concat(operator, "' is not supported"));
93
+ });
94
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "visitTerminalClause", function (terminalClause) {
95
+ var _terminalClause$opera;
96
+ var fieldName = terminalClause.field.value.toLowerCase();
97
+ if (!allowedFields.includes(fieldName)) {
98
+ throw new JqlClauseCollectingVisitorError("Field with name '".concat(fieldName, "' of type ").concat(terminalClause.clauseType, " is not supported"));
99
+ }
100
+ var operator = (_terminalClause$opera = terminalClause.operator) === null || _terminalClause$opera === void 0 ? void 0 : _terminalClause$opera.value;
101
+ var allowedOperators = fieldSpecificOperators[fieldName] || fallbackOperators;
102
+ if (operator && !allowedOperators.includes(operator.toLowerCase())) {
103
+ throw new JqlClauseCollectingVisitorError("Field with name '".concat(fieldName, "' using operator ").concat(operator, " is not supported"));
104
+ }
105
+ return (0, _defineProperty2.default)({}, terminalClause.field.value.toLowerCase(), [terminalClause]);
106
+ });
107
+ return _this;
108
+ }
109
+ (0, _createClass2.default)(JqlClauseCollectingVisitor, [{
110
+ key: "aggregateResult",
111
+ value: function aggregateResult(aggregate, nextResult) {
112
+ return (0, _mergeWith.default)(aggregate, nextResult, function (destValue, srcValue) {
113
+ return srcValue.concat(destValue !== null && destValue !== void 0 ? destValue : []);
114
+ });
115
+ }
116
+ }, {
117
+ key: "defaultResult",
118
+ value: function defaultResult() {
119
+ return {};
120
+ }
121
+ }]);
122
+ return JqlClauseCollectingVisitor;
123
+ }(_jqlAst.AbstractJastVisitor);
124
+ var isQueryTooComplex = exports.isQueryTooComplex = function isQueryTooComplex(jql) {
125
+ if (!(0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.datasource.show-jlol-basic-filters') || !jql) {
126
+ return false;
127
+ }
128
+ if (!(0, _index.isValidJql)(jql)) {
129
+ return true;
130
+ }
131
+ var jast = new _jqlAst.JastBuilder().build(jql);
132
+ try {
133
+ var jqlClauseCollectingVisitor = new JqlClauseCollectingVisitor();
134
+ var clauseMap = jast.query ? jast.query.accept(jqlClauseCollectingVisitor) : {}; // jast.query is defined as void | Query, hence the fallback
135
+
136
+ var hasAnyKeyWithComplexClause = Object.entries(clauseMap).some(function (_ref2) {
137
+ var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
138
+ key = _ref3[0],
139
+ clauses = _ref3[1];
140
+ return (0, _isClauseTooComplex.isClauseTooComplex)(clauses, key);
141
+ });
142
+ return hasAnyKeyWithComplexClause;
143
+ } catch (error) {
144
+ return true;
145
+ }
146
+ };
@@ -4,11 +4,12 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.buildJQL = void 0;
7
+ exports.fuzzyCharacter = exports.buildJQL = void 0;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
9
  var _jqlAst = require("@atlaskit/jql-ast");
10
10
  var fuzzySearchRegExp = /^"(.+)"$/;
11
11
  var jiraIssueKeyRegExp = /[A-Z]+-\d+/;
12
+ var fuzzyCharacter = exports.fuzzyCharacter = '*';
12
13
  var constructTerminalClause = function constructTerminalClause(field, operator, value) {
13
14
  return _jqlAst.creators.terminalClause(_jqlAst.creators.field(field), _jqlAst.creators.operator(operator), _jqlAst.creators.valueOperand(value));
14
15
  };
@@ -30,7 +31,7 @@ var buildJQL = exports.buildJQL = function buildJQL(input) {
30
31
  return '';
31
32
  }
32
33
  if (trimmedRawSearch) {
33
- var fuzzy = !trimmedRawSearch.match(fuzzySearchRegExp) ? '*' : '';
34
+ var fuzzy = !trimmedRawSearch.match(fuzzySearchRegExp) ? fuzzyCharacter : '';
34
35
  var basicSearch = trimmedRawSearch.replace(/['"?*]+/g, '');
35
36
  var text = constructTerminalClause('text', _jqlAst.OPERATOR_LIKE, "".concat(basicSearch).concat(fuzzy));
36
37
  var summary = constructTerminalClause('summary', _jqlAst.OPERATOR_LIKE, "".concat(basicSearch).concat(fuzzy));