@atlaskit/link-datasource 1.12.3 → 1.13.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 (116) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/services/useBasicFilterAGG.js +40 -82
  4. package/dist/cjs/services/utils.js +1 -1
  5. package/dist/cjs/ui/issue-like-table/draggable-table-heading.js +0 -12
  6. package/dist/cjs/ui/issue-like-table/styled.js +1 -1
  7. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +94 -0
  8. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +24 -13
  9. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/index.js +3 -1
  10. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.js +93 -0
  11. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.js +146 -0
  12. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/transformers.js +15 -3
  13. package/dist/cjs/ui/jira-issues-modal/jira-search-container/buildJQL.js +3 -2
  14. package/dist/cjs/ui/jira-issues-modal/jira-search-container/index.js +23 -9
  15. package/dist/cjs/ui/jira-issues-modal/jira-search-container/messages.js +5 -0
  16. package/dist/cjs/ui/jira-issues-modal/mode-switcher/index.js +28 -16
  17. package/dist/es2019/analytics/constants.js +1 -1
  18. package/dist/es2019/services/useBasicFilterAGG.js +30 -53
  19. package/dist/es2019/services/utils.js +1 -1
  20. package/dist/es2019/ui/issue-like-table/draggable-table-heading.js +0 -12
  21. package/dist/es2019/ui/issue-like-table/styled.js +16 -4
  22. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +52 -0
  23. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +15 -7
  24. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/index.js +3 -1
  25. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.js +77 -0
  26. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.js +105 -0
  27. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/transformers.js +14 -2
  28. package/dist/es2019/ui/jira-issues-modal/jira-search-container/buildJQL.js +2 -1
  29. package/dist/es2019/ui/jira-issues-modal/jira-search-container/index.js +15 -4
  30. package/dist/es2019/ui/jira-issues-modal/jira-search-container/messages.js +5 -0
  31. package/dist/es2019/ui/jira-issues-modal/mode-switcher/index.js +19 -9
  32. package/dist/esm/analytics/constants.js +1 -1
  33. package/dist/esm/services/useBasicFilterAGG.js +41 -83
  34. package/dist/esm/services/utils.js +1 -1
  35. package/dist/esm/ui/issue-like-table/draggable-table-heading.js +0 -12
  36. package/dist/esm/ui/issue-like-table/styled.js +1 -1
  37. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +87 -0
  38. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +24 -13
  39. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/index.js +3 -1
  40. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.js +86 -0
  41. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.js +140 -0
  42. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/transformers.js +12 -2
  43. package/dist/esm/ui/jira-issues-modal/jira-search-container/buildJQL.js +2 -1
  44. package/dist/esm/ui/jira-issues-modal/jira-search-container/index.js +23 -9
  45. package/dist/esm/ui/jira-issues-modal/jira-search-container/messages.js +5 -0
  46. package/dist/esm/ui/jira-issues-modal/mode-switcher/index.js +29 -17
  47. package/dist/types/services/useBasicFilterAGG.d.ts +9 -1
  48. package/dist/types/services/utils.d.ts +1 -1
  49. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +18 -0
  50. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  51. package/dist/types/ui/jira-issues-modal/basic-filters/ui/index.d.ts +2 -1
  52. package/dist/types/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.d.ts +2 -0
  53. package/dist/types/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.d.ts +1 -0
  54. package/dist/types/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +3 -1
  55. package/dist/types/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +1 -0
  56. package/dist/types/ui/jira-issues-modal/jira-search-container/index.d.ts +1 -0
  57. package/dist/types/ui/jira-issues-modal/jira-search-container/messages.d.ts +5 -0
  58. package/dist/types/ui/jira-issues-modal/mode-switcher/index.d.ts +2 -0
  59. package/dist/types-ts4.5/services/useBasicFilterAGG.d.ts +9 -1
  60. package/dist/types-ts4.5/services/utils.d.ts +1 -1
  61. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +18 -0
  62. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  63. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/index.d.ts +2 -1
  64. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/isClauseTooComplex.d.ts +2 -0
  65. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/isQueryTooComplex.d.ts +1 -0
  66. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +3 -1
  67. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +1 -0
  68. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/index.d.ts +1 -0
  69. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/messages.d.ts +5 -0
  70. package/dist/types-ts4.5/ui/jira-issues-modal/mode-switcher/index.d.ts +2 -0
  71. package/package.json +1 -2
  72. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.js +0 -75
  73. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.js +0 -12
  74. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +0 -20
  75. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +0 -155
  76. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +0 -82
  77. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +0 -87
  78. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +0 -97
  79. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +0 -18
  80. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +0 -111
  81. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.js +0 -39
  82. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.js +0 -6
  83. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +0 -14
  84. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +0 -149
  85. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +0 -76
  86. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +0 -81
  87. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +0 -91
  88. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +0 -12
  89. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +0 -105
  90. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.js +0 -68
  91. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.js +0 -6
  92. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +0 -14
  93. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +0 -149
  94. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +0 -76
  95. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +0 -81
  96. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +0 -91
  97. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +0 -12
  98. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +0 -105
  99. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.d.ts +0 -12
  100. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.d.ts +0 -3
  101. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.d.ts +0 -3
  102. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.d.ts +0 -17
  103. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.d.ts +0 -8
  104. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.d.ts +0 -8
  105. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.d.ts +0 -8
  106. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.d.ts +0 -3
  107. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.d.ts +0 -29
  108. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.d.ts +0 -12
  109. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useIsComplexQuery.d.ts +0 -3
  110. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.d.ts +0 -3
  111. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.d.ts +0 -17
  112. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.d.ts +0 -8
  113. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.d.ts +0 -8
  114. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.d.ts +0 -8
  115. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.d.ts +0 -3
  116. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.d.ts +0 -29
