@atlaskit/link-datasource 1.18.0 → 1.19.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/hooks/useDatasourceTableState.js +15 -10
  4. package/dist/cjs/hooks/useErrorLogger.js +48 -0
  5. package/dist/cjs/ui/common/error-state/messages.js +10 -0
  6. package/dist/cjs/ui/common/error-state/no-instances-svg.js +154 -0
  7. package/dist/cjs/ui/common/error-state/no-instances.js +36 -0
  8. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +1 -1
  9. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.js +28 -21
  10. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/index.js +10 -34
  11. package/dist/cjs/ui/jira-issues-modal/jira-search-container/index.js +50 -18
  12. package/dist/cjs/ui/jira-issues-modal/modal/index.js +11 -9
  13. package/dist/cjs/ui/jira-issues-modal/site-selector/index.js +3 -3
  14. package/dist/es2019/analytics/constants.js +1 -1
  15. package/dist/es2019/hooks/useDatasourceTableState.js +8 -2
  16. package/dist/es2019/hooks/useErrorLogger.js +44 -0
  17. package/dist/es2019/ui/common/error-state/messages.js +10 -0
  18. package/dist/es2019/ui/common/error-state/no-instances-svg.js +147 -0
  19. package/dist/es2019/ui/common/error-state/no-instances.js +27 -0
  20. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +1 -1
  21. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.js +17 -14
  22. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/index.js +17 -32
  23. package/dist/es2019/ui/jira-issues-modal/jira-search-container/index.js +50 -15
  24. package/dist/es2019/ui/jira-issues-modal/modal/index.js +10 -8
  25. package/dist/es2019/ui/jira-issues-modal/site-selector/index.js +3 -3
  26. package/dist/esm/analytics/constants.js +1 -1
  27. package/dist/esm/hooks/useDatasourceTableState.js +15 -10
  28. package/dist/esm/hooks/useErrorLogger.js +42 -0
  29. package/dist/esm/ui/common/error-state/messages.js +10 -0
  30. package/dist/esm/ui/common/error-state/no-instances-svg.js +147 -0
  31. package/dist/esm/ui/common/error-state/no-instances.js +29 -0
  32. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +1 -1
  33. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/trigger.js +29 -22
  34. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/index.js +10 -31
  35. package/dist/esm/ui/jira-issues-modal/jira-search-container/index.js +50 -16
  36. package/dist/esm/ui/jira-issues-modal/modal/index.js +11 -9
  37. package/dist/esm/ui/jira-issues-modal/site-selector/index.js +3 -3
  38. package/dist/types/analytics/generated/analytics.types.d.ts +9 -1
  39. package/dist/types/hooks/useErrorLogger.d.ts +4 -0
  40. package/dist/types/ui/common/error-state/messages.d.ts +10 -0
  41. package/dist/types/ui/common/error-state/no-instances-svg.d.ts +2 -0
  42. package/dist/types/ui/common/error-state/no-instances.d.ts +3 -0
  43. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  44. package/dist/types/ui/jira-issues-modal/basic-filters/ui/index.d.ts +6 -4
  45. package/dist/types/ui/jira-issues-modal/site-selector/index.d.ts +1 -1
  46. package/dist/types-ts4.5/analytics/generated/analytics.types.d.ts +9 -1
  47. package/dist/types-ts4.5/hooks/useErrorLogger.d.ts +4 -0
  48. package/dist/types-ts4.5/ui/common/error-state/messages.d.ts +10 -0
  49. package/dist/types-ts4.5/ui/common/error-state/no-instances-svg.d.ts +2 -0
  50. package/dist/types-ts4.5/ui/common/error-state/no-instances.d.ts +3 -0
  51. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  52. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/index.d.ts +6 -4
  53. package/dist/types-ts4.5/ui/jira-issues-modal/site-selector/index.d.ts +1 -1
  54. package/package.json +6 -3
@@ -1,5 +1,5 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import React, { forwardRef } from 'react';
2
+ import React, { forwardRef, useCallback } from 'react';
3
3
  import styled from '@emotion/styled';
4
4
  import { FormattedMessage } from 'react-intl-next';
5
5
  import Badge from '@atlaskit/badge';
