@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.
Files changed (98) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/hooks/useAssetsClient.js +50 -31
  3. package/dist/cjs/hooks/useObjectSchemas.js +74 -0
  4. package/dist/cjs/hooks/useValidateAqlText.js +42 -13
  5. package/dist/cjs/index.js +7 -1
  6. package/dist/cjs/services/cmdbService.js +17 -8
  7. package/dist/cjs/types/assets/types.js +7 -1
  8. package/dist/cjs/ui/assets-modal/modal/index.js +46 -10
  9. package/dist/cjs/ui/assets-modal/modal/messages.js +5 -0
  10. package/dist/cjs/ui/assets-modal/modal/styled.js +1 -1
  11. package/dist/cjs/ui/assets-modal/search-container/aql-search-input/index.js +161 -0
  12. package/dist/cjs/ui/assets-modal/search-container/aql-search-input/loading-state.js +18 -0
  13. package/dist/cjs/ui/assets-modal/search-container/aql-search-input/messages.js +15 -0
  14. package/dist/cjs/ui/assets-modal/search-container/index.js +50 -0
  15. package/dist/cjs/ui/assets-modal/search-container/loading-state.js +21 -0
  16. package/dist/cjs/ui/assets-modal/search-container/object-schema-select/index.js +103 -0
  17. package/dist/cjs/ui/assets-modal/search-container/object-schema-select/loading-state.js +18 -0
  18. package/dist/cjs/ui/assets-modal/search-container/object-schema-select/messages.js +25 -0
  19. package/dist/cjs/ui/assets-modal/search-container/object-schema-select/utils.js +13 -0
  20. package/dist/cjs/ui/assets-modal/search-container/styled.js +22 -0
  21. package/dist/cjs/version.json +1 -1
  22. package/dist/es2019/hooks/useAssetsClient.js +22 -13
  23. package/dist/es2019/hooks/useObjectSchemas.js +32 -0
  24. package/dist/es2019/hooks/useValidateAqlText.js +26 -9
  25. package/dist/es2019/index.js +1 -0
  26. package/dist/es2019/services/cmdbService.js +14 -6
  27. package/dist/es2019/types/assets/types.js +3 -1
  28. package/dist/es2019/ui/assets-modal/modal/index.js +42 -8
  29. package/dist/es2019/ui/assets-modal/modal/messages.js +5 -0
  30. package/dist/es2019/ui/assets-modal/modal/styled.js +3 -3
  31. package/dist/es2019/ui/assets-modal/search-container/aql-search-input/index.js +129 -0
  32. package/dist/es2019/ui/assets-modal/search-container/aql-search-input/loading-state.js +8 -0
  33. package/dist/es2019/ui/assets-modal/search-container/aql-search-input/messages.js +8 -0
  34. package/dist/es2019/ui/assets-modal/search-container/index.js +46 -0
  35. package/dist/es2019/ui/assets-modal/search-container/loading-state.js +14 -0
  36. package/dist/es2019/ui/assets-modal/search-container/object-schema-select/index.js +65 -0
  37. package/dist/es2019/ui/assets-modal/search-container/object-schema-select/loading-state.js +8 -0
  38. package/dist/es2019/ui/assets-modal/search-container/object-schema-select/messages.js +18 -0
  39. package/dist/es2019/ui/assets-modal/search-container/object-schema-select/utils.js +4 -0
  40. package/dist/es2019/ui/assets-modal/search-container/styled.js +22 -0
  41. package/dist/es2019/version.json +1 -1
  42. package/dist/esm/hooks/useAssetsClient.js +51 -32
  43. package/dist/esm/hooks/useObjectSchemas.js +66 -0
  44. package/dist/esm/hooks/useValidateAqlText.js +42 -13
  45. package/dist/esm/index.js +1 -0
  46. package/dist/esm/services/cmdbService.js +15 -7
  47. package/dist/esm/types/assets/types.js +3 -1
  48. package/dist/esm/ui/assets-modal/modal/index.js +46 -10
  49. package/dist/esm/ui/assets-modal/modal/messages.js +5 -0
  50. package/dist/esm/ui/assets-modal/modal/styled.js +1 -1
  51. package/dist/esm/ui/assets-modal/search-container/aql-search-input/index.js +152 -0
  52. package/dist/esm/ui/assets-modal/search-container/aql-search-input/loading-state.js +10 -0
  53. package/dist/esm/ui/assets-modal/search-container/aql-search-input/messages.js +8 -0
  54. package/dist/esm/ui/assets-modal/search-container/index.js +41 -0
  55. package/dist/esm/ui/assets-modal/search-container/loading-state.js +13 -0
  56. package/dist/esm/ui/assets-modal/search-container/object-schema-select/index.js +94 -0
  57. package/dist/esm/ui/assets-modal/search-container/object-schema-select/loading-state.js +10 -0
  58. package/dist/esm/ui/assets-modal/search-container/object-schema-select/messages.js +18 -0
  59. package/dist/esm/ui/assets-modal/search-container/object-schema-select/utils.js +6 -0
  60. package/dist/esm/ui/assets-modal/search-container/styled.js +11 -0
  61. package/dist/esm/version.json +1 -1
  62. package/dist/types/hooks/useAssetsClient.d.ts +8 -6
  63. package/dist/types/hooks/useObjectSchemas.d.ts +8 -0
  64. package/dist/types/hooks/useValidateAqlText.d.ts +5 -2
  65. package/dist/types/index.d.ts +1 -0
  66. package/dist/types/services/cmdbService.d.ts +4 -3
  67. package/dist/types/types/assets/types.d.ts +21 -10
  68. package/dist/types/ui/assets-modal/modal/messages.d.ts +5 -0
  69. package/dist/types/ui/assets-modal/search-container/aql-search-input/index.d.ts +8 -0
  70. package/dist/types/ui/assets-modal/search-container/aql-search-input/loading-state.d.ts +3 -0
  71. package/dist/types/ui/assets-modal/search-container/aql-search-input/messages.d.ts +7 -0
  72. package/dist/types/ui/assets-modal/search-container/index.d.ts +16 -0
  73. package/dist/types/ui/assets-modal/search-container/loading-state.d.ts +8 -0
  74. package/dist/types/ui/assets-modal/search-container/object-schema-select/index.d.ts +10 -0
  75. package/dist/types/ui/assets-modal/search-container/object-schema-select/loading-state.d.ts +3 -0
  76. package/dist/types/ui/assets-modal/search-container/object-schema-select/messages.d.ts +17 -0
  77. package/dist/types/ui/assets-modal/search-container/object-schema-select/utils.d.ts +2 -0
  78. package/dist/types/ui/assets-modal/search-container/styled.d.ts +19 -0
  79. package/dist/types-ts4.5/hooks/useAssetsClient.d.ts +8 -6
  80. package/dist/types-ts4.5/hooks/useObjectSchemas.d.ts +8 -0
  81. package/dist/types-ts4.5/hooks/useValidateAqlText.d.ts +5 -2
  82. package/dist/types-ts4.5/index.d.ts +1 -0
  83. package/dist/types-ts4.5/services/cmdbService.d.ts +4 -3
  84. package/dist/types-ts4.5/types/assets/types.d.ts +21 -10
  85. package/dist/types-ts4.5/ui/assets-modal/modal/messages.d.ts +5 -0
  86. package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/index.d.ts +8 -0
  87. package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/loading-state.d.ts +3 -0
  88. package/dist/types-ts4.5/ui/assets-modal/search-container/aql-search-input/messages.d.ts +7 -0
  89. package/dist/types-ts4.5/ui/assets-modal/search-container/index.d.ts +16 -0
  90. package/dist/types-ts4.5/ui/assets-modal/search-container/loading-state.d.ts +8 -0
  91. package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/index.d.ts +10 -0
  92. package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/loading-state.d.ts +3 -0
  93. package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/messages.d.ts +17 -0
  94. package/dist/types-ts4.5/ui/assets-modal/search-container/object-schema-select/utils.d.ts +2 -0
  95. package/dist/types-ts4.5/ui/assets-modal/search-container/styled.d.ts +19 -0
  96. package/package.json +4 -2
  97. package/report.api.md +7 -5
  98. 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
