@atlaskit/link-datasource 1.12.2 → 1.12.4

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 (87) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/analytics/constants.js +1 -1
  3. package/dist/cjs/services/useBasicFilterAGG.js +40 -82
  4. package/dist/cjs/services/utils.js +1 -1
  5. package/dist/cjs/ui/issue-like-table/draggable-table-heading.js +0 -12
  6. package/dist/cjs/ui/issue-like-table/index.js +5 -0
  7. package/dist/cjs/ui/issue-like-table/styled.js +1 -1
  8. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +94 -0
  9. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +24 -13
  10. package/dist/cjs/ui/jira-issues-modal/basic-filters/ui/index.js +3 -1
  11. package/dist/cjs/ui/jira-issues-modal/basic-filters/utils/transformers.js +15 -3
  12. package/dist/cjs/ui/jira-issues-modal/jira-search-container/index.js +2 -1
  13. package/dist/es2019/analytics/constants.js +1 -1
  14. package/dist/es2019/services/useBasicFilterAGG.js +30 -53
  15. package/dist/es2019/services/utils.js +1 -1
  16. package/dist/es2019/ui/issue-like-table/draggable-table-heading.js +0 -12
  17. package/dist/es2019/ui/issue-like-table/index.js +5 -0
  18. package/dist/es2019/ui/issue-like-table/styled.js +16 -4
  19. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +52 -0
  20. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +15 -7
  21. package/dist/es2019/ui/jira-issues-modal/basic-filters/ui/index.js +3 -1
  22. package/dist/es2019/ui/jira-issues-modal/basic-filters/utils/transformers.js +14 -2
  23. package/dist/es2019/ui/jira-issues-modal/jira-search-container/index.js +2 -1
  24. package/dist/esm/analytics/constants.js +1 -1
  25. package/dist/esm/services/useBasicFilterAGG.js +41 -83
  26. package/dist/esm/services/utils.js +1 -1
  27. package/dist/esm/ui/issue-like-table/draggable-table-heading.js +0 -12
  28. package/dist/esm/ui/issue-like-table/index.js +5 -0
  29. package/dist/esm/ui/issue-like-table/styled.js +1 -1
  30. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.js +87 -0
  31. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.js +24 -13
  32. package/dist/esm/ui/jira-issues-modal/basic-filters/ui/index.js +3 -1
  33. package/dist/esm/ui/jira-issues-modal/basic-filters/utils/transformers.js +12 -2
  34. package/dist/esm/ui/jira-issues-modal/jira-search-container/index.js +2 -1
  35. package/dist/types/services/useBasicFilterAGG.d.ts +9 -1
  36. package/dist/types/services/utils.d.ts +1 -1
  37. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +18 -0
  38. package/dist/types/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  39. package/dist/types/ui/jira-issues-modal/basic-filters/ui/index.d.ts +2 -1
  40. package/dist/types/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +3 -1
  41. package/dist/types-ts4.5/services/useBasicFilterAGG.d.ts +9 -1
  42. package/dist/types-ts4.5/services/utils.d.ts +1 -1
  43. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFilterOptions.d.ts +18 -0
  44. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/async-popup-select/index.d.ts +2 -1
  45. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/ui/index.d.ts +2 -1
  46. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/utils/transformers.d.ts +3 -1
  47. package/package.json +1 -1
  48. package/dist/cjs/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.js +0 -75
  49. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +0 -20
  50. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +0 -155
  51. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +0 -82
  52. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +0 -87
  53. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +0 -97
  54. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +0 -18
  55. package/dist/cjs/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +0 -111
  56. package/dist/es2019/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.js +0 -39
  57. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +0 -14
  58. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +0 -149
  59. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +0 -76
  60. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +0 -81
  61. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +0 -91
  62. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +0 -12
  63. package/dist/es2019/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +0 -105
  64. package/dist/esm/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.js +0 -68
  65. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.js +0 -14
  66. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.js +0 -149
  67. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.js +0 -76
  68. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.js +0 -81
  69. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.js +0 -91
  70. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.js +0 -12
  71. package/dist/esm/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.js +0 -105
  72. package/dist/types/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.d.ts +0 -12
  73. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.d.ts +0 -3
  74. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.d.ts +0 -17
  75. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.d.ts +0 -8
  76. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.d.ts +0 -8
  77. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.d.ts +0 -8
  78. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.d.ts +0 -3
  79. package/dist/types/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.d.ts +0 -29
  80. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/hooks/useFieldValues.d.ts +0 -12
  81. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesEmptyResponse.d.ts +0 -3
  82. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesExpectedResponseForAssignees.d.ts +0 -17
  83. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForProjects.d.ts +0 -8
  84. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForStatuses.d.ts +0 -8
  85. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/fieldValuesStandardResponseForTypes.d.ts +0 -8
  86. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlEmptyResponse.d.ts +0 -3
  87. package/dist/types-ts4.5/ui/jira-issues-modal/basic-filters/mocks/hydrateJqlStandardResponse.d.ts +0 -29
@@ -7,13 +7,25 @@ export const Table = styled.table`
7
7
  `;
