@atlaskit/link-datasource 1.15.3 → 1.16.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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/analytics/constants.js +1 -1
- package/dist/cjs/hooks/useAssetsClient.js +71 -27
- package/dist/cjs/services/cmdbService.js +128 -28
- package/dist/cjs/services/cmdbService.utils.js +64 -0
- package/dist/cjs/ui/assets-modal/modal/index.js +73 -9
- package/dist/cjs/ui/assets-modal/modal/render-assets-content/index.js +25 -12
- package/dist/cjs/ui/assets-modal/search-container/index.js +2 -1
- package/dist/cjs/ui/assets-modal/search-container/object-schema-select/index.js +21 -63
- package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +14 -14
- package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +18 -3
- package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
- package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.js +22 -0
- package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +21 -4
- package/dist/es2019/analytics/constants.js +1 -1
- package/dist/es2019/hooks/useAssetsClient.js +39 -15
- package/dist/es2019/services/cmdbService.js +60 -14
- package/dist/es2019/services/cmdbService.utils.js +39 -0
- package/dist/es2019/ui/assets-modal/modal/index.js +70 -9
- package/dist/es2019/ui/assets-modal/modal/render-assets-content/index.js +24 -9
- package/dist/es2019/ui/assets-modal/search-container/index.js +2 -1
- package/dist/es2019/ui/assets-modal/search-container/object-schema-select/index.js +2 -25
- package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +2 -2
- package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +18 -3
- package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
- package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.js +17 -0
- package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +18 -3
- package/dist/esm/analytics/constants.js +1 -1
- package/dist/esm/hooks/useAssetsClient.js +72 -28
- package/dist/esm/services/cmdbService.js +128 -28
- package/dist/esm/services/cmdbService.utils.js +57 -0
- package/dist/esm/ui/assets-modal/modal/index.js +73 -9
- package/dist/esm/ui/assets-modal/modal/render-assets-content/index.js +24 -9
- package/dist/esm/ui/assets-modal/search-container/index.js +2 -1
- package/dist/esm/ui/assets-modal/search-container/object-schema-select/index.js +18 -60
- package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +14 -14
- package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +18 -3
- package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.js +5 -0
- package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.js +15 -0
- package/dist/esm/ui/jira-issues-modal/basic-filters/ui/menu-list/index.js +21 -4
- package/dist/types/hooks/useAssetsClient.d.ts +5 -1
- package/dist/types/services/cmdbService.utils.d.ts +9 -0
- package/dist/types/ui/assets-modal/modal/render-assets-content/index.d.ts +3 -2
- package/dist/types/ui/assets-modal/search-container/index.d.ts +1 -0
- package/dist/types/ui/assets-modal/search-container/object-schema-select/index.d.ts +2 -1
- package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +1 -1
- package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.d.ts +5 -0
- package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.d.ts +6 -0
- package/dist/types/ui/jira-issues-modal/basic-filters/ui/menu-list/index.d.ts +4 -1
- package/dist/types-ts4.5/hooks/useAssetsClient.d.ts +5 -1
- package/dist/types-ts4.5/services/cmdbService.utils.d.ts +9 -0
- package/dist/types-ts4.5/ui/assets-modal/modal/render-assets-content/index.d.ts +3 -2
- package/dist/types-ts4.5/ui/assets-modal/search-container/index.d.ts +1 -0
- package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/index.d.ts +2 -1
- package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +1 -1
- package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/messages.d.ts +5 -0
- package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.d.ts +6 -0
- package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/menu-list/index.d.ts +4 -1
- package/package.json +1 -1
|
@@ -18,6 +18,8 @@ import { fetchMessagesForLocale } from '../../../common/utils/locale/fetch-messa
|
|
|
18
18
|
import { useAssetsClient } from '../../../hooks/useAssetsClient';
|
|
19
19
|
import { useDatasourceTableState } from '../../../hooks/useDatasourceTableState';
|
|
20
20
|
import i18nEN from '../../../i18n/en';
|
|
21
|
+
import { PermissionError } from '../../../services/cmdbService.utils';
|
|
22
|
+
import { AccessRequired } from '../../../ui/common/error-state/access-required';
|
|
21
23
|
import { ModalLoadingError } from '../../common/error-state/modal-loading-error';
|
|
22
24
|
import { AssetsSearchContainer } from '../search-container';
|
|
23
25
|
import { AssetsSearchContainerLoading } from '../search-container/loading-state';
|
|
@@ -28,6 +30,9 @@ const modalBodyWrapperStyles = css({
|
|
|
28
30
|
height: '420px',
|
|
29
31
|
overflow: 'auto'
|
|
30
32
|
});
|
|
33
|
+
const modalBodyErrorWrapperStyles = css({
|
|
34
|
+
alignItems: 'center'
|
|
35
|
+
});
|
|
31
36
|
const AssetsModalTitle = jsx(ModalTitle, null, jsx(FormattedMessage, modalMessages.insertObjectsTitle));
|
|
32
37
|
const PlainAssetsConfigModal = props => {
|
|
33
38
|
const {
|
|
@@ -41,20 +46,53 @@ const PlainAssetsConfigModal = props => {
|
|
|
41
46
|
const [schemaId, setSchemaId] = useState(initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.schemaId);
|
|
42
47
|
const [visibleColumnKeys, setVisibleColumnKeys] = useState(initialVisibleColumnKeys);
|
|
43
48
|
const [isNewSearch, setIsNewSearch] = useState(false);
|
|
49
|
+
const [errorState, setErrorState] = useState();
|
|
44
50
|
const {
|
|
45
51
|
fireEvent
|
|
46
52
|
} = useDatasourceAnalyticsEvents();
|
|
47
53
|
const {
|
|
48
54
|
current: modalRenderInstanceId
|
|
49
55
|
} = useRef(uuidv4());
|
|
50
|
-
|
|
51
|
-
// If a workspaceError occurs this is a critical error
|
|
52
56
|
const {
|
|
53
57
|
workspaceId,
|
|
54
58
|
workspaceError,
|
|
55
|
-
|
|
59
|
+
existingObjectSchema,
|
|
60
|
+
existingObjectSchemaError,
|
|
61
|
+
objectSchemas,
|
|
62
|
+
objectSchemasError,
|
|
63
|
+
totalObjectSchemas,
|
|
56
64
|
assetsClientLoading
|
|
57
65
|
} = useAssetsClient(initialParameters);
|
|
66
|
+
|
|
67
|
+
/* ------------------------------ PERMISSIONS ------------------------------ */
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (workspaceError) {
|
|
70
|
+
// If a workspaceError occurs this is a critical error
|
|
71
|
+
if (workspaceError instanceof PermissionError) {
|
|
72
|
+
setErrorState('permission');
|
|
73
|
+
} else {
|
|
74
|
+
setErrorState('network');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, [workspaceError]);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (objectSchemasError) {
|
|
80
|
+
// We only care about permission errors for objectSchemas fetching as the user can retry this action
|
|
81
|
+
if (objectSchemasError instanceof PermissionError) {
|
|
82
|
+
setErrorState('permission');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, [objectSchemasError]);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (existingObjectSchemaError) {
|
|
88
|
+
// We only care about permission errors for existingObjectSchema fetching as the user can retry this action
|
|
89
|
+
if (existingObjectSchemaError instanceof PermissionError) {
|
|
90
|
+
setErrorState('permission');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}, [existingObjectSchemaError]);
|
|
94
|
+
/* ------------------------------ END PERMISSIONS ------------------------------ */
|
|
95
|
+
|
|
58
96
|
const parameters = useMemo(() => ({
|
|
59
97
|
aql: aql || '',
|
|
60
98
|
schemaId: schemaId || '',
|
|
@@ -90,6 +128,15 @@ const PlainAssetsConfigModal = props => {
|
|
|
90
128
|
destinationObjectTypes: destinationObjectTypes
|
|
91
129
|
};
|
|
92
130
|
}, [destinationObjectTypes, extensionKey]);
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
// We only want to send modal ready event once after we've fetched the schema count
|
|
133
|
+
if (totalObjectSchemas !== undefined) {
|
|
134
|
+
fireEvent('ui.modal.ready.datasource', {
|
|
135
|
+
schemasCount: totalObjectSchemas,
|
|
136
|
+
instancesCount: null
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}, [fireEvent, totalObjectSchemas]);
|
|
93
140
|
useEffect(() => {
|
|
94
141
|
fireEvent('screen.datasourceModalDialog.viewed', {});
|
|
95
142
|
}, [fireEvent]);
|
|
@@ -144,7 +191,7 @@ const PlainAssetsConfigModal = props => {
|
|
|
144
191
|
setVisibleColumnKeys(defaultVisibleColumnKeys);
|
|
145
192
|
}
|
|
146
193
|
}, [defaultVisibleColumnKeys, isNewSearch]);
|
|
147
|
-
const isDisabled = !!
|
|
194
|
+
const isDisabled = !!errorState || status !== 'resolved' || assetsClientLoading || !aql || !schemaId;
|
|
148
195
|
const retrieveUrlForSmartCardRender = useCallback(() => {
|
|
149
196
|
var _data$key, _data$key$data;
|
|
150
197
|
const [data] = responseItems;
|
|
@@ -232,8 +279,20 @@ const PlainAssetsConfigModal = props => {
|
|
|
232
279
|
setIsNewSearch(true);
|
|
233
280
|
}
|
|
234
281
|
}, [aql, reset, schemaId, status]);
|
|
282
|
+
const renderErrorState = useCallback(() => {
|
|
283
|
+
if (errorState) {
|
|
284
|
+
switch (errorState) {
|
|
285
|
+
case 'permission':
|
|
286
|
+
return jsx(AccessRequired, null);
|
|
287
|
+
case 'network':
|
|
288
|
+
return jsx(ModalLoadingError, null);
|
|
289
|
+
default:
|
|
290
|
+
return jsx(ModalLoadingError, null);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}, [errorState]);
|
|
235
294
|
const renderModalTitleContent = useCallback(() => {
|
|
236
|
-
if (
|
|
295
|
+
if (errorState) {
|
|
237
296
|
return undefined;
|
|
238
297
|
} else {
|
|
239
298
|
if (!workspaceId || assetsClientLoading) {
|
|
@@ -245,14 +304,15 @@ const PlainAssetsConfigModal = props => {
|
|
|
245
304
|
workspaceId: workspaceId,
|
|
246
305
|
initialSearchData: {
|
|
247
306
|
aql,
|
|
248
|
-
objectSchema
|
|
307
|
+
objectSchema: existingObjectSchema,
|
|
308
|
+
objectSchemas
|
|
249
309
|
},
|
|
250
310
|
onSearch: handleOnSearch,
|
|
251
311
|
modalTitle: AssetsModalTitle,
|
|
252
312
|
isSearching: status === 'loading'
|
|
253
313
|
});
|
|
254
314
|
}
|
|
255
|
-
}, [
|
|
315
|
+
}, [errorState, workspaceId, assetsClientLoading, aql, existingObjectSchema, objectSchemas, handleOnSearch, status]);
|
|
256
316
|
return jsx(IntlMessagesProvider, {
|
|
257
317
|
defaultMessages: i18nEN,
|
|
258
318
|
loaderFn: fetchMessagesForLocale
|
|
@@ -263,8 +323,9 @@ const PlainAssetsConfigModal = props => {
|
|
|
263
323
|
shouldScrollInViewport: true,
|
|
264
324
|
shouldCloseOnOverlayClick: false
|
|
265
325
|
}, jsx(ModalHeader, null, renderModalTitleContent()), jsx(ModalBody, null, jsx("div", {
|
|
266
|
-
css: modalBodyWrapperStyles
|
|
267
|
-
},
|
|
326
|
+
css: [modalBodyWrapperStyles, errorState && modalBodyErrorWrapperStyles]
|
|
327
|
+
}, errorState ? renderErrorState() : jsx(RenderAssetsContent, {
|
|
328
|
+
isFetchingInitialData: assetsClientLoading,
|
|
268
329
|
status: status,
|
|
269
330
|
responseItems: responseItems,
|
|
270
331
|
visibleColumnKeys: visibleColumnKeys,
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { css, jsx } from '@emotion/react';
|
|
2
4
|
import { AccessRequired } from '../../../common/error-state/access-required';
|
|
3
5
|
import { ModalLoadingError } from '../../../common/error-state/modal-loading-error';
|
|
4
6
|
import { NoResults } from '../../../common/error-state/no-results';
|
|
5
7
|
import { EmptyState, IssueLikeDataTableView } from '../../../issue-like-table';
|
|
6
8
|
import { InitialStateView } from './initial-state-view';
|
|
9
|
+
// This is to prevent y scrollbar when initially fetching data
|
|
10
|
+
const emptyStateOverrideStyles = css({
|
|
11
|
+
height: '420px',
|
|
12
|
+
overflow: 'hidden'
|
|
13
|
+
});
|
|
7
14
|
export const RenderAssetsContent = props => {
|
|
8
15
|
const {
|
|
9
16
|
status,
|
|
@@ -15,10 +22,11 @@ export const RenderAssetsContent = props => {
|
|
|
15
22
|
columns,
|
|
16
23
|
defaultVisibleColumnKeys,
|
|
17
24
|
onVisibleColumnKeysChange,
|
|
18
|
-
modalRenderInstanceId
|
|
25
|
+
modalRenderInstanceId,
|
|
26
|
+
isFetchingInitialData
|
|
19
27
|
} = props;
|
|
20
28
|
const resolvedWithNoResults = status === 'resolved' && !responseItems.length;
|
|
21
|
-
const issueLikeDataTableView = useMemo(() =>
|
|
29
|
+
const issueLikeDataTableView = useMemo(() => jsx(IssueLikeDataTableView, {
|
|
22
30
|
testId: "asset-datasource-table",
|
|
23
31
|
status: status,
|
|
24
32
|
columns: columns,
|
|
@@ -30,16 +38,23 @@ export const RenderAssetsContent = props => {
|
|
|
30
38
|
onVisibleColumnKeysChange: onVisibleColumnKeysChange,
|
|
31
39
|
parentContainerRenderInstanceId: modalRenderInstanceId
|
|
32
40
|
}), [columns, defaultVisibleColumnKeys, hasNextPage, loadDatasourceDetails, onNextPage, onVisibleColumnKeysChange, responseItems, status, visibleColumnKeys, modalRenderInstanceId]);
|
|
33
|
-
if (
|
|
34
|
-
|
|
41
|
+
if (isFetchingInitialData) {
|
|
42
|
+
// Placing this check first as it's a priority before all others
|
|
43
|
+
return jsx("div", {
|
|
44
|
+
css: emptyStateOverrideStyles
|
|
45
|
+
}, jsx(EmptyState, {
|
|
46
|
+
testId: "assets-aql-datasource-modal--loading-state"
|
|
47
|
+
}));
|
|
48
|
+
} else if (status === 'rejected') {
|
|
49
|
+
return jsx(ModalLoadingError, null);
|
|
35
50
|
} else if (status === 'unauthorized') {
|
|
36
|
-
return
|
|
51
|
+
return jsx(AccessRequired, null);
|
|
37
52
|
} else if (status === 'empty') {
|
|
38
|
-
return
|
|
53
|
+
return jsx(InitialStateView, null);
|
|
39
54
|
} else if (resolvedWithNoResults) {
|
|
40
|
-
return
|
|
55
|
+
return jsx(NoResults, null);
|
|
41
56
|
} else if (status === 'loading' && !columns.length) {
|
|
42
|
-
return
|
|
57
|
+
return jsx(EmptyState, {
|
|
43
58
|
testId: "assets-aql-datasource-modal--loading-state"
|
|
44
59
|
});
|
|
45
60
|
}
|
|
@@ -35,7 +35,7 @@ export const AssetsSearchContainer = props => {
|
|
|
35
35
|
}, ({
|
|
36
36
|
formProps
|
|
37
37
|
}) => {
|
|
38
|
-
var _initialSearchData$ob, _initialSearchData$aq;
|
|
38
|
+
var _initialSearchData$ob, _initialSearchData$ob2, _initialSearchData$aq;
|
|
39
39
|
return jsx(FormContainer, _extends({}, formProps, {
|
|
40
40
|
id: SEARCH_FORM_ID
|
|
41
41
|
}), jsx(FormRowContainer, {
|
|
@@ -43,6 +43,7 @@ export const AssetsSearchContainer = props => {
|
|
|
43
43
|
}, modalTitle, jsx(SchemaSelectContainer, null, jsx(AssetsObjectSchemaSelect, {
|
|
44
44
|
value: (_initialSearchData$ob = initialSearchData.objectSchema) !== null && _initialSearchData$ob !== void 0 ? _initialSearchData$ob : undefined,
|
|
45
45
|
workspaceId: workspaceId,
|
|
46
|
+
initialObjectSchemas: (_initialSearchData$ob2 = initialSearchData.objectSchemas) !== null && _initialSearchData$ob2 !== void 0 ? _initialSearchData$ob2 : undefined,
|
|
46
47
|
classNamePrefix: "assets-datasource-modal--object-schema-select"
|
|
47
48
|
}))), jsx(FormRowContainer, null, jsx(AqlSearchInput, {
|
|
48
49
|
value: (_initialSearchData$aq = initialSearchData.aql) !== null && _initialSearchData$aq !== void 0 ? _initialSearchData$aq : DEFAULT_AQL_QUERY,
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
/** @jsx jsx */
|
|
3
3
|
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
5
4
|
import { jsx } from '@emotion/react';
|
|
6
5
|
import debounce from 'debounce-promise';
|
|
7
6
|
import { useIntl } from 'react-intl-next';
|
|
8
7
|
import { Field } from '@atlaskit/form';
|
|
9
8
|
import { AsyncSelect } from '@atlaskit/select';
|
|
10
9
|
import { layers } from '@atlaskit/theme/constants';
|
|
11
|
-
import { useDatasourceAnalyticsEvents } from '../../../../analytics';
|
|
12
10
|
import { useObjectSchemas } from '../../../../hooks/useObjectSchemas';
|
|
13
11
|
import { objectSchemaKey } from '../../../../types/assets/types';
|
|
14
12
|
import { FieldContainer } from '../styled';
|
|
@@ -35,12 +33,9 @@ export const selectInAModalStyleFixProps = {
|
|
|
35
33
|
export const AssetsObjectSchemaSelect = ({
|
|
36
34
|
value,
|
|
37
35
|
workspaceId,
|
|
36
|
+
initialObjectSchemas,
|
|
38
37
|
classNamePrefix = 'assets-datasource-modal--object-schema-select'
|
|
39
38
|
}) => {
|
|
40
|
-
const [defaultOptions, setDefaultOptions] = useState(null);
|
|
41
|
-
const {
|
|
42
|
-
fireEvent
|
|
43
|
-
} = useDatasourceAnalyticsEvents();
|
|
44
39
|
const {
|
|
45
40
|
formatMessage
|
|
46
41
|
} = useIntl();
|
|
@@ -49,24 +44,6 @@ export const AssetsObjectSchemaSelect = ({
|
|
|
49
44
|
objectSchemasLoading
|
|
50
45
|
} = useObjectSchemas(workspaceId);
|
|
51
46
|
const selectedObjectSchema = value ? objectSchemaToSelectOption(value) : undefined;
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
const fetchInitialData = async () => {
|
|
54
|
-
const {
|
|
55
|
-
objectSchemas,
|
|
56
|
-
totalObjectSchemas
|
|
57
|
-
} = await fetchObjectSchemas('');
|
|
58
|
-
// We only want to send modal ready event once after we've fetched the schema count
|
|
59
|
-
fireEvent('ui.modal.ready.datasource', {
|
|
60
|
-
schemasCount: totalObjectSchemas !== null && totalObjectSchemas !== void 0 ? totalObjectSchemas : 0,
|
|
61
|
-
instancesCount: null
|
|
62
|
-
});
|
|
63
|
-
setDefaultOptions(mapObjectSchemasToOptions(objectSchemas));
|
|
64
|
-
};
|
|
65
|
-
if (defaultOptions === null) {
|
|
66
|
-
fetchInitialData();
|
|
67
|
-
}
|
|
68
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
69
|
-
}, []);
|
|
70
47
|
const loadOptions = async inputValue => {
|
|
71
48
|
const {
|
|
72
49
|
objectSchemas
|
|
@@ -94,7 +71,7 @@ export const AssetsObjectSchemaSelect = ({
|
|
|
94
71
|
autoFocus: true,
|
|
95
72
|
classNamePrefix: classNamePrefix,
|
|
96
73
|
isLoading: objectSchemasLoading,
|
|
97
|
-
defaultOptions:
|
|
74
|
+
defaultOptions: mapObjectSchemasToOptions(initialObjectSchemas),
|
|
98
75
|
isSearchable: true,
|
|
99
76
|
loadOptions: debouncedLoadOptions,
|
|
100
77
|
placeholder: formatMessage(objectSchemaSelectMessages.placeholder),
|
|
@@ -17,7 +17,8 @@ export const useFilterOptions = ({
|
|
|
17
17
|
pageCursor,
|
|
18
18
|
searchString
|
|
19
19
|
} = {}) => {
|
|
20
|
-
|
|
20
|
+
const isNewSearch = !pageCursor;
|
|
21
|
+
isNewSearch ? setStatus('loading') : setStatus('loadingMore');
|
|
21
22
|
const isRequestLikeInitialSearch = !pageCursor && !searchString;
|
|
22
23
|
const {
|
|
23
24
|
current: initialResponseData
|
|
@@ -34,7 +35,6 @@ export const useFilterOptions = ({
|
|
|
34
35
|
setStatus('rejected');
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
|
-
const isNewSearch = !pageCursor;
|
|
38
38
|
if (isNewSearch) {
|
|
39
39
|
setFilterOptions(mapFieldValuesToFilterOptions(response));
|
|
40
40
|
if (isRequestLikeInitialSearch) {
|
|
@@ -31,7 +31,8 @@ const AsyncPopupSelect = ({
|
|
|
31
31
|
filterOptions,
|
|
32
32
|
fetchFilterOptions,
|
|
33
33
|
totalCount,
|
|
34
|
-
status
|
|
34
|
+
status,
|
|
35
|
+
pageCursor
|
|
35
36
|
} = useFilterOptions({
|
|
36
37
|
filterType,
|
|
37
38
|
cloudId
|
|
@@ -59,6 +60,14 @@ const AsyncPopupSelect = ({
|
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
}, [fetchFilterOptions, searchTerm, status]);
|
|
63
|
+
const handleShowMore = useCallback(() => {
|
|
64
|
+
if (pageCursor) {
|
|
65
|
+
fetchFilterOptions({
|
|
66
|
+
pageCursor,
|
|
67
|
+
searchString: searchTerm
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}, [fetchFilterOptions, pageCursor, searchTerm]);
|
|
62
71
|
useEffect(() => {
|
|
63
72
|
if (status === 'resolved') {
|
|
64
73
|
var _pickerRef$current, _pickerRef$current$se, _pickerRef$current$se2;
|
|
@@ -69,8 +78,11 @@ const AsyncPopupSelect = ({
|
|
|
69
78
|
const filterOptionsLength = filterOptions.length;
|
|
70
79
|
const isError = status === 'rejected';
|
|
71
80
|
const isLoading = status === 'loading' || status === 'empty';
|
|
81
|
+
const isLoadingMore = status === 'loadingMore';
|
|
72
82
|
const isEmpty = status === 'resolved' && filterOptionsLength === 0;
|
|
73
|
-
const
|
|
83
|
+
const areAllResultsLoaded = filterOptions.length === totalCount;
|
|
84
|
+
const shouldShowFooter = (status === 'resolved' || isLoadingMore) && filterOptions.length > 0; // footer should not disappear when there is an inline spinner for loading more data
|
|
85
|
+
const shouldDisplayShowMoreButton = status === 'resolved' && !!pageCursor && !areAllResultsLoaded;
|
|
74
86
|
const options = isLoading || isError ? [] : filterOptions; // if not set to [], for eg: on loading, no loading UI will be shown
|
|
75
87
|
|
|
76
88
|
return /*#__PURE__*/React.createElement(PopupSelect, {
|
|
@@ -98,7 +110,10 @@ const AsyncPopupSelect = ({
|
|
|
98
110
|
MenuList: props => /*#__PURE__*/React.createElement(CustomMenuList, _extends({}, props, {
|
|
99
111
|
isError: isError,
|
|
100
112
|
isEmpty: isEmpty,
|
|
101
|
-
isLoading: isLoading
|
|
113
|
+
isLoading: isLoading,
|
|
114
|
+
isLoadingMore: isLoadingMore,
|
|
115
|
+
showMore: shouldDisplayShowMoreButton,
|
|
116
|
+
handleShowMore: handleShowMore
|
|
102
117
|
})),
|
|
103
118
|
DropdownIndicator: CustomDropdownIndicator,
|
|
104
119
|
LoadingIndicator: undefined,
|
|
@@ -28,5 +28,10 @@ export const asyncPopupSelectMessages = {
|
|
|
28
28
|
id: 'linkDataSource.basic-filter.assignee.label',
|
|
29
29
|
description: 'Label to be displayed for assignee filter dropdown button.',
|
|
30
30
|
defaultMessage: 'Assignee'
|
|
31
|
+
},
|
|
32
|
+
showMoreMessage: {
|
|
33
|
+
id: 'linkDataSource.basic-filter.showMoreButton',
|
|
34
|
+
defaultMessage: 'Show more',
|
|
35
|
+
description: 'The text to show more options in dropdown'
|
|
31
36
|
}
|
|
32
37
|
};
|
package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/showMoreButton.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl-next';
|
|
3
|
+
import Button from '@atlaskit/button';
|
|
4
|
+
import { asyncPopupSelectMessages } from './messages';
|
|
5
|
+
const ShowMoreButton = ({
|
|
6
|
+
onShowMore
|
|
7
|
+
}) => {
|
|
8
|
+
const {
|
|
9
|
+
formatMessage
|
|
10
|
+
} = useIntl();
|
|
11
|
+
return /*#__PURE__*/React.createElement(Button, {
|
|
12
|
+
onClick: onShowMore,
|
|
13
|
+
appearance: "link",
|
|
14
|
+
testId: "jlol-basic-filter-popup-select--show-more-button"
|
|
15
|
+
}, formatMessage(asyncPopupSelectMessages.showMoreMessage));
|
|
16
|
+
};
|
|
17
|
+
export default ShowMoreButton;
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { Flex } from '@atlaskit/primitives';
|
|
2
3
|
import { components } from '@atlaskit/select';
|
|
4
|
+
import Spinner from '@atlaskit/spinner';
|
|
5
|
+
import ShowMoreButton from '../async-popup-select/showMoreButton';
|
|
3
6
|
import CustomErrorMessage from './errorMessage';
|
|
4
7
|
import CustomDropdownLoadingMessage from './loadingMessage';
|
|
5
8
|
import CustomNoOptionsMessage from './noOptionsMessage';
|
|
6
9
|
const CustomMenuList = ({
|
|
7
10
|
isLoading,
|
|
11
|
+
isLoadingMore,
|
|
8
12
|
isError,
|
|
9
13
|
isEmpty,
|
|
14
|
+
showMore,
|
|
15
|
+
handleShowMore,
|
|
10
16
|
children,
|
|
11
17
|
...props
|
|
12
18
|
}) => {
|
|
13
|
-
const
|
|
19
|
+
const shouldDisplayShowMore = showMore && !isLoadingMore;
|
|
20
|
+
const isLoadingMoreData = !shouldDisplayShowMore && isLoadingMore;
|
|
21
|
+
const InlineSpinner = () => /*#__PURE__*/React.createElement(Flex, {
|
|
22
|
+
justifyContent: "center"
|
|
23
|
+
}, /*#__PURE__*/React.createElement(Spinner, {
|
|
24
|
+
size: "medium"
|
|
25
|
+
}));
|
|
26
|
+
const renderChildren = () => {
|
|
14
27
|
if (isLoading) {
|
|
15
28
|
return /*#__PURE__*/React.createElement(CustomDropdownLoadingMessage, null);
|
|
16
29
|
}
|
|
@@ -20,8 +33,10 @@ const CustomMenuList = ({
|
|
|
20
33
|
if (isEmpty) {
|
|
21
34
|
return /*#__PURE__*/React.createElement(CustomNoOptionsMessage, null);
|
|
22
35
|
}
|
|
23
|
-
return children
|
|
36
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, children, shouldDisplayShowMore && /*#__PURE__*/React.createElement(ShowMoreButton, {
|
|
37
|
+
onShowMore: handleShowMore
|
|
38
|
+
}), isLoadingMoreData && /*#__PURE__*/React.createElement(InlineSpinner, null));
|
|
24
39
|
};
|
|
25
|
-
return /*#__PURE__*/React.createElement(components.MenuList, props,
|
|
40
|
+
return /*#__PURE__*/React.createElement(components.MenuList, props, renderChildren());
|
|
26
41
|
};
|
|
27
42
|
export default CustomMenuList;
|
|
@@ -2,7 +2,14 @@ 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 { fetchObjectSchema, getWorkspaceId } from '../services/cmdbService';
|
|
5
|
+
import { fetchObjectSchema, fetchObjectSchemas, getWorkspaceId } from '../services/cmdbService';
|
|
6
|
+
var handleAssetsClientErrors = function handleAssetsClientErrors(errorSetter, error) {
|
|
7
|
+
if (error instanceof Error) {
|
|
8
|
+
errorSetter(error);
|
|
9
|
+
} else {
|
|
10
|
+
errorSetter(new Error('Unexpected error occured'));
|
|
11
|
+
}
|
|
12
|
+
};
|
|
6
13
|
export var useAssetsClient = function useAssetsClient(initialParameters) {
|
|
7
14
|
var _useState = useState(false),
|
|
8
15
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -14,29 +21,51 @@ export var useAssetsClient = function useAssetsClient(initialParameters) {
|
|
|
14
21
|
setWorkspaceId = _useState4[1];
|
|
15
22
|
var _useState5 = useState(),
|
|
16
23
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
workspaceError = _useState6[0],
|
|
25
|
+
setWorkspaceError = _useState6[1];
|
|
19
26
|
var _useState7 = useState(),
|
|
20
27
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
existingObjectSchema = _useState8[0],
|
|
29
|
+
setExistingObjectSchema = _useState8[1];
|
|
30
|
+
var _useState9 = useState(),
|
|
31
|
+
_useState10 = _slicedToArray(_useState9, 2),
|
|
32
|
+
existingObjectSchemaError = _useState10[0],
|
|
33
|
+
setExistingObjectSchemaError = _useState10[1];
|
|
34
|
+
var _useState11 = useState(),
|
|
35
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
36
|
+
objectSchemas = _useState12[0],
|
|
37
|
+
setObjectSchemas = _useState12[1];
|
|
38
|
+
var _useState13 = useState(),
|
|
39
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
40
|
+
totalObjectSchemas = _useState14[0],
|
|
41
|
+
setTotalObjectSchemas = _useState14[1];
|
|
42
|
+
var _useState15 = useState(),
|
|
43
|
+
_useState16 = _slicedToArray(_useState15, 2),
|
|
44
|
+
objectSchemasError = _useState16[0],
|
|
45
|
+
setObjectSchemasError = _useState16[1];
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* We wrap this in nested try/catch blocks because we want to handle
|
|
49
|
+
* workspaceError/existingObjectSchemaError/objectSchemasError differently
|
|
50
|
+
* if we need to implement more initial data fetching/errors we should look at a store
|
|
51
|
+
*/
|
|
23
52
|
useEffect(function () {
|
|
24
53
|
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
25
|
-
var _workspaceId, fetchedObjectSchema;
|
|
54
|
+
var _workspaceId, fetchedObjectSchema, fetchedObjectSchemasResponse;
|
|
26
55
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
27
56
|
while (1) switch (_context.prev = _context.next) {
|
|
28
57
|
case 0:
|
|
29
58
|
setLoading(true);
|
|
30
|
-
|
|
59
|
+
setWorkspaceError(undefined);
|
|
31
60
|
_context.prev = 2;
|
|
32
61
|
_context.next = 5;
|
|
33
62
|
return getWorkspaceId();
|
|
34
63
|
case 5:
|
|
35
64
|
_workspaceId = _context.sent;
|
|
36
65
|
setWorkspaceId(_workspaceId);
|
|
37
|
-
// Check schema from initial parameters still exists and fetch name for schema select
|
|
66
|
+
// Check schema from initial parameters still exists and fetch name/permissions for schema select
|
|
38
67
|
if (!(initialParameters !== null && initialParameters !== void 0 && initialParameters.schemaId)) {
|
|
39
|
-
_context.next =
|
|
68
|
+
_context.next = 18;
|
|
40
69
|
break;
|
|
41
70
|
}
|
|
42
71
|
_context.prev = 8;
|
|
@@ -44,38 +73,53 @@ export var useAssetsClient = function useAssetsClient(initialParameters) {
|
|
|
44
73
|
return fetchObjectSchema(_workspaceId, initialParameters === null || initialParameters === void 0 ? void 0 : initialParameters.schemaId);
|
|
45
74
|
case 11:
|
|
46
75
|
fetchedObjectSchema = _context.sent;
|
|
47
|
-
|
|
48
|
-
_context.next =
|
|
76
|
+
setExistingObjectSchema(fetchedObjectSchema);
|
|
77
|
+
_context.next = 18;
|
|
49
78
|
break;
|
|
50
79
|
case 15:
|
|
51
80
|
_context.prev = 15;
|
|
52
81
|
_context.t0 = _context["catch"](8);
|
|
53
|
-
|
|
54
|
-
|
|
82
|
+
handleAssetsClientErrors(setExistingObjectSchemaError, _context.t0);
|
|
83
|
+
case 18:
|
|
84
|
+
_context.prev = 18;
|
|
85
|
+
_context.next = 21;
|
|
86
|
+
return fetchObjectSchemas(_workspaceId);
|
|
87
|
+
case 21:
|
|
88
|
+
fetchedObjectSchemasResponse = _context.sent;
|
|
89
|
+
setObjectSchemas(fetchedObjectSchemasResponse.values);
|
|
90
|
+
setTotalObjectSchemas(fetchedObjectSchemasResponse.total);
|
|
91
|
+
_context.next = 29;
|
|
55
92
|
break;
|
|
56
|
-
case
|
|
57
|
-
_context.prev =
|
|
58
|
-
_context.t1 = _context["catch"](
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
_context.
|
|
93
|
+
case 26:
|
|
94
|
+
_context.prev = 26;
|
|
95
|
+
_context.t1 = _context["catch"](18);
|
|
96
|
+
handleAssetsClientErrors(setObjectSchemasError, _context.t1);
|
|
97
|
+
case 29:
|
|
98
|
+
_context.next = 34;
|
|
99
|
+
break;
|
|
100
|
+
case 31:
|
|
101
|
+
_context.prev = 31;
|
|
102
|
+
_context.t2 = _context["catch"](2);
|
|
103
|
+
handleAssetsClientErrors(setWorkspaceError, _context.t2);
|
|
104
|
+
case 34:
|
|
105
|
+
_context.prev = 34;
|
|
66
106
|
setLoading(false);
|
|
67
|
-
return _context.finish(
|
|
68
|
-
case
|
|
107
|
+
return _context.finish(34);
|
|
108
|
+
case 37:
|
|
69
109
|
case "end":
|
|
70
110
|
return _context.stop();
|
|
71
111
|
}
|
|
72
|
-
}, _callee, null, [[2,
|
|
112
|
+
}, _callee, null, [[2, 31, 34, 37], [8, 15], [18, 26]]);
|
|
73
113
|
}))();
|
|
74
114
|
}, [initialParameters]);
|
|
75
115
|
return {
|
|
76
116
|
workspaceId: workspaceId,
|
|
77
|
-
workspaceError:
|
|
78
|
-
|
|
117
|
+
workspaceError: workspaceError,
|
|
118
|
+
existingObjectSchema: existingObjectSchema,
|
|
119
|
+
existingObjectSchemaError: existingObjectSchemaError,
|
|
120
|
+
objectSchemas: objectSchemas,
|
|
121
|
+
totalObjectSchemas: totalObjectSchemas,
|
|
122
|
+
objectSchemasError: objectSchemasError,
|
|
79
123
|
assetsClientLoading: loading
|
|
80
124
|
};
|
|
81
125
|
};
|