@@ -4,7 +4,9 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.mapFieldValuesResponseData = mapFieldValuesResponseData;
7
+ exports.mapFieldValuesToFilterOptions = mapFieldValuesToFilterOptions;
8
+ exports.mapFieldValuesToPageCursor = mapFieldValuesToPageCursor;
9
+ exports.mapFieldValuesToTotalCount = mapFieldValuesToTotalCount;
8
10
  exports.mapHydrateResponseData = mapHydrateResponseData;
9
11
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
12
  var _types = require("../types");
@@ -38,7 +40,7 @@ function mapNodeToOption(_ref) {
38
40
  return _objectSpread(_objectSpread({}, baseProps), {}, {
39
41
  optionType: 'avatarLabel',
40
42
  avatar: user.picture,
41
- isSquare: true
43
+ isSquare: false
42
44
  });
43
45
  }
44
46
  if (group) {
@@ -88,10 +90,20 @@ function mapHydrateResponseData(_ref2) {
88
90
  });
89
91
  return transformedHydrateResponseData;
90
92
  }
91
- function mapFieldValuesResponseData(_ref5) {
93
+ function mapFieldValuesToFilterOptions(_ref5) {
92
94
  var _data$jira2;
93
95
  var data = _ref5.data;
94
96
  return (data === null || data === void 0 || (_data$jira2 = data.jira) === null || _data$jira2 === void 0 || (_data$jira2 = _data$jira2.jqlBuilder) === null || _data$jira2 === void 0 || (_data$jira2 = _data$jira2.fieldValues) === null || _data$jira2 === void 0 || (_data$jira2 = _data$jira2.edges) === null || _data$jira2 === void 0 ? void 0 : _data$jira2.map(function (edge) {
95
97
  return edge.node ? mapNodeToOption(edge.node) : null;
96
98
  }).filter(isNonNullSelectOption)) || [];
99
+ }
100
+ function mapFieldValuesToTotalCount(_ref6) {
101
+ var _data$jira3;
102
+ var data = _ref6.data;
103
+ return (data === null || data === void 0 || (_data$jira3 = data.jira) === null || _data$jira3 === void 0 || (_data$jira3 = _data$jira3.jqlBuilder) === null || _data$jira3 === void 0 || (_data$jira3 = _data$jira3.fieldValues) === null || _data$jira3 === void 0 ? void 0 : _data$jira3.totalCount) || 0;
104
+ }
105
+ function mapFieldValuesToPageCursor(_ref7) {
106
+ var _data$jira4;
107
+ var data = _ref7.data;
108
+ return data === null || data === void 0 || (_data$jira4 = data.jira) === null || _data$jira4 === void 0 || (_data$jira4 = _data$jira4.jqlBuilder) === null || _data$jira4 === void 0 || (_data$jira4 = _data$jira4.fieldValues) === null || _data$jira4 === void 0 || (_data$jira4 = _data$jira4.pageInfo) === null || _data$jira4 === void 0 ? void 0 : _data$jira4.endCursor;
97
109
  }
@@ -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));
@@ -5,7 +5,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.JiraSearchContainer = void 0;
8
+ exports.JiraSearchContainer = exports.ALLOWED_ORDER_BY_KEYS = void 0;
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
  var _react2 = require("@emotion/react");
