@atlaskit/link-datasource 1.17.12 → 1.18.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 (31) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +7 -3
  4. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/index.js +7 -7
  5. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/transformers.js +3 -1
  6. package/dist/cjs/ui/jira-issues-modal/jira-search-container/index.js +34 -8
  7. package/dist/es2019/analytics/constants.js +1 -1
  8. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +7 -3
  9. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/index.js +7 -5
  10. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/transformers.js +3 -1
  11. package/dist/es2019/ui/jira-issues-modal/jira-search-container/index.js +30 -9
  12. package/dist/esm/analytics/constants.js +1 -1
  13. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +7 -3
  14. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/index.js +7 -7
  15. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/transformers.js +3 -1
  16. package/dist/esm/ui/jira-issues-modal/jira-search-container/index.js +34 -8
  17. package/dist/types/analytics/generated/analytics.types.d.ts +8 -1
  18. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useHydrateJqlQuery.d.ts +2 -4
  19. package/dist/types/ui/jira-issues-modal/basic-filters/types.d.ts +3 -0
  20. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +1 -1
  21. package/dist/types/ui/jira-issues-modal/basic-filters/ui/index.d.ts +3 -1
  22. package/dist/types/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +2 -7
  23. package/dist/types/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +2 -4
  24. package/dist/types-ts4.5/analytics/generated/analytics.types.d.ts +8 -1
  25. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useHydrateJqlQuery.d.ts +2 -4
  26. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/types.d.ts +3 -0
  27. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +1 -1
  28. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/index.d.ts +3 -1
  29. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +2 -7
  30. package/dist/types-ts4.5/ui/jira-issues-modal/jira-search-container/buildJQL.d.ts +2 -4
  31. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/link-datasource
2
2
 
3
+ ## 1.18.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#43374](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/43374) [`0d93cf12d25`](https://bitbucket.org/atlassian/atlassian-frontend/commits/0d93cf12d25) - Selecting and unselecting filters causes search to occur and datasource table to refresh
8
+
9
+ ### Patch Changes
10
+
11
+ - [#43417](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/43417) [`3f3c17f0273`](https://bitbucket.org/atlassian/atlassian-frontend/commits/3f3c17f0273) - ED-20971 Upgrade adf-schema package to ^34.0.0
12
+
13
+ ## 1.17.13
14
+
15
+ ### Patch Changes
16
+
17
+ - [#43512](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/43512) [`b84de957bd4`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b84de957bd4) - Add analytics event when basic filter dropdown show more button is clicked.
18
+
3
19
  ## 1.17.12
4
20
 
5
21
  ### Patch Changes
@@ -7,5 +7,5 @@ exports.packageMetaData = exports.EVENT_CHANNEL = void 0;
7
7
  var EVENT_CHANNEL = exports.EVENT_CHANNEL = 'media';
8
8
  var packageMetaData = exports.packageMetaData = {
9
9
  packageName: "@atlaskit/link-datasource",
10
- packageVersion: "1.17.12"
10
+ packageVersion: "1.18.0"
11
11
  };
@@ -101,8 +101,8 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
101
101
  };
102
102
  }(), [handleDebouncedFetchFilterOptions, searchTerm]);
103
103
  var handleOptionSelection = (0, _react.useCallback)(function (newValue) {
104
- onSelectionChange(newValue);
105
- }, [onSelectionChange]);
104
+ onSelectionChange(filterType, newValue);
105
+ }, [filterType, onSelectionChange]);
106
106
  var sortOptionsOnPopupOpen = (0, _react.useCallback)(function () {
107
107
  if (selectedOptions.length === 0) {
108
108
  return setSortedOptions(filterOptions);
@@ -152,8 +152,12 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
152
152
  pageCursor: pageCursor,
153
153
  searchString: searchTerm
154
154
  });
155
+ fireEvent('ui.button.clicked.basicSearchDropdown', {
156
+ filterType: filterType,
157
+ type: 'showMore'
158
+ });
155
159
  }