8
8
  export const TableHeading = styled.th`
9
9
  position: relative;
10
- padding-block: ${"var(--ds-space-300, 24px)"} ${"var(--ds-space-100, 8px)"};
11
10
  line-height: ${"var(--ds-font-lineHeight-300, 16px)"};
12
11
  border-bottom: 2px solid ${`var(--ds-background-accent-gray-subtler, ${N40})`};
12
+ height: calc(52px - ${"var(--ds-space-050, 4px)"} * 2 - 2px);
13
+ vertical-align: bottom;
14
+
13
15
  & [data-testid='datasource-header-content--container'] {
14
- margin-top: 0;
16
+ width: 100%;
17
+ padding: ${"var(--ds-space-100, 4px)"} ${"var(--ds-space-050, 2px)"};
18
+ display: -webkit-box;
19
+ -webkit-line-clamp: 2;
20
+ -webkit-box-orient: vertical;
21
+ white-space: normal;
15
22
  overflow: hidden;
16
- text-overflow: ellipsis;
17
- white-space: nowrap;
23
+ max-height: 2.5rem;
24
+ word-wrap: break-word;
25
+
26
+ &:hover {
27
+ background: ${"var(--ds-background-input-hovered, #F7F8F9)"};
28
+ border-radius: 3px;
29
+ }
18
30
  }
19
31
  `;
@@ -0,0 +1,52 @@
1
+ import { useCallback, useState } from 'react';
2
+ import { useBasicFilterAGG } from '../../../../services/useBasicFilterAGG';
3
+ import { mapFieldValuesToFilterOptions, mapFieldValuesToPageCursor, mapFieldValuesToTotalCount } from '../utils/transformers';
4
+ export const useFilterOptions = ({
5
+ filterType,
6
+ cloudId
7
+ }) => {
8
+ const [filterOptions, setFilterOptions] = useState([]);
9
+ const [totalCount, setTotalCount] = useState(0);
10
+ const [status, setStatus] = useState('empty');
11
+ const [nextPageCursor, setNextPageCursor] = useState(undefined);
12
+ const {
13
+ getFieldValues
14
+ } = useBasicFilterAGG();
15
+ const fetchFilterOptions = useCallback(async ({
16
+ pageCursor,
17
+ searchString
18
+ } = {}) => {
19
+ setStatus('loading');
20
+ try {
21
+ const response = await getFieldValues({
22
+ cloudId,
23
+ jql: '',
24
+ jqlTerm: filterType,
25
+ searchString,
26
+ pageCursor
27
+ });
28
+ if (response.errors && response.errors.length > 0) {
29
+ setStatus('rejected');
30
+ return;
31
+ }
32
+ const isNewSearch = !pageCursor;
33
+ if (isNewSearch) {
34
+ setFilterOptions(mapFieldValuesToFilterOptions(response));
35
+ } else {
36
+ setFilterOptions([...filterOptions, ...mapFieldValuesToFilterOptions(response)]);
37
+ }
38
+ setTotalCount(mapFieldValuesToTotalCount(response));
39
+ setNextPageCursor(mapFieldValuesToPageCursor(response));
40
+ setStatus('resolved');
41
+ } catch (error) {
42
+ setStatus('rejected');
43
+ }
44
+ }, [cloudId, filterOptions, filterType, getFieldValues]);
45
+ return {
46
+ filterOptions,
47
+ fetchFilterOptions,
48
+ totalCount,
49
+ pageCursor: nextPageCursor,
50
+ status
51
+ };
52
+ };
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import { useIntl } from 'react-intl-next';
4
4
  import { CheckboxOption, PopupSelect } from '@atlaskit/select';
5
- import { useFieldValues } from '../../hooks/useFieldValues';
5
+ import { useFilterOptions } from '../../hooks/useFilterOptions';
6
6
  import CustomControl from './control';
7
7
  import PopupFooter from './footer';
8
8
  import formatOptionLabel from './formatOptionLabel';
@@ -12,6 +12,7 @@ import PopupTrigger from './trigger';
12
12
  const noFilterOptions = () => true;