- } = useAssetsClient();
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: '' /* TODO FLY-1240: Add workspace Id */
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' || !aql || !workspaceId || !schemaId;
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, jsx(ModalTitle, null)), jsx(ModalBody, null, jsx(ModalContentContainer, null, jsx(RenderAssetsContent, {
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
  });
@@ -1,6 +1,6 @@
1
1
  import styled from '@emotion/styled';
2
2
  export const ModalContentContainer = styled.div`
3
- display: 'grid';
4
- height: '420px';
5
- overflow: 'auto';
3
+ display: grid;
4
+ height: 420px;
5
+ overflow: auto;
6
6
  `;
@@ -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,4 @@
1
+ export const objectSchemaToSelectOption = objectSchema => ({
2
+ label: objectSchema.name,
3
+ value: objectSchema.id
4
+ });
@@ -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
+ `;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "0.29.3",
3
+ "version": "0.29.5",
4
4
  "sideEffects": false
5
5
  }
@@ -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 { fetchObjectSchemas, getWorkspaceId } from '../services/cmdbService';
6
- // TODO: Pass in localhost:3000 for testing locally - remember to remove this code after
7
- // You must also have a proxy server running to forward requests from http://localhost:3000 to a JSM premium url
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
- objectSchemas = _useState2[0],
12
- setObjectSchemas = _useState2[1];
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
- error = _useState6[0],
20
- setError = _useState6[1];
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, objectSchemasResponse;
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
- _context.prev = 0;
28
- _context.next = 3;
29
- return getWorkspaceId(hostname);
30
- case 3:
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
- setObjectSchemas(objectSchemasResponse.values);
38
- _context.next = 14;
39
- break;
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
- _context.prev = 11;
42
- _context.t0 = _context["catch"](0);
43
- if (_context.t0 instanceof Error) {
44
- setError(_context.t0);
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 14:
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, [[0, 11]]);
72
+ }, _callee, null, [[2, 19, 22, 25], [8, 15]]);
55
73
  }))();
56
- }, [hostname]);
74
+ }, [initialParameters]);
57
75
  return {
58
76
  workspaceId: workspaceId,
59
- objectSchemas: objectSchemas,
60
- error: error
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
+ };