@@ -13,6 +13,7 @@ var _reactIntlNext = require("react-intl-next");
13
13
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
14
  var _analytics = require("../../../analytics");
15
15
  var _basicFilters = require("../basic-filters");
16
+ var _isQueryTooComplex = require("../basic-filters/utils/isQueryTooComplex");
16
17
  var _basicSearchInput = require("../basic-search-input");
17
18
  var _jqlEditor = require("../jql-editor");
18
19
  var _modeSwitcher = require("../mode-switcher");
@@ -29,6 +30,7 @@ var inputContainerStyles = (0, _react2.css)({
29
30
  minHeight: '60px'
30
31
  });
31
32
  var DEFAULT_JQL_QUERY = 'created >= -30d order by created DESC';
33
+ var ALLOWED_ORDER_BY_KEYS = exports.ALLOWED_ORDER_BY_KEYS = ['key', 'summary', 'assignee', 'status', 'created'];
32
34
  var JiraSearchMethodSwitcher = _modeSwitcher.ModeSwitcher;
33
35
  var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchContainer(props) {
34
36
  var isSearching = props.isSearching,
@@ -53,14 +55,18 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
53
55
  _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
54
56
  jql = _useState6[0],
55
57
  setJql = _useState6[1];
56
- var _useState7 = (0, _react.useState)(),
58
+ var _useState7 = (0, _react.useState)(false),
57
59
  _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
58
- orderKey = _useState8[0],
59
- setOrderKey = _useState8[1];
60
+ isComplexQuery = _useState8[0],
61
+ setIsComplexQuery = _useState8[1];
60
62
  var _useState9 = (0, _react.useState)(),
61
63
  _useState10 = (0, _slicedToArray2.default)(_useState9, 2),
62
- orderDirection = _useState10[0],
63
- setOrderDirection = _useState10[1];
64
+ orderKey = _useState10[0],
65
+ setOrderKey = _useState10[1];
66
+ var _useState11 = (0, _react.useState)(),
67
+ _useState12 = (0, _slicedToArray2.default)(_useState11, 2),
68
+ orderDirection = _useState12[0],
69
+ setOrderDirection = _useState12[1];
64
70
  var _useDatasourceAnalyti = (0, _analytics.useDatasourceAnalyticsEvents)(),
65
71
  fireEvent = _useDatasourceAnalyti.fireEvent;
66
72
  var onSearchMethodChange = (0, _react.useCallback)(function (searchMethod) {
@@ -87,7 +93,7 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
87
93
  var order = hasOrder ? (_fragments$at3 = fragments.at(-1)) === null || _fragments$at3 === void 0 ? void 0 : _fragments$at3.split(' ').at(-1) : undefined;
88
94
 
89
95
  // TODO: confirm if these are the only order keys we want to preserve - existing whiteboard logic
90
- if (key && ['key', 'summary', 'assignee', 'status'].includes(key)) {
96
+ if (key && ALLOWED_ORDER_BY_KEYS.includes(key)) {
91
97
  setOrderKey(key);
92
98
  setOrderDirection(order);
93
99
  }
@@ -97,6 +103,7 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
97
103
  onSearch({
98
104
  jql: jql
99
105
  }, currentSearchMethod);
106
+ setIsComplexQuery((0, _isQueryTooComplex.isQueryTooComplex)(jql));
100
107
  if (currentSearchMethod === 'basic') {
101
108
  fireEvent('ui.form.submitted.basicSearch', {});
102
109
  } else if (currentSearchMethod === 'jql') {
@@ -109,6 +116,10 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
109
116
  }
110
117
  return false;
111
118
  }, []);
119
+ (0, _react.useEffect)(function () {
120
+ setIsComplexQuery((0, _isQueryTooComplex.isQueryTooComplex)(jql));
121
+ // eslint-disable-next-line react-hooks/exhaustive-deps
122
+ }, []);
112
123
  return (0, _react2.jsx)("div", {
113
124
  css: inputContainerStyles
114
125
  }, currentSearchMethod === 'basic' && (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_basicSearchInput.BasicSearchInput, {
@@ -117,7 +128,8 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
117
128
  onSearch: handleSearch,
118
129
  searchTerm: basicSearchTerm
119
130
  }), showBasicFilters && (0, _react2.jsx)(_basicFilters.BasicFilters, {
120
- jql: jql
131
+ jql: jql,
132
+ cloudId: cloudId || ''
121
133
  })), currentSearchMethod === 'jql' && (0, _react2.jsx)(_jqlEditor.JiraJQLEditor, {
122
134
  cloudId: cloudId || '',
123
135
  isSearching: isSearching,
@@ -132,7 +144,9 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
132
144
  value: 'jql'
133
145
  }, {
134
146
  label: formatMessage(_messages.modeSwitcherMessages.basicTextSearchLabel),
135
- value: 'basic'
147
+ value: 'basic',
148
+ disabled: isComplexQuery,
149
+ tooltipText: isComplexQuery ? formatMessage(_messages.modeSwitcherMessages.basicModeSwitchDisabledTooltipText) : ''
136
150
  }]
137
151
  }));