13
13
  const AsyncPopupSelect = ({
14
14
  filterType,
15
+ cloudId,
15
16
  selection,
16
17
  onSelectionChange = () => {}
17
18
  }) => {
@@ -26,8 +27,9 @@ const AsyncPopupSelect = ({
26
27
  fetchFilterOptions,
27
28
  totalCount,
28
29
  status
29
- } = useFieldValues({
30
- filterType
30
+ } = useFilterOptions({
31
+ filterType,
32
+ cloudId
31
33
  });
32
34
  const handleInputChange = useCallback((searchString, actionMeta) => {
33
35
  if (actionMeta.action === 'input-change' && searchString !== searchTerm) {
@@ -40,7 +42,7 @@ const AsyncPopupSelect = ({
40
42
  };
41
43
  const handleOpenPopup = useCallback(async () => {
42
44
  if (status === 'empty') {
43
- fetchFilterOptions();
45
+ await fetchFilterOptions();
44
46
  }
45
47
  }, [fetchFilterOptions, status]);
46
48
  useEffect(() => {
@@ -50,18 +52,24 @@ const AsyncPopupSelect = ({
50
52
  pickerRef === null || pickerRef === void 0 ? void 0 : (_pickerRef$current = pickerRef.current) === null || _pickerRef$current === void 0 ? void 0 : (_pickerRef$current$se = _pickerRef$current.selectRef) === null || _pickerRef$current$se === void 0 ? void 0 : (_pickerRef$current$se2 = _pickerRef$current$se.inputRef) === null || _pickerRef$current$se2 === void 0 ? void 0 : _pickerRef$current$se2.focus();
51
53
  }
52
54
  }, [status]);
55
+ const isLoading = status === 'loading' || status === 'empty';
53
56
  return /*#__PURE__*/React.createElement(PopupSelect, {
54
57
  isMulti: true,
55
58
  maxMenuWidth: 300,
56
59
  minMenuWidth: 300,
57
60
  ref: pickerRef,
58
61
  testId: "jlol-basic-filter-popup-select",
59
- inputId: "jlol-basic-filter-popup-select--input",
60
- searchThreshold: 0,
62
+ inputId: "jlol-basic-filter-popup-select--input"
63
+ /*
64
+ this threshold controls the display of the search control (input field for search)
65
+ if this threshold is less than 0, when typing a search string that returns no results it will not remove the search control
66
+ if this threshold is 0 or higher, it will remove the search control when there are no results, the user will be unable to clear the search to see more results
67
+ */,
68
+ searchThreshold: -1,
61
69
  inputValue: searchTerm,
62
70
  closeMenuOnSelect: false,
63
71
  hideSelectedOptions: false,
64
- isLoading: status === 'loading',
72
+ isLoading: isLoading,
65
73
  placeholder: formatMessage(asyncPopupSelectMessages.selectPlaceholder),
66
74
  components: {
67
75
  /* @ts-expect-error - This component has stricter OptionType, hence a temp setup untill its made generic */
@@ -4,7 +4,8 @@ import { isValidJql } from '../utils';
4
4
  import AsyncPopupSelect from './async-popup-select';
5
5
  const availableBasicFilterTypes = ['project', 'issuetype', 'status', 'assignee'];
6
6
  const BasicFilterContainer = ({
7
- jql
7
+ jql,
8
+ cloudId
8
9
  }) => {
9
10
  const [selection] = useState([]);
10
11
  useEffect(() => {
@@ -17,6 +18,7 @@ const BasicFilterContainer = ({
17
18
  gap: "space.100",
18
19
  testId: "jlol-basic-filter-container"
19
20
  }, availableBasicFilterTypes.map(filter => /*#__PURE__*/React.createElement(AsyncPopupSelect, {
21
+ cloudId: cloudId,
20
22
  filterType: filter,
21
23
  key: filter,
22
24
  selection: selection,
@@ -29,7 +29,7 @@ function mapNodeToOption({
29
29
  ...baseProps,
30
30
  optionType: 'avatarLabel',
31
31
  avatar: user.picture,
32
- isSquare: true
32
+ isSquare: false
33
33
  };
34
34
  }
35
35
  if (group) {
@@ -83,9 +83,21 @@ export function mapHydrateResponseData({
83
83
  });
84
84
  return transformedHydrateResponseData;
85
85
  }
86
- export function mapFieldValuesResponseData({
86
+ export function mapFieldValuesToFilterOptions({
87
87
  data
88
88
  }) {
89
89
  var _data$jira2, _data$jira2$jqlBuilde, _data$jira2$jqlBuilde2, _data$jira2$jqlBuilde3;
90
90
  return (data === null || data === void 0 ? void 0 : (_data$jira2 = data.jira) === null || _data$jira2 === void 0 ? void 0 : (_data$jira2$jqlBuilde = _data$jira2.jqlBuilder) === null || _data$jira2$jqlBuilde === void 0 ? void 0 : (_data$jira2$jqlBuilde2 = _data$jira2$jqlBuilde.fieldValues) === null || _data$jira2$jqlBuilde2 === void 0 ? void 0 : (_data$jira2$jqlBuilde3 = _data$jira2$jqlBuilde2.edges) === null || _data$jira2$jqlBuilde3 === void 0 ? void 0 : _data$jira2$jqlBuilde3.map(edge => edge.node ? mapNodeToOption(edge.node) : null).filter(isNonNullSelectOption)) || [];
91
+ }
92
+ export function mapFieldValuesToTotalCount({
93
+ data
94
+ }) {
95
+ var _data$jira3, _data$jira3$jqlBuilde, _data$jira3$jqlBuilde2;
96
+ return (data === null || data === void 0 ? void 0 : (_data$jira3 = data.jira) === null || _data$jira3 === void 0 ? void 0 : (_data$jira3$jqlBuilde = _data$jira3.jqlBuilder) === null || _data$jira3$jqlBuilde === void 0 ? void 0 : (_data$jira3$jqlBuilde2 = _data$jira3$jqlBuilde.fieldValues) === null || _data$jira3$jqlBuilde2 === void 0 ? void 0 : _data$jira3$jqlBuilde2.totalCount) || 0;
97
+ }
98
+ export function mapFieldValuesToPageCursor({
99
+ data
100
+ }) {
101
+ var _data$jira4, _data$jira4$jqlBuilde, _data$jira4$jqlBuilde2, _data$jira4$jqlBuilde3;
102
+ return data === null || data === void 0 ? void 0 : (_data$jira4 = data.jira) === null || _data$jira4 === void 0 ? void 0 : (_data$jira4$jqlBuilde = _data$jira4.jqlBuilder) === null || _data$jira4$jqlBuilde === void 0 ? void 0 : (_data$jira4$jqlBuilde2 = _data$jira4$jqlBuilde.fieldValues) === null || _data$jira4$jqlBuilde2 === void 0 ? void 0 : (_data$jira4$jqlBuilde3 = _data$jira4$jqlBuilde2.pageInfo) === null || _data$jira4$jqlBuilde3 === void 0 ? void 0 : _data$jira4$jqlBuilde3.endCursor;
91
103
  }
@@ -93,7 +93,8 @@ export const JiraSearchContainer = props => {
93
93
  onSearch: handleSearch,
94
94
  searchTerm: basicSearchTerm
95
95
  }), showBasicFilters && jsx(BasicFilters, {
96
- jql: jql
96
+ jql: jql,
97
+ cloudId: cloudId || ''
97
98
  })), currentSearchMethod === 'jql' && jsx(JiraJQLEditor, {
98
99
  cloudId: cloudId || '',
99
100
  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.12.2"
4
+ packageVersion: "1.12.4"
5
5
  };
@@ -2,7 +2,7 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  import { useCallback, useMemo } from 'react';
4
4
  import { useSmartLinkContext } from '@atlaskit/link-provider';
5
- import { getBaseUrl } from '@atlaskit/linking-common';
5
+ import { getBaseUrl, request } from '@atlaskit/linking-common';
6
6
  import { fieldValuesQuery, hydrateJQLQuery } from './utils';
7
7
  var getGraphqlUrl = function getGraphqlUrl(envKey, baseUrlOverride) {
8
8
  var baseUrl = baseUrlOverride || getBaseUrl(envKey);
@@ -12,97 +12,55 @@ export var useBasicFilterAGG = function useBasicFilterAGG() {
12
12
  var _useSmartLinkContext = useSmartLinkContext(),
13
13
  client = _useSmartLinkContext.connections.client;
14
14
  var gatewayGraphqlUrl = getGraphqlUrl(client.envKey, client.baseUrlOverride);
15
- var aggHeaders = useMemo(function () {
16
- return new Headers({
17
- 'Content-Type': 'application/json',
18
- 'X-ExperimentalApi': 'JiraJqlBuilder'
19
- });
20
- }, []);
21
- var getHydratedJQL = useCallback( /*#__PURE__*/function () {
22
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(cloudId, jql) {
23
- var body, request, response;
15
+ var requestCall = useCallback( /*#__PURE__*/function () {
16
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(body) {
24
17
  return _regeneratorRuntime.wrap(function _callee$(_context) {
25
18
  while (1) switch (_context.prev = _context.next) {
26
19
  case 0:
27
- body = JSON.stringify({
28
- variables: {
29
- cloudId: cloudId,
30
- jql: jql
31
- },
32
- operationName: 'hydrate',
33
- query: hydrateJQLQuery
34
- });
35
- request = new Request(gatewayGraphqlUrl, {
36
- method: 'POST',
37
- headers: aggHeaders,
38
- body: body
39
- });
40
- _context.prev = 2;
41
- _context.next = 5;
42
- return fetch(request);
43
- case 5:
44
- response = _context.sent;
45
- return _context.abrupt("return", response.json());
46
- case 9:
47
- _context.prev = 9;
48
- _context.t0 = _context["catch"](2);
49
- throw new Error(_context.t0);
50
- case 12:
20
+ return _context.abrupt("return", request('post', gatewayGraphqlUrl, body, {
21
+ 'X-ExperimentalApi': 'JiraJqlBuilder'
22
+ }, [200, 201, 202, 203, 204]));
23
+ case 1:
51
24
  case "end":
52
25
  return _context.stop();
53
26
  }
54
- }, _callee, null, [[2, 9]]);
27
+ }, _callee);
55
28
  }));
56
- return function (_x, _x2) {
29
+ return function (_x) {
57
30
  return _ref.apply(this, arguments);
58
31
  };
59
- }(), [gatewayGraphqlUrl, aggHeaders]);
60
- var getFieldValues = useCallback( /*#__PURE__*/function () {
61
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(cloudId, jql, jqlTerm, searchString, pageCursor) {
62
- var body, request, response;
63
- return _regeneratorRuntime.wrap(function _callee2$(_context2) {
64
- while (1) switch (_context2.prev = _context2.next) {
65
- case 0:
66
- body = JSON.stringify({
67
- variables: {
68
- cloudId: cloudId,
69
- jql: jql,
70
- first: 10,
71
- jqlTerm: jqlTerm,
72
- searchString: searchString,
73
- after: pageCursor
74
- },
75
- operationName: 'fieldValues',
76
- query: fieldValuesQuery
77
- });
78
- request = new Request(gatewayGraphqlUrl, {
79
- method: 'POST',
80
- headers: aggHeaders,
81
- body: body
82
- });
83
- _context2.prev = 2;
84
- _context2.next = 5;
85
- return fetch(request);
86
- case 5:
87
- response = _context2.sent;
88
- _context2.next = 8;
89
- return response.json();
90
- case 8:
91
- return _context2.abrupt("return", _context2.sent);
92
- case 11:
93
- _context2.prev = 11;
94
- _context2.t0 = _context2["catch"](2);
95
- throw new Error(_context2.t0);
96
- case 14:
97
- case "end":
98
- return _context2.stop();
99
- }
100
- }, _callee2, null, [[2, 11]]);
101
- }));
102
- return function (_x3, _x4, _x5, _x6, _x7) {
103
- return _ref2.apply(this, arguments);
104
- };
105
- }(), [gatewayGraphqlUrl, aggHeaders]);
32
+ }(), [gatewayGraphqlUrl]);
33
+ var getHydratedJQL = useCallback(function (cloudId, jql) {
34
+ return requestCall({
35
+ variables: {
36
+ cloudId: cloudId,
37
+ jql: jql
38
+ },
39
+ operationName: 'hydrate',
40
+ query: hydrateJQLQuery
41
+ });
42
+ }, [requestCall]);
43
+ var getFieldValues = useCallback(function (_ref2) {
44
+ var cloudId = _ref2.cloudId,
45
+ _ref2$jql = _ref2.jql,
46
+ jql = _ref2$jql === void 0 ? '' : _ref2$jql,
47
+ jqlTerm = _ref2.jqlTerm,
48
+ _ref2$searchString = _ref2.searchString,
49
+ searchString = _ref2$searchString === void 0 ? '' : _ref2$searchString,
50
+ pageCursor = _ref2.pageCursor;
51
+ return requestCall({
52
+ variables: {
53
+ cloudId: cloudId,
54
+ jql: jql,
55
+ first: 10,
56
+ jqlTerm: jqlTerm,
57
+ searchString: searchString,
58
+ after: pageCursor
59
+ },
60
+ operationName: 'fieldValues',
61
+ query: fieldValuesQuery
62
+ });
63
+ }, [requestCall]);
106
64
  return useMemo(function () {
107
65
  return {
108
66
  getHydratedJQL: getHydratedJQL,
@@ -1,2 +1,2 @@
1
1
  export var hydrateJQLQuery = "query hydrate($cloudId: ID!, $jql: String!) {\n jira {\n jqlBuilder(cloudId: $cloudId) {\n hydrateJqlQuery(query: $jql) {\n ... on JiraJqlHydratedQuery {\n fields {\n ... on JiraJqlQueryHydratedField {\n jqlTerm\n values {\n ... on JiraJqlQueryHydratedValue {\n values {\n ... on JiraJqlProjectFieldValue {\n jqlTerm\n displayName\n project {\n avatar {\n small\n }\n }\n }\n ... on JiraJqlStatusFieldValue {\n jqlTerm\n displayName\n statusCategory {\n colorName\n }\n }\n ... on JiraJqlIssueTypeFieldValue {\n jqlTerm\n displayName\n issueTypes {\n avatar {\n small\n }\n }\n }\n ... on JiraJqlUserFieldValue {\n jqlTerm\n displayName\n user {\n picture\n }\n }\n ... on JiraJqlGroupFieldValue {\n jqlTerm\n displayName\n group {\n name\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n}";
2
- export var fieldValuesQuery = "query fieldValues($cloudId: ID!, $first: Int = 10, $jqlTerm: String!, $jql: String!, $searchString: String!, $after: String, $projectOptions: JiraProjectOptions) {\n jira {\n jqlBuilder(cloudId: $cloudId) {\n fieldValues(\n first: $first\n jqlTerm: $jqlTerm\n jqlContext: $jql\n searchString: $searchString\n after: $after\n ) {\n totalCount\n pageInfo {\n endCursor\n }\n edges {\n node {\n jqlTerm\n displayName\n ... on JiraJqlProjectFieldValue {\n project {\n avatar {\n small\n }\n }\n }\n ... on JiraJqlIssueTypeFieldValue {\n issueTypes {\n avatar {\n small\n }\n }\n }\n ... on JiraJqlStatusFieldValue {\n statusCategory {\n colorName\n }\n }\n ... on JiraJqlUserFieldValue {\n user {\n picture\n }\n }\n ... on JiraJqlGroupFieldValue {\n group {\n name\n }\n }\n }\n }\n }\n }\n }\n}";
2
+ export var fieldValuesQuery = "query fieldValues($cloudId: ID!, $first: Int = 10, $jqlTerm: String!, $jql: String!, $searchString: String!, $after: String) {\n jira {\n jqlBuilder(cloudId: $cloudId) {\n fieldValues(\n first: $first\n jqlTerm: $jqlTerm\n jqlContext: $jql\n searchString: $searchString\n after: $after\n ) {\n totalCount\n pageInfo {\n endCursor\n }\n edges {\n node {\n jqlTerm\n displayName\n ... on JiraJqlProjectFieldValue {\n project {\n avatar {\n small\n }\n }\n }\n ... on JiraJqlIssueTypeFieldValue {\n issueTypes {\n avatar {\n small\n }\n }\n }\n ... on JiraJqlStatusFieldValue {\n statusCategory {\n colorName\n }\n }\n ... on JiraJqlUserFieldValue {\n user {\n picture\n }\n }\n ... on JiraJqlGroupFieldValue {\n group {\n name\n }\n }\n }\n }\n }\n }\n }\n}";
@@ -14,17 +14,6 @@ import { offsetFromPointer } from '@atlaskit/pragmatic-drag-and-drop/util/offset
14
14
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/util/set-custom-native-drag-preview';
15
15
  import { TableHeading } from './styled';
16
16
  import { COLUMN_MIN_WIDTH } from './index';
17
- var tableHeadingStatusStyles = {
18
- idle: css({
19
- ':hover': {
20
- background: "var(--ds-surface-hovered, #091E4224)"
21
- }
22
- }),
23
- dragging: css({
24
- background: "var(--ds-background-disabled, #091E4224)",
25
- color: "var(--ds-text-disabled, #091E424F)"
26
- })
27
- };
28
17
  var verticallyAlignedStyles = css({
29
18
  display: 'flex',
30
19
  alignItems: 'center',
@@ -267,7 +256,6 @@ export var DraggableTableHeading = function DraggableTableHeading(_ref) {
267
256
  }, [id, index, onWidthChange, state, tableId, width]);
268
257
  return jsx(TableHeading, {
269
258
  ref: mainHeaderCellRef,
270
- css: [tableHeadingStatusStyles[state.type]],
271
259
  "data-testid": "".concat(id, "-column-heading"),
272
260
  style: {
273
261
  width: width,
@@ -366,6 +366,11 @@ export var IssueLikeDataTableView = function IssueLikeDataTableView(_ref) {
366
366
  }, _callee, null, [[3, 9]]);
367
367
  })), [parentContainerRenderInstanceId, extensionKey, hasFullSchema, onLoadDatasourceDetails]);
368
368
  return jsx("div", {
369
+ /* There is required contentEditable={true} in editor-card-plugin
370
+ * But this brakes how DND works. We set contentEditable={false} to allow DND to work
371
+ * when dragging is initiated on top of a column label.
372
+ */
373
+ contentEditable: false,
369
374
  ref: containerRef,
370
375
  css: scrollableContainerHeight ? scrollableContainerStyles : null,
371
376
  style: scrollableContainerHeight ? {
@@ -5,4 +5,4 @@ import { N40 } from '@atlaskit/theme/colors';
5
5
  export var ScrollableContainerHeight = 590;
6
6
  export var FieldTextFontSize = '14px';
7
7
  export var Table = styled.table(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n width: 100%;\n"])));
8
- export var TableHeading = styled.th(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n padding-block: ", " ", ";\n line-height: ", ";\n border-bottom: 2px solid ", ";\n & [data-testid='datasource-header-content--container'] {\n margin-top: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n"])), "var(--ds-space-300, 24px)", "var(--ds-space-100, 8px)", "var(--ds-font-lineHeight-300, 16px)", "var(--ds-background-accent-gray-subtler, ".concat(N40, ")"));
8
+ export var TableHeading = styled.th(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n line-height: ", ";\n border-bottom: 2px solid ", ";\n height: calc(52px - ", " * 2 - 2px);\n vertical-align: bottom;\n\n & [data-testid='datasource-header-content--container'] {\n width: 100%;\n padding: ", " ", ";\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n white-space: normal;\n overflow: hidden;\n max-height: 2.5rem;\n word-wrap: break-word;\n\n &:hover {\n background: ", ";\n border-radius: 3px;\n }\n }\n"])), "var(--ds-font-lineHeight-300, 16px)", "var(--ds-background-accent-gray-subtler, ".concat(N40, ")"), "var(--ds-space-050, 4px)", "var(--ds-space-100, 4px)", "var(--ds-space-050, 2px)", "var(--ds-background-input-hovered, #F7F8F9)");
@@ -0,0 +1,87 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
5
+ import { useCallback, useState } from 'react';
6
+ import { useBasicFilterAGG } from '../../../../services/useBasicFilterAGG';
7
+ import { mapFieldValuesToFilterOptions, mapFieldValuesToPageCursor, mapFieldValuesToTotalCount } from '../utils/transformers';
8
+ export var useFilterOptions = function useFilterOptions(_ref) {
9
+ var filterType = _ref.filterType,
10
+ cloudId = _ref.cloudId;
11
+ var _useState = useState([]),
12
+ _useState2 = _slicedToArray(_useState, 2),
13
+ filterOptions = _useState2[0],
14
+ setFilterOptions = _useState2[1];
15
+ var _useState3 = useState(0),
16
+ _useState4 = _slicedToArray(_useState3, 2),
17
+ totalCount = _useState4[0],
18
+ setTotalCount = _useState4[1];
19
+ var _useState5 = useState('empty'),
20
+ _useState6 = _slicedToArray(_useState5, 2),
21
+ status = _useState6[0],
22
+ setStatus = _useState6[1];
23
+ var _useState7 = useState(undefined),
24
+ _useState8 = _slicedToArray(_useState7, 2),
25
+ nextPageCursor = _useState8[0],
26
+ setNextPageCursor = _useState8[1];
27
+ var _useBasicFilterAGG = useBasicFilterAGG(),
28
+ getFieldValues = _useBasicFilterAGG.getFieldValues;
29
+ var fetchFilterOptions = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
30
+ var _ref3,
31
+ pageCursor,
32
+ searchString,
33
+ response,
34
+ isNewSearch,
35
+ _args = arguments;
36
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
37
+ while (1) switch (_context.prev = _context.next) {
38
+ case 0:
39
+ _ref3 = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, pageCursor = _ref3.pageCursor, searchString = _ref3.searchString;
40
+ setStatus('loading');
41
+ _context.prev = 2;
42
+ _context.next = 5;
43
+ return getFieldValues({
44
+ cloudId: cloudId,
45
+ jql: '',
46
+ jqlTerm: filterType,
47
+ searchString: searchString,
48
+ pageCursor: pageCursor
49
+ });
50
+ case 5:
51
+ response = _context.sent;
52
+ if (!(response.errors && response.errors.length > 0)) {
53
+ _context.next = 9;
54
+ break;
55
+ }
56
+ setStatus('rejected');
57
+ return _context.abrupt("return");
58
+ case 9:
59
+ isNewSearch = !pageCursor;
60
+ if (isNewSearch) {
61
+ setFilterOptions(mapFieldValuesToFilterOptions(response));
62
+ } else {
63
+ setFilterOptions([].concat(_toConsumableArray(filterOptions), _toConsumableArray(mapFieldValuesToFilterOptions(response))));
64
+ }
65
+ setTotalCount(mapFieldValuesToTotalCount(response));
66
+ setNextPageCursor(mapFieldValuesToPageCursor(response));
67
+ setStatus('resolved');
68
+ _context.next = 19;
69
+ break;
70
+ case 16:
71
+ _context.prev = 16;
72
+ _context.t0 = _context["catch"](2);
73
+ setStatus('rejected');
74
+ case 19:
75
+ case "end":
76
+ return _context.stop();
77
+ }
78
+ }, _callee, null, [[2, 16]]);
79
+ })), [cloudId, filterOptions, filterType, getFieldValues]);
80
+ return {
81
+ filterOptions: filterOptions,
82
+ fetchFilterOptions: fetchFilterOptions,
83
+ totalCount: totalCount,
84
+ pageCursor: nextPageCursor,
85
+ status: status
86
+ };
87
+ };
@@ -7,7 +7,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
7
7
  import React, { useCallback, useEffect, useRef, useState } from 'react';
8
8
  import { useIntl } from 'react-intl-next';
9
9
  import { CheckboxOption, PopupSelect } from '@atlaskit/select';
10
- import { useFieldValues } from '../../hooks/useFieldValues';
10
+ import { useFilterOptions } from '../../hooks/useFilterOptions';
11
11
  import CustomControl from './control';
12
12
  import PopupFooter from './footer';
13
13
  import formatOptionLabel from './formatOptionLabel';
@@ -19,6 +19,7 @@ var noFilterOptions = function noFilterOptions() {
19
19
  };
20
20
  var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
21
21
  var filterType = _ref.filterType,
22
+ cloudId = _ref.cloudId,
22
23
  selection = _ref.selection,
23
24
  _ref$onSelectionChang = _ref.onSelectionChange,
24
25
  onSelectionChange = _ref$onSelectionChang === void 0 ? function () {} : _ref$onSelectionChang;
@@ -33,13 +34,14 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
33
34
  _useState4 = _slicedToArray(_useState3, 2),
34
35
  selectedOptions = _useState4[0],
35
36
  setSelectedOptions = _useState4[1];
36
- var _useFieldValues = useFieldValues({
37
- filterType: filterType
37
+ var _useFilterOptions = useFilterOptions({
38
+ filterType: filterType,
39
+ cloudId: cloudId
38
40
  }),
39
- filterOptions = _useFieldValues.filterOptions,
40
- fetchFilterOptions = _useFieldValues.fetchFilterOptions,
41
- totalCount = _useFieldValues.totalCount,
42
- status = _useFieldValues.status;
41
+ filterOptions = _useFilterOptions.filterOptions,
42
+ fetchFilterOptions = _useFilterOptions.fetchFilterOptions,
43
+ totalCount = _useFilterOptions.totalCount,
44
+ status = _useFilterOptions.status;
43
45
  var handleInputChange = useCallback(function (searchString, actionMeta) {
44
46
  if (actionMeta.action === 'input-change' && searchString !== searchTerm) {
45
47
  setSearchTerm(searchString);
@@ -53,10 +55,13 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
53
55
  return _regeneratorRuntime.wrap(function _callee$(_context) {
54
56
  while (1) switch (_context.prev = _context.next) {
55
57
  case 0:
56
- if (status === 'empty') {
57
- fetchFilterOptions();
58
+ if (!(status === 'empty')) {
59
+ _context.next = 3;
60
+ break;
58
61
  }
59
- case 1:
62
+ _context.next = 3;
63
+ return fetchFilterOptions();
64
+ case 3:
60
65
  case "end":
61
66
  return _context.stop();
62
67
  }
@@ -69,18 +74,24 @@ var AsyncPopupSelect = function AsyncPopupSelect(_ref) {
69
74
  pickerRef === null || pickerRef === void 0 || (_pickerRef$current = pickerRef.current) === null || _pickerRef$current === void 0 || (_pickerRef$current = _pickerRef$current.selectRef) === null || _pickerRef$current === void 0 || (_pickerRef$current = _pickerRef$current.inputRef) === null || _pickerRef$current === void 0 || _pickerRef$current.focus();
70
75
  }
71
76
  }, [status]);
77
+ var isLoading = status === 'loading' || status === 'empty';
72
78
  return /*#__PURE__*/React.createElement(PopupSelect, {
73
79
  isMulti: true,
74
80
  maxMenuWidth: 300,
75
81
  minMenuWidth: 300,
76
82
  ref: pickerRef,
77
83
  testId: "jlol-basic-filter-popup-select",
78
- inputId: "jlol-basic-filter-popup-select--input",
79
- searchThreshold: 0,
84
+ inputId: "jlol-basic-filter-popup-select--input"
85
+ /*
86
+ this threshold controls the display of the search control (input field for search)
87
+ if this threshold is less than 0, when typing a search string that returns no results it will not remove the search control
88
+ if this threshold is 0 or higher, it will remove the search control when there are no results, the user will be unable to clear the search to see more results
89
+ */,
90
+ searchThreshold: -1,
80
91
  inputValue: searchTerm,
81
92
  closeMenuOnSelect: false,
82
93
  hideSelectedOptions: false,
83
- isLoading: status === 'loading',
94
+ isLoading: isLoading,
84
95
  placeholder: formatMessage(asyncPopupSelectMessages.selectPlaceholder),
85
96
  components: {
86
97
  /* @ts-expect-error - This component has stricter OptionType, hence a temp setup untill its made generic */
@@ -5,7 +5,8 @@ import { isValidJql } from '../utils';
5
5
  import AsyncPopupSelect from './async-popup-select';
6
6
  var availableBasicFilterTypes = ['project', 'issuetype', 'status', 'assignee'];
7
7
  var BasicFilterContainer = function BasicFilterContainer(_ref) {
8
- var jql = _ref.jql;
8
+ var jql = _ref.jql,
9
+ cloudId = _ref.cloudId;
9
10
  var _useState = useState([]),
10
11
  _useState2 = _slicedToArray(_useState, 1),
11
12
  selection = _useState2[0];
@@ -20,6 +21,7 @@ var BasicFilterContainer = function BasicFilterContainer(_ref) {
20
21
  testId: "jlol-basic-filter-container"
21
22
  }, availableBasicFilterTypes.map(function (filter) {
22
23
  return /*#__PURE__*/React.createElement(AsyncPopupSelect, {
24
+ cloudId: cloudId,
23
25
  filterType: filter,
24
26
  key: filter,
25
27
  selection: selection,
@@ -30,7 +30,7 @@ function mapNodeToOption(_ref) {
30
30
  return _objectSpread(_objectSpread({}, baseProps), {}, {
31
31
  optionType: 'avatarLabel',
32
32
  avatar: user.picture,
33
- isSquare: true
33
+ isSquare: false
34
34
  });
35
35
  }
36
36
  if (group) {
@@ -80,10 +80,20 @@ export function mapHydrateResponseData(_ref2) {
80
80
  });
81
81
  return transformedHydrateResponseData;
82
82
  }
83
- export function mapFieldValuesResponseData(_ref5) {
83
+ export function mapFieldValuesToFilterOptions(_ref5) {
84
84
  var _data$jira2;
85
85
  var data = _ref5.data;
86
86
  return (data === null || data === void 0 || (_data$jira2 = data.jira) === null || _data$jira2 === void 0 || (_data$jira2 = _data$jira2.jqlBuilder) === null || _data$jira2 === void 0 || (_data$jira2 = _data$jira2.fieldValues) === null || _data$jira2 === void 0 || (_data$jira2 = _data$jira2.edges) === null || _data$jira2 === void 0 ? void 0 : _data$jira2.map(function (edge) {
87
87
  return edge.node ? mapNodeToOption(edge.node) : null;
88
88
  }).filter(isNonNullSelectOption)) || [];
89
+ }
90
+ export function mapFieldValuesToTotalCount(_ref6) {
91
+ var _data$jira3;
92
+ var data = _ref6.data;
93
+ return (data === null || data === void 0 || (_data$jira3 = data.jira) === null || _data$jira3 === void 0 || (_data$jira3 = _data$jira3.jqlBuilder) === null || _data$jira3 === void 0 || (_data$jira3 = _data$jira3.fieldValues) === null || _data$jira3 === void 0 ? void 0 : _data$jira3.totalCount) || 0;
94
+ }
95
+ export function mapFieldValuesToPageCursor(_ref7) {
96
+ var _data$jira4;
97
+ var data = _ref7.data;
98
+ return data === null || data === void 0 || (_data$jira4 = data.jira) === null || _data$jira4 === void 0 || (_data$jira4 = _data$jira4.jqlBuilder) === null || _data$jira4 === void 0 || (_data$jira4 = _data$jira4.fieldValues) === null || _data$jira4 === void 0 || (_data$jira4 = _data$jira4.pageInfo) === null || _data$jira4 === void 0 ? void 0 : _data$jira4.endCursor;
89
99
  }