@atlaskit/link-datasource 1.19.21 → 1.19.23

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 (58) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/hooks/useValidateAqlText.js +83 -45
  4. package/dist/cjs/ui/assets-modal/modal/index.js +20 -34
  5. package/dist/cjs/ui/assets-modal/modal/render-assets-content/index.js +18 -15
  6. package/dist/cjs/ui/assets-modal/search-container/aql-search-input/index.js +14 -84
  7. package/dist/cjs/ui/assets-modal/search-container/index.js +1 -1
  8. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +34 -20
  9. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +11 -9
  10. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/index.js +4 -2
  11. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/transformers.js +18 -5
  12. package/dist/cjs/ui/jira-issues-modal/jira-search-container/index.js +3 -2
  13. package/dist/cjs/ui/jira-issues-modal/modal/index.js +2 -1
  14. package/dist/es2019/analytics/constants.js +1 -1
  15. package/dist/es2019/hooks/useValidateAqlText.js +70 -31
  16. package/dist/es2019/ui/assets-modal/modal/index.js +5 -4
  17. package/dist/es2019/ui/assets-modal/modal/render-assets-content/index.js +19 -16
  18. package/dist/es2019/ui/assets-modal/search-container/aql-search-input/index.js +13 -56
  19. package/dist/es2019/ui/assets-modal/search-container/index.js +1 -1
  20. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +13 -3
  21. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +7 -4
  22. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/index.js +5 -2
  23. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/transformers.js +19 -5
  24. package/dist/es2019/ui/jira-issues-modal/jira-search-container/index.js +3 -2
  25. package/dist/es2019/ui/jira-issues-modal/modal/index.js +2 -1
  26. package/dist/esm/analytics/constants.js +1 -1
  27. package/dist/esm/hooks/useValidateAqlText.js +83 -45
  28. package/dist/esm/ui/assets-modal/modal/index.js +20 -34
  29. package/dist/esm/ui/assets-modal/modal/render-assets-content/index.js +19 -16
  30. package/dist/esm/ui/assets-modal/search-container/aql-search-input/index.js +14 -85
  31. package/dist/esm/ui/assets-modal/search-container/index.js +1 -1
  32. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +34 -20
  33. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +11 -9
  34. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/index.js +4 -2
  35. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/transformers.js +18 -5
  36. package/dist/esm/ui/jira-issues-modal/jira-search-container/index.js +3 -2
  37. package/dist/esm/ui/jira-issues-modal/modal/index.js +2 -1
  38. package/dist/types/hooks/useValidateAqlText.d.ts +21 -5
  39. package/dist/types/services/getAvailableJiraSites.d.ts +1 -5
  40. package/dist/types/ui/assets-modal/search-container/aql-search-input/index.d.ts +0 -1
  41. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +3 -2
  42. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +3 -2
  43. package/dist/types/ui/jira-issues-modal/basic-filters/ui/index.d.ts +3 -2
  44. package/dist/types/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +3 -1
  45. package/dist/types/ui/jira-issues-modal/jira-search-container/index.d.ts +2 -1
  46. package/dist/types/ui/jira-issues-modal/site-selector/index.d.ts +1 -1
  47. package/dist/types/ui/jira-issues-modal/types.d.ts +5 -0
  48. package/dist/types-ts4.5/hooks/useValidateAqlText.d.ts +21 -5
  49. package/dist/types-ts4.5/services/getAvailableJiraSites.d.ts +1 -5
  50. package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/index.d.ts +0 -1
  51. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +3 -2
  52. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +3 -2
  53. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/index.d.ts +3 -2
  54. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +3 -1
  55. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/index.d.ts +2 -1
  56. package/dist/types-ts4.5/ui/jira-issues-modal/site-selector/index.d.ts +1 -1
  57. package/dist/types-ts4.5/ui/jira-issues-modal/types.d.ts +5 -0
  58. package/package.json +4 -4
@@ -11,6 +11,15 @@ const getLozengeAppearance = colorName => {
11
11
  return appearanceMap[colorName];
12
12
  }
13
13
  };
