@atlaskit/link-datasource 0.20.0 → 0.21.1

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 (32) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/hooks/useDatasourceTableState.js +137 -57
  3. package/dist/cjs/ui/datasource-table-view/datasourceTableView.js +8 -2
  4. package/dist/cjs/ui/issue-like-table/column-picker/index.js +9 -3
  5. package/dist/cjs/ui/issue-like-table/index.js +61 -21
  6. package/dist/cjs/ui/jira-issues-modal/modal/index.js +13 -12
  7. package/dist/cjs/version.json +1 -1
  8. package/dist/es2019/hooks/useDatasourceTableState.js +84 -19
  9. package/dist/es2019/ui/datasource-table-view/datasourceTableView.js +8 -2
  10. package/dist/es2019/ui/issue-like-table/column-picker/index.js +9 -3
  11. package/dist/es2019/ui/issue-like-table/index.js +24 -5
  12. package/dist/es2019/ui/jira-issues-modal/modal/index.js +10 -9
  13. package/dist/es2019/version.json +1 -1
  14. package/dist/esm/hooks/useDatasourceTableState.js +137 -57
  15. package/dist/esm/ui/datasource-table-view/datasourceTableView.js +8 -2
  16. package/dist/esm/ui/issue-like-table/column-picker/index.js +9 -3
  17. package/dist/esm/ui/issue-like-table/index.js +61 -21
  18. package/dist/esm/ui/jira-issues-modal/modal/index.js +13 -12
  19. package/dist/esm/version.json +1 -1
  20. package/dist/types/hooks/useDatasourceTableState.d.ts +14 -3
  21. package/dist/types/ui/issue-like-table/column-picker/index.d.ts +1 -1
  22. package/dist/types/ui/issue-like-table/column-picker/types.d.ts +1 -0
  23. package/dist/types/ui/issue-like-table/index.d.ts +1 -1
  24. package/dist/types/ui/issue-like-table/types.d.ts +3 -1
  25. package/dist/types-ts4.5/hooks/useDatasourceTableState.d.ts +14 -3
  26. package/dist/types-ts4.5/ui/issue-like-table/column-picker/index.d.ts +1 -1
  27. package/dist/types-ts4.5/ui/issue-like-table/column-picker/types.d.ts +1 -0
  28. package/dist/types-ts4.5/ui/issue-like-table/index.d.ts +1 -1
  29. package/dist/types-ts4.5/ui/issue-like-table/types.d.ts +3 -1
  30. package/examples-helpers/buildIssueLikeTable.tsx +11 -3
  31. package/examples-helpers/buildJiraIssuesTable.tsx +7 -2
  32. package/package.json +3 -3
@@ -1,7 +1,12 @@
1
1
  import { useCallback, useEffect, useState } from 'react';
2
2
  import { useDatasourceClientExtension } from '@atlaskit/link-client-extension';