@@ -40,33 +40,40 @@ var PopupTrigger = /*#__PURE__*/forwardRef(function (_ref, ref) {
40
40
  var _ref2 = selectedOptions || [],
41
41
  _ref3 = _slicedToArray(_ref2, 1),
42
42
  firstOption = _ref3[0];
43
- var testId = "jlol-basic-filter-".concat(filterType, "-trigger");
44
43
  var hasOptions = selectedOptions && selectedOptions.length > 0;
45
44
  var showButtonLoading = !isDisabled && isLoading;
46
- if (showButtonLoading) {
45
+ var LoadingButton = useCallback(function () {
47
46
  return /*#__PURE__*/React.createElement(LoadingStateAnimationWrapper, null, /*#__PURE__*/React.createElement(Button, {
48
47
  iconAfter: /*#__PURE__*/React.createElement(Spinner, {
49
48
  size: 'xsmall'
50
- }),
51
- testId: testId
49
+ })
52
50
  }, /*#__PURE__*/React.createElement(FormattedMessage, asyncPopupSelectMessages["".concat(filterType, "Label")])));
53
- }
54
- return /*#__PURE__*/React.createElement(Button, {
51
+ }, [filterType]);
52
+ var DefaultButton = useCallback(function () {
53
+ return /*#__PURE__*/React.createElement(Button, {
54
+ appearance: "default",
55
+ isSelected: isSelected || hasOptions,
56
+ isDisabled: isDisabled,
57
+ iconAfter: /*#__PURE__*/React.createElement(ChevronDownIcon, {
58
+ label: ""
59
+ })
60
+ }, /*#__PURE__*/React.createElement(Flex, null, /*#__PURE__*/React.createElement(Box, {
61
+ xcss: triggerButtonLabelStyles
62
+ }, /*#__PURE__*/React.createElement(FormattedMessage, asyncPopupSelectMessages["".concat(filterType, "Label")]), firstOption && /*#__PURE__*/React.createElement(React.Fragment, null, ": ", firstOption.label)), selectedOptions && selectedOptions.length > 1 && /*#__PURE__*/React.createElement(Flex, {
63
+ xcss: badgeStyles,
64
+ alignItems: "center"
65
+ }, /*#__PURE__*/React.createElement(Badge, {
66
+ appearance: "primary"
67
+ }, "+", selectedOptions.length - 1))));
68
+ }, [filterType, firstOption, hasOptions, isDisabled, isSelected, selectedOptions]);
69
+
70
+ /**
71
+ * We had an issue with the popup component referencing a stale DOM ref for the trigger button.
72
+ * Hence introducing a Box to make sure ref is always the same and only content is refreshed on re-renders
73
+ */
74
+ return /*#__PURE__*/React.createElement(Box, {
55
75
  ref: ref,
56
- appearance: "default",
57
- isSelected: isSelected || hasOptions,
58
- isDisabled: isDisabled,
59
- testId: testId,
60
- iconAfter: /*#__PURE__*/React.createElement(ChevronDownIcon, {
61
- label: ""
62
- })
63
- }, /*#__PURE__*/React.createElement(Flex, null, /*#__PURE__*/React.createElement(Box, {
64
- xcss: triggerButtonLabelStyles
65
- }, /*#__PURE__*/React.createElement(FormattedMessage, asyncPopupSelectMessages["".concat(filterType, "Label")]), firstOption && /*#__PURE__*/React.createElement(React.Fragment, null, ": ", firstOption.label)), selectedOptions && selectedOptions.length > 1 && /*#__PURE__*/React.createElement(Flex, {
66
- xcss: badgeStyles,
67
- alignItems: "center"
68
- }, /*#__PURE__*/React.createElement(Badge, {
69
- appearance: "primary"
70
- }, "+", selectedOptions.length - 1))));
76
+ testId: "jlol-basic-filter-".concat(filterType, "-trigger")
77
+ }, showButtonLoading ? /*#__PURE__*/React.createElement(LoadingButton, null) : /*#__PURE__*/React.createElement(DefaultButton, null));
71
78
  });
72
79
  export default PopupTrigger;
@@ -1,38 +1,16 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
- import React, { useCallback, useEffect, useState } from 'react';
1
+ import React from 'react';
6
2
  import { Flex, xcss } from '@atlaskit/primitives';
7
- import { isValidJql } from '../utils';
8
3
  import AsyncPopupSelect from './async-popup-select';
9
4
  var availableBasicFilterTypes = ['project', 'issuetype', 'status', 'assignee'];
10
5
  var basicFilterContainerStyles = xcss({
11
6
  paddingLeft: "var(--ds-space-100, 8px)"
12
7
  });
