@atlaskit/link-datasource 0.29.3 → 0.29.5
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 +13 -0
- package/dist/cjs/hooks/useAssetsClient.js +50 -31
- package/dist/cjs/hooks/useObjectSchemas.js +74 -0
- package/dist/cjs/hooks/useValidateAqlText.js +42 -13
- package/dist/cjs/index.js +7 -1
- package/dist/cjs/services/cmdbService.js +17 -8
- package/dist/cjs/types/assets/types.js +7 -1
- package/dist/cjs/ui/assets-modal/modal/index.js +46 -10
- package/dist/cjs/ui/assets-modal/modal/messages.js +5 -0
- package/dist/cjs/ui/assets-modal/modal/styled.js +1 -1
- package/dist/cjs/ui/assets-modal/search-container/aql-search-input/index.js +161 -0
- package/dist/cjs/ui/assets-modal/search-container/aql-search-input/loading-state.js +18 -0
- package/dist/cjs/ui/assets-modal/search-container/aql-search-input/messages.js +15 -0
- package/dist/cjs/ui/assets-modal/search-container/index.js +50 -0
- package/dist/cjs/ui/assets-modal/search-container/loading-state.js +21 -0
- package/dist/cjs/ui/assets-modal/search-container/object-schema-select/index.js +103 -0
- package/dist/cjs/ui/assets-modal/search-container/object-schema-select/loading-state.js +18 -0
- package/dist/cjs/ui/assets-modal/search-container/object-schema-select/messages.js +25 -0
- package/dist/cjs/ui/assets-modal/search-container/object-schema-select/utils.js +13 -0
- package/dist/cjs/ui/assets-modal/search-container/styled.js +22 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/hooks/useAssetsClient.js +22 -13
- package/dist/es2019/hooks/useObjectSchemas.js +32 -0
- package/dist/es2019/hooks/useValidateAqlText.js +26 -9
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/services/cmdbService.js +14 -6
- package/dist/es2019/types/assets/types.js +3 -1
- package/dist/es2019/ui/assets-modal/modal/index.js +42 -8
- package/dist/es2019/ui/assets-modal/modal/messages.js +5 -0
- package/dist/es2019/ui/assets-modal/modal/styled.js +3 -3
- package/dist/es2019/ui/assets-modal/search-container/aql-search-input/index.js +129 -0
- package/dist/es2019/ui/assets-modal/search-container/aql-search-input/loading-state.js +8 -0
- package/dist/es2019/ui/assets-modal/search-container/aql-search-input/messages.js +8 -0
- package/dist/es2019/ui/assets-modal/search-container/index.js +46 -0
- package/dist/es2019/ui/assets-modal/search-container/loading-state.js +14 -0
- package/dist/es2019/ui/assets-modal/search-container/object-schema-select/index.js +65 -0
- package/dist/es2019/ui/assets-modal/search-container/object-schema-select/loading-state.js +8 -0
- package/dist/es2019/ui/assets-modal/search-container/object-schema-select/messages.js +18 -0
- package/dist/es2019/ui/assets-modal/search-container/object-schema-select/utils.js +4 -0
- package/dist/es2019/ui/assets-modal/search-container/styled.js +22 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/hooks/useAssetsClient.js +51 -32
- package/dist/esm/hooks/useObjectSchemas.js +66 -0
- package/dist/esm/hooks/useValidateAqlText.js +42 -13
- package/dist/esm/index.js +1 -0
- package/dist/esm/services/cmdbService.js +15 -7
- package/dist/esm/types/assets/types.js +3 -1
- package/dist/esm/ui/assets-modal/modal/index.js +46 -10
- package/dist/esm/ui/assets-modal/modal/messages.js +5 -0
- package/dist/esm/ui/assets-modal/modal/styled.js +1 -1
- package/dist/esm/ui/assets-modal/search-container/aql-search-input/index.js +152 -0
- package/dist/esm/ui/assets-modal/search-container/aql-search-input/loading-state.js +10 -0
- package/dist/esm/ui/assets-modal/search-container/aql-search-input/messages.js +8 -0
- package/dist/esm/ui/assets-modal/search-container/index.js +41 -0
- package/dist/esm/ui/assets-modal/search-container/loading-state.js +13 -0
- package/dist/esm/ui/assets-modal/search-container/object-schema-select/index.js +94 -0
- package/dist/esm/ui/assets-modal/search-container/object-schema-select/loading-state.js +10 -0
- package/dist/esm/ui/assets-modal/search-container/object-schema-select/messages.js +18 -0
- package/dist/esm/ui/assets-modal/search-container/object-schema-select/utils.js +6 -0
- package/dist/esm/ui/assets-modal/search-container/styled.js +11 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/hooks/useAssetsClient.d.ts +8 -6
- package/dist/types/hooks/useObjectSchemas.d.ts +8 -0
- package/dist/types/hooks/useValidateAqlText.d.ts +5 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/services/cmdbService.d.ts +4 -3
- package/dist/types/types/assets/types.d.ts +21 -10
- package/dist/types/ui/assets-modal/modal/messages.d.ts +5 -0
- package/dist/types/ui/assets-modal/search-container/aql-search-input/index.d.ts +8 -0
- package/dist/types/ui/assets-modal/search-container/aql-search-input/loading-state.d.ts +3 -0
- package/dist/types/ui/assets-modal/search-container/aql-search-input/messages.d.ts +7 -0
- package/dist/types/ui/assets-modal/search-container/index.d.ts +16 -0
- package/dist/types/ui/assets-modal/search-container/loading-state.d.ts +8 -0
- package/dist/types/ui/assets-modal/search-container/object-schema-select/index.d.ts +10 -0
- package/dist/types/ui/assets-modal/search-container/object-schema-select/loading-state.d.ts +3 -0
- package/dist/types/ui/assets-modal/search-container/object-schema-select/messages.d.ts +17 -0
- package/dist/types/ui/assets-modal/search-container/object-schema-select/utils.d.ts +2 -0
- package/dist/types/ui/assets-modal/search-container/styled.d.ts +19 -0
- package/dist/types-ts4.5/hooks/useAssetsClient.d.ts +8 -6
- package/dist/types-ts4.5/hooks/useObjectSchemas.d.ts +8 -0
- package/dist/types-ts4.5/hooks/useValidateAqlText.d.ts +5 -2
- package/dist/types-ts4.5/index.d.ts +1 -0
- package/dist/types-ts4.5/services/cmdbService.d.ts +4 -3
- package/dist/types-ts4.5/types/assets/types.d.ts +21 -10
- package/dist/types-ts4.5/ui/assets-modal/modal/messages.d.ts +5 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/index.d.ts +8 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/loading-state.d.ts +3 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/messages.d.ts +7 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/index.d.ts +16 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/loading-state.d.ts +8 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/index.d.ts +10 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/loading-state.d.ts +3 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/messages.d.ts +17 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/utils.d.ts +2 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/styled.d.ts +19 -0
- package/package.json +4 -2
- package/report.api.md +7 -5
- package/tmp/api-report-tmp.d.ts +5 -3
|
@@ -6,9 +6,13 @@ import Button from '@atlaskit/button/standard-button';
|
|
|
6
6
|
import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
|
|
7
7
|
import { useAssetsClient } from '../../../hooks/useAssetsClient';
|
|
8
8
|
import { useDatasourceTableState } from '../../../hooks/useDatasourceTableState';
|
|
9
|
+
import { ModalLoadingError } from '../../common/error-state/modal-loading-error';
|
|
10
|
+
import { AssetsSearchContainer } from '../search-container';
|
|
11
|
+
import { AssetsSearchContainerLoading } from '../search-container/loading-state';
|
|
9
12
|
import { modalMessages } from './messages';
|
|
10
13
|
import { RenderAssetsContent } from './render-assets-content';
|
|
11
14
|
import { ModalContentContainer } from './styled';
|
|
15
|
+
const AssetsModalTitle = jsx(ModalTitle, null, jsx(FormattedMessage, modalMessages.insertObjectsTitle));
|
|
12
16
|
export const AssetsConfigModal = props => {
|
|
13
17
|
const {
|
|
14
18
|
datasourceId,
|
|
@@ -17,16 +21,22 @@ export const AssetsConfigModal = props => {
|
|
|
17
21
|
onInsert,
|
|
18
22
|
visibleColumnKeys: initialVisibleColumnKeys
|
|
19
23
|
} = props;
|
|
20
|
-
const [aql] = useState(initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.aql);
|
|
21
|
-
const [schemaId] = useState(initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.schemaId);
|
|
24
|
+
const [aql, setAql] = useState(initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.aql);
|
|
25
|
+
const [schemaId, setSchemaId] = useState(initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.schemaId);
|
|
22
26
|
const [visibleColumnKeys, setVisibleColumnKeys] = useState(initialVisibleColumnKeys);
|
|
27
|
+
|
|
28
|
+
// If a workspaceError occurs this is a critical error
|
|
23
29
|
const {
|
|
24
|
-
workspaceId
|
|
25
|
-
|
|
30
|
+
workspaceId,
|
|
31
|
+
workspaceError,
|
|
32
|
+
objectSchema,
|
|
33
|
+
assetsClientLoading
|
|
34
|
+
} = useAssetsClient(initialParameters);
|
|
26
35
|
const parameters = useMemo(() => ({
|
|
27
36
|
aql: aql || '',
|
|
28
37
|
schemaId: schemaId || '',
|
|
29
|
-
workspaceId: ''
|
|
38
|
+
workspaceId: '',
|
|
39
|
+
cloudId: ''
|
|
30
40
|
}), [aql, schemaId]);
|
|
31
41
|
const {
|
|
32
42
|
status,
|
|
@@ -40,7 +50,7 @@ export const AssetsConfigModal = props => {
|
|
|
40
50
|
const newVisibleColumnKeys = !initialVisibleColumnKeys || (initialVisibleColumnKeys || []).length === 0 ? defaultVisibleColumnKeys : initialVisibleColumnKeys;
|
|
41
51
|
setVisibleColumnKeys(newVisibleColumnKeys);
|
|
42
52
|
}, [initialVisibleColumnKeys, defaultVisibleColumnKeys]);
|
|
43
|
-
const isDisabled = status === 'rejected' || status === 'loading' || status === 'empty' ||
|
|
53
|
+
const isDisabled = status === 'rejected' || status === 'loading' || status === 'empty' || !!workspaceError || assetsClientLoading || !aql || !schemaId;
|
|
44
54
|
const retrieveUrlForSmartCardRender = useCallback(() => {
|
|
45
55
|
var _data$key, _data$key$data;
|
|
46
56
|
const [data] = responseItems;
|
|
@@ -48,7 +58,7 @@ export const AssetsConfigModal = props => {
|
|
|
48
58
|
return data === null || data === void 0 ? void 0 : (_data$key = data.key) === null || _data$key === void 0 ? void 0 : (_data$key$data = _data$key.data) === null || _data$key$data === void 0 ? void 0 : _data$key$data.url;
|
|
49
59
|
}, [responseItems]);
|
|
50
60
|
const onInsertPressed = useCallback(() => {
|
|
51
|
-
if (!aql) {
|
|
61
|
+
if (!aql || !schemaId) {
|
|
52
62
|
return;
|
|
53
63
|
}
|
|
54
64
|
const firstAssetUrl = retrieveUrlForSmartCardRender();
|
|
@@ -84,12 +94,36 @@ export const AssetsConfigModal = props => {
|
|
|
84
94
|
});
|
|
85
95
|
}
|
|
86
96
|
}, [aql, datasourceId, onInsert, responseItems.length, retrieveUrlForSmartCardRender, schemaId, visibleColumnKeys]);
|
|
97
|
+
const handleOnSearch = useCallback((aql, schemaId) => {
|
|
98
|
+
setAql(aql);
|
|
99
|
+
setSchemaId(schemaId);
|
|
100
|
+
}, []);
|
|
101
|
+
const renderModalTitleContent = useCallback(() => {
|
|
102
|
+
if (workspaceError) {
|
|
103
|
+
return undefined;
|
|
104
|
+
} else {
|
|
105
|
+
if (!workspaceId || assetsClientLoading) {
|
|
106
|
+
return jsx(AssetsSearchContainerLoading, {
|
|
107
|
+
modalTitle: AssetsModalTitle
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return jsx(AssetsSearchContainer, {
|
|
111
|
+
workspaceId: workspaceId,
|
|
112
|
+
initialSearchData: {
|
|
113
|
+
aql,
|
|
114
|
+
objectSchema
|
|
115
|
+
},
|
|
116
|
+
onSearch: handleOnSearch,
|
|
117
|
+
modalTitle: AssetsModalTitle
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}, [aql, assetsClientLoading, handleOnSearch, objectSchema, workspaceError, workspaceId]);
|
|
87
121
|
return jsx(ModalTransition, null, jsx(Modal, {
|
|
88
122
|
testId: 'asset-datasource-modal',
|
|
89
123
|
onClose: onCancel,
|
|
90
124
|
width: "x-large",
|
|
91
125
|
shouldScrollInViewport: true
|
|
92
|
-
}, jsx(ModalHeader, null,
|
|
126
|
+
}, jsx(ModalHeader, null, renderModalTitleContent()), jsx(ModalBody, null, jsx(ModalContentContainer, null, workspaceError ? jsx(ModalLoadingError, null) : jsx(RenderAssetsContent, {
|
|
93
127
|
status: status,
|
|
94
128
|
responseItems: responseItems
|
|
95
129
|
}))), jsx(ModalFooter, null, jsx(Button, {
|
|
@@ -9,5 +9,10 @@ export const modalMessages = defineMessages({
|
|
|
9
9
|
id: 'linkDataSource.assets.configmodal.insertIssuesButtonText',
|
|
10
10
|
description: 'Button text to insert the displayed content',
|
|
11
11
|
defaultMessage: 'Insert objects'
|
|
12
|
+
},
|
|
13
|
+
insertObjectsTitle: {
|
|
14
|
+
id: 'linkDataSource.assets.configmodal.insertObjectsTitle',
|
|
15
|
+
description: 'Title for the Assets Objects Datasource config modal which prefixes a select picker',
|
|
16
|
+
defaultMessage: 'Insert objects from'
|
|
12
17
|
}
|
|
13
18
|
});
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
/** @jsx jsx */
|
|
3
|
+
import { useCallback, useRef } from 'react';
|
|
4
|
+
import { css, jsx } from '@emotion/react';
|
|
5
|
+
import { useIntl } from 'react-intl-next';
|
|
6
|
+
import Button from '@atlaskit/button';
|
|
7
|
+
import { Field } from '@atlaskit/form';
|
|
8
|
+
import CheckCircleIcon from '@atlaskit/icon/glyph/check-circle';
|
|
9
|
+
import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
|
|
10
|
+
import SearchIcon from '@atlaskit/icon/glyph/editor/search';
|
|
11
|
+
import Spinner from '@atlaskit/spinner';
|
|
12
|
+
import Textfield from '@atlaskit/textfield';
|
|
13
|
+
import { useValidateAqlText } from '../../../../hooks/useValidateAqlText';
|
|
14
|
+
import { aqlKey } from '../../../../types/assets/types';
|
|
15
|
+
import { FieldContainer } from '../styled';
|
|
16
|
+
import { searchInputMessages } from './messages';
|
|
17
|
+
|
|
18
|
+
/* Meta isn't exported in @atlaskit/form
|
|
19
|
+
Taken from packages/design-system/form/src/field.tsx */
|
|
20
|
+
|
|
21
|
+
const searchButtonStyles = css({
|
|
22
|
+
marginRight: "var(--ds-space-075, 6px)"
|
|
23
|
+
});
|
|
24
|
+
export const SEARCH_DEBOUNCE_MS = 350;
|
|
25
|
+
const renderValidatorIcon = (value, error, meta) => {
|
|
26
|
+
if (value && meta !== null && meta !== void 0 && meta.validating) {
|
|
27
|
+
return jsx(Spinner, {
|
|
28
|
+
size: "medium",
|
|
29
|
+
testId: "assets-datasource-modal--aql-validating"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (value && error) {
|
|
33
|
+
return jsx(CrossCircleIcon, {
|
|
34
|
+
label: "label",
|
|
35
|
+
primaryColor: "red",
|
|
36
|
+
size: "medium",
|
|
37
|
+
testId: "assets-datasource-modal--aql-invalid"
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (value && meta.valid) {
|
|
41
|
+
return jsx(CheckCircleIcon, {
|
|
42
|
+
label: "label",
|
|
43
|
+
primaryColor: "green",
|
|
44
|
+
size: "medium",
|
|
45
|
+
testId: "assets-datasource-modal--aql-valid"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return jsx(SearchIcon, {
|
|
49
|
+
label: "label",
|
|
50
|
+
size: "medium",
|
|
51
|
+
testId: "assets-datasource-modal--aql-idle"
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
export const AqlSearchInput = ({
|
|
55
|
+
value,
|
|
56
|
+
workspaceId,
|
|
57
|
+
testId = 'assets-datasource-modal--aql-search-input'
|
|
58
|
+
}) => {
|
|
59
|
+
const {
|
|
60
|
+
formatMessage
|
|
61
|
+
} = useIntl();
|
|
62
|
+
const timeout = useRef();
|
|
63
|
+
const lastValue = useRef(value);
|
|
64
|
+
const lastResult = useRef(Promise.resolve(undefined));
|
|
65
|
+
const {
|
|
66
|
+
validateAqlText
|
|
67
|
+
} = useValidateAqlText(workspaceId);
|
|
68
|
+
|
|
69
|
+
// Validation expects undefined when valid and a string as an error message when invalid
|
|
70
|
+
const handleValidation = useCallback(async newUnvalidatedQlQuery => {
|
|
71
|
+
if (!newUnvalidatedQlQuery) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const isValid = await validateAqlText(newUnvalidatedQlQuery);
|
|
75
|
+
return isValid ? undefined : 'invalid';
|
|
76
|
+
}, [validateAqlText]);
|
|
77
|
+
|
|
78
|
+
/* Debounce async validation for input, validation is also called on every field change
|
|
79
|
+
in a form so we need to also memoize. The async validate function is expected to either:
|
|
80
|
+
Immediately return a promise (which is then collected into an array, every single time validation is run),
|
|
81
|
+
or immediately return either undefined or an error message */
|
|
82
|
+
const debouncedMemoizedValidation = value => new Promise(resolve => {
|
|
83
|
+
if (timeout.current) {
|
|
84
|
+
timeout.current();
|
|
85
|
+
}
|
|
86
|
+
if (value !== lastValue.current) {
|
|
87
|
+
const timerId = setTimeout(() => {
|
|
88
|
+
lastValue.current = value;
|
|
89
|
+
lastResult.current = handleValidation(value);
|
|
90
|
+
resolve(lastResult.current);
|
|
91
|
+
}, SEARCH_DEBOUNCE_MS);
|
|
92
|
+
timeout.current = () => {
|
|
93
|
+
clearTimeout(timerId);
|
|
94
|
+
resolve('debouncing');
|
|
95
|
+
};
|
|
96
|
+
} else {
|
|
97
|
+
resolve(lastResult.current);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return jsx(FieldContainer, null, jsx(Field, {
|
|
101
|
+
name: aqlKey,
|
|
102
|
+
defaultValue: value,
|
|
103
|
+
validate: debouncedMemoizedValidation
|
|
104
|
+
}, ({
|
|
105
|
+
fieldProps,
|
|
106
|
+
meta,
|
|
107
|
+
error
|
|
108
|
+
}) => jsx(Textfield, _extends({}, fieldProps, {
|
|
109
|
+
elemBeforeInput: jsx("span", {
|
|
110
|
+
style: {
|
|
111
|
+
paddingLeft: 6,
|
|
112
|
+
width: 24
|
|
113
|
+
}
|
|
114
|
+
}, renderValidatorIcon(fieldProps.value, error, meta)),
|
|
115
|
+
elemAfterInput: jsx(Button, {
|
|
116
|
+
appearance: "primary",
|
|
117
|
+
css: searchButtonStyles,
|
|
118
|
+
iconBefore: jsx(SearchIcon, {
|
|
119
|
+
label: formatMessage(searchInputMessages.placeholder),
|
|
120
|
+
size: "medium"
|
|
121
|
+
}),
|
|
122
|
+
spacing: "none",
|
|
123
|
+
testId: "assets-datasource-modal--aql-search-button",
|
|
124
|
+
type: "submit"
|
|
125
|
+
}),
|
|
126
|
+
placeholder: formatMessage(searchInputMessages.placeholder),
|
|
127
|
+
testId: testId
|
|
128
|
+
}))));
|
|
129
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/react';
|
|
3
|
+
import { Skeleton } from '@atlaskit/linking-common';
|
|
4
|
+
export const AssetsAqlSearchInputSkeleton = () => jsx(Skeleton, {
|
|
5
|
+
width: "100%",
|
|
6
|
+
height: "40px",
|
|
7
|
+
testId: "assets-datasource-modal--aql-search-input-skeleton"
|
|
8
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export const searchInputMessages = defineMessages({
|
|
3
|
+
placeholder: {
|
|
4
|
+
id: 'linkDataSource.assets.configModal.aqlSearchInput.placeholder',
|
|
5
|
+
description: 'Display text for AQL search button',
|
|
6
|
+
defaultMessage: 'Search via AQL'
|
|
7
|
+
}
|
|
8
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
/** @jsx jsx */
|
|
3
|
+
import { jsx } from '@emotion/react';
|
|
4
|
+
import Form from '@atlaskit/form';
|
|
5
|
+
import { AqlSearchInput } from './aql-search-input';
|
|
6
|
+
import { AssetsObjectSchemaSelect } from './object-schema-select';
|
|
7
|
+
import { FormContainer, FormRowContainer, SchemaSelectContainer } from './styled';
|
|
8
|
+
const DEFAULT_AQL_QUERY = '';
|
|
9
|
+
const SEARCH_FORM_ID = 'linkDataSource.assets.configModal.searchContainer-form';
|
|
10
|
+
export const AssetsSearchContainer = props => {
|
|
11
|
+
const {
|
|
12
|
+
onSearch,
|
|
13
|
+
workspaceId,
|
|
14
|
+
initialSearchData,
|
|
15
|
+
modalTitle
|
|
16
|
+
} = props;
|
|
17
|
+
const onFormSubmit = searchFormValues => {
|
|
18
|
+
const {
|
|
19
|
+
aql,
|
|
20
|
+
objectSchema
|
|
21
|
+
} = searchFormValues;
|
|
22
|
+
if (objectSchema) {
|
|
23
|
+
// Pass the validated aql and object schema back to modal
|
|
24
|
+
onSearch(aql, objectSchema.value);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
return jsx(Form, {
|
|
28
|
+
onSubmit: onFormSubmit
|
|
29
|
+
}, ({
|
|
30
|
+
formProps
|
|
31
|
+
}) => {
|
|
32
|
+
var _initialSearchData$ob, _initialSearchData$aq;
|
|
33
|
+
return jsx(FormContainer, _extends({}, formProps, {
|
|
34
|
+
id: SEARCH_FORM_ID
|
|
35
|
+
}), jsx(FormRowContainer, {
|
|
36
|
+
isNarrowGap: true
|
|
37
|
+
}, modalTitle, jsx(SchemaSelectContainer, null, jsx(AssetsObjectSchemaSelect, {
|
|
38
|
+
value: (_initialSearchData$ob = initialSearchData.objectSchema) !== null && _initialSearchData$ob !== void 0 ? _initialSearchData$ob : undefined,
|
|
39
|
+
workspaceId: workspaceId,
|
|
40
|
+
classNamePrefix: "assets-datasource-modal--object-schema-select"
|
|
41
|
+
}))), jsx(FormRowContainer, null, jsx(AqlSearchInput, {
|
|
42
|
+
value: (_initialSearchData$aq = initialSearchData.aql) !== null && _initialSearchData$aq !== void 0 ? _initialSearchData$aq : DEFAULT_AQL_QUERY,
|
|
43
|
+
workspaceId: workspaceId
|
|
44
|
+
})));
|
|
45
|
+
});
|
|
46
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/react';
|
|
3
|
+
import { AssetsAqlSearchInputSkeleton } from './aql-search-input/loading-state';
|
|
4
|
+
import { AssetsObjectSchemaSelectSkeleton } from './object-schema-select/loading-state';
|
|
5
|
+
import { FormContainer, FormRowContainer, SchemaSelectContainer } from './styled';
|
|
6
|
+
export const AssetsSearchContainerLoading = ({
|
|
7
|
+
modalTitle
|
|
8
|
+
}) => {
|
|
9
|
+
return jsx(FormContainer, {
|
|
10
|
+
"data-testid": "assets-datasource-modal--search-container-skeleton"
|
|
11
|
+
}, jsx(FormRowContainer, {
|
|
12
|
+
isNarrowGap: true
|
|
13
|
+
}, modalTitle, jsx(SchemaSelectContainer, null, jsx(AssetsObjectSchemaSelectSkeleton, null))), jsx(FormRowContainer, null, jsx(AssetsAqlSearchInputSkeleton, null)));
|
|
14
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
/** @jsx jsx */
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { jsx } from '@emotion/react';
|
|
5
|
+
import debounce from 'debounce-promise';
|
|
6
|
+
import { useIntl } from 'react-intl-next';
|
|
7
|
+
import { Field } from '@atlaskit/form';
|
|
8
|
+
import { AsyncSelect } from '@atlaskit/select';
|
|
9
|
+
import { useObjectSchemas } from '../../../../hooks/useObjectSchemas';
|
|
10
|
+
import { objectSchemaKey } from '../../../../types/assets/types';
|
|
11
|
+
import { FieldContainer } from '../styled';
|
|
12
|
+
import { objectSchemaSelectMessages } from './messages';
|
|
13
|
+
import { objectSchemaToSelectOption } from './utils';
|
|
14
|
+
export const SEARCH_DEBOUNCE_MS = 350;
|
|
15
|
+
export const AssetsObjectSchemaSelect = ({
|
|
16
|
+
value,
|
|
17
|
+
workspaceId,
|
|
18
|
+
classNamePrefix = 'assets-datasource-modal--object-schema-select'
|
|
19
|
+
}) => {
|
|
20
|
+
const {
|
|
21
|
+
formatMessage
|
|
22
|
+
} = useIntl();
|
|
23
|
+
const {
|
|
24
|
+
fetchObjectSchemas,
|
|
25
|
+
objectSchemasLoading
|
|
26
|
+
} = useObjectSchemas(workspaceId);
|
|
27
|
+
const [defaultOptions, setDefaultOptions] = useState(undefined);
|
|
28
|
+
const selectedObjectSchema = value ? objectSchemaToSelectOption(value) : undefined;
|
|
29
|
+
const loadOptions = async inputValue => {
|
|
30
|
+
const objectSchemas = await fetchObjectSchemas(inputValue);
|
|
31
|
+
const options = objectSchemas ? objectSchemas.map(objectSchema => objectSchemaToSelectOption(objectSchema)) : [];
|
|
32
|
+
return options;
|
|
33
|
+
};
|
|
34
|
+
const debouncedLoadOptions = debounce(loadOptions, SEARCH_DEBOUNCE_MS);
|
|
35
|
+
const validateSchema = value => {
|
|
36
|
+
if (!value || !value.value) {
|
|
37
|
+
return formatMessage(objectSchemaSelectMessages.schemaRequired);
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
};
|
|
41
|
+
return jsx(FieldContainer, null, jsx(Field, {
|
|
42
|
+
name: objectSchemaKey,
|
|
43
|
+
defaultValue: selectedObjectSchema,
|
|
44
|
+
validate: value => validateSchema(value)
|
|
45
|
+
}, ({
|
|
46
|
+
fieldProps: {
|
|
47
|
+
onChange,
|
|
48
|
+
onFocus,
|
|
49
|
+
...restFieldProps
|
|
50
|
+
}
|
|
51
|
+
}) => jsx(AsyncSelect, _extends({
|
|
52
|
+
classNamePrefix: classNamePrefix,
|
|
53
|
+
isLoading: objectSchemasLoading,
|
|
54
|
+
defaultOptions: defaultOptions || [],
|
|
55
|
+
isSearchable: true,
|
|
56
|
+
loadOptions: debouncedLoadOptions,
|
|
57
|
+
placeholder: formatMessage(objectSchemaSelectMessages.placeholder),
|
|
58
|
+
onChange: newOption => newOption && onChange(newOption),
|
|
59
|
+
onFocus: () => {
|
|
60
|
+
if (!defaultOptions) {
|
|
61
|
+
loadOptions('').then(setDefaultOptions);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, restFieldProps))));
|
|
65
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/react';
|
|
3
|
+
import { Skeleton } from '@atlaskit/linking-common';
|
|
4
|
+
export const AssetsObjectSchemaSelectSkeleton = () => jsx(Skeleton, {
|
|
5
|
+
width: "100%",
|
|
6
|
+
height: "40px",
|
|
7
|
+
testId: "assets-datasource-modal--object-schema-select-skeleton"
|
|
8
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export const objectSchemaSelectMessages = defineMessages({
|
|
3
|
+
label: {
|
|
4
|
+
id: 'linkDataSource.assets.configModal.objectSchemaSelect.label',
|
|
5
|
+
description: 'Label text for a select input where users can choose an Assets object schema to use',
|
|
6
|
+
defaultMessage: 'Select schema'
|
|
7
|
+
},
|
|
8
|
+
placeholder: {
|
|
9
|
+
id: 'linkDataSource.assets.configModal.objectSchemaSelect.placeholder',
|
|
10
|
+
description: 'Placeholder text for a select input where users can choose an Assets object schema to use',
|
|
11
|
+
defaultMessage: 'Select schema'
|
|
12
|
+
},
|
|
13
|
+
schemaRequired: {
|
|
14
|
+
id: 'linkDataSource.assets.configModal.objectSchemaSelect.schemaRequired',
|
|
15
|
+
description: 'Validation message displayed to the user when the select is blank',
|
|
16
|
+
defaultMessage: 'Schema is required'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
export const FormRowContainer = styled.div`
|
|
3
|
+
align-items: center;
|
|
4
|
+
display: flex;
|
|
5
|
+
gap: ${props => props.isNarrowGap ? "var(--ds-space-100, 8px)" : "var(--ds-space-200, 16px)"};
|
|
6
|
+
flex-grow: 1;
|
|
7
|
+
width: 100%;
|
|
8
|
+
`;
|
|
9
|
+
export const FormContainer = styled.form`
|
|
10
|
+
display: grid;
|
|
11
|
+
row-gap: ${"var(--ds-space-200, 16px)"};
|
|
12
|
+
width: 100%;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
// Override the top margin of fields
|
|
16
|
+
export const FieldContainer = styled.div`
|
|
17
|
+
flex: 1;
|
|
18
|
+
margin-top: calc(-1 * ${"var(--ds-space-100, 8px)"});
|
|
19
|
+
`;
|
|
20
|
+
export const SchemaSelectContainer = styled.div`
|
|
21
|
+
width: 200px;
|
|
22
|
+
`;
|
package/dist/es2019/version.json
CHANGED
|
@@ -2,61 +2,80 @@ 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
4
|
import { useEffect, useState } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export var useAssetsClient = function useAssetsClient(hostname) {
|
|
9
|
-
var _useState = useState(),
|
|
5
|
+
import { fetchObjectSchema, getWorkspaceId } from '../services/cmdbService';
|
|
6
|
+
export var useAssetsClient = function useAssetsClient(initialParameters) {
|
|
7
|
+
var _useState = useState(false),
|
|
10
8
|
_useState2 = _slicedToArray(_useState, 2),
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
loading = _useState2[0],
|
|
10
|
+
setLoading = _useState2[1];
|
|
13
11
|
var _useState3 = useState(),
|
|
14
12
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
15
13
|
workspaceId = _useState4[0],
|
|
16
14
|
setWorkspaceId = _useState4[1];
|
|
17
15
|
var _useState5 = useState(),
|
|
18
16
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
objectSchema = _useState6[0],
|
|
18
|
+
setObjectSchema = _useState6[1];
|
|
19
|
+
var _useState7 = useState(),
|
|
20
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
21
|
+
error = _useState8[0],
|
|
22
|
+
setError = _useState8[1];
|
|
21
23
|
useEffect(function () {
|
|
22
24
|
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
23
|
-
var _workspaceId,
|
|
25
|
+
var _workspaceId, fetchedObjectSchema;
|
|
24
26
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
25
27
|
while (1) switch (_context.prev = _context.next) {
|
|
26
28
|
case 0:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
setLoading(true);
|
|
30
|
+
setError(undefined);
|
|
31
|
+
_context.prev = 2;
|
|
32
|
+
_context.next = 5;
|
|
33
|
+
return getWorkspaceId();
|
|
34
|
+
case 5:
|
|
31
35
|
_workspaceId = _context.sent;
|
|
32
|
-
_context.next = 6;
|
|
33
|
-
return fetchObjectSchemas(_workspaceId, hostname);
|
|
34
|
-
case 6:
|
|
35
|
-
objectSchemasResponse = _context.sent;
|
|
36
36
|
setWorkspaceId(_workspaceId);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
// Check schema from initial parameters still exists and fetch name for schema select
|
|
38
|
+
if (!(initialParameters !== null && initialParameters !== void 0 && initialParameters.schemaId)) {
|
|
39
|
+
_context.next = 17;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
_context.prev = 8;
|
|
43
|
+
_context.next = 11;
|
|
44
|
+
return fetchObjectSchema(_workspaceId, initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.schemaId);
|
|
40
45
|
case 11:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
fetchedObjectSchema = _context.sent;
|
|
47
|
+
setObjectSchema(fetchedObjectSchema);
|
|
48
|
+
_context.next = 17;
|
|
49
|
+
break;
|
|
50
|
+
case 15:
|
|
51
|
+
_context.prev = 15;
|
|
52
|
+
_context.t0 = _context["catch"](8);
|
|
53
|
+
case 17:
|
|
54
|
+
_context.next = 22;
|
|
55
|
+
break;
|
|
56
|
+
case 19:
|
|
57
|
+
_context.prev = 19;
|
|
58
|
+
_context.t1 = _context["catch"](2);
|
|
59
|
+
if (_context.t1 instanceof Error) {
|
|
60
|
+
setError(_context.t1);
|
|
45
61
|
} else {
|
|
46
62
|
setError(new Error('Unexpected error occured'));
|
|
47
|
-
// eslint-disable-next-line no-console
|
|
48
|
-
console.error(_context.t0);
|
|
49
63
|
}
|
|
50
|
-
case
|
|
64
|
+
case 22:
|
|
65
|
+
_context.prev = 22;
|
|
66
|
+
setLoading(false);
|
|
67
|
+
return _context.finish(22);
|
|
68
|
+
case 25:
|
|
51
69
|
case "end":
|
|
52
70
|
return _context.stop();
|
|
53
71
|
}
|
|
54
|
-
}, _callee, null, [[
|
|
72
|
+
}, _callee, null, [[2, 19, 22, 25], [8, 15]]);
|
|
55
73
|
}))();
|
|
56
|
-
}, [
|
|
74
|
+
}, [initialParameters]);
|
|
57
75
|
return {
|
|
58
76
|
workspaceId: workspaceId,
|
|
59
|
-
|
|
60
|
-
|
|
77
|
+
workspaceError: error,
|
|
78
|
+
objectSchema: objectSchema,
|
|
79
|
+
assetsClientLoading: loading
|
|
61
80
|
};
|
|
62
81
|
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
|
+
import { useCallback, useState } from 'react';
|
|
5
|
+
import { fetchObjectSchemas } from '../services/cmdbService';
|
|
6
|
+
export var useObjectSchemas = function useObjectSchemas(workspaceId) {
|
|
7
|
+
var _useState = useState(false),
|
|
8
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
9
|
+
loading = _useState2[0],
|
|
10
|
+
setLoading = _useState2[1];
|
|
11
|
+
var _useState3 = useState(),
|
|
12
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
13
|
+
objectSchemas = _useState4[0],
|
|
14
|
+
setObjectSchemas = _useState4[1];
|
|
15
|
+
var _useState5 = useState(),
|
|
16
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
17
|
+
error = _useState6[0],
|
|
18
|
+
setError = _useState6[1];
|
|
19
|
+
var request = useCallback( /*#__PURE__*/function () {
|
|
20
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
|
|
21
|
+
var fetchedObjectSchemas, fetchedObjectSchemasResponse;
|
|
22
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
23
|
+
while (1) switch (_context.prev = _context.next) {
|
|
24
|
+
case 0:
|
|
25
|
+
setLoading(true);
|
|
26
|
+
setError(undefined);
|
|
27
|
+
_context.prev = 2;
|
|
28
|
+
_context.next = 5;
|
|
29
|
+
return fetchObjectSchemas(workspaceId, query);
|
|
30
|
+
case 5:
|
|
31
|
+
fetchedObjectSchemasResponse = _context.sent;
|
|
32
|
+
setObjectSchemas(fetchedObjectSchemasResponse.values);
|
|
33
|
+
fetchedObjectSchemas = fetchedObjectSchemasResponse.values;
|
|
34
|
+
_context.next = 13;
|
|
35
|
+
break;
|
|
36
|
+
case 10:
|
|
37
|
+
_context.prev = 10;
|
|
38
|
+
_context.t0 = _context["catch"](2);
|
|
39
|
+
if (_context.t0 instanceof Error) {
|
|
40
|
+
setError(_context.t0);
|
|
41
|
+
} else {
|
|
42
|
+
setError(new Error('Unexpected error occured'));
|
|
43
|
+
}
|
|
44
|
+
case 13:
|
|
45
|
+
_context.prev = 13;
|
|
46
|
+
setLoading(false);
|
|
47
|
+
return _context.finish(13);
|
|
48
|
+
case 16:
|
|
49
|
+
return _context.abrupt("return", fetchedObjectSchemas);
|
|
50
|
+
case 17:
|
|
51
|
+
case "end":
|
|
52
|
+
return _context.stop();
|
|
53
|
+
}
|
|
54
|
+
}, _callee, null, [[2, 10, 13, 16]]);
|
|
55
|
+
}));
|
|
56
|
+
return function (_x) {
|
|
57
|
+
return _ref.apply(this, arguments);
|
|
58
|
+
};
|
|
59
|
+
}(), [workspaceId]);
|
|
60
|
+
return {
|
|
61
|
+
objectSchemasLoading: loading,
|
|
62
|
+
objectSchemasError: error,
|
|
63
|
+
objectSchemas: objectSchemas,
|
|
64
|
+
fetchObjectSchemas: request
|
|
65
|
+
};
|
|
66
|
+
};
|