@atlaskit/link-datasource 1.19.22 → 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.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/analytics/constants.js +1 -1
- package/dist/cjs/hooks/useValidateAqlText.js +83 -45
- package/dist/cjs/ui/assets-modal/modal/index.js +20 -34
- package/dist/cjs/ui/assets-modal/modal/render-assets-content/index.js +18 -15
- package/dist/cjs/ui/assets-modal/search-container/aql-search-input/index.js +14 -84
- package/dist/cjs/ui/assets-modal/search-container/index.js +1 -1
- package/dist/es2019/analytics/constants.js +1 -1
- package/dist/es2019/hooks/useValidateAqlText.js +70 -31
- package/dist/es2019/ui/assets-modal/modal/index.js +5 -4
- package/dist/es2019/ui/assets-modal/modal/render-assets-content/index.js +19 -16
- package/dist/es2019/ui/assets-modal/search-container/aql-search-input/index.js +13 -56
- package/dist/es2019/ui/assets-modal/search-container/index.js +1 -1
- package/dist/esm/analytics/constants.js +1 -1
- package/dist/esm/hooks/useValidateAqlText.js +83 -45
- package/dist/esm/ui/assets-modal/modal/index.js +20 -34
- package/dist/esm/ui/assets-modal/modal/render-assets-content/index.js +19 -16
- package/dist/esm/ui/assets-modal/search-container/aql-search-input/index.js +14 -85
- package/dist/esm/ui/assets-modal/search-container/index.js +1 -1
- package/dist/types/hooks/useValidateAqlText.d.ts +21 -5
- package/dist/types/ui/assets-modal/search-container/aql-search-input/index.d.ts +0 -1
- package/dist/types-ts4.5/hooks/useValidateAqlText.d.ts +21 -5
- package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/index.d.ts +0 -1
- package/package.json +4 -4
|
@@ -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';
|
|
@@ -74,19 +74,22 @@ export const RenderAssetsContent = props => {
|
|
|
74
74
|
onVisibleColumnKeysChange: onVisibleColumnKeysChange,
|
|
75
75
|
parentContainerRenderInstanceId: modalRenderInstanceId
|
|
76
76
|
})), [columns, defaultVisibleColumnKeys, hasNextPage, loadDatasourceDetails, onNextPage, onVisibleColumnKeysChange, responseItems, status, visibleColumnKeys, modalRenderInstanceId]);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
const renderAssetsContentView = useCallback(() => {
|
|
78
|
+
if (isFetchingInitialData) {
|
|
79
|
+
// Placing this check first as it's a priority before all others
|
|
80
|
+
return jsx(LoadingView, null);
|
|
81
|
+
} else if (status === 'rejected') {
|
|
82
|
+
return jsx(RejectedView, null);
|
|
83
|
+
} else if (status === 'unauthorized') {
|
|
84
|
+
return jsx(UnauthorizedView, null);
|
|
85
|
+
} else if (status === 'empty') {
|
|
86
|
+
return jsx(EmptyView, null);
|
|
87
|
+
} else if (resolvedWithNoResults) {
|
|
88
|
+
return jsx(NoResultsView, null);
|
|
89
|
+
} else if (status === 'loading' && !columns.length) {
|
|
90
|
+
return jsx(LoadingView, null);
|
|
91
|
+
}
|
|
92
|
+
return issueLikeDataTableView;
|
|
93
|
+
}, [columns.length, isFetchingInitialData, issueLikeDataTableView, resolvedWithNoResults, status]);
|
|
94
|
+
return renderAssetsContentView();
|
|
92
95
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
/** @jsx jsx */
|
|
3
|
-
import { Fragment
|
|
3
|
+
import { Fragment } from 'react';
|
|
4
4
|
import { css, jsx } from '@emotion/react';
|
|
5
5
|
import { useIntl } from 'react-intl-next';
|
|
6
6
|
import { LoadingButton } from '@atlaskit/button';
|
|
@@ -17,10 +17,6 @@ import { useValidateAqlText } from '../../../../hooks/useValidateAqlText';
|
|
|
17
17
|
import { aqlKey } from '../../../../types/assets/types';
|
|
18
18
|
import { FieldContainer } from '../styled';
|
|
19
19
|
import { searchInputMessages } from './messages';
|
|
20
|
-
|
|
21
|
-
/* Meta isn't exported in @atlaskit/form
|
|
22
|
-
Taken from packages/design-system/form/src/field.tsx */
|
|
23
|
-
|
|
24
20
|
const buttonBaseStyles = css({
|
|
25
21
|
display: 'flex',
|
|
26
22
|
height: '100%',
|
|
@@ -34,15 +30,14 @@ const AQLSupportDocumentLink = 'https://support.atlassian.com/jira-service-manag
|
|
|
34
30
|
const searchButtonStyles = css({
|
|
35
31
|
marginRight: "var(--ds-space-075, 6px)"
|
|
36
32
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (value && meta !== null && meta !== void 0 && meta.validating) {
|
|
33
|
+
const renderValidatorIcon = lastValidationResult => {
|
|
34
|
+
if (lastValidationResult.type === 'loading') {
|
|
40
35
|
return jsx(Spinner, {
|
|
41
36
|
size: "medium",
|
|
42
37
|
testId: "assets-datasource-modal--aql-validating"
|
|
43
38
|
});
|
|
44
39
|
}
|
|
45
|
-
if (
|
|
40
|
+
if (lastValidationResult.type === 'invalid') {
|
|
46
41
|
return jsx(CrossCircleIcon, {
|
|
47
42
|
label: "label",
|
|
48
43
|
primaryColor: "red",
|
|
@@ -50,7 +45,7 @@ const renderValidatorIcon = (value, error, meta) => {
|
|
|
50
45
|
testId: "assets-datasource-modal--aql-invalid"
|
|
51
46
|
});
|
|
52
47
|
}
|
|
53
|
-
if (
|
|
48
|
+
if (lastValidationResult.type === 'valid') {
|
|
54
49
|
return jsx(CheckCircleIcon, {
|
|
55
50
|
label: "label",
|
|
56
51
|
primaryColor: "green",
|
|
@@ -73,61 +68,23 @@ export const AqlSearchInput = ({
|
|
|
73
68
|
const {
|
|
74
69
|
formatMessage
|
|
75
70
|
} = useIntl();
|
|
76
|
-
const timeout = useRef();
|
|
77
|
-
const lastValue = useRef(value);
|
|
78
|
-
const lastResult = useRef(Promise.resolve(undefined));
|
|
79
|
-
const [message, setMessage] = useState(null);
|
|
80
71
|
const {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Validation expects undefined when valid and a string as an error message when invalid
|
|
85
|
-
const handleValidation = useCallback(async newUnvalidatedQlQuery => {
|
|
86
|
-
if (!newUnvalidatedQlQuery) {
|
|
87
|
-
return undefined;
|
|
88
|
-
}
|
|
89
|
-
const validation = await validateAqlText(newUnvalidatedQlQuery);
|
|
90
|
-
setMessage(validation.message);
|
|
91
|
-
return validation.isValid ? undefined : 'invalid';
|
|
92
|
-
}, [validateAqlText]);
|
|
93
|
-
|
|
94
|
-
/* Debounce async validation for input, validation is also called on every field change
|
|
95
|
-
in a form so we need to also memoize. The async validate function is expected to either:
|
|
96
|
-
Immediately return a promise (which is then collected into an array, every single time validation is run),
|
|
97
|
-
or immediately return either undefined or an error message */
|
|
98
|
-
const debouncedMemoizedValidation = value => new Promise(resolve => {
|
|
99
|
-
if (timeout.current) {
|
|
100
|
-
timeout.current();
|
|
101
|
-
}
|
|
102
|
-
if (value !== lastValue.current) {
|
|
103
|
-
const timerId = setTimeout(() => {
|
|
104
|
-
lastValue.current = value;
|
|
105
|
-
lastResult.current = handleValidation(value);
|
|
106
|
-
resolve(lastResult.current);
|
|
107
|
-
}, SEARCH_DEBOUNCE_MS);
|
|
108
|
-
timeout.current = () => {
|
|
109
|
-
clearTimeout(timerId);
|
|
110
|
-
resolve('debouncing');
|
|
111
|
-
};
|
|
112
|
-
} else {
|
|
113
|
-
resolve(lastResult.current);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
72
|
+
debouncedValidation,
|
|
73
|
+
lastValidationResult
|
|
74
|
+
} = useValidateAqlText(workspaceId, value);
|
|
116
75
|
return jsx(FieldContainer, null, jsx(Field, {
|
|
117
76
|
name: aqlKey,
|
|
118
77
|
defaultValue: value,
|
|
119
|
-
validate:
|
|
78
|
+
validate: debouncedValidation
|
|
120
79
|
}, ({
|
|
121
|
-
fieldProps
|
|
122
|
-
meta,
|
|
123
|
-
error
|
|
80
|
+
fieldProps
|
|
124
81
|
}) => jsx(Fragment, null, jsx(Textfield, _extends({}, fieldProps, {
|
|
125
82
|
elemBeforeInput: jsx("span", {
|
|
126
83
|
style: {
|
|
127
84
|
paddingLeft: 6,
|
|
128
85
|
width: 24
|
|
129
86
|
}
|
|
130
|
-
}, renderValidatorIcon(
|
|
87
|
+
}, renderValidatorIcon(lastValidationResult)),
|
|
131
88
|
elemAfterInput: jsx(Fragment, null, jsx(Tooltip, {
|
|
132
89
|
content: formatMessage(searchInputMessages.helpTooltipText),
|
|
133
90
|
position: "bottom"
|
|
@@ -151,9 +108,9 @@ export const AqlSearchInput = ({
|
|
|
151
108
|
spacing: "none",
|
|
152
109
|
testId: "assets-datasource-modal--aql-search-button",
|
|
153
110
|
type: "submit",
|
|
154
|
-
isDisabled:
|
|
111
|
+
isDisabled: lastValidationResult.type !== 'valid'
|
|
155
112
|
})),
|
|
156
113
|
placeholder: formatMessage(searchInputMessages.placeholder),
|
|
157
114
|
testId: testId
|
|
158
|
-
})),
|
|
115
|
+
})), lastValidationResult.type === 'invalid' && lastValidationResult.error && jsx(ErrorMessage, null, lastValidationResult.error))));
|
|
159
116
|
};
|
|
@@ -24,7 +24,7 @@ export const AssetsSearchContainer = props => {
|
|
|
24
24
|
aql,
|
|
25
25
|
objectSchema
|
|
26
26
|
} = searchFormValues;
|
|
27
|
-
if (objectSchema) {
|
|
27
|
+
if (aql && objectSchema) {
|
|
28
28
|
fireEvent('ui.aqlEditor.searched', {});
|
|
29
29
|
// Pass the validated aql and object schema back to modal
|
|
30
30
|
onSearch(aql, objectSchema.value);
|
|
@@ -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
|
|
8
|
-
|
|
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
|
-
|
|
11
|
-
|
|
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
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
_context.prev =
|
|
33
|
-
_context.next =
|
|
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
|
|
39
|
+
case 4:
|
|
38
40
|
validateAqlResponse = _context.sent;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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, [[
|
|
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
|
-
|
|
111
|
+
debouncedValidation: debouncedValidation,
|
|
73
112
|
validateAqlText: validateAqlText,
|
|
74
|
-
|
|
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(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
|
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
|
-
|
|
41
|
-
|
|
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 (
|
|
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 (
|
|
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
|
|
79
|
-
|
|
80
|
-
|
|
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:
|
|
146
|
-
}, function (
|
|
147
|
-
var 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(
|
|
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:
|
|
109
|
+
isDisabled: lastValidationResult.type !== 'valid'
|
|
181
110
|
})),
|
|
182
111
|
placeholder: formatMessage(searchInputMessages.placeholder),
|
|
183
112
|
testId: testId
|
|
184
|
-
})),
|
|
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);
|