13
8
  var BasicFilterContainer = function BasicFilterContainer(_ref) {
14
- var jql = _ref.jql,
15
- cloudId = _ref.cloudId,
16
- onChange = _ref.onChange;
17
- var _useState = useState({}),
18
- _useState2 = _slicedToArray(_useState, 2),
19
- selection = _useState2[0],
20
- setSelection = _useState2[1];
21
- useEffect(function () {
22
- if (isValidJql(jql)) {
23
- // hydrate hook call goes in here
24
- }
25
- }, [jql]);
26
- var handleSelectionChange = useCallback(function (filterType, options) {
27
- var updatedSelection = _objectSpread(_objectSpread({}, selection), {}, _defineProperty({}, filterType, options));
28
- setSelection(updatedSelection);
29
- onChange(updatedSelection);
30
- }, [onChange, selection]);
31
- var handleReset = useCallback(function () {
32
- if (Object.keys(selection).length > 0) {
33
- setSelection({});
34
- }
35
- }, [selection]);
9
+ var cloudId = _ref.cloudId,
10
+ onChange = _ref.onChange,
11
+ selections = _ref.selections,
12
+ onReset = _ref.onReset,
13
+ isJQLHydrating = _ref.isJQLHydrating;
36
14
  return /*#__PURE__*/React.createElement(Flex, {
37
15
  xcss: basicFilterContainerStyles,
38
16
  gap: "space.100",
@@ -42,10 +20,11 @@ var BasicFilterContainer = function BasicFilterContainer(_ref) {
42
20
  cloudId: cloudId,
43
21
  filterType: filter,
44
22
  key: filter,
45
- selection: selection[filter] || [],
23
+ selection: selections[filter] || [],
24
+ isJQLHydrating: isJQLHydrating,
46
25
  isDisabled: !cloudId,
47
- onSelectionChange: handleSelectionChange,
48
- onReset: handleReset
26
+ onSelectionChange: onChange,
27
+ onReset: onReset
49
28
  });
50
29
  }));
51
30
  };
@@ -1,4 +1,7 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2
5
  /** @jsx jsx */
3
6
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
4
7
  import { css, jsx } from '@emotion/react';
@@ -8,6 +11,7 @@ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
8
11
  import { Flex, xcss } from '@atlaskit/primitives';
9
12
  import { useDatasourceAnalyticsEvents } from '../../../analytics';
10
13
  import { BasicFilters } from '../basic-filters';
14
+ import { useHydrateJqlQuery } from '../basic-filters/hooks/useHydrateJqlQuery';
11
15
  import { SEARCH_DEBOUNCE_MS } from '../basic-filters/ui/async-popup-select';
12
16
  import { isQueryTooComplex } from '../basic-filters/utils/isQueryTooComplex';
13
17
  import { BasicSearchInput } from '../basic-search-input';
@@ -65,8 +69,18 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
65
69
  setOrderDirection = _useState12[1];
66
70
  var _useState13 = useState({}),
67
71
  _useState14 = _slicedToArray(_useState13, 2),