3
- export const useDatasourceTableState = (datasourceId, parameters, fields) => {
3
+ export const useDatasourceTableState = ({
4
+ datasourceId,
5
+ parameters,
6
+ fieldKeys = []
7
+ }) => {
4
8
  const [defaultVisibleColumnKeys, setDefaultVisibleColumnKeys] = useState([]);
9
+ const [lastRequestedFieldKeys, setLastRequestedFieldKeys] = useState([]);
5
10
  const [status, setStatus] = useState('empty');
6
11
  const [responseItems, setResponseItems] = useState([]);
7
12
  const [hasNextPage, setHasNextPage] = useState(true);
@@ -12,51 +17,111 @@ export const useDatasourceTableState = (datasourceId, parameters, fields) => {
12
17
  getDatasourceData,
13
18
  getDatasourceDetails
14
19
  } = useDatasourceClientExtension();
15
- const loadDatasourceDetails = useCallback(async parameters => {
20
+ const loadDatasourceDetails = useCallback(async () => {
21
+ if (!parameters) {
22
+ return;
23
+ }
16
24
  const result = await getDatasourceDetails(datasourceId, {
17
25
  parameters
18
26
  });
19
- setColumns(result.schema.properties);
20
- setDefaultVisibleColumnKeys(result.schema.defaultProperties);
21
- }, [datasourceId, getDatasourceDetails]);
22
- useEffect(() => {
23
- if (parameters) {
24
- void loadDatasourceDetails(parameters);
27
+ const isColumnNotPresentInCurrentColumnsList = col => !columns.find(column => column.key === col.key);
28
+ const allColumns = result.schema.properties;
29
+ const newColumns = allColumns.filter(isColumnNotPresentInCurrentColumnsList);
30
+ newColumns.length > 0 && setColumns([...columns, ...newColumns]);
31
+ }, [columns, datasourceId, getDatasourceDetails, parameters]);
32
+ const applySchemaProperties = useCallback(properties => {
33
+ if (columns.length === 0) {
34
+ setColumns(properties);
35
+ }
36
+ const defaultProperties = properties.map(prop => prop.key);
37
+
38
+ // when loading for the first time, we will need to set default visible props as /data does not give you that info
39
+ // also, since we dont pass any fields, we will need to set this info as lastRequestedFieldKeys
40
+ if (defaultVisibleColumnKeys.length === 0) {
41
+ setDefaultVisibleColumnKeys(defaultProperties);
25
42
  }
26
- }, [loadDatasourceDetails, parameters]);
27
- const onNextPage = useCallback(async () => {
43
+ if (lastRequestedFieldKeys.length === 0) {
44
+ setLastRequestedFieldKeys(defaultProperties);
45
+ }
46
+ }, [columns.length, defaultVisibleColumnKeys.length, lastRequestedFieldKeys === null || lastRequestedFieldKeys === void 0 ? void 0 : lastRequestedFieldKeys.length]);
47
+ const onNextPage = useCallback(async (requestInfo = {}) => {
28
48
  if (!parameters) {
29
49
  return;
30
50
  }
51
+ const {
52
+ isSchemaFromData = true,
53
+ shouldRequestFirstPage
54
+ } = requestInfo;
55
+ const datasourceDataRequest = {
56
+ parameters,
57
+ pageSize: 20,
58
+ pageCursor: shouldRequestFirstPage ? undefined : nextCursor,
59
+ fields: fieldKeys,
60
+ includeSchema: isSchemaFromData
61
+ };
31
62
  setStatus('loading');
32
63
  const {
33
64
  data,
34
65
  nextPageCursor,
35
- totalIssues
36
- } = await getDatasourceData(datasourceId, {
37
- parameters,
38
- pageSize: 20,
39
- pageCursor: nextCursor,
40
- fields
41
- });
66
+ totalIssues,
67
+ schema
68
+ } = await getDatasourceData(datasourceId, datasourceDataRequest);
42
69
  setTotalIssueCount(totalIssues);
43
70
  setNextCursor(nextPageCursor);
44
- setResponseItems(currentResponseItems => [...currentResponseItems, ...data]);
71
+ setResponseItems(currentResponseItems => {
72
+ if (shouldRequestFirstPage) {
73
+ return data;
74
+ }
75
+ return [...currentResponseItems, ...data];
76
+ });
45
77
  setStatus('resolved');
46
78
  setHasNextPage(Boolean(nextPageCursor));
47
- }, [parameters, getDatasourceData, datasourceId, nextCursor, fields]);
79
+ if (fieldKeys.length > 0) {
80
+ setLastRequestedFieldKeys(fieldKeys);
81
+ }
82
+ if (isSchemaFromData && schema) {
83
+ applySchemaProperties(schema.properties);
84
+ }
85
+ }, [parameters, fieldKeys, getDatasourceData, datasourceId, nextCursor, applySchemaProperties]);
48
86
  const reset = useCallback(() => {
49
87
  setStatus('empty');
50
88
  setResponseItems([]);
51
89
  setHasNextPage(true);
52
90
  setNextCursor(undefined);
53
91
  setTotalIssueCount(undefined);
92
+ setLastRequestedFieldKeys([]);
54
93
  }, []);
94
+
95
+ // this takes care of requesting /data initally
96
+ useEffect(() => {
97
+ const isEmptyState = Object.keys(parameters || {}).length > 0 && lastRequestedFieldKeys.length === 0 && status === 'empty';
98
+ if (isEmptyState) {
99
+ void onNextPage();
100
+ }
101
+ }, [lastRequestedFieldKeys, loadDatasourceDetails, onNextPage, parameters, status]);
102
+
103
+ // this takes care of requesting /data when user selects/unselects a column
104
+ useEffect(() => {
105
+ const canHaveNewColumns = fieldKeys.length > 0 && lastRequestedFieldKeys.length > 0;
106
+ if (canHaveNewColumns) {
107
+ const hasNewColumns = fieldKeys.some(key => !lastRequestedFieldKeys.includes(key));
108
+ if (!hasNewColumns) {
109
+ return;
110
+ }
111
+ reset();
112
+ void onNextPage({
113
+ isSchemaFromData: false,
114
+ // since this is not inital load, we will already have schema
115
+ shouldRequestFirstPage: true
116
+ });
117
+ }
118
+ }, [fieldKeys, lastRequestedFieldKeys, onNextPage, reset]);
55
119
  return {
56
120
  status,
57
121
  onNextPage,
58
122
  responseItems,
59
123
  reset,
124
+ loadDatasourceDetails,
60
125
  hasNextPage,
61
126
  columns,
62
127
  defaultVisibleColumnKeys,
@@ -29,8 +29,13 @@ export const DatasourceTableView = ({
29
29
  hasNextPage,
30
30
  columns,
31
31
  defaultVisibleColumnKeys,
32
- totalIssueCount
33
- } = useDatasourceTableState(datasourceId, parameters);
32
+ totalIssueCount,
33
+ loadDatasourceDetails
34
+ } = useDatasourceTableState({
35
+ datasourceId,
36
+ parameters,
37
+ fieldKeys: visibleColumnKeys
38
+ });
34
39
  useEffect(() => {
35
40
  if (onVisibleColumnKeysChange && (visibleColumnKeys || []).length === 0 && defaultVisibleColumnKeys.length > 0) {
36
41
  onVisibleColumnKeysChange(defaultVisibleColumnKeys);
@@ -43,6 +48,7 @@ export const DatasourceTableView = ({
43
48
  hasNextPage: hasNextPage,
44
49
  items: responseItems,
45
50
  onNextPage: onNextPage,
51
+ onLoadDatasourceDetails: loadDatasourceDetails,
46
52
  status: status,
47
53
  columns: columns,
48
54
  visibleColumnKeys: visibleColumnKeys || defaultVisibleColumnKeys,
@@ -12,7 +12,8 @@ export const ColumnPicker = ({
12
12
  isDatasourceLoading,
13
13
  columns,
14
14
  selectedColumnKeys,
15
- onSelectedColumnKeysChange
15
+ onSelectedColumnKeysChange,
16
+ onOpen
16
17
  }) => {
17
18
  const intl = useIntl();
18
19
  const [allOptions, setAllOptions] = useState([]);
@@ -46,7 +47,7 @@ export const ColumnPicker = ({
46
47
  });
47
48
  onSelectedColumnKeysChange(selectedValues);
48
49
  }, [columns, onSelectedColumnKeysChange]);
49
- const onPopupOpen = useCallback(() => {
50
+ const sortSelectedColumnsTop = useCallback(() => {
50
51
  if (!allOptions.length) {
51
52
  return;
52
53
  }
@@ -54,6 +55,10 @@ export const ColumnPicker = ({
54
55
  const sortedOptions = [...selectedOptions, ...nonSelectedOptions];
55
56
  sortedOptions.length > 0 && setAllOptions(sortedOptions);
56
57
  }, [allOptions, selectedOptions]);
58
+ const handleOpen = useCallback(() => {
59
+ onOpen && void onOpen();
60
+ void sortSelectedColumnsTop();
61
+ }, [onOpen, sortSelectedColumnsTop]);
57
62
  return jsx(PopupSelect, {
58
63
  classNamePrefix: 'column-picker-popup',
59
64
  testId: 'column-picker-popup',
@@ -62,13 +67,14 @@ export const ColumnPicker = ({
62
67
  },
63
68
  options: allOptions,
64
69
  value: selectedOptions,
65
- onOpen: onPopupOpen,
70
+ onOpen: handleOpen,
66
71
  closeMenuOnSelect: false,
67
72
  hideSelectedOptions: false,
68
73
  isMulti: true,
69
74
  placeholder: intl.formatMessage(columnPickerMessages.search),
70
75
  "aria-label": "Search for fields",
71
76
  onChange: handleChange,
77
+ isLoading: allOptions.length === 0,
72
78
  target: ({
73
79
  isOpen,
74
80
  ...triggerProps
@@ -85,6 +85,7 @@ function getColumnWidth(key, type) {
85
85
  export const IssueLikeDataTableView = ({
86
86
  testId,
87
87
  onNextPage,
88
+ onLoadDatasourceDetails,
88
89
  items,
89
90
  columns,
90
91
  renderItem = fallbackRenderType,
@@ -96,9 +97,13 @@ export const IssueLikeDataTableView = ({
96
97
  const tableId = useMemo(() => Symbol('unique-id'), []);
97
98
  const [lastRowElement, setLastRowElement] = useState(null);
98
99
  const [isDragPreview, setIsDragPreview] = useState(false);
100
+ const [hasFullSchema, setHasFullSchema] = useState(false);
99
101
  const isBottomOfTableVisibleRaw = useIsOnScreen(lastRowElement);
100
102
  const containerRef = useRef(null);
101
103
  const [orderedColumns, setOrderedColumns] = useState(() => orderColumns([...columns], [...visibleColumnKeys]));
104
+ useEffect(() => {
105
+ setOrderedColumns(orderColumns([...columns], [...visibleColumnKeys]));
106
+ }, [columns, visibleColumnKeys]);
102
107
  const visibleSortedColumns = useMemo(() => visibleColumnKeys.map(visibleKey => orderedColumns.find(({
103
108
  key
104
109
  }) => visibleKey === key)).filter(Boolean), [orderedColumns, visibleColumnKeys]);
@@ -135,8 +140,10 @@ export const IssueLikeDataTableView = ({
135
140
  maxWidth: getColumnWidth(key, type)
136
141
  }));
137
142
  useEffect(() => {
138
- if (status === 'empty' || isBottomOfTableVisibleRaw && hasNextPage && status !== 'loading') {
139
- void onNextPage();
143
+ if (isBottomOfTableVisibleRaw && hasNextPage && status === 'resolved') {
144
+ void onNextPage({
145
+ isSchemaFromData: false
146
+ });
140
147
  }
141
148
  }, [isBottomOfTableVisibleRaw, status, hasNextPage, onNextPage]);
142
149
  let dndPreviewHeight = 0;
@@ -235,6 +242,17 @@ export const IssueLikeDataTableView = ({
235
242
  const onSelectedColumnKeysChange = useCallback(newSelectedColumnKeys => {
236
243
  onVisibleColumnKeysChange === null || onVisibleColumnKeysChange === void 0 ? void 0 : onVisibleColumnKeysChange(newSelectedColumnKeys);
237
244
  }, [onVisibleColumnKeysChange]);
245
+ const handlePickerOpen = useCallback(async () => {
246
+ if (hasFullSchema) {
247
+ return;
248
+ }
249
+ try {
250
+ await onLoadDatasourceDetails();
251
+ setHasFullSchema(true);
252
+ } catch (e) {
253
+ setHasFullSchema(false);
254
+ }
255
+ }, [hasFullSchema, onLoadDatasourceDetails]);
238
256
  return jsx("div", {
239
257
  ref: containerRef,
240
258
  css: isDragPreview ? containerDragPreviewStyles : null
@@ -275,10 +293,11 @@ export const IssueLikeDataTableView = ({
275
293
  }), onVisibleColumnKeysChange && jsx("th", {
276
294
  css: columnPickerHeaderStyles
277
295
  }, jsx(ColumnPicker, {
296
+ columns: hasFullSchema ? orderedColumns : [],
297
+ selectedColumnKeys: hasFullSchema ? visibleColumnKeys : [],
278
298
  isDatasourceLoading: status === 'loading',
279
- columns: orderedColumns,
280
- selectedColumnKeys: visibleColumnKeys,
281
- onSelectedColumnKeysChange: onSelectedColumnKeysChange
299
+ onSelectedColumnKeysChange: onSelectedColumnKeysChange,
300
+ onOpen: handlePickerOpen
282
301
  })))), jsx("tbody", {
283
302
  "data-testid": testId && `${testId}--body`
284
303
  }, rows.map(({
@@ -46,6 +46,7 @@ export const JiraIssuesConfigModal = props => {
46
46
  cloudId,
47
47
  jql: jql || ''
48
48
  } : undefined, [cloudId, jql]);
49
+ const [visibleColumnKeys, setVisibleColumnKeys] = useState(initialVisibleColumnKeys);
49
50
  const {
50
51
  reset,
51
52
  status,
@@ -53,9 +54,13 @@ export const JiraIssuesConfigModal = props => {
53
54
  responseItems,
54
55
  hasNextPage,
55
56
  columns,
56
- defaultVisibleColumnKeys
57
- } = useDatasourceTableState(datasourceId, parameters);
58
- const [visibleColumnKeys, setVisibleColumnKeys] = useState(initialVisibleColumnKeys || defaultVisibleColumnKeys);
57
+ defaultVisibleColumnKeys,
58
+ loadDatasourceDetails
59
+ } = useDatasourceTableState({
60
+ datasourceId,
61
+ parameters: isParametersSet ? parameters : undefined,
62
+ fieldKeys: visibleColumnKeys
63
+ });
59
64
  useEffect(() => {
60
65
  const newVisibleColumnKeys = !initialVisibleColumnKeys || (initialVisibleColumnKeys || []).length === 0 ? defaultVisibleColumnKeys : initialVisibleColumnKeys;
61
66
  setVisibleColumnKeys(newVisibleColumnKeys);
@@ -134,11 +139,6 @@ export const JiraIssuesConfigModal = props => {
134
139
  const handleViewModeChange = selectedMode => {
135
140
  setCurrentViewMode(selectedMode);
136
141
  };
137
- useEffect(() => {
138
- if (status === 'empty' && isParametersSet) {
139
- void onNextPage();
140
- }
141
- }, [status, isParametersSet, onNextPage, reset]);
142
142
  const issueLikeDataTableView = useMemo(() => jsx(IssueLikeDataTableView, {
143
143
  testId: "jira-jql-datasource-table",
144
144
  status: status,
@@ -147,8 +147,9 @@ export const JiraIssuesConfigModal = props => {
147
147
  hasNextPage: hasNextPage,
148
148
  visibleColumnKeys: visibleColumnKeys || defaultVisibleColumnKeys,
149
149
  onNextPage: onNextPage,
150
+ onLoadDatasourceDetails: loadDatasourceDetails,
150
151
  onVisibleColumnKeysChange: setVisibleColumnKeys
151
- }), [columns, defaultVisibleColumnKeys, hasNextPage, onNextPage, responseItems, status, visibleColumnKeys]);
152
+ }), [columns, defaultVisibleColumnKeys, hasNextPage, loadDatasourceDetails, onNextPage, responseItems, status, visibleColumnKeys]);
152
153
  const renderCountModeContent = useCallback(() => {
153
154
  const url = selectedJiraSite === null || selectedJiraSite === void 0 ? void 0 : selectedJiraSite.url;
154
155
  if (status === 'empty' || !jql || !url) {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "0.20.0",
3
+ "version": "0.21.1",
4
4
  "sideEffects": false
5
5
  }
@@ -4,116 +4,196 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
4
  import _regeneratorRuntime from "@babel/runtime/regenerator";
5
5
  import { useCallback, useEffect, useState } from 'react';
6
6
  import { useDatasourceClientExtension } from '@atlaskit/link-client-extension';
7
- export var useDatasourceTableState = function useDatasourceTableState(datasourceId, parameters, fields) {
7
+ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
8
+ var datasourceId = _ref.datasourceId,
9
+ parameters = _ref.parameters,
10
+ _ref$fieldKeys = _ref.fieldKeys,
11
+ fieldKeys = _ref$fieldKeys === void 0 ? [] : _ref$fieldKeys;
8
12
  var _useState = useState([]),
9
13
  _useState2 = _slicedToArray(_useState, 2),
10
14
  defaultVisibleColumnKeys = _useState2[0],
11
15
  setDefaultVisibleColumnKeys = _useState2[1];
12
- var _useState3 = useState('empty'),
16
+ var _useState3 = useState([]),
13
17
  _useState4 = _slicedToArray(_useState3, 2),
14
- status = _useState4[0],
15
- setStatus = _useState4[1];
16
- var _useState5 = useState([]),
18
+ lastRequestedFieldKeys = _useState4[0],
19
+ setLastRequestedFieldKeys = _useState4[1];
20
+ var _useState5 = useState('empty'),
17
21
  _useState6 = _slicedToArray(_useState5, 2),
18
- responseItems = _useState6[0],
19
- setResponseItems = _useState6[1];
20
- var _useState7 = useState(true),
22
+ status = _useState6[0],
23
+ setStatus = _useState6[1];
24
+ var _useState7 = useState([]),
21
25
  _useState8 = _slicedToArray(_useState7, 2),
22
- hasNextPage = _useState8[0],
23
- setHasNextPage = _useState8[1];
24
- var _useState9 = useState(undefined),
26
+ responseItems = _useState8[0],
27
+ setResponseItems = _useState8[1];
28
+ var _useState9 = useState(true),
25
29
  _useState10 = _slicedToArray(_useState9, 2),
26
- nextCursor = _useState10[0],
27
- setNextCursor = _useState10[1];
28
- var _useState11 = useState([]),
30
+ hasNextPage = _useState10[0],
31
+ setHasNextPage = _useState10[1];
32
+ var _useState11 = useState(undefined),
29
33
  _useState12 = _slicedToArray(_useState11, 2),
30
- columns = _useState12[0],
31
- setColumns = _useState12[1];
32
- var _useState13 = useState(undefined),
34
+ nextCursor = _useState12[0],
35
+ setNextCursor = _useState12[1];
36
+ var _useState13 = useState([]),
33
37
  _useState14 = _slicedToArray(_useState13, 2),
34
- totalIssueCount = _useState14[0],
35
- setTotalIssueCount = _useState14[1];
38
+ columns = _useState14[0],
39
+ setColumns = _useState14[1];
40
+ var _useState15 = useState(undefined),
41
+ _useState16 = _slicedToArray(_useState15, 2),
42
+ totalIssueCount = _useState16[0],
43
+ setTotalIssueCount = _useState16[1];
36
44
  var _useDatasourceClientE = useDatasourceClientExtension(),
37
45
  getDatasourceData = _useDatasourceClientE.getDatasourceData,
38
46
  getDatasourceDetails = _useDatasourceClientE.getDatasourceDetails;
39
- var loadDatasourceDetails = useCallback( /*#__PURE__*/function () {
40
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(parameters) {
41
- var result;
42
- return _regeneratorRuntime.wrap(function _callee$(_context) {
43
- while (1) switch (_context.prev = _context.next) {
44
- case 0:
47
+ var loadDatasourceDetails = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
48
+ var result, isColumnNotPresentInCurrentColumnsList, allColumns, newColumns;
49
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
50
+ while (1) switch (_context.prev = _context.next) {
51
+ case 0:
52
+ if (parameters) {
45
53
  _context.next = 2;
46
- return getDatasourceDetails(datasourceId, {
47
- parameters: parameters
54
+ break;
55
+ }
56
+ return _context.abrupt("return");
57
+ case 2:
58
+ _context.next = 4;
59
+ return getDatasourceDetails(datasourceId, {
60
+ parameters: parameters
61
+ });
62
+ case 4:
63
+ result = _context.sent;
64
+ isColumnNotPresentInCurrentColumnsList = function isColumnNotPresentInCurrentColumnsList(col) {
65
+ return !columns.find(function (column) {
66
+ return column.key === col.key;
48
67
  });
49
- case 2:
50
- result = _context.sent;
51
- setColumns(result.schema.properties);
52
- setDefaultVisibleColumnKeys(result.schema.defaultProperties);
53
- case 5:
54
- case "end":
55
- return _context.stop();
56
- }
57
- }, _callee);
58
- }));
59
- return function (_x) {
60
- return _ref.apply(this, arguments);
61
- };
62
- }(), [datasourceId, getDatasourceDetails]);
63
- useEffect(function () {
64
- if (parameters) {
65
- void loadDatasourceDetails(parameters);
68
+ };
69
+ allColumns = result.schema.properties;
70
+ newColumns = allColumns.filter(isColumnNotPresentInCurrentColumnsList);
71
+ newColumns.length > 0 && setColumns([].concat(_toConsumableArray(columns), _toConsumableArray(newColumns)));
72
+ case 9:
73
+ case "end":
74
+ return _context.stop();
75
+ }
76
+ }, _callee);
77
+ })), [columns, datasourceId, getDatasourceDetails, parameters]);
78
+ var applySchemaProperties = useCallback(function (properties) {
79
+ if (columns.length === 0) {
80
+ setColumns(properties);
81
+ }
82
+ var defaultProperties = properties.map(function (prop) {
83
+ return prop.key;
84
+ });
85
+
86
+ // when loading for the first time, we will need to set default visible props as /data does not give you that info
87
+ // also, since we dont pass any fields, we will need to set this info as lastRequestedFieldKeys
88
+ if (defaultVisibleColumnKeys.length === 0) {
89
+ setDefaultVisibleColumnKeys(defaultProperties);
90
+ }
91
+ if (lastRequestedFieldKeys.length === 0) {
92
+ setLastRequestedFieldKeys(defaultProperties);
66
93
  }
67
- }, [loadDatasourceDetails, parameters]);
94
+ }, [columns.length, defaultVisibleColumnKeys.length, lastRequestedFieldKeys === null || lastRequestedFieldKeys === void 0 ? void 0 : lastRequestedFieldKeys.length]);
68
95
  var onNextPage = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
69
- var _yield$getDatasourceD, data, nextPageCursor, totalIssues;
96
+ var requestInfo,
97
+ _requestInfo$isSchema,
98
+ isSchemaFromData,
99
+ shouldRequestFirstPage,
100
+ datasourceDataRequest,
101
+ _yield$getDatasourceD,
102
+ data,
103
+ nextPageCursor,
104
+ totalIssues,
105
+ schema,
106
+ _args2 = arguments;
70
107
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
71
108
  while (1) switch (_context2.prev = _context2.next) {
72
109
  case 0:
110
+ requestInfo = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};
73
111
  if (parameters) {
74
- _context2.next = 2;
112
+ _context2.next = 3;
75
113
  break;
76
114
  }
77
115
  return _context2.abrupt("return");
78
- case 2:
79
- setStatus('loading');
80
- _context2.next = 5;
81
- return getDatasourceData(datasourceId, {
116
+ case 3:
117
+ _requestInfo$isSchema = requestInfo.isSchemaFromData, isSchemaFromData = _requestInfo$isSchema === void 0 ? true : _requestInfo$isSchema, shouldRequestFirstPage = requestInfo.shouldRequestFirstPage;
118
+ datasourceDataRequest = {
82
119
  parameters: parameters,
83
120
  pageSize: 20,
84
- pageCursor: nextCursor,
85
- fields: fields
86
- });
87
- case 5:
121
+ pageCursor: shouldRequestFirstPage ? undefined : nextCursor,
122
+ fields: fieldKeys,
123
+ includeSchema: isSchemaFromData
124
+ };
125
+ setStatus('loading');
126
+ _context2.next = 8;
127
+ return getDatasourceData(datasourceId, datasourceDataRequest);
128
+ case 8:
88
129
  _yield$getDatasourceD = _context2.sent;
89
130
  data = _yield$getDatasourceD.data;
90
131
  nextPageCursor = _yield$getDatasourceD.nextPageCursor;
91
132
  totalIssues = _yield$getDatasourceD.totalIssues;
133
+ schema = _yield$getDatasourceD.schema;
92
134
  setTotalIssueCount(totalIssues);
93
135
  setNextCursor(nextPageCursor);
94
136
  setResponseItems(function (currentResponseItems) {
137
+ if (shouldRequestFirstPage) {
138
+ return data;
139
+ }
95
140
  return [].concat(_toConsumableArray(currentResponseItems), _toConsumableArray(data));
96
141
  });
97
142
  setStatus('resolved');
98
143
  setHasNextPage(Boolean(nextPageCursor));
99
- case 14:
144
+ if (fieldKeys.length > 0) {
145
+ setLastRequestedFieldKeys(fieldKeys);
146
+ }
147
+ if (isSchemaFromData && schema) {
148
+ applySchemaProperties(schema.properties);
149
+ }
150
+ case 20:
100
151
  case "end":
101
152
  return _context2.stop();
102
153
  }
103
154
  }, _callee2);
104
- })), [parameters, getDatasourceData, datasourceId, nextCursor, fields]);
155
+ })), [parameters, fieldKeys, getDatasourceData, datasourceId, nextCursor, applySchemaProperties]);
105
156
  var reset = useCallback(function () {
106
157
  setStatus('empty');
107
158
  setResponseItems([]);
108
159
  setHasNextPage(true);
109
160
  setNextCursor(undefined);
110
161
  setTotalIssueCount(undefined);
162
+ setLastRequestedFieldKeys([]);
111
163
  }, []);
164
+
165
+ // this takes care of requesting /data initally
166
+ useEffect(function () {
167
+ var isEmptyState = Object.keys(parameters || {}).length > 0 && lastRequestedFieldKeys.length === 0 && status === 'empty';
168
+ if (isEmptyState) {
169
+ void onNextPage();
170
+ }
171
+ }, [lastRequestedFieldKeys, loadDatasourceDetails, onNextPage, parameters, status]);
172
+
173
+ // this takes care of requesting /data when user selects/unselects a column
174
+ useEffect(function () {
175
+ var canHaveNewColumns = fieldKeys.length > 0 && lastRequestedFieldKeys.length > 0;
176
+ if (canHaveNewColumns) {
177
+ var hasNewColumns = fieldKeys.some(function (key) {
178
+ return !lastRequestedFieldKeys.includes(key);
179
+ });
180
+ if (!hasNewColumns) {
181
+ return;
182
+ }
183
+ reset();
184
+ void onNextPage({
185
+ isSchemaFromData: false,
186
+ // since this is not inital load, we will already have schema
187
+ shouldRequestFirstPage: true
188
+ });
189
+ }
190
+ }, [fieldKeys, lastRequestedFieldKeys, onNextPage, reset]);
112
191
  return {
113
192
  status: status,
114
193
  onNextPage: onNextPage,
115
194
  responseItems: responseItems,
116
195
  reset: reset,
196
+ loadDatasourceDetails: loadDatasourceDetails,
117
197
  hasNextPage: hasNextPage,
118
198
  columns: columns,
119
199
  defaultVisibleColumnKeys: defaultVisibleColumnKeys,
@@ -20,7 +20,11 @@ export var DatasourceTableView = function DatasourceTableView(_ref) {
20
20
  parameters = _ref.parameters,
21
21
  visibleColumnKeys = _ref.visibleColumnKeys,
22
22
  onVisibleColumnKeysChange = _ref.onVisibleColumnKeysChange;
23
- var _useDatasourceTableSt = useDatasourceTableState(datasourceId, parameters),
23
+ var _useDatasourceTableSt = useDatasourceTableState({
24
+ datasourceId: datasourceId,
25
+ parameters: parameters,
26
+ fieldKeys: visibleColumnKeys
27
+ }),
24
28
  reset = _useDatasourceTableSt.reset,
25
29
  status = _useDatasourceTableSt.status,
26
30
  onNextPage = _useDatasourceTableSt.onNextPage,
@@ -28,7 +32,8 @@ export var DatasourceTableView = function DatasourceTableView(_ref) {
28
32
  hasNextPage = _useDatasourceTableSt.hasNextPage,
29
33
  columns = _useDatasourceTableSt.columns,
30
34
  defaultVisibleColumnKeys = _useDatasourceTableSt.defaultVisibleColumnKeys,
31
- totalIssueCount = _useDatasourceTableSt.totalIssueCount;
35
+ totalIssueCount = _useDatasourceTableSt.totalIssueCount,
36
+ loadDatasourceDetails = _useDatasourceTableSt.loadDatasourceDetails;
32
37
  useEffect(function () {
33
38
  if (onVisibleColumnKeysChange && (visibleColumnKeys || []).length === 0 && defaultVisibleColumnKeys.length > 0) {
34
39
  onVisibleColumnKeysChange(defaultVisibleColumnKeys);
@@ -41,6 +46,7 @@ export var DatasourceTableView = function DatasourceTableView(_ref) {
41
46
  hasNextPage: hasNextPage,
42
47
  items: responseItems,
43
48
  onNextPage: onNextPage,
49
+ onLoadDatasourceDetails: loadDatasourceDetails,
44
50
  status: status,
45
51
  columns: columns,
46
52
  visibleColumnKeys: visibleColumnKeys || defaultVisibleColumnKeys,
@@ -16,7 +16,8 @@ export var ColumnPicker = function ColumnPicker(_ref) {
16
16
  var isDatasourceLoading = _ref.isDatasourceLoading,
17
17
  columns = _ref.columns,
18
18
  selectedColumnKeys = _ref.selectedColumnKeys,
19
- onSelectedColumnKeysChange = _ref.onSelectedColumnKeysChange;
19
+ onSelectedColumnKeysChange = _ref.onSelectedColumnKeysChange,
20
+ onOpen = _ref.onOpen;
20
21
  var intl = useIntl();
21
22
  var _useState = useState([]),
22
23
  _useState2 = _slicedToArray(_useState, 2),
@@ -58,7 +59,7 @@ export var ColumnPicker = function ColumnPicker(_ref) {
58
59
  });
59
60
  onSelectedColumnKeysChange(selectedValues);
60
61
  }, [columns, onSelectedColumnKeysChange]);
61
- var onPopupOpen = useCallback(function () {
62
+ var sortSelectedColumnsTop = useCallback(function () {
62
63
  if (!allOptions.length) {
63
64
  return;
64
65
  }
@@ -70,6 +71,10 @@ export var ColumnPicker = function ColumnPicker(_ref) {
70
71
  var sortedOptions = [].concat(_toConsumableArray(selectedOptions), _toConsumableArray(nonSelectedOptions));
71
72
  sortedOptions.length > 0 && setAllOptions(sortedOptions);
72
73
  }, [allOptions, selectedOptions]);
74
+ var handleOpen = useCallback(function () {
75
+ onOpen && void onOpen();
76
+ void sortSelectedColumnsTop();
77
+ }, [onOpen, sortSelectedColumnsTop]);
73
78
  return jsx(PopupSelect, {
74
79
  classNamePrefix: 'column-picker-popup',
75
80
  testId: 'column-picker-popup',
@@ -78,13 +83,14 @@ export var ColumnPicker = function ColumnPicker(_ref) {
78
83
  },
79
84
  options: allOptions,
80
85
  value: selectedOptions,
81
- onOpen: onPopupOpen,
86
+ onOpen: handleOpen,
82
87
  closeMenuOnSelect: false,
83
88
  hideSelectedOptions: false,
84
89
  isMulti: true,
85
90
  placeholder: intl.formatMessage(columnPickerMessages.search),
86
91
  "aria-label": "Search for fields",
87
92
  onChange: handleChange,
93
+ isLoading: allOptions.length === 0,
88
94
  target: function target(_ref8) {
89
95
  var isOpen = _ref8.isOpen,
90
96
  triggerProps = _objectWithoutProperties(_ref8, _excluded);