156
- }, [fetchFilterOptions, pageCursor, searchTerm]);
160
+ }, [fetchFilterOptions, filterType, fireEvent, pageCursor, searchTerm]);
157
161
  var handleMenuOpen = (0, _react.useCallback)(function () {
158
162
  if (status === 'empty' || status === 'rejected') {
159
163
  // if user searches and gets status as rejected, we want the dropdown to try load the request with searchString when the user reopens the dropdown
@@ -22,7 +22,8 @@ var basicFilterContainerStyles = (0, _primitives.xcss)({
22
22
  });
23
23
  var BasicFilterContainer = function BasicFilterContainer(_ref) {
24
24
  var jql = _ref.jql,
25
- cloudId = _ref.cloudId;
25
+ cloudId = _ref.cloudId,
26
+ onChange = _ref.onChange;
26
27
  var _useState = (0, _react.useState)({}),
27
28
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
28
29
  selection = _useState2[0],
@@ -32,10 +33,11 @@ var BasicFilterContainer = function BasicFilterContainer(_ref) {
32
33
  // hydrate hook call goes in here
33
34
  }
34
35
  }, [jql]);
35
- var handleSelectionChange = (0, _react.useCallback)(function (options, filter) {
36
- var updatedSelection = _objectSpread(_objectSpread({}, selection), {}, (0, _defineProperty2.default)({}, filter, options));
36
+ var handleSelectionChange = (0, _react.useCallback)(function (filterType, options) {
37
+ var updatedSelection = _objectSpread(_objectSpread({}, selection), {}, (0, _defineProperty2.default)({}, filterType, options));
37
38
  setSelection(updatedSelection);
38
- }, [selection]);
39
+ onChange(updatedSelection);
40
+ }, [onChange, selection]);
39
41
  var handleReset = (0, _react.useCallback)(function () {
40
42
  if (Object.keys(selection).length > 0) {
41
43
  setSelection({});
@@ -52,9 +54,7 @@ var BasicFilterContainer = function BasicFilterContainer(_ref) {
52
54
  key: filter,
53
55
  selection: selection[filter] || [],
54
56
  isDisabled: !cloudId,
55
- onSelectionChange: function onSelectionChange(options) {
56
- return handleSelectionChange(options, filter);
57
- },
57
+ onSelectionChange: handleSelectionChange,
58
58
  onReset: handleReset
59
59
  });
60
60
  }));
@@ -34,7 +34,9 @@ function mapNodeToOption(_ref) {
34
34
  try {
35
35
  var baseProps = {
36
36
  label: displayName,
37
- value: jqlTerm
37
+ // this ensures that the returned value is not wrapped in single and double quotes
38
+ // e.g. '"value"' -> 'value'
39
+ value: decodeURIComponent(jqlTerm).replace(/^"|"$/g, '')
38
40
  };
39
41
  if (user) {
40
42
  return _objectSpread(_objectSpread({}, baseProps), {}, {
@@ -10,10 +10,12 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
  var _react2 = require("@emotion/react");
12
12
  var _reactIntlNext = require("react-intl-next");
13
+ var _useDebounce = require("use-debounce");
13
14
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
15
  var _primitives = require("@atlaskit/primitives");
15
16
  var _analytics = require("../../../analytics");
16
17
  var _basicFilters = require("../basic-filters");
18
+ var _asyncPopupSelect = require("../basic-filters/ui/async-popup-select");
17
19
  var _isQueryTooComplex = require("../basic-filters/utils/isQueryTooComplex");
18
20
  var _basicSearchInput = require("../basic-search-input");
19
21
  var _jqlEditor = require("../jql-editor");
@@ -46,6 +48,8 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
46
48
  initialJql = _ref.jql;
47
49
  var _useIntl = (0, _reactIntlNext.useIntl)(),
48
50
  formatMessage = _useIntl.formatMessage;
51
+ var _useDatasourceAnalyti = (0, _analytics.useDatasourceAnalyticsEvents)(),
52
+ fireEvent = _useDatasourceAnalyti.fireEvent;
49
53
  var _useState = (0, _react.useState)(''),
50
54
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
51
55
  basicSearchTerm = _useState2[0],
@@ -70,8 +74,10 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
70
74
  _useState12 = (0, _slicedToArray2.default)(_useState11, 2),
71
75
  orderDirection = _useState12[0],
72
76
  setOrderDirection = _useState12[1];
73
- var _useDatasourceAnalyti = (0, _analytics.useDatasourceAnalyticsEvents)(),
74
- fireEvent = _useDatasourceAnalyti.fireEvent;
77
+ var _useState13 = (0, _react.useState)({}),
78
+ _useState14 = (0, _slicedToArray2.default)(_useState13, 2),
79
+ filters = _useState14[0],
80
+ setFilters = _useState14[1];
75
81
  var onSearchMethodChange = (0, _react.useCallback)(function (searchMethod) {
76
82
  onSearchMethodChangeCallback(searchMethod);
77
83
  setCurrentSearchMethod(searchMethod);
@@ -81,10 +87,11 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
81
87
  setBasicSearchTerm(rawSearch);
82
88
  setJql((0, _buildJQL.buildJQL)({
83
89
  rawSearch: rawSearch,
90
+ filterValues: filters,
84
91
  orderDirection: orderDirection,
85
92
  orderKey: orderKey
86
93
  }));
87
- }, [orderDirection, orderKey]);
94
+ }, [filters, orderDirection, orderKey]);
88
95
  var onQueryChange = (0, _react.useCallback)(function (query) {
89
96
  var _query$split$map$filt, _fragments$at, _fragments$at2, _fragments$at3;
90
97
  // determine if order keys have been set so they can be saved and persisted when changes occur in basic search
@@ -113,16 +120,34 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
113
120
  fireEvent('ui.jqlEditor.searched', {});
114
121
  }
115
122
  }, [currentSearchMethod, fireEvent, jql, onSearch]);
123
+ var _useDebouncedCallback = (0, _useDebounce.useDebouncedCallback)(function (filterValues) {
124
+ var jqlWithFilterValues = (0, _buildJQL.buildJQL)({
125
+ rawSearch: basicSearchTerm,
126
+ filterValues: filterValues,
127
+ orderDirection: orderDirection,
128
+ orderKey: orderKey
129
+ });
130
+ setJql(jqlWithFilterValues);
131
+ onSearch({
132
+ jql: jqlWithFilterValues
133
+ }, currentSearchMethod);
134
+ }, _asyncPopupSelect.SEARCH_DEBOUNCE_MS),
135
+ _useDebouncedCallback2 = (0, _slicedToArray2.default)(_useDebouncedCallback, 1),
136
+ debouncedBasicFilterSelectionChange = _useDebouncedCallback2[0];
137
+ var handleBasicFilterSelectionChange = (0, _react.useCallback)(function (filterValues) {
138
+ setFilters(filterValues);
139
+ debouncedBasicFilterSelectionChange(filterValues);
140
+ }, [debouncedBasicFilterSelectionChange]);
141
+ (0, _react.useEffect)(function () {
142
+ setIsComplexQuery((0, _isQueryTooComplex.isQueryTooComplex)(jql));
143
+ // eslint-disable-next-line react-hooks/exhaustive-deps
144
+ }, []);
116
145
  var showBasicFilters = (0, _react.useMemo)(function () {
117
146
  if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.datasource.show-jlol-basic-filters')) {
118
147
  return true;
119
148
  }
120
149
  return false;
121
150
  }, []);
122
- (0, _react.useEffect)(function () {
123
- setIsComplexQuery((0, _isQueryTooComplex.isQueryTooComplex)(jql));
124
- // eslint-disable-next-line react-hooks/exhaustive-deps
125
- }, []);
126
151
  return (0, _react2.jsx)("div", {
127
152
  css: inputContainerStyles
128
153
  }, currentSearchMethod === 'basic' && (0, _react2.jsx)(_primitives.Flex, {
@@ -135,7 +160,8 @@ var JiraSearchContainer = exports.JiraSearchContainer = function JiraSearchConta
135
160
  searchTerm: basicSearchTerm
136
161
  }), showBasicFilters && (0, _react2.jsx)(_basicFilters.BasicFilters, {
137
162
  jql: jql,
138
- cloudId: cloudId || ''
163
+ cloudId: cloudId || '',
164
+ onChange: handleBasicFilterSelectionChange
139
165
  })), currentSearchMethod === 'jql' && (0, _react2.jsx)(_jqlEditor.JiraJQLEditor, {
140
166
  cloudId: cloudId || '',
141
167
  isSearching: isSearching,
@@ -1,5 +1,5 @@
1
1
  export const EVENT_CHANNEL = 'media';
2
2
  export const packageMetaData = {
3
3
  packageName: "@atlaskit/link-datasource",
4
- packageVersion: "1.17.12"
4
+ packageVersion: "1.18.0"
5
5
  };
@@ -60,8 +60,8 @@ const AsyncPopupSelect = ({
60
60
  }
61
61
  }, [handleDebouncedFetchFilterOptions, searchTerm]);
62
62
  const handleOptionSelection = useCallback(newValue => {
63
- onSelectionChange(newValue);
64
- }, [onSelectionChange]);
63
+ onSelectionChange(filterType, newValue);
64
+ }, [filterType, onSelectionChange]);
65
65
  const sortOptionsOnPopupOpen = useCallback(() => {
66
66
  if (selectedOptions.length === 0) {
67
67
  return setSortedOptions(filterOptions);
@@ -103,8 +103,12 @@ const AsyncPopupSelect = ({
103
103
  pageCursor,
104
104
  searchString: searchTerm
105
105
  });
106
+ fireEvent('ui.button.clicked.basicSearchDropdown', {
107
+ filterType,
108
+ type: 'showMore'
109
+ });
106
110
  }
107
- }, [fetchFilterOptions, pageCursor, searchTerm]);
111
+ }, [fetchFilterOptions, filterType, fireEvent, pageCursor, searchTerm]);
108
112
  const handleMenuOpen = useCallback(() => {
109
113
  if (status === 'empty' || status === 'rejected') {
110
114
  // if user searches and gets status as rejected, we want the dropdown to try load the request with searchString when the user reopens the dropdown
@@ -8,7 +8,8 @@ const basicFilterContainerStyles = xcss({
8
8
  });
9
9
  const BasicFilterContainer = ({
10
10
  jql,
11
- cloudId
11
+ cloudId,
12
+ onChange
12
13
  }) => {
13
14
  const [selection, setSelection] = useState({});
14
15
  useEffect(() => {
@@ -16,13 +17,14 @@ const BasicFilterContainer = ({
16
17
  // hydrate hook call goes in here
17
18
  }
18
19
  }, [jql]);
19
- const handleSelectionChange = useCallback((options, filter) => {
20
+ const handleSelectionChange = useCallback((filterType, options) => {
20
21
  const updatedSelection = {
21
22
  ...selection,
22
- [filter]: options
23
+ [filterType]: options
23
24
  };
24
25
  setSelection(updatedSelection);
25
- }, [selection]);
26
+ onChange(updatedSelection);
27
+ }, [onChange, selection]);
26
28
  const handleReset = useCallback(() => {
27
29
  if (Object.keys(selection).length > 0) {
28
30
  setSelection({});
@@ -38,7 +40,7 @@ const BasicFilterContainer = ({
38
40
  key: filter,
39
41
  selection: selection[filter] || [],
40
42
  isDisabled: !cloudId,
41
- onSelectionChange: options => handleSelectionChange(options, filter),
43
+ onSelectionChange: handleSelectionChange,
42
44
  onReset: handleReset
43
45
  })));
44
46
  };
@@ -22,7 +22,9 @@ function mapNodeToOption({
22
22
  try {
23
23
  const baseProps = {
24
24
  label: displayName,
25
- value: jqlTerm
25
+ // this ensures that the returned value is not wrapped in single and double quotes
26
+ // e.g. '"value"' -> 'value'
27
+ value: decodeURIComponent(jqlTerm).replace(/^"|"$/g, '')
26
28
  };
27
29
  if (user) {
28
30
  return {
@@ -2,10 +2,12 @@
2
2
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
4
  import { useIntl } from 'react-intl-next';
5
+ import { useDebouncedCallback } from 'use-debounce';
5
6
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
6
7
  import { Flex, xcss } from '@atlaskit/primitives';
7
8
  import { useDatasourceAnalyticsEvents } from '../../../analytics';
8
9
  import { BasicFilters } from '../basic-filters';
10
+ import { SEARCH_DEBOUNCE_MS } from '../basic-filters/ui/async-popup-select';
9
11
  import { isQueryTooComplex } from '../basic-filters/utils/isQueryTooComplex';
10
12
  import { BasicSearchInput } from '../basic-search-input';
11
13
  import { JiraJQLEditor } from '../jql-editor';
@@ -38,15 +40,16 @@ export const JiraSearchContainer = props => {
38
40
  const {
39
41
  formatMessage
40
42
  } = useIntl();
43
+ const {
44
+ fireEvent
45
+ } = useDatasourceAnalyticsEvents();
41
46
  const [basicSearchTerm, setBasicSearchTerm] = useState('');
42
47
  const [currentSearchMethod, setCurrentSearchMethod] = useState(initialSearchMethod);
43
48
  const [jql, setJql] = useState(initialJql || DEFAULT_JQL_QUERY);
44
49
  const [isComplexQuery, setIsComplexQuery] = useState(false);
45
50
  const [orderKey, setOrderKey] = useState();
46
51
  const [orderDirection, setOrderDirection] = useState();
47
- const {
48
- fireEvent
49
- } = useDatasourceAnalyticsEvents();
52
+ const [filters, setFilters] = useState({});
50
53
  const onSearchMethodChange = useCallback(searchMethod => {
51
54
  onSearchMethodChangeCallback(searchMethod);
52
55
  setCurrentSearchMethod(searchMethod);
@@ -56,10 +59,11 @@ export const JiraSearchContainer = props => {
56
59
  setBasicSearchTerm(rawSearch);
57
60
  setJql(buildJQL({
58
61
  rawSearch,
62
+ filterValues: filters,
59
63
  orderDirection,
60
64
  orderKey
61
65
  }));
62
- }, [orderDirection, orderKey]);
66
+ }, [filters, orderDirection, orderKey]);
63
67
  const onQueryChange = useCallback(query => {
64
68
  var _query$split$map$filt, _fragments$at, _fragments$at2, _fragments$at3;
65
69
  // determine if order keys have been set so they can be saved and persisted when changes occur in basic search
@@ -86,16 +90,32 @@ export const JiraSearchContainer = props => {
86
90
  fireEvent('ui.jqlEditor.searched', {});
87
91
  }
88
92
  }, [currentSearchMethod, fireEvent, jql, onSearch]);
93
+ const [debouncedBasicFilterSelectionChange] = useDebouncedCallback(filterValues => {
94
+ const jqlWithFilterValues = buildJQL({
95
+ rawSearch: basicSearchTerm,
96
+ filterValues,
97
+ orderDirection,
98
+ orderKey
99
+ });
100
+ setJql(jqlWithFilterValues);
101
+ onSearch({
102
+ jql: jqlWithFilterValues
103
+ }, currentSearchMethod);
104
+ }, SEARCH_DEBOUNCE_MS);
105
+ const handleBasicFilterSelectionChange = useCallback(filterValues => {
106
+ setFilters(filterValues);
107
+ debouncedBasicFilterSelectionChange(filterValues);
108
+ }, [debouncedBasicFilterSelectionChange]);
109
+ useEffect(() => {
110
+ setIsComplexQuery(isQueryTooComplex(jql));
111
+ // eslint-disable-next-line react-hooks/exhaustive-deps
112
+ }, []);
89
113
  const showBasicFilters = useMemo(() => {
90
114
  if (getBooleanFF('platform.linking-platform.datasource.show-jlol-basic-filters')) {
91
115
  return true;
92
116
  }
93
117
  return false;
94
118
  }, []);
95
- useEffect(() => {
96
- setIsComplexQuery(isQueryTooComplex(jql));
97
- // eslint-disable-next-line react-hooks/exhaustive-deps
98
- }, []);
99
119
  return jsx("div", {
100
120
  css: inputContainerStyles
101
121
  }, currentSearchMethod === 'basic' && jsx(Flex, {
@@ -108,7 +128,8 @@ export const JiraSearchContainer = props => {
108
128
  searchTerm: basicSearchTerm
109
129
  }), showBasicFilters && jsx(BasicFilters, {
110
130
  jql: jql,
111
- cloudId: cloudId || ''
131
+ cloudId: cloudId || '',
132
+ onChange: handleBasicFilterSelectionChange
112
133
  })), currentSearchMethod === 'jql' && jsx(JiraJQLEditor, {
113
134
  cloudId: cloudId || '',
114
135
  isSearching: isSearching,
@@ -1,5 +1,5 @@
1
1
  export var EVENT_CHANNEL = 'media';
2
2
  export var packageMetaData = {
3
3
  packageName: "@atlaskit/link-datasource",
4
- packageVersion: "1.17.12"
4
+ packageVersion: "1.18.0"
5
5
  };
@@ -91,8 +91,8 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
91
91
  };
92
92
  }(), [handleDebouncedFetchFilterOptions, searchTerm]);
93
93
  var handleOptionSelection = useCallback(function (newValue) {
94
- onSelectionChange(newValue);
95
- }, [onSelectionChange]);
94
+ onSelectionChange(filterType, newValue);
95
+ }, [filterType, onSelectionChange]);
96
96
  var sortOptionsOnPopupOpen = useCallback(function () {
97
97
  if (selectedOptions.length === 0) {
98
98
  return setSortedOptions(filterOptions);
@@ -142,8 +142,12 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
142
142
  pageCursor: pageCursor,
143
143
  searchString: searchTerm
144
144
  });
145
+ fireEvent('ui.button.clicked.basicSearchDropdown', {
146
+ filterType: filterType,
147
+ type: 'showMore'
148
+ });
145
149
  }
146
- }, [fetchFilterOptions, pageCursor, searchTerm]);
150
+ }, [fetchFilterOptions, filterType, fireEvent, pageCursor, searchTerm]);
147
151
  var handleMenuOpen = useCallback(function () {
148
152
  if (status === 'empty' || status === 'rejected') {
149
153
  // if user searches and gets status as rejected, we want the dropdown to try load the request with searchString when the user reopens the dropdown
@@ -12,7 +12,8 @@ var basicFilterContainerStyles = xcss({
12
12
  });
13
13
  var BasicFilterContainer = function BasicFilterContainer(_ref) {
14
14
  var jql = _ref.jql,
15
- cloudId = _ref.cloudId;
15
+ cloudId = _ref.cloudId,
16
+ onChange = _ref.onChange;
16
17
  var _useState = useState({}),
17
18
  _useState2 = _slicedToArray(_useState, 2),
18
19
  selection = _useState2[0],
@@ -22,10 +23,11 @@ var BasicFilterContainer = function BasicFilterContainer(_ref) {
22
23
  // hydrate hook call goes in here
23
24
  }
24
25
  }, [jql]);
25
- var handleSelectionChange = useCallback(function (options, filter) {
26
- var updatedSelection = _objectSpread(_objectSpread({}, selection), {}, _defineProperty({}, filter, options));
26
+ var handleSelectionChange = useCallback(function (filterType, options) {
27
+ var updatedSelection = _objectSpread(_objectSpread({}, selection), {}, _defineProperty({}, filterType, options));
27
28
  setSelection(updatedSelection);
28
- }, [selection]);
29
+ onChange(updatedSelection);
30
+ }, [onChange, selection]);
29
31
  var handleReset = useCallback(function () {
30
32
  if (Object.keys(selection).length > 0) {
31
33
  setSelection({});
@@ -42,9 +44,7 @@ var BasicFilterContainer = function BasicFilterContainer(_ref) {
42
44
  key: filter,
43
45
  selection: selection[filter] || [],
44
46
  isDisabled: !cloudId,
45
- onSelectionChange: function onSelectionChange(options) {
46
- return handleSelectionChange(options, filter);
47
- },
47
+ onSelectionChange: handleSelectionChange,
48
48
  onReset: handleReset
49
49
  });
50
50
  }));
@@ -24,7 +24,9 @@ function mapNodeToOption(_ref) {
24
24
  try {
25
25
  var baseProps = {
26
26
  label: displayName,
27
- value: jqlTerm
27
+ // this ensures that the returned value is not wrapped in single and double quotes
28
+ // e.g. '"value"' -> 'value'
29
+ value: decodeURIComponent(jqlTerm).replace(/^"|"$/g, '')
28
30
  };
29
31
  if (user) {
30
32
  return _objectSpread(_objectSpread({}, baseProps), {}, {
@@ -3,10 +3,12 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
4
4
  import { css, jsx } from '@emotion/react';
5
5
  import { useIntl } from 'react-intl-next';
6
+ import { useDebouncedCallback } from 'use-debounce';
6
7
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
8
  import { Flex, xcss } from '@atlaskit/primitives';
8
9
  import { useDatasourceAnalyticsEvents } from '../../../analytics';
9
10
  import { BasicFilters } from '../basic-filters';
11
+ import { SEARCH_DEBOUNCE_MS } from '../basic-filters/ui/async-popup-select';
10
12
  import { isQueryTooComplex } from '../basic-filters/utils/isQueryTooComplex';
11
13
  import { BasicSearchInput } from '../basic-search-input';
12
14
  import { JiraJQLEditor } from '../jql-editor';
@@ -35,6 +37,8 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
35
37
  initialJql = _ref.jql;
36
38
  var _useIntl = useIntl(),
37
39
  formatMessage = _useIntl.formatMessage;
40
+ var _useDatasourceAnalyti = useDatasourceAnalyticsEvents(),
41
+ fireEvent = _useDatasourceAnalyti.fireEvent;
38
42
  var _useState = useState(''),
39
43
  _useState2 = _slicedToArray(_useState, 2),
40
44
  basicSearchTerm = _useState2[0],
@@ -59,8 +63,10 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
59
63
  _useState12 = _slicedToArray(_useState11, 2),
60
64
  orderDirection = _useState12[0],
61
65
  setOrderDirection = _useState12[1];
62
- var _useDatasourceAnalyti = useDatasourceAnalyticsEvents(),
63
- fireEvent = _useDatasourceAnalyti.fireEvent;
66
+ var _useState13 = useState({}),
67
+ _useState14 = _slicedToArray(_useState13, 2),
68
+ filters = _useState14[0],
69
+ setFilters = _useState14[1];
64
70
  var onSearchMethodChange = useCallback(function (searchMethod) {
65
71
  onSearchMethodChangeCallback(searchMethod);
66
72
  setCurrentSearchMethod(searchMethod);
@@ -70,10 +76,11 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
70
76
  setBasicSearchTerm(rawSearch);
71
77
  setJql(buildJQL({
72
78
  rawSearch: rawSearch,
79
+ filterValues: filters,
73
80
  orderDirection: orderDirection,
74
81
  orderKey: orderKey
75
82
  }));
76
- }, [orderDirection, orderKey]);
83
+ }, [filters, orderDirection, orderKey]);
77
84
  var onQueryChange = useCallback(function (query) {
78
85
  var _query$split$map$filt, _fragments$at, _fragments$at2, _fragments$at3;
79
86
  // determine if order keys have been set so they can be saved and persisted when changes occur in basic search
@@ -102,16 +109,34 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
102
109
  fireEvent('ui.jqlEditor.searched', {});
103
110
  }
104
111
  }, [currentSearchMethod, fireEvent, jql, onSearch]);
112
+ var _useDebouncedCallback = useDebouncedCallback(function (filterValues) {
113
+ var jqlWithFilterValues = buildJQL({
114
+ rawSearch: basicSearchTerm,
115
+ filterValues: filterValues,
116
+ orderDirection: orderDirection,
117
+ orderKey: orderKey
118
+ });
119
+ setJql(jqlWithFilterValues);
120
+ onSearch({
121
+ jql: jqlWithFilterValues
122
+ }, currentSearchMethod);
123
+ }, SEARCH_DEBOUNCE_MS),
124
+ _useDebouncedCallback2 = _slicedToArray(_useDebouncedCallback, 1),
125
+ debouncedBasicFilterSelectionChange = _useDebouncedCallback2[0];
126
+ var handleBasicFilterSelectionChange = useCallback(function (filterValues) {
127
+ setFilters(filterValues);
128
+ debouncedBasicFilterSelectionChange(filterValues);
129
+ }, [debouncedBasicFilterSelectionChange]);
130
+ useEffect(function () {
131
+ setIsComplexQuery(isQueryTooComplex(jql));
132
+ // eslint-disable-next-line react-hooks/exhaustive-deps
133
+ }, []);
105
134
  var showBasicFilters = useMemo(function () {
106
135
  if (getBooleanFF('platform.linking-platform.datasource.show-jlol-basic-filters')) {
107
136
  return true;
108
137
  }
109
138
  return false;
110
139
  }, []);
111
- useEffect(function () {
112
- setIsComplexQuery(isQueryTooComplex(jql));
113
- // eslint-disable-next-line react-hooks/exhaustive-deps
114
- }, []);
115
140
  return jsx("div", {
116
141
  css: inputContainerStyles
117
142
  }, currentSearchMethod === 'basic' && jsx(Flex, {
@@ -124,7 +149,8 @@ export var JiraSearchContainer = function JiraSearchContainer(props) {
124
149
  searchTerm: basicSearchTerm
125
150
  }), showBasicFilters && jsx(BasicFilters, {
126
151
  jql: jql,
127
- cloudId: cloudId || ''
152
+ cloudId: cloudId || '',
153
+ onChange: handleBasicFilterSelectionChange
128
154
  })), currentSearchMethod === 'jql' && jsx(JiraJQLEditor, {
129
155
  cloudId: cloudId || '',
130
156
  isSearching: isSearching,
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generates Typescript types for analytics events from analytics.spec.yaml
5
5
  *
6
- * @codegen <<SignedSource::7b6bf74dbad7e14356c81bb8d6285cbe>>
6
+ * @codegen <<SignedSource::ccda345ed2d15f3bbe167f871f676090>>
7
7
  * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen link-datasource
8
8
  */
9
9
  export type PackageMetaDataType = {
@@ -97,6 +97,10 @@ export type DropdownClosedBasicSearchDropdownAttributesType = {
97
97
  filterType: 'project' | 'assignee' | 'issuetype' | 'status';
98
98
  selectionCount: number;
99
99
  };
100
+ export type ButtonClickedBasicSearchDropdownAttributesType = {
101
+ filterType: 'project' | 'assignee' | 'issuetype' | 'status';
102
+ type: 'showMore';
103
+ };
100
104
  export type AqlEditorSearchedAttributesType = {};
101
105
  export type GetWorkspaceIdSuccessAttributesType = {};
102
106
  export type GetWorkspaceIdFailedAttributesType = {
@@ -175,6 +179,9 @@ export type AnalyticsEventAttributes = {
175
179
  /**
176
180
  * Fired when the basic filter dropdown is closed */
177
181
  'ui.dropdown.closed.basicSearchDropdown': DropdownClosedBasicSearchDropdownAttributesType;
182
+ /**
183
+ * Fired when the “show more” button inside the dropdown menu is clicked */
184
+ 'ui.button.clicked.basicSearchDropdown': ButtonClickedBasicSearchDropdownAttributesType;
178
185
  /**
179
186
  * Fired when search is initiated via the search icon or enter key press for aql editor input field. */
180
187
  'ui.aqlEditor.searched': AqlEditorSearchedAttributesType;
@@ -1,8 +1,6 @@
1
- import { BasicFilterFieldType, SelectOption } from '../types';
1
+ import { SelectedOptionsMap } from '../types';
2
2
  export interface HydrateJqlState {
3
- hydratedOptions: {
4
- [key in BasicFilterFieldType]?: SelectOption[];
5
- };
3
+ hydratedOptions: SelectedOptionsMap;
6
4
  fetchHydratedJqlOptions: () => Promise<void>;
7
5
  status: 'empty' | 'loading' | 'resolved' | 'rejected';
8
6
  errors: unknown[];
@@ -20,6 +20,9 @@ export type AvatarLabelOption = OptionBase & {
20
20
  isGroup?: boolean;
21
21
  };
22
22
  export type SelectOption = IconLabelOption | LozengeLabelOption | AvatarLabelOption;
23
+ export type SelectedOptionsMap = {
24
+ [key in BasicFilterFieldType]?: SelectOption[];
25
+ };
23
26
  export type FormatOptionLabel = (option: SelectOption) => ReactElement;
24
27
  export declare const appearanceMap: {
25
28
  readonly BLUE_GRAY: "default";
@@ -4,7 +4,7 @@ export interface AsyncPopupSelectProps {
4
4
  filterType: BasicFilterFieldType;
5
5
  cloudId: string;
6
6
  selection: SelectOption[];
7
- onSelectionChange?: (selection: SelectOption[]) => void;
7
+ onSelectionChange?: (filterType: BasicFilterFieldType, options: SelectOption[]) => void;
8
8
  onReset?: () => void;
9
9
  isDisabled?: boolean;
10
10
  }
@@ -1,7 +1,9 @@
1
1
  /// <reference types="react" />
2
+ import type { SelectedOptionsMap } from '../types';
2
3
  export interface BasicFilterContainerProps {
3
4
  jql: string;
4
5
  cloudId: string;
6
+ onChange: (selection: SelectedOptionsMap) => void;
5
7
  }
6
- declare const BasicFilterContainer: ({ jql, cloudId }: BasicFilterContainerProps) => JSX.Element;
8
+ declare const BasicFilterContainer: ({ jql, cloudId, onChange, }: BasicFilterContainerProps) => JSX.Element;
7
9
  export default BasicFilterContainer;
@@ -1,10 +1,5 @@
1
- import { FieldValuesResponse, HydrateResponse, SelectOption } from '../types';
2
- export declare function mapHydrateResponseData({ data }: HydrateResponse): {
3
- project?: SelectOption[] | undefined;
4
- assignee?: SelectOption[] | undefined;
5
- issuetype?: SelectOption[] | undefined;
6
- status?: SelectOption[] | undefined;
7
- };
1
+ import { FieldValuesResponse, HydrateResponse, SelectedOptionsMap, SelectOption } from '../types';
2
+ export declare function mapHydrateResponseData({ data }: HydrateResponse): SelectedOptionsMap;
8
3
  export declare function mapFieldValuesToFilterOptions({ data, }: FieldValuesResponse): SelectOption[];
9
4
  export declare function mapFieldValuesToTotalCount({ data, }: FieldValuesResponse): number;
10
5
  export declare function mapFieldValuesToPageCursor({ data, }: FieldValuesResponse): string | undefined;
@@ -1,11 +1,9 @@
1
- import { BasicFilterFieldType, SelectOption } from '../basic-filters/types';
1
+ import { SelectedOptionsMap } from '../basic-filters/types';
2
2
  type BuildJQLInput = {
3
3
  rawSearch: string;
4
4
  orderDirection?: string;
5
5
  orderKey?: string;
6
- filterValues?: {
7
- [key in BasicFilterFieldType]?: SelectOption[];
8
- };
6
+ filterValues?: SelectedOptionsMap;
9
7
  };
10
8
  export declare const fuzzyCharacter = "*";
11
9
  export declare const buildJQL: (input: BuildJQLInput) => string;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generates Typescript types for analytics events from analytics.spec.yaml
5
5
  *
6
- * @codegen <<SignedSource::7b6bf74dbad7e14356c81bb8d6285cbe>>
6
+ * @codegen <<SignedSource::ccda345ed2d15f3bbe167f871f676090>>
7
7
  * @codegenCommand yarn workspace @atlassian/analytics-tooling run analytics:codegen link-datasource
8
8
  */
9
9
  export type PackageMetaDataType = {
@@ -97,6 +97,10 @@ export type DropdownClosedBasicSearchDropdownAttributesType = {
97
97
  filterType: 'project' | 'assignee' | 'issuetype' | 'status';
98
98
  selectionCount: number;
99
99
  };
100
+ export type ButtonClickedBasicSearchDropdownAttributesType = {
101
+ filterType: 'project' | 'assignee' | 'issuetype' | 'status';
102
+ type: 'showMore';
103
+ };
100
104
  export type AqlEditorSearchedAttributesType = {};
101
105
  export type GetWorkspaceIdSuccessAttributesType = {};
102
106
  export type GetWorkspaceIdFailedAttributesType = {
@@ -175,6 +179,9 @@ export type AnalyticsEventAttributes = {
175
179
  /**
176
180
  * Fired when the basic filter dropdown is closed */
177
181
  'ui.dropdown.closed.basicSearchDropdown': DropdownClosedBasicSearchDropdownAttributesType;
182
+ /**
183
+ * Fired when the “show more” button inside the dropdown menu is clicked */
184
+ 'ui.button.clicked.basicSearchDropdown': ButtonClickedBasicSearchDropdownAttributesType;
178
185
  /**
179
186
  * Fired when search is initiated via the search icon or enter key press for aql editor input field. */
180
187
  'ui.aqlEditor.searched': AqlEditorSearchedAttributesType;
@@ -1,8 +1,6 @@
1
- import { BasicFilterFieldType, SelectOption } from '../types';
1
+ import { SelectedOptionsMap } from '../types';
2
2
  export interface HydrateJqlState {
3
- hydratedOptions: {
4
- [key in BasicFilterFieldType]?: SelectOption[];
5
- };
3
+ hydratedOptions: SelectedOptionsMap;
6
4
  fetchHydratedJqlOptions: () => Promise<void>;
7
5
  status: 'empty' | 'loading' | 'resolved' | 'rejected';
8
6
  errors: unknown[];
@@ -20,6 +20,9 @@ export type AvatarLabelOption = OptionBase & {
20
20
  isGroup?: boolean;
21
21
  };
22
22
  export type SelectOption = IconLabelOption | LozengeLabelOption | AvatarLabelOption;
23
+ export type SelectedOptionsMap = {
24
+ [key in BasicFilterFieldType]?: SelectOption[];
25
+ };
23
26
  export type FormatOptionLabel = (option: SelectOption) => ReactElement;
24
27
  export declare const appearanceMap: {
25
28
  readonly BLUE_GRAY: "default";
@@ -4,7 +4,7 @@ export interface AsyncPopupSelectProps {
4
4
  filterType: BasicFilterFieldType;
5
5
  cloudId: string;
6
6
  selection: SelectOption[];
7
- onSelectionChange?: (selection: SelectOption[]) => void;
7
+ onSelectionChange?: (filterType: BasicFilterFieldType, options: SelectOption[]) => void;
8
8
  onReset?: () => void;
9
9
  isDisabled?: boolean;
10
10
  }
@@ -1,7 +1,9 @@
1
1
  /// <reference types="react" />
2
+ import type { SelectedOptionsMap } from '../types';
2
3
  export interface BasicFilterContainerProps {
3
4
  jql: string;
4
5
  cloudId: string;
6
+ onChange: (selection: SelectedOptionsMap) => void;
5
7
  }
6
- declare const BasicFilterContainer: ({ jql, cloudId }: BasicFilterContainerProps) => JSX.Element;
8
+ declare const BasicFilterContainer: ({ jql, cloudId, onChange, }: BasicFilterContainerProps) => JSX.Element;
7
9
  export default BasicFilterContainer;
@@ -1,10 +1,5 @@
1
- import { FieldValuesResponse, HydrateResponse, SelectOption } from '../types';
2
- export declare function mapHydrateResponseData({ data }: HydrateResponse): {
3
- project?: SelectOption[] | undefined;
4
- assignee?: SelectOption[] | undefined;
5
- issuetype?: SelectOption[] | undefined;
6
- status?: SelectOption[] | undefined;
7
- };
1
+ import { FieldValuesResponse, HydrateResponse, SelectedOptionsMap, SelectOption } from '../types';
2
+ export declare function mapHydrateResponseData({ data }: HydrateResponse): SelectedOptionsMap;
8
3
  export declare function mapFieldValuesToFilterOptions({ data, }: FieldValuesResponse): SelectOption[];
9
4
  export declare function mapFieldValuesToTotalCount({ data, }: FieldValuesResponse): number;
10
5
  export declare function mapFieldValuesToPageCursor({ data, }: FieldValuesResponse): string | undefined;
@@ -1,11 +1,9 @@
1
- import { BasicFilterFieldType, SelectOption } from '../basic-filters/types';
1
+ import { SelectedOptionsMap } from '../basic-filters/types';
2
2
  type BuildJQLInput = {
3
3
  rawSearch: string;
4
4
  orderDirection?: string;
5
5
  orderKey?: string;
6
- filterValues?: {
7
- [key in BasicFilterFieldType]?: SelectOption[];
8
- };
6
+ filterValues?: SelectedOptionsMap;
9
7
  };
10
8
  export declare const fuzzyCharacter = "*";
11
9
  export declare const buildJQL: (input: BuildJQLInput) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "1.17.12",
3
+ "version": "1.18.0",
4
4
  "description": "UI Components to support linking platform dataset feature",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -30,7 +30,7 @@
30
30
  "analytics:codegen": "yarn workspace @atlassian/analytics-tooling run analytics:codegen link-datasource --output ./src/analytics/generated"
31
31
  },
32
32
  "dependencies": {
33
- "@atlaskit/adf-schema": "^33.2.3",
33
+ "@atlaskit/adf-schema": "^34.0.0",
34
34
  "@atlaskit/analytics-next": "^9.1.3",
35
35
  "@atlaskit/avatar": "^21.4.0",
36
36
  "@atlaskit/badge": "^15.1.16",