138
152
  };
@@ -10,5 +10,10 @@ var modeSwitcherMessages = exports.modeSwitcherMessages = (0, _reactIntlNext.def
10
10
  id: 'linkDataSource.jira-issues.configmodal.basicModeText',
11
11
  description: 'Display text for basic text search toggle button',
12
12
  defaultMessage: 'Basic'
13
+ },
14
+ basicModeSwitchDisabledTooltipText: {
15
+ id: 'linkDataSource.jira-issues.configmodal.basicModeSwitchDisabledTooltipText',
16
+ description: 'Display tooltip text when basic mode switch is disabled',
17
+ defaultMessage: "You can't switch to basic for this query."
13
18
  }
14
19
  });
@@ -5,9 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.ModeSwitcher = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
8
9
  var _react = _interopRequireDefault(require("react"));
9
10
  var _react2 = require("@emotion/react");
10
11
  var _colors = require("@atlaskit/theme/colors");
12
+ var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
11
13
  /** @jsx jsx */
12
14
 
13
15
  var modeSwitcherStyles = (0, _react2.css)({
@@ -52,8 +54,12 @@ var modeSwitcherLabelSelectedStyles = (0, _react2.css)({
52
54
  }
53
55
  });
54
56
  var modeSwitcherLabelDisabledStyles = (0, _react2.css)({
57
+ color: "var(--ds-text-disabled, ".concat(_colors.N60, ")")
58
+ });
59
+ var modeSwitcherDisabledStyles = (0, _react2.css)({
55
60
  ':hover': {
56
- cursor: 'not-allowed'
61
+ cursor: 'not-allowed',
62
+ background: 'transparent'
57
63
  }
58
64
  });
59
65
  var compactModeSwitcherLabelStyles = (0, _react2.css)({
@@ -76,21 +82,27 @@ var ModeSwitcher = exports.ModeSwitcher = function ModeSwitcher(props) {
76
82
  disabled: isDisabled
77
83
  }, options.map(function (_ref) {
78
84
  var value = _ref.value,
79
- label = _ref.label;
85
+ label = _ref.label,
86
+ isOptionDisabled = _ref.disabled,
87
+ tooltipText = _ref.tooltipText;
80
88
  var isSelected = value === selectedOptionValue;
81
- return (0, _react2.jsx)("label", {
82
- key: value,
83
- css: [modeSwitcherLabelStyles, isCompact && compactModeSwitcherLabelStyles, isSelected && modeSwitcherLabelSelectedStyles, isDisabled && modeSwitcherLabelDisabledStyles],
84
- "data-testid": "mode-toggle-".concat(value)
85
- }, label, (0, _react2.jsx)("input", {
86
- "aria-checked": isSelected,
87
- "aria-disabled": isDisabled,
88
- checked: isSelected,
89
- css: modeInputStyles,
90
- disabled: isDisabled,
91
- onChange: handleModeChange,
92
- type: "radio",
93
- value: value
94
- }));
89
+ return (0, _react2.jsx)(_tooltip.default, {
90
+ content: tooltipText
91
+ }, function (tooltipProps) {
92
+ return (0, _react2.jsx)("label", (0, _extends2.default)({}, tooltipProps, {
93
+ key: value,
94
+ css: [modeSwitcherLabelStyles, isCompact && compactModeSwitcherLabelStyles, isSelected && modeSwitcherLabelSelectedStyles, isDisabled && modeSwitcherDisabledStyles, isOptionDisabled && [modeSwitcherLabelDisabledStyles, modeSwitcherDisabledStyles]],
95
+ "data-testid": "mode-toggle-".concat(value)
96
+ }), label, (0, _react2.jsx)("input", {
97
+ "aria-checked": isSelected,
98
+ "aria-disabled": isOptionDisabled,
99
+ checked: isSelected,
100
+ css: modeInputStyles,
101
+ disabled: isOptionDisabled,
102
+ onChange: handleModeChange,
103
+ type: "radio",
104
+ value: value
105
+ }));
106
+ });
95
107
  })) : null;
96
108
  };
@@ -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.12.3"
4
+ packageVersion: "1.13.0"
5
5
  };
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useMemo } from 'react';
2
2
  import { useSmartLinkContext } from '@atlaskit/link-provider';