68
- filters = _useState14[0],
69
- setFilters = _useState14[1];
72
+ filterSelections = _useState14[0],
73
+ setFilterSelections = _useState14[1];
74
+ var showBasicFilters = useMemo(function () {
75
+ if (getBooleanFF('platform.linking-platform.datasource.show-jlol-basic-filters')) {
76
+ return true;
77
+ }
78
+ return false;
79
+ }, []);
80
+ var _useHydrateJqlQuery = useHydrateJqlQuery(cloudId || '', jql),
81
+ hydratedOptions = _useHydrateJqlQuery.hydratedOptions,
82
+ fetchHydratedJqlOptions = _useHydrateJqlQuery.fetchHydratedJqlOptions,
83
+ basicFilterHydrationStatus = _useHydrateJqlQuery.status;
70
84
  var onSearchMethodChange = useCallback(function (searchMethod) {
71
85
  onSearchMethodChangeCallback(searchMethod);
72
86
  setCurrentSearchMethod(searchMethod);
@@ -76,11 +90,11 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
76
90
  setBasicSearchTerm(rawSearch);
77
91
  setJql(buildJQL({
78
92
  rawSearch: rawSearch,
79
- filterValues: filters,
93
+ filterValues: filterSelections,
80
94
  orderDirection: orderDirection,
81
95
  orderKey: orderKey
82
96
  }));
83
- }, [filters, orderDirection, orderKey]);
97
+ }, [filterSelections, orderDirection, orderKey]);
84
98
  var onQueryChange = useCallback(function (query) {
85
99
  var _query$split$map$filt, _fragments$at, _fragments$at2, _fragments$at3;
86
100
  // determine if order keys have been set so they can be saved and persisted when changes occur in basic search
@@ -102,13 +116,17 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
102
116
  onSearch({
103
117
  jql: jql
104
118
  }, currentSearchMethod);
105
- setIsComplexQuery(isQueryTooComplex(jql));
106
119
  if (currentSearchMethod === 'basic') {
107
120
  fireEvent('ui.form.submitted.basicSearch', {});
108
121
  } else if (currentSearchMethod === 'jql') {
109
122
  fireEvent('ui.jqlEditor.searched', {});
123
+ var isCurrentQueryComplex = isQueryTooComplex(jql);
124
+ setIsComplexQuery(isCurrentQueryComplex);
125
+ if (showBasicFilters && !isCurrentQueryComplex) {
126
+ fetchHydratedJqlOptions();
127
+ }
110
128
  }
111
- }, [currentSearchMethod, fireEvent, jql, onSearch]);
129
+ }, [currentSearchMethod, fetchHydratedJqlOptions, fireEvent, jql, onSearch, showBasicFilters]);
112
130
  var _useDebouncedCallback = useDebouncedCallback(function (filterValues) {
113
131
  var jqlWithFilterValues = buildJQL({
114
132
  rawSearch: basicSearchTerm,
@@ -124,21 +142,35 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
124
142
  _useDebouncedCallback2 = _slicedToArray(_useDebouncedCallback, 1),
125
143
  debouncedBasicFilterSelectionChange = _useDebouncedCallback2[0];
126
144
  var handleBasicFilterSelectionChange = useCallback(function (filterValues) {
127
- setFilters(filterValues);
145
+ setFilterSelections(filterValues);
128
146
  debouncedBasicFilterSelectionChange(filterValues);
129
147
  }, [debouncedBasicFilterSelectionChange]);
130
148
  useEffect(function () {
131
- setIsComplexQuery(isQueryTooComplex(jql));
149
+ var isCurrentQueryComplex = isQueryTooComplex(jql);
150
+ setIsComplexQuery(isCurrentQueryComplex);
151
+ if (showBasicFilters && !isCurrentQueryComplex && jql !== DEFAULT_JQL_QUERY) {
152
+ fetchHydratedJqlOptions();
153
+ }
132
154
  // eslint-disable-next-line react-hooks/exhaustive-deps
133
155
  }, []);
134
- var showBasicFilters = useMemo(function () {
135
- if (getBooleanFF('platform.linking-platform.datasource.show-jlol-basic-filters')) {
136
- return true;
156
+ useEffect(function () {
157
+ if (basicFilterHydrationStatus === 'resolved') {
158
+ setFilterSelections(hydratedOptions);
137
159
  }
138
- return false;
139
- }, []);
160
+ }, [hydratedOptions, basicFilterHydrationStatus]);
161
+ var handleSelectionChange = useCallback(function (filterType, options) {
162
+ var updatedSelection = _objectSpread(_objectSpread({}, filterSelections), {}, _defineProperty({}, filterType, options));
163
+ setFilterSelections(updatedSelection);
164
+ handleBasicFilterSelectionChange(updatedSelection);
165
+ }, [handleBasicFilterSelectionChange, filterSelections]);
166
+ var handleBasicFiltersReset = useCallback(function () {
167
+ if (Object.keys(filterSelections).length > 0) {
168
+ setFilterSelections({});
169
+ }
170
+ }, [filterSelections]);
140
171
  return jsx("div", {
141
- css: inputContainerStyles
172
+ css: inputContainerStyles,
173
+ "data-testid": "jira-search-container"
142
174
  }, currentSearchMethod === 'basic' && jsx(Flex, {
143
175
  alignItems: "center",
144
176
  xcss: basicSearchInputContainerStyles
@@ -148,9 +180,11 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
148
180
  onSearch: handleSearch,
149
181
  searchTerm: basicSearchTerm
150
182
  }), showBasicFilters && jsx(BasicFilters, {
151
- jql: jql,
152
183
  cloudId: cloudId || '',
153
- onChange: handleBasicFilterSelectionChange
184
+ onChange: handleSelectionChange,
185
+ selections: filterSelections,
186
+ onReset: handleBasicFiltersReset,
187
+ isJQLHydrating: basicFilterHydrationStatus === 'loading'
154
188
  })), currentSearchMethod === 'jql' && jsx(JiraJQLEditor, {
155
189
  cloudId: cloudId || '',
156
190
  isSearching: isSearching,
@@ -27,6 +27,7 @@ import { useDatasourceTableState } from '../../../hooks/useDatasourceTableState'
27
27
  import { getAvailableJiraSites } from '../../../services/getAvailableJiraSites';
28
28
  import { AccessRequired } from '../../common/error-state/access-required';
29
29
  import { ModalLoadingError } from '../../common/error-state/modal-loading-error';
30
+ import { NoInstancesView } from '../../common/error-state/no-instances';
30
31
  import { NoResults } from '../../common/error-state/no-results';
31
32
  import { EmptyState, IssueLikeDataTableView } from '../../issue-like-table';
32
33
  import LinkRenderType from '../../issue-like-table/render-type/link';
@@ -99,7 +100,7 @@ export var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(prop
99
100
  initialParameters = props.parameters,
100
101
  urlBeingEdited = props.url,
101
102
  initialVisibleColumnKeys = props.visibleColumnKeys;
102
- var _useState = useState([]),
103
+ var _useState = useState(undefined),
103
104
  _useState2 = _slicedToArray(_useState, 2),
104
105
  availableSites = _useState2[0],
105
106
  setAvailableSites = _useState2[1];
@@ -169,14 +170,14 @@ export var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(prop
169
170
  modalRenderInstanceId = _useRef.current;
170
171
  var selectedJiraSite = useMemo(function () {
171
172
  if (cloudId) {
172
- return availableSites.find(function (jiraSite) {
173
+ return availableSites === null || availableSites === void 0 ? void 0 : availableSites.find(function (jiraSite) {
173
174
  return jiraSite.cloudId === cloudId;
174
175
  });
175
176
  } else {
176
177
  var currentlyLoggedInSiteUrl = window.location.origin;
177
- return availableSites.find(function (jiraSite) {
178
+ return (availableSites === null || availableSites === void 0 ? void 0 : availableSites.find(function (jiraSite) {
178
179
  return jiraSite.url === currentlyLoggedInSiteUrl;
179
- }) || availableSites[0];
180
+ })) || (availableSites === null || availableSites === void 0 ? void 0 : availableSites[0]);
180
181
  }
181
182
  }, [availableSites, cloudId]);
182
183
  var analyticsPayload = useMemo(function () {
@@ -190,6 +191,7 @@ export var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(prop
190
191
  var isInsertDisabled = !isParametersSet || status === 'rejected' || status === 'unauthorized' || status === 'loading';
191
192
  var shouldShowIssueCount = !!totalCount && totalCount !== 1 && currentViewMode === 'issue';
192
193
  var isDataReady = (visibleColumnKeys || []).length > 0;
194
+ var hasNoJiraSites = availableSites && availableSites.length === 0;
193
195
  useEffect(function () {
194
196
  var shouldStartUfoExperience = status === 'loading';
195
197
  if (shouldStartUfoExperience) {
@@ -506,12 +508,12 @@ export var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(prop
506
508
  shouldScrollInViewport: true
507
509
  }, jsx(ModalHeader, null, jsx(ModalTitle, null, jsx("div", {
508
510
  css: dropdownContainerStyles
509
- }, availableSites.length < 2 ? jsx(FormattedMessage, modalMessages.insertIssuesTitle) : jsx(Fragment, null, jsx(FormattedMessage, modalMessages.insertIssuesTitleManySites), jsx(JiraSiteSelector, {
511
+ }, availableSites && availableSites.length > 1 ? jsx(Fragment, null, jsx(FormattedMessage, modalMessages.insertIssuesTitleManySites), jsx(JiraSiteSelector, {
510
512
  availableSites: availableSites,
511
513
  onSiteSelection: onSiteSelection,
512
514
  selectedJiraSite: selectedJiraSite,
513
515
  testId: "jira-jql-datasource-modal--site-selector"
514
- })))), jsx(ModeSwitcher, {
516
+ })) : jsx(FormattedMessage, modalMessages.insertIssuesTitle))), !hasNoJiraSites && jsx(ModeSwitcher, {
515
517
  isCompact: true,
516
518
  options: [{
517
519
  label: formatMessage(modalMessages.issueViewModeLabel),
@@ -522,13 +524,13 @@ export var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(prop
522
524
  }],
523
525
  onOptionValueChange: handleViewModeChange,
524
526
  selectedOptionValue: currentViewMode
525
- })), jsx(ModalBody, null, jsx(JiraSearchContainer, {
527
+ })), jsx(ModalBody, null, !hasNoJiraSites ? jsx(Fragment, null, jsx(JiraSearchContainer, {
526
528
  isSearching: status === 'loading',
527
529
  parameters: parameters,
528
530
  onSearch: onSearch,
529
531
  initialSearchMethod: initialSearchMethod,
530
532
  onSearchMethodChange: setCurrentSearchMethod
531
- }), currentViewMode === 'count' ? renderCountModeContent() : renderIssuesModeContent()), jsx(ModalFooter, null, shouldShowIssueCount && jsx("div", {
533
+ }), currentViewMode === 'count' ? renderCountModeContent() : renderIssuesModeContent()) : jsx(NoInstancesView, null)), jsx(ModalFooter, null, shouldShowIssueCount && jsx("div", {
532
534
  "data-testid": "jira-jql-datasource-modal-total-issues-count",
533
535
  css: issueCountStyles
534
536
  }, jsx(LinkUrl, {
@@ -547,7 +549,7 @@ export var PlainJiraIssuesConfigModal = function PlainJiraIssuesConfigModal(prop
547
549
  })))), jsx(Button, {
548
550
  appearance: "default",
549
551
  onClick: onCancelClick
550
- }, jsx(FormattedMessage, modalMessages.cancelButtonText)), jsx(Button, {
552
+ }, jsx(FormattedMessage, modalMessages.cancelButtonText)), !hasNoJiraSites && jsx(Button, {
551
553
  appearance: "primary",
552
554
  onClick: onInsertPressed,
553
555
  isDisabled: isInsertDisabled,
@@ -24,7 +24,7 @@ export var JiraSiteSelector = function JiraSiteSelector(props) {
24
24
  var _useIntl = useIntl(),
25
25
  formatMessage = _useIntl.formatMessage;
26
26
  var onChange = function onChange(newValue) {
27
- var selectedSite = availableSites.find(function (site) {
27
+ var selectedSite = availableSites === null || availableSites === void 0 ? void 0 : availableSites.find(function (site) {
28
28
  return site.cloudId === (newValue === null || newValue === void 0 ? void 0 : newValue.value);
29
29
  });
30
30
  if (selectedSite) {
@@ -32,7 +32,7 @@ export var JiraSiteSelector = function JiraSiteSelector(props) {
32
32
  }
33
33
  };
34
34
  var availableSitesOptions = useMemo(function () {
35
- return availableSites.map(function (site) {
35
+ return availableSites === null || availableSites === void 0 ? void 0 : availableSites.map(function (site) {
36
36
  return {
37
37
  label: site.displayName,
38
38
  value: site.cloudId
@@ -48,7 +48,7 @@ export var JiraSiteSelector = function JiraSiteSelector(props) {
48
48
  }, jsx(Select, {
49
49
  css: selectStyles,
50
50
  classNamePrefix: testId,
51
- isLoading: availableSites.length === 0,
51
+ isLoading: !availableSites,
52
52
  onChange: onChange,
53
53
  options: availableSitesOptions,
54
54
  placeholder: formatMessage(siteSelectorMessages.chooseSite),
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generates Typescript types for analytics events from analytics.spec.yaml
5
5
  *
6
- * @codegen <<SignedSource::ccda345ed2d15f3bbe167f871f676090>>
6
+ * @codegen <<SignedSource::4e6414d2c19c29a67f20beee73d4b788>>
7
7
  * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen link-datasource
8
8
  */
9
9
  export type PackageMetaDataType = {
@@ -59,6 +59,11 @@ export type DatasourceRenderSuccessAttributesType = {
59
59
  display: 'table';
60
60
  };
61
61
  export type DatasourceRenderFailureAttributesType = {};
62
+ export type DatasourceOperationFailedAttributesType = {
63
+ errorLocation: string | null;
64
+ traceId: string | null;
65
+ status: number | null;
66
+ };
62
67
  export type NextItemLoadedAttributesType = {
63
68
  destinationObjectTypes: unknown[];
64
69
  extensionKey: string | null;
@@ -155,6 +160,9 @@ export type AnalyticsEventAttributes = {
155
160
  /**
156
161
  * Fired when an inserted datasource fails to render */
157
162
  'operational.datasource.renderFailure': DatasourceRenderFailureAttributesType;
163
+ /**
164
+ * Fired when a generic operation failed */
165
+ 'operational.datasource.operationFailed': DatasourceOperationFailedAttributesType;
158
166
  /**
159
167
  * Fired when user scrolls to the next page/list of the objects */
160
168
  'track.nextItem.loaded': NextItemLoadedAttributesType;
@@ -0,0 +1,4 @@
1
+ declare const useErrorLogger: () => {
2
+ captureError: (errorLocation: string, error: unknown) => void;
3
+ };
4
+ export default useErrorLogger;
@@ -44,4 +44,14 @@ export declare const loadingErrorMessages: {
44
44
  description: string;
45
45
  defaultMessage: string;
46
46
  };
47
+ noAccessToJiraSitesTitle: {
48
+ id: string;
49
+ description: string;
50
+ defaultMessage: string;
51
+ };
52
+ noAccessToJiraSitesDescription: {
53
+ id: string;
54
+ description: string;
55
+ defaultMessage: string;
56
+ };
47
57
  };
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const NoInstancesSvg: () => JSX.Element;
@@ -0,0 +1,3 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from '@emotion/react';
3
+ export declare const NoInstancesView: () => jsx.JSX.Element;
@@ -4,10 +4,11 @@ export interface AsyncPopupSelectProps {
4
4
  filterType: BasicFilterFieldType;
5
5
  cloudId: string;
6
6
  selection: SelectOption[];
7
+ isJQLHydrating: boolean;
7
8
  onSelectionChange?: (filterType: BasicFilterFieldType, options: SelectOption[]) => void;
8
9
  onReset?: () => void;
9
10
  isDisabled?: boolean;
10
11
  }
11
12
  export declare const SEARCH_DEBOUNCE_MS = 350;
12
- declare const AsyncPopupSelect: ({ filterType, cloudId, selection, onSelectionChange, onReset: resetSelection, isDisabled, }: AsyncPopupSelectProps) => JSX.Element;
13
+ declare const AsyncPopupSelect: ({ filterType, cloudId, selection, isJQLHydrating, onSelectionChange, onReset: resetSelection, isDisabled, }: AsyncPopupSelectProps) => JSX.Element;
13
14
  export default AsyncPopupSelect;
@@ -1,9 +1,11 @@
1
1
  /// <reference types="react" />
2
- import type { SelectedOptionsMap } from '../types';
2
+ import type { BasicFilterFieldType, SelectedOptionsMap, SelectOption } from '../types';
3
3
  export interface BasicFilterContainerProps {
4
- jql: string;
5
4
  cloudId: string;
6
- onChange: (selection: SelectedOptionsMap) => void;
5
+ selections: SelectedOptionsMap;
6
+ onChange: (filterType: BasicFilterFieldType, options: SelectOption[]) => void;
7
+ onReset: () => void;
8
+ isJQLHydrating: boolean;
7
9
  }
8
- declare const BasicFilterContainer: ({ jql, cloudId, onChange, }: BasicFilterContainerProps) => JSX.Element;
10
+ declare const BasicFilterContainer: ({ cloudId, onChange, selections, onReset, isJQLHydrating, }: BasicFilterContainerProps) => JSX.Element;
9
11
  export default BasicFilterContainer;
@@ -1,7 +1,7 @@
1
1
  import { jsx } from '@emotion/react';
2
2
  import { Site } from '../../../services/getAvailableJiraSites';
3
3
  export interface JiraSiteSelectorProps {
4
- availableSites: Site[];
4
+ availableSites: Site[] | undefined;
5
5
  onSiteSelection: (selectedSite: Site) => void;
6
6
  selectedJiraSite?: Site;
7
7
  testId?: string;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generates Typescript types for analytics events from analytics.spec.yaml
5
5
  *
6
- * @codegen <<SignedSource::ccda345ed2d15f3bbe167f871f676090>>
6
+ * @codegen <<SignedSource::4e6414d2c19c29a67f20beee73d4b788>>
7
7
  * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen link-datasource
8
8
  */
9
9
  export type PackageMetaDataType = {
@@ -59,6 +59,11 @@ export type DatasourceRenderSuccessAttributesType = {
59
59
  display: 'table';
60
60
  };
61
61
  export type DatasourceRenderFailureAttributesType = {};
62
+ export type DatasourceOperationFailedAttributesType = {
63
+ errorLocation: string | null;
64
+ traceId: string | null;
65
+ status: number | null;
66
+ };
62
67
  export type NextItemLoadedAttributesType = {
63
68
  destinationObjectTypes: unknown[];
64
69
  extensionKey: string | null;
@@ -155,6 +160,9 @@ export type AnalyticsEventAttributes = {
155
160
  /**
156
161
  * Fired when an inserted datasource fails to render */
157
162
  'operational.datasource.renderFailure': DatasourceRenderFailureAttributesType;
163
+ /**
164
+ * Fired when a generic operation failed */
165
+ 'operational.datasource.operationFailed': DatasourceOperationFailedAttributesType;
158
166
  /**
159
167
  * Fired when user scrolls to the next page/list of the objects */
160
168
  'track.nextItem.loaded': NextItemLoadedAttributesType;
@@ -0,0 +1,4 @@
1
+ declare const useErrorLogger: () => {
2
+ captureError: (errorLocation: string, error: unknown) => void;
3
+ };
4
+ export default useErrorLogger;
@@ -44,4 +44,14 @@ export declare const loadingErrorMessages: {
44
44
  description: string;
45
45
  defaultMessage: string;
46
46
  };
47
+ noAccessToJiraSitesTitle: {
48
+ id: string;
49
+ description: string;
50
+ defaultMessage: string;
51
+ };
52
+ noAccessToJiraSitesDescription: {
53
+ id: string;
54
+ description: string;
55
+ defaultMessage: string;
56
+ };
47
57
  };
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const NoInstancesSvg: () => JSX.Element;
@@ -0,0 +1,3 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from '@emotion/react';
3
+ export declare const NoInstancesView: () => jsx.JSX.Element;
@@ -4,10 +4,11 @@ export interface AsyncPopupSelectProps {
4
4
  filterType: BasicFilterFieldType;
5
5
  cloudId: string;
6
6
  selection: SelectOption[];
7
+ isJQLHydrating: boolean;
7
8
  onSelectionChange?: (filterType: BasicFilterFieldType, options: SelectOption[]) => void;
8
9
  onReset?: () => void;
9
10
  isDisabled?: boolean;
10
11
  }
11
12
  export declare const SEARCH_DEBOUNCE_MS = 350;
12
- declare const AsyncPopupSelect: ({ filterType, cloudId, selection, onSelectionChange, onReset: resetSelection, isDisabled, }: AsyncPopupSelectProps) => JSX.Element;
13
+ declare const AsyncPopupSelect: ({ filterType, cloudId, selection, isJQLHydrating, onSelectionChange, onReset: resetSelection, isDisabled, }: AsyncPopupSelectProps) => JSX.Element;
13
14
  export default AsyncPopupSelect;
@@ -1,9 +1,11 @@
1
1
  /// <reference types="react" />
2
- import type { SelectedOptionsMap } from '../types';
2
+ import type { BasicFilterFieldType, SelectedOptionsMap, SelectOption } from '../types';
3
3
  export interface BasicFilterContainerProps {
4
- jql: string;
5
4
  cloudId: string;
6
- onChange: (selection: SelectedOptionsMap) => void;
5
+ selections: SelectedOptionsMap;
6
+ onChange: (filterType: BasicFilterFieldType, options: SelectOption[]) => void;
7
+ onReset: () => void;
8
+ isJQLHydrating: boolean;
7
9
  }
8
- declare const BasicFilterContainer: ({ jql, cloudId, onChange, }: BasicFilterContainerProps) => JSX.Element;
10
+ declare const BasicFilterContainer: ({ cloudId, onChange, selections, onReset, isJQLHydrating, }: BasicFilterContainerProps) => JSX.Element;
9
11
  export default BasicFilterContainer;
@@ -1,7 +1,7 @@
1
1
  import { jsx } from '@emotion/react';
2
2
  import { Site } from '../../../services/getAvailableJiraSites';
3
3
  export interface JiraSiteSelectorProps {
4
- availableSites: Site[];
4
+ availableSites: Site[] | undefined;
5
5
  onSiteSelection: (selectedSite: Site) => void;
6
6
  selectedJiraSite?: Site;
7
7
  testId?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "UI Components to support linking platform dataset feature",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -46,7 +46,7 @@
46
46
  "@atlaskit/jql-ast": "^3.0.0",
47
47
  "@atlaskit/jql-editor-autocomplete-rest": "^2.0.0",
48
48
  "@atlaskit/link-client-extension": "^1.8.0",
49
- "@atlaskit/linking-common": "^4.18.0",
49
+ "@atlaskit/linking-common": "^4.19.0",
50
50
  "@atlaskit/linking-types": "^8.5.0",
51
51
  "@atlaskit/lozenge": "^11.4.0",
52
52
  "@atlaskit/modal-dialog": "^12.8.0",
@@ -55,7 +55,7 @@
55
55
  "@atlaskit/pragmatic-drag-and-drop-hitbox": "^0.12.0",
56
56
  "@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll": "^0.6.0",
57
57
  "@atlaskit/pragmatic-drag-and-drop-react-indicator": "^0.17.0",
58
- "@atlaskit/primitives": "^1.11.0",
58
+ "@atlaskit/primitives": "^1.12.0",
59
59
  "@atlaskit/select": "^17.0.0",
60
60
  "@atlaskit/smart-card": "^26.42.0",
61
61
  "@atlaskit/spinner": "^16.0.0",
@@ -138,6 +138,9 @@
138
138
  "platform-feature-flags": {
139
139
  "platform.linking-platform.datasource.show-jlol-basic-filters": {
140
140
  "type": "boolean"
141
+ },
142
+ "platform.linking-platform.datasources.enable-sentry-client": {
143
+ "type": "boolean"
141
144
  }
142
145
  }
143
146
  }