14
+ const checkAndConvertToAbsoluteUrl = (url, siteUrl) => {
15
+ if (!url) {
16
+ return '';
17
+ }
18
+ if (/^data:(.*)/.test(url) || /^http(.*)/.test(url) || !siteUrl) {
19
+ return url;
20
+ }
21
+ return `${siteUrl}${url}`;
22
+ };
14
23
  function mapNodeToOption({
15
24
  displayName,
16
25
  jqlTerm,
@@ -18,7 +27,8 @@ function mapNodeToOption({
18
27
  issueTypes,
19
28
  project,
20
29
  statusCategory,
21
- user
30
+ user,
31
+ siteUrl
22
32
  }) {
23
33
  try {
24
34
  const baseProps = {
@@ -47,7 +57,7 @@ function mapNodeToOption({
47
57
  return {
48
58
  ...baseProps,
49
59
  optionType: 'iconLabel',
50
- icon: (_project$avatar = project.avatar) === null || _project$avatar === void 0 ? void 0 : _project$avatar.small
60
+ icon: checkAndConvertToAbsoluteUrl((_project$avatar = project.avatar) === null || _project$avatar === void 0 ? void 0 : _project$avatar.small, siteUrl)
51
61
  };
52
62
  }
53
63
  if (issueTypes) {
@@ -55,7 +65,7 @@ function mapNodeToOption({
55
65
  return {
56
66
  ...baseProps,
57
67
  optionType: 'iconLabel',
58
- icon: (_issueTypes$ = issueTypes[0]) === null || _issueTypes$ === void 0 ? void 0 : _issueTypes$.avatar.small
68
+ icon: checkAndConvertToAbsoluteUrl((_issueTypes$ = issueTypes[0]) === null || _issueTypes$ === void 0 ? void 0 : _issueTypes$.avatar.small, siteUrl)
59
69
  };
60
70
  }
61
71
  if (statusCategory) {
@@ -94,10 +104,14 @@ export function mapHydrateResponseData({
94
104
  return transformedHydrateResponseData;
95
105
  }
96
106
  export function mapFieldValuesToFilterOptions({
97
- data
107
+ data,
108
+ siteUrl
98
109
  }) {
99
110
  var _data$jira2, _data$jira2$jqlBuilde, _data$jira2$jqlBuilde2, _data$jira2$jqlBuilde3;
100
- return (data === null || data === void 0 ? void 0 : (_data$jira2 = data.jira) === null || _data$jira2 === void 0 ? void 0 : (_data$jira2$jqlBuilde = _data$jira2.jqlBuilder) === null || _data$jira2$jqlBuilde === void 0 ? void 0 : (_data$jira2$jqlBuilde2 = _data$jira2$jqlBuilde.fieldValues) === null || _data$jira2$jqlBuilde2 === void 0 ? void 0 : (_data$jira2$jqlBuilde3 = _data$jira2$jqlBuilde2.edges) === null || _data$jira2$jqlBuilde3 === void 0 ? void 0 : _data$jira2$jqlBuilde3.map(edge => edge.node ? mapNodeToOption(edge.node) : null).filter(isNonNullSelectOption)) || [];
111
+ return (data === null || data === void 0 ? void 0 : (_data$jira2 = data.jira) === null || _data$jira2 === void 0 ? void 0 : (_data$jira2$jqlBuilde = _data$jira2.jqlBuilder) === null || _data$jira2$jqlBuilde === void 0 ? void 0 : (_data$jira2$jqlBuilde2 = _data$jira2$jqlBuilde.fieldValues) === null || _data$jira2$jqlBuilde2 === void 0 ? void 0 : (_data$jira2$jqlBuilde3 = _data$jira2$jqlBuilde2.edges) === null || _data$jira2$jqlBuilde3 === void 0 ? void 0 : _data$jira2$jqlBuilde3.map(edge => edge.node ? mapNodeToOption({
112
+ ...edge.node,
113
+ siteUrl
114
+ }) : null).filter(isNonNullSelectOption)) || [];
101
115
  }
102
116
  export function mapFieldValuesToTotalCount({
103
117
  data
@@ -33,7 +33,8 @@ export const JiraSearchContainer = props => {
33
33
  onSearchMethodChange: onSearchMethodChangeCallback,
34
34
  initialSearchMethod,
35
35
  setSearchBarJql,
36
- searchBarJql = DEFAULT_JQL_QUERY
36
+ searchBarJql = DEFAULT_JQL_QUERY,
37
+ site
37
38
  } = props;
38
39
  const {
39
40
  cloudId: currentCloudId
@@ -194,7 +195,7 @@ export const JiraSearchContainer = props => {
194
195
  searchTerm: basicSearchTerm
195
196
  }), showBasicFilters && jsx(BasicFilters, {
196
197
  jql: searchBarJql,
197
- cloudId: cloudId || '',
198
+ site: site,
198
199
  onChange: handleBasicFilterSelectionChange,
199
200
  selections: filterSelections,
200
201
  isJQLHydrating: basicFilterHydrationStatus === 'loading'
@@ -518,7 +518,8 @@ export const PlainJiraIssuesConfigModal = props => {
518
518
  parameters: parameters,
519
519
  onSearch: onSearch,
520
520
  initialSearchMethod: initialSearchMethod,
521
- onSearchMethodChange: setCurrentSearchMethod
521
+ onSearchMethodChange: setCurrentSearchMethod,
522
+ site: selectedJiraSite
522
523
  }), currentViewMode === 'count' ? renderCountModeContent() : renderIssuesModeContent()) : jsx(NoInstancesView, null)), jsx(ModalFooter, null, shouldShowIssueCount && jsx("div", {
523
524
  "data-testid": "jira-jql-datasource-modal-total-issues-count",
524
525
  css: issueCountStyles
@@ -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.19.21"
4
+ packageVersion: "1.19.23"
5
5
  };
@@ -1,77 +1,115 @@
1
1
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
- import { useCallback, useState } from 'react';
4
+ import { useCallback, useRef, useState } from 'react';
5
5
  import { useDatasourceAnalyticsEvents } from '../analytics';
6
6
  import { validateAql } from '../services/cmdbService';
7
- export var useValidateAqlText = function useValidateAqlText(workspaceId) {
8
- var _useState = useState(false),
7
+ export var SEARCH_DEBOUNCE = 350;
8
+ export var useValidateAqlText = function useValidateAqlText(workspaceId, initialValue) {
9
+ var timeout = useRef();
10
+ var lastValue = useRef('');
11
+ var lastResult = useRef(Promise.resolve(undefined));
12
+ var _useState = useState(initialValue.trim() === '' ? {
13
+ type: 'idle'
14
+ } : {
15
+ type: 'loading'
16
+ }),
9
17
  _useState2 = _slicedToArray(_useState, 2),
10
- loading = _useState2[0],
11
- setLoading = _useState2[1];
12
- var _useState3 = useState(false),
13
- _useState4 = _slicedToArray(_useState3, 2),
14
- isValidAqlText = _useState4[0],
15
- setIsValidAqlText = _useState4[1];
16
- var _useState5 = useState(),
17
- _useState6 = _slicedToArray(_useState5, 2),
18
- error = _useState6[0],
19
- setError = _useState6[1];
18
+ lastValidationResult = _useState2[0],
19
+ setLastValidationResult = _useState2[1];
20
20
  var _useDatasourceAnalyti = useDatasourceAnalyticsEvents(),
21
21
  fireEvent = _useDatasourceAnalyti.fireEvent;
22
+
23
+ // We return undefined when valid and 'error' when invalid
22
24
  var validateAqlText = useCallback( /*#__PURE__*/function () {
23
25
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(aql) {
24
- var isValid, message, _validateAqlResponse$, validateAqlResponse;
26
+ var validateAqlResponse, _validateAqlResponse$, _validateAqlResponse$2;
25
27
  return _regeneratorRuntime.wrap(function _callee$(_context) {
26
28
  while (1) switch (_context.prev = _context.next) {
27
29
  case 0:
28
- setLoading(true);
29
- setError(undefined);
30
- isValid = false;
31
- message = null;
32
- _context.prev = 4;
33
- _context.next = 7;
30
+ if (!(aql !== null && aql !== void 0 && aql.trim())) {
31
+ _context.next = 18;
32
+ break;
33
+ }
34
+ _context.prev = 1;
35
+ _context.next = 4;
34
36
  return validateAql(workspaceId, {
35
37
  qlQuery: aql
36
38
  }, fireEvent);
37
- case 7:
39
+ case 4:
38
40
  validateAqlResponse = _context.sent;
39
- setIsValidAqlText(validateAqlResponse.isValid);
40
- isValid = validateAqlResponse.isValid;
41
- message = ((_validateAqlResponse$ = validateAqlResponse.errors) === null || _validateAqlResponse$ === void 0 ? void 0 : _validateAqlResponse$.iql) || null;
42
- _context.next = 16;
43
- break;
44
- case 13:
45
- _context.prev = 13;
46
- _context.t0 = _context["catch"](4);
47
- if (_context.t0 instanceof Error) {
48
- setError(_context.t0);
49
- } else {
50
- setError(new Error('Unexpected error occured'));
41
+ if (!validateAqlResponse.isValid) {
42
+ _context.next = 10;
43
+ break;
51
44
  }
52
- case 16:
53
- _context.prev = 16;
54
- setLoading(false);
55
- return _context.finish(16);
56
- case 19:
57
- return _context.abrupt("return", {
58
- isValid: isValid,
59
- message: message
45
+ setLastValidationResult({
46
+ type: 'valid',
47
+ validatedAql: aql
60
48
  });
49
+ return _context.abrupt("return", undefined);
50
+ case 10:
51
+ setLastValidationResult({
52
+ type: 'invalid',
53
+ error: (_validateAqlResponse$ = (_validateAqlResponse$2 = validateAqlResponse.errors) === null || _validateAqlResponse$2 === void 0 ? void 0 : _validateAqlResponse$2.iql) !== null && _validateAqlResponse$ !== void 0 ? _validateAqlResponse$ : ''
54
+ });
55
+ return _context.abrupt("return", 'error');
56
+ case 12:
57
+ _context.next = 18;
58
+ break;
59
+ case 14:
60
+ _context.prev = 14;
61
+ _context.t0 = _context["catch"](1);
62
+ setLastValidationResult({
63
+ type: 'invalid',
64
+ error: ''
65
+ });
66
+ return _context.abrupt("return", 'error');
67
+ case 18:
68
+ setLastValidationResult({
69
+ type: 'idle'
70
+ });
71
+ return _context.abrupt("return", undefined);
61
72
  case 20:
62
73
  case "end":
63
74
  return _context.stop();
64
75
  }
65
- }, _callee, null, [[4, 13, 16, 19]]);
76
+ }, _callee, null, [[1, 14]]);
66
77
  }));
67
78
  return function (_x) {
68
79
  return _ref.apply(this, arguments);
69
80
  };
70
81
  }(), [workspaceId, fireEvent]);
82
+
83
+ /* Debounce async validation for input, validation is also called on every field change
84
+ in a form so we need to also memoize. The async validate function is expected to either:
85
+ Immediately return a promise (which is then collected into an array, every single time validation is run),
86
+ or immediately return either undefined or an error message */
87
+ var debouncedValidation = function debouncedValidation(value) {
88
+ return new Promise(function (resolve) {
89
+ if (timeout.current) {
90
+ timeout.current();
91
+ }
92
+ if (value !== lastValue.current) {
93
+ var timerId = setTimeout(function () {
94
+ setLastValidationResult({
95
+ type: 'loading'
96
+ });
97
+ lastValue.current = value;
98
+ lastResult.current = validateAqlText(value);
99
+ resolve(lastResult.current);
100
+ }, SEARCH_DEBOUNCE);
101
+ timeout.current = function () {
102
+ clearTimeout(timerId);
103
+ resolve('debouncing');
104
+ };
105
+ } else {
106
+ resolve(lastResult.current);
107
+ }
108
+ });
109
+ };
71
110
  return {
72
- isValidAqlText: isValidAqlText,
111
+ debouncedValidation: debouncedValidation,
73
112
  validateAqlText: validateAqlText,
74
- validateAqlTextLoading: loading,
75
- validateAqlTextError: error
113
+ lastValidationResult: lastValidationResult
76
114
  };
77
115
  };
@@ -1,8 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
- import _regeneratorRuntime from "@babel/runtime/regenerator";
6
4
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
5
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
6
  /** @jsx jsx */
@@ -277,36 +275,24 @@ var PlainAssetsConfigModal = function PlainAssetsConfigModal(props) {
277
275
  }).fire(EVENT_CHANNEL);
278
276
  onCancel();
279
277
  }, [analyticsPayload, onCancel]);
280
- var handleOnSearch = useCallback( /*#__PURE__*/function () {
281
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(searchAql, searchSchemaId) {
282
- return _regeneratorRuntime.wrap(function _callee$(_context) {
283
- while (1) switch (_context.prev = _context.next) {
284
- case 0:
285
- if (schemaId !== searchSchemaId || aql !== searchAql || status === 'rejected') {
286
- searchCount.current++;
287
- if (schemaId !== searchSchemaId) {
288
- userInteractionActions.current.add(DatasourceAction.SCHEMA_UPDATED);
289
- }
290
- if (aql !== searchAql) {
291
- userInteractionActions.current.add(DatasourceAction.QUERY_UPDATED);
292
- }
293
- reset({
294
- shouldResetColumns: true
295
- });
296
- setAql(searchAql);
297
- setSchemaId(searchSchemaId);
298
- setIsNewSearch(true);
299
- }
300
- case 1:
301
- case "end":
302
- return _context.stop();
303
- }
304
- }, _callee);
305
- }));
306
- return function (_x, _x2) {
307
- return _ref.apply(this, arguments);
308
- };
309
- }(), [aql, reset, schemaId, status]);
278
+ var handleOnSearch = useCallback(function (searchAql, searchSchemaId) {
279
+ if (schemaId !== searchSchemaId || aql !== searchAql || status === 'rejected') {
280
+ searchCount.current++;
281
+ if (schemaId !== searchSchemaId) {
282
+ userInteractionActions.current.add(DatasourceAction.SCHEMA_UPDATED);
283
+ }
284
+ if (aql !== searchAql) {
285
+ userInteractionActions.current.add(DatasourceAction.QUERY_UPDATED);
286
+ }
287
+ reset({
288
+ shouldResetColumns: true,
289
+ shouldForceRequest: true
290
+ });
291
+ setAql(searchAql);
292
+ setSchemaId(searchSchemaId);
293
+ setIsNewSearch(true);
294
+ }
295
+ }, [aql, reset, schemaId, status]);
310
296
  var renderErrorState = useCallback(function () {
311
297
  if (errorState) {
312
298
  switch (errorState) {
@@ -331,7 +317,7 @@ var PlainAssetsConfigModal = function PlainAssetsConfigModal(props) {
331
317
  return jsx(AssetsSearchContainer, {
332
318
  workspaceId: workspaceId,
333
319
  initialSearchData: {
334
- aql: aql,
320
+ aql: initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.aql,
335
321
  objectSchema: existingObjectSchema,
336
322
  objectSchemas: objectSchemas
337
323
  },
@@ -340,7 +326,7 @@ var PlainAssetsConfigModal = function PlainAssetsConfigModal(props) {
340
326
  isSearching: status === 'loading'
341
327
  });
342
328
  }
343
- }, [errorState, workspaceId, assetsClientLoading, aql, existingObjectSchema, objectSchemas, handleOnSearch, status]);
329
+ }, [errorState, workspaceId, assetsClientLoading, initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.aql, existingObjectSchema, objectSchemas, handleOnSearch, status]);
344
330
  return jsx(IntlMessagesProvider, {
345
331
  defaultMessages: i18nEN,
346
332
  loaderFn: fetchMessagesForLocale
@@ -1,5 +1,5 @@
1
1
  /** @jsx jsx */
2
- import { useMemo } from 'react';
2
+ import { useCallback, useMemo } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
4
  import { N40 } from '@atlaskit/theme/colors';
5
5
  import { AccessRequired } from '../../../common/error-state/access-required';
@@ -84,19 +84,22 @@ export var RenderAssetsContent = function RenderAssetsContent(props) {
84
84
  parentContainerRenderInstanceId: modalRenderInstanceId
85
85
  }));
86
86
  }, [columns, defaultVisibleColumnKeys, hasNextPage, loadDatasourceDetails, onNextPage, onVisibleColumnKeysChange, responseItems, status, visibleColumnKeys, modalRenderInstanceId]);
87
- if (isFetchingInitialData) {
88
- // Placing this check first as it's a priority before all others
89
- return jsx(LoadingView, null);
90
- } else if (status === 'rejected') {
91
- return jsx(RejectedView, null);
92
- } else if (status === 'unauthorized') {
93
- return jsx(UnauthorizedView, null);
94
- } else if (status === 'empty') {
95
- return jsx(EmptyView, null);
96
- } else if (resolvedWithNoResults) {
97
- return jsx(NoResultsView, null);
98
- } else if (status === 'loading' && !columns.length) {
99
- return jsx(LoadingView, null);
100
- }
101
- return issueLikeDataTableView;
87
+ var renderAssetsContentView = useCallback(function () {
88
+ if (isFetchingInitialData) {
89
+ // Placing this check first as it's a priority before all others
90
+ return jsx(LoadingView, null);
91
+ } else if (status === 'rejected') {
92
+ return jsx(RejectedView, null);
93
+ } else if (status === 'unauthorized') {
94
+ return jsx(UnauthorizedView, null);
95
+ } else if (status === 'empty') {
96
+ return jsx(EmptyView, null);
97
+ } else if (resolvedWithNoResults) {
98
+ return jsx(NoResultsView, null);
99
+ } else if (status === 'loading' && !columns.length) {
100
+ return jsx(LoadingView, null);
101
+ }
102
+ return issueLikeDataTableView;
103
+ }, [columns.length, isFetchingInitialData, issueLikeDataTableView, resolvedWithNoResults, status]);
104
+ return renderAssetsContentView();
102
105
  };
@@ -1,9 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
- import _regeneratorRuntime from "@babel/runtime/regenerator";
5
2
  /** @jsx jsx */
6
- import { Fragment, useCallback, useRef, useState } from 'react';
3
+ import { Fragment } from 'react';
7
4
  import { css, jsx } from '@emotion/react';
8
5
  import { useIntl } from 'react-intl-next';
9
6
  import { LoadingButton } from '@atlaskit/button';
@@ -20,10 +17,6 @@ import { useValidateAqlText } from '../../../../hooks/useValidateAqlText';
20
17
  import { aqlKey } from '../../../../types/assets/types';
21
18
  import { FieldContainer } from '../styled';
22
19
  import { searchInputMessages } from './messages';
23
-
24
- /* Meta isn't exported in @atlaskit/form
25
- Taken from packages/design-system/form/src/field.tsx */
26
-
27
20
  var buttonBaseStyles = css({
28
21
  display: 'flex',
29
22
  height: '100%',
@@ -37,15 +30,14 @@ var AQLSupportDocumentLink = 'https://support.atlassian.com/jira-service-managem
37
30
  var searchButtonStyles = css({
38
31
  marginRight: "var(--ds-space-075, 6px)"
39
32
  });
40
- export var SEARCH_DEBOUNCE_MS = 350;
41
- var renderValidatorIcon = function renderValidatorIcon(value, error, meta) {
42
- if (value && meta !== null && meta !== void 0 && meta.validating) {
33
+ var renderValidatorIcon = function renderValidatorIcon(lastValidationResult) {
34
+ if (lastValidationResult.type === 'loading') {
43
35
  return jsx(Spinner, {
44
36
  size: "medium",
45
37
  testId: "assets-datasource-modal--aql-validating"
46
38
  });
47
39
  }
48
- if (value && error) {
40
+ if (lastValidationResult.type === 'invalid') {
49
41
  return jsx(CrossCircleIcon, {
50
42
  label: "label",
51
43
  primaryColor: "red",
@@ -53,7 +45,7 @@ var renderValidatorIcon = function renderValidatorIcon(value, error, meta) {
53
45
  testId: "assets-datasource-modal--aql-invalid"
54
46
  });
55
47
  }
56
- if (value && meta.valid) {
48
+ if (lastValidationResult.type === 'valid') {
57
49
  return jsx(CheckCircleIcon, {
58
50
  label: "label",
59
51
  primaryColor: "green",
@@ -75,85 +67,22 @@ export var AqlSearchInput = function AqlSearchInput(_ref) {
75
67
  isSearching = _ref.isSearching;
76
68
  var _useIntl = useIntl(),
77
69
  formatMessage = _useIntl.formatMessage;
78
- var timeout = useRef();
79
- var lastValue = useRef(value);
80
- var lastResult = useRef(Promise.resolve(undefined));
81
- var _useState = useState(null),
82
- _useState2 = _slicedToArray(_useState, 2),
83
- message = _useState2[0],
84
- setMessage = _useState2[1];
85
- var _useValidateAqlText = useValidateAqlText(workspaceId),
86
- validateAqlText = _useValidateAqlText.validateAqlText;
87
-
88
- // Validation expects undefined when valid and a string as an error message when invalid
89
- var handleValidation = useCallback( /*#__PURE__*/function () {
90
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(newUnvalidatedQlQuery) {
91
- var validation;
92
- return _regeneratorRuntime.wrap(function _callee$(_context) {
93
- while (1) switch (_context.prev = _context.next) {
94
- case 0:
95
- if (newUnvalidatedQlQuery) {
96
- _context.next = 2;
97
- break;
98
- }
99
- return _context.abrupt("return", undefined);
100
- case 2:
101
- _context.next = 4;
102
- return validateAqlText(newUnvalidatedQlQuery);
103
- case 4:
104
- validation = _context.sent;
105
- setMessage(validation.message);
106
- return _context.abrupt("return", validation.isValid ? undefined : 'invalid');
107
- case 7:
108
- case "end":
109
- return _context.stop();
110
- }
111
- }, _callee);
112
- }));
113
- return function (_x) {
114
- return _ref2.apply(this, arguments);
115
- };
116
- }(), [validateAqlText]);
117
-
118
- /* Debounce async validation for input, validation is also called on every field change
119
- in a form so we need to also memoize. The async validate function is expected to either:
120
- Immediately return a promise (which is then collected into an array, every single time validation is run),
121
- or immediately return either undefined or an error message */
122
- var debouncedMemoizedValidation = function debouncedMemoizedValidation(value) {
123
- return new Promise(function (resolve) {
124
- if (timeout.current) {
125
- timeout.current();
126
- }
127
- if (value !== lastValue.current) {
128
- var timerId = setTimeout(function () {
129
- lastValue.current = value;
130
- lastResult.current = handleValidation(value);
131
- resolve(lastResult.current);
132
- }, SEARCH_DEBOUNCE_MS);
133
- timeout.current = function () {
134
- clearTimeout(timerId);
135
- resolve('debouncing');
136
- };
137
- } else {
138
- resolve(lastResult.current);
139
- }
140
- });
141
- };
70
+ var _useValidateAqlText = useValidateAqlText(workspaceId, value),
71
+ debouncedValidation = _useValidateAqlText.debouncedValidation,
72
+ lastValidationResult = _useValidateAqlText.lastValidationResult;
142
73
  return jsx(FieldContainer, null, jsx(Field, {
143
74
  name: aqlKey,
144
75
  defaultValue: value,
145
- validate: debouncedMemoizedValidation
146
- }, function (_ref3) {
147
- var fieldProps = _ref3.fieldProps,
148
- meta = _ref3.meta,
149
- error = _ref3.error;
76
+ validate: debouncedValidation
77
+ }, function (_ref2) {
78
+ var fieldProps = _ref2.fieldProps;
150
79
  return jsx(Fragment, null, jsx(Textfield, _extends({}, fieldProps, {
151
80
  elemBeforeInput: jsx("span", {
152
81
  style: {
153
82
  paddingLeft: 6,
154
83
  width: 24
155
84
  }
156
- }, renderValidatorIcon(fieldProps.value, error, meta)),
85
+ }, renderValidatorIcon(lastValidationResult)),
157
86
  elemAfterInput: jsx(Fragment, null, jsx(Tooltip, {
158
87
  content: formatMessage(searchInputMessages.helpTooltipText),
159
88
  position: "bottom"
@@ -177,10 +106,10 @@ export var AqlSearchInput = function AqlSearchInput(_ref) {
177
106
  spacing: "none",
178
107
  testId: "assets-datasource-modal--aql-search-button",
179
108
  type: "submit",
180
- isDisabled: fieldProps.value.trim() === '' || meta.validating || !meta.valid
109
+ isDisabled: lastValidationResult.type !== 'valid'
181
110
  })),
182
111
  placeholder: formatMessage(searchInputMessages.placeholder),
183
112
  testId: testId
184
- })), fieldProps.value && error && message && jsx(ErrorMessage, null, message));
113
+ })), lastValidationResult.type === 'invalid' && lastValidationResult.error && jsx(ErrorMessage, null, lastValidationResult.error));
185
114
  }));
186
115
  };
@@ -19,7 +19,7 @@ export var AssetsSearchContainer = function AssetsSearchContainer(props) {
19
19
  var onFormSubmit = function onFormSubmit(searchFormValues) {
20
20
  var aql = searchFormValues.aql,
21
21
  objectSchema = searchFormValues.objectSchema;
22
- if (objectSchema) {
22
+ if (aql && objectSchema) {
23
23
  fireEvent('ui.aqlEditor.searched', {});
24
24
  // Pass the validated aql and object schema back to modal
25
25
  onSearch(aql, objectSchema.value);