3
- import { getBaseUrl } from '@atlaskit/linking-common';
3
+ import { getBaseUrl, request } from '@atlaskit/linking-common';
4
4
  import { fieldValuesQuery, hydrateJQLQuery } from './utils';
5
5
  const getGraphqlUrl = (envKey, baseUrlOverride) => {
6
6
  const baseUrl = baseUrlOverride || getBaseUrl(envKey);
@@ -13,58 +13,35 @@ export const useBasicFilterAGG = () => {
13
13
  }
14
14
  } = useSmartLinkContext();
15
15
  const gatewayGraphqlUrl = getGraphqlUrl(client.envKey, client.baseUrlOverride);
16
- const aggHeaders = useMemo(() => {
17
- return new Headers({
18
- 'Content-Type': 'application/json',
19
- 'X-ExperimentalApi': 'JiraJqlBuilder'
20
- });
21
- }, []);
22
- const getHydratedJQL = useCallback(async (cloudId, jql) => {
23
- const body = JSON.stringify({
24
- variables: {
25
- cloudId,
26
- jql
27
- },
28
- operationName: 'hydrate',
29
- query: hydrateJQLQuery
30
- });
31
- const request = new Request(gatewayGraphqlUrl, {
32
- method: 'POST',
33
- headers: aggHeaders,
34
- body
35
- });
36
- try {
37
- const response = await fetch(request);
38
- return response.json();
39
- } catch (e) {
40
- throw new Error(e);
41
- }
42
- }, [gatewayGraphqlUrl, aggHeaders]);
43
- const getFieldValues = useCallback(async (cloudId, jql, jqlTerm, searchString, pageCursor) => {
44
- const body = JSON.stringify({
45
- variables: {
46
- cloudId,
47
- jql,
48
- first: 10,
49
- jqlTerm,
50
- searchString,
51
- after: pageCursor
52
- },
53
- operationName: 'fieldValues',
54
- query: fieldValuesQuery
55
- });
56
- const request = new Request(gatewayGraphqlUrl, {
57
- method: 'POST',
58
- headers: aggHeaders,
59
- body
60
- });
61
- try {
62
- const response = await fetch(request);
63
- return await response.json();
64
- } catch (e) {
65
- throw new Error(e);
66
- }
67
- }, [gatewayGraphqlUrl, aggHeaders]);
16
+ const requestCall = useCallback(async body => request('post', gatewayGraphqlUrl, body, {
17
+ 'X-ExperimentalApi': 'JiraJqlBuilder'
18
+ }, [200, 201, 202, 203, 204]), [gatewayGraphqlUrl]);
19
+ const getHydratedJQL = useCallback((cloudId, jql) => requestCall({
20
+ variables: {
21
+ cloudId,
22
+ jql
23
+ },
24
+ operationName: 'hydrate',
25
+ query: hydrateJQLQuery
26
+ }), [requestCall]);
27
+ const getFieldValues = useCallback(({
28
+ cloudId,
29
+ jql = '',
30
+ jqlTerm,
31
+ searchString = '',
32
+ pageCursor
33
+ }) => requestCall({
34
+ variables: {
35
+ cloudId,
36
+ jql,
37
+ first: 10,
38
+ jqlTerm,
39
+ searchString,
40
+ after: pageCursor
41
+ },
42
+ operationName: 'fieldValues',
43
+ query: fieldValuesQuery
44
+ }), [requestCall]);
68
45
  return useMemo(() => ({
69
46
  getHydratedJQL,
70
47
  getFieldValues
@@ -58,7 +58,7 @@ export const hydrateJQLQuery = `query hydrate($cloudId: ID!, $jql: String!) {
58
58
  }
59
59
  }
60
60
  }`;
61
- export const fieldValuesQuery = `query fieldValues($cloudId: ID!, $first: Int = 10, $jqlTerm: String!, $jql: String!, $searchString: String!, $after: String, $projectOptions: JiraProjectOptions) {
61
+ export const fieldValuesQuery = `query fieldValues($cloudId: ID!, $first: Int = 10, $jqlTerm: String!, $jql: String!, $searchString: String!, $after: String) {
62
62
  jira {
63
63
  jqlBuilder(cloudId: $cloudId) {
64
64
  fieldValues(
@@ -13,17 +13,6 @@ import { offsetFromPointer } from '@atlaskit/pragmatic-drag-and-drop/util/offset
13
13
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
14
14
  import { TableHeading } from './styled';
15
15
  import { COLUMN_MIN_WIDTH } from './index';
16
- const tableHeadingStatusStyles = {
17
- idle: css({
18
- ':hover': {
19
- background: "var(--ds-surface-hovered, #091E4224)"
20
- }
21
- }),
22
- dragging: css({
23
- background: "var(--ds-background-disabled, #091E4224)",
24
- color: "var(--ds-text-disabled, #091E424F)"
25
- })
26
- };
27
16
  const verticallyAlignedStyles = css({
28
17
  display: 'flex',
29
18
  alignItems: 'center',
@@ -264,7 +253,6 @@ export const DraggableTableHeading = ({
264
253
  }, [id, index, onWidthChange, state, tableId, width]);
265
254
  return jsx(TableHeading, {
266
255
  ref: mainHeaderCellRef,
267
- css: [tableHeadingStatusStyles[state.type]],
268
256
  "data-testid": `${id}-column-heading`,
269
257
  style: {
270
258
  width,
@@ -7,13 +7,25 @@ export const Table = styled.table`
7
7
  `;
8
8
  export const TableHeading = styled.th`
9
9
  position: relative;
10
- padding-block: ${"var(--ds-space-300, 24px)"} ${"var(--ds-space-100, 8px)"};
11
10
  line-height: ${"var(--ds-font-lineHeight-300, 16px)"};
12
11
  border-bottom: 2px solid ${`var(--ds-background-accent-gray-subtler, ${N40})`};
12
+ height: calc(52px - ${"var(--ds-space-050, 4px)"} * 2 - 2px);
13
+ vertical-align: bottom;
14
+
13
15
  & [data-testid='datasource-header-content--container'] {
14
- margin-top: 0;
16
+ width: 100%;
17
+ padding: ${"var(--ds-space-100, 4px)"} ${"var(--ds-space-050, 2px)"};
18
+ display: -webkit-box;
19
+ -webkit-line-clamp: 2;
20
+ -webkit-box-orient: vertical;
21
+ white-space: normal;
15
22
  overflow: hidden;
16
- text-overflow: ellipsis;
17
- white-space: nowrap;
23
+ max-height: 2.5rem;
24
+ word-wrap: break-word;
25
+
26
+ &:hover {
27
+ background: ${"var(--ds-background-input-hovered, #F7F8F9)"};
28
+ border-radius: 3px;
29
+ }
18
30
  }
19
31
  `;
@@ -0,0 +1,52 @@
1
+ import { useCallback, useState } from 'react';
2
+ import { useBasicFilterAGG } from '../../../../services/useBasicFilterAGG';
3
+ import { mapFieldValuesToFilterOptions, mapFieldValuesToPageCursor, mapFieldValuesToTotalCount } from '../utils/transformers';
4
+ export const useFilterOptions = ({
5
+ filterType,
6
+ cloudId
7
+ }) => {
8
+ const [filterOptions, setFilterOptions] = useState([]);
9
+ const [totalCount, setTotalCount] = useState(0);
10
+ const [status, setStatus] = useState('empty');
11
+ const [nextPageCursor, setNextPageCursor] = useState(undefined);
12
+ const {
13
+ getFieldValues
14
+ } = useBasicFilterAGG();
15
+ const fetchFilterOptions = useCallback(async ({
16
+ pageCursor,
17
+ searchString
18
+ } = {}) => {
19
+ setStatus('loading');
20
+ try {
21
+ const response = await getFieldValues({
22
+ cloudId,
23
+ jql: '',
24
+ jqlTerm: filterType,
25
+ searchString,
26
+ pageCursor
27
+ });
28
+ if (response.errors && response.errors.length > 0) {
29
+ setStatus('rejected');
30
+ return;
31
+ }
32
+ const isNewSearch = !pageCursor;
33
+ if (isNewSearch) {
34
+ setFilterOptions(mapFieldValuesToFilterOptions(response));
35
+ } else {
36
+ setFilterOptions([...filterOptions, ...mapFieldValuesToFilterOptions(response)]);
37
+ }
38
+ setTotalCount(mapFieldValuesToTotalCount(response));
39
+ setNextPageCursor(mapFieldValuesToPageCursor(response));
40
+ setStatus('resolved');
41
+ } catch (error) {
42
+ setStatus('rejected');
43
+ }
44
+ }, [cloudId, filterOptions, filterType, getFieldValues]);
45
+ return {
46
+ filterOptions,
47
+ fetchFilterOptions,
48
+ totalCount,
49
+ pageCursor: nextPageCursor,
50
+ status
51
+ };
52
+ };
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import { useIntl } from 'react-intl-next';
4
4
  import { CheckboxOption, PopupSelect } from '@atlaskit/select';
5
- import { useFieldValues } from '../../hooks/useFieldValues';
5
+ import { useFilterOptions } from '../../hooks/useFilterOptions';
6
6
  import CustomControl from './control';
7
7
  import PopupFooter from './footer';
8
8
  import formatOptionLabel from './formatOptionLabel';
@@ -12,6 +12,7 @@ import PopupTrigger from './trigger';
12
12
  const noFilterOptions = () => true;
13
13
  const AsyncPopupSelect = ({
14
14
  filterType,
15
+ cloudId,
15
16
  selection,
16
17
  onSelectionChange = () => {}
17
18
  }) => {
@@ -26,8 +27,9 @@ const AsyncPopupSelect = ({
26
27
  fetchFilterOptions,
27
28
  totalCount,
28
29
  status
29
- } = useFieldValues({
30
- filterType
30
+ } = useFilterOptions({
31
+ filterType,
32
+ cloudId
31
33
  });
32
34
  const handleInputChange = useCallback((searchString, actionMeta) => {
33
35
  if (actionMeta.action === 'input-change' && searchString !== searchTerm) {
@@ -40,7 +42,7 @@ const AsyncPopupSelect = ({
40
42
  };
41
43
  const handleOpenPopup = useCallback(async () => {
42
44
  if (status === 'empty') {
43
- fetchFilterOptions();
45
+ await fetchFilterOptions();
44
46
  }
45
47
  }, [fetchFilterOptions, status]);
46
48
  useEffect(() => {
@@ -50,18 +52,24 @@ const AsyncPopupSelect = ({
50
52
  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();
51
53
  }
52
54
  }, [status]);
55
+ const isLoading = status === 'loading' || status === 'empty';
53
56
  return /*#__PURE__*/React.createElement(PopupSelect, {
54
57
  isMulti: true,
55
58
  maxMenuWidth: 300,
56
59
  minMenuWidth: 300,
57
60
  ref: pickerRef,
58
61
  testId: "jlol-basic-filter-popup-select",
59
- inputId: "jlol-basic-filter-popup-select--input",
60
- searchThreshold: 0,
62
+ inputId: "jlol-basic-filter-popup-select--input"
63
+ /*
64
+ this threshold controls the display of the search control (input field for search)
65
+ if this threshold is less than 0, when typing a search string that returns no results it will not remove the search control
66
+ if this threshold is 0 or higher, it will remove the search control when there are no results, the user will be unable to clear the search to see more results
67
+ */,
68
+ searchThreshold: -1,
61
69
  inputValue: searchTerm,
62
70
  closeMenuOnSelect: false,
63
71
  hideSelectedOptions: false,
64
- isLoading: status === 'loading',
72
+ isLoading: isLoading,
65
73
  placeholder: formatMessage(asyncPopupSelectMessages.selectPlaceholder),
66
74
  components: {
67
75
  /* @ts-expect-error - This component has stricter OptionType, hence a temp setup untill its made generic */
@@ -4,7 +4,8 @@ import { isValidJql } from '../utils';
4
4
  import AsyncPopupSelect from './async-popup-select';
5
5
  const availableBasicFilterTypes = ['project', 'issuetype', 'status', 'assignee'];
6
6
  const BasicFilterContainer = ({
7
- jql
7
+ jql,
8
+ cloudId
8
9
  }) => {
9
10
  const [selection] = useState([]);
10
11
  useEffect(() => {
@@ -17,6 +18,7 @@ const BasicFilterContainer = ({
17
18
  gap: "space.100",
18
19
  testId: "jlol-basic-filter-container"
19
20
  }, availableBasicFilterTypes.map(filter => /*#__PURE__*/React.createElement(AsyncPopupSelect, {
21
+ cloudId: cloudId,
20
22
  filterType: filter,
21
23
  key: filter,
22
24
  selection: selection,
@@ -0,0 +1,77 @@
1
+ import { CLAUSE_TYPE_COMPOUND, CLAUSE_TYPE_TERMINAL, OPERAND_TYPE_VALUE } from '@atlaskit/jql-ast';
2
+ import { fuzzyCharacter } from '../../jira-search-container/buildJQL';
3
+ const removeFuzzyCharacter = value => {
4
+ if (value !== null && value !== void 0 && value.endsWith(fuzzyCharacter)) {
5
+ return value.slice(0, -1);
6
+ }
7
+ return value;
8
+ };
9
+ const getValueFromTerminalClause = clause => {
10
+ const {
11
+ operand
12
+ } = clause;
13
+ return operand !== undefined && operand.operandType === OPERAND_TYPE_VALUE && removeFuzzyCharacter(operand.value) || undefined;
14
+ };
15
+ const areClauseFieldValuesEqual = (clauseA, clauseB, clauseC) => {
16
+ const valueA = clauseA && getValueFromTerminalClause(clauseA);
17
+ const valueB = clauseB && getValueFromTerminalClause(clauseB);
18
+ const valueC = clauseC && getValueFromTerminalClause(clauseC);
19
+ const values = [valueA, valueB, valueC].filter(Boolean);
20
+
21
+ // 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
22
+ return values.length > 1 && values.every(value => value === values[0]);
23
+ };
24
+ const areClauseFieldKeysAllowed = (clauseA, clauseB, clauseC) => {
25
+ const fieldA = clauseA.field.value;
26
+ const fieldB = clauseB.field.value;
27
+ const 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',
28
+
29
+ return [fieldA, fieldB, fieldC].filter(Boolean).every(field => ['summary', 'text', 'key'].includes(field));
30
+ };
31
+ const doesCompoundClauseContainAllTerminalClauses = clauses => {
32
+ return clauses.every(clauses => clauses.clauseType === CLAUSE_TYPE_TERMINAL);
33
+ };
34
+ export const isClauseTooComplex = (clauses, key) => {
35
+ if (key === 'text') {
36
+ const [clause] = clauses;
37
+ if (clause.clauseType === CLAUSE_TYPE_COMPOUND) {
38
+ const textClauses = clause.clauses;
39
+
40
+ /**
41
+ * valid: text ~ "test*" or summary ~ "test*" ORDER BY created DESC
42
+ * valid: text ~ "EDM-6023*" or summary ~ "EDM-6023*" or key = EDM-6023 ORDER BY created DESC
43
+ * invalid: assignee = "me" or text ~ "EDM-6023*" or summary ~ "EDM-6023*" or key = EDM-6023 ORDER BY created DESC
44
+ */
45
+ if (textClauses.length !== 2 && textClauses.length !== 3) {
46
+ return true;
47
+ }
48
+
49
+ /**
50
+ * valid: text ~ "test*" or summary ~ "test*"
51
+ * invalid: text ~ "test" or (summary ~ "test" or key = "test")
52
+ */
53
+ if (!doesCompoundClauseContainAllTerminalClauses(textClauses)) {
54
+ return true;
55
+ }
56
+ const [clauseA, clauseB, clauseC] = textClauses;
57
+
58
+ /**
59
+ * valid: text ~ "EDM-6023*" or summary ~ "EDM-6023*" or key = EDM-6023 ORDER BY created DESC
60
+ * invalid: text ~ "EDM-6023*" or summary ~ "anotherValue" ORDER BY created DESC
61
+ * invalid: text ~ "EDM-6023*" or text ~ "anotherValue" ORDER BY created DESC
62
+ */
63
+ if (!areClauseFieldValuesEqual(clauseA, clauseB, clauseC)) {
64
+ return true;
65
+ }
66
+
67
+ /**
68
+ * valid: text ~ "EDM-6023*" ORDER BY created DESC
69
+ * invalid: resolution = 40134 ORDER BY created DESC
70
+ */
71
+ if (!areClauseFieldKeysAllowed(clauseA, clauseB, clauseC)) {
72
+ return true;
73
+ }
74
+ }
75
+ }
76
+ return clauses.length > 1;
77
+ };