@atlaskit/link-datasource 0.19.1 → 0.21.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.
- package/CHANGELOG.md +16 -0
- package/dist/cjs/hooks/useDatasourceTableState.js +138 -58
- package/dist/cjs/ui/datasource-table-view/datasourceTableView.js +8 -2
- package/dist/cjs/ui/issue-like-table/column-picker/index.js +17 -7
- package/dist/cjs/ui/issue-like-table/column-picker/messages.js +15 -0
- package/dist/cjs/ui/issue-like-table/index.js +65 -24
- package/dist/cjs/ui/issue-like-table/styled.js +1 -1
- package/dist/cjs/ui/jira-issues-modal/modal/index.js +14 -13
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/hooks/useDatasourceTableState.js +84 -19
- package/dist/es2019/ui/datasource-table-view/datasourceTableView.js +8 -2
- package/dist/es2019/ui/issue-like-table/column-picker/index.js +16 -6
- package/dist/es2019/ui/issue-like-table/column-picker/messages.js +8 -0
- package/dist/es2019/ui/issue-like-table/index.js +28 -8
- package/dist/es2019/ui/issue-like-table/styled.js +1 -1
- package/dist/es2019/ui/jira-issues-modal/modal/index.js +11 -10
- package/dist/es2019/version.json +1 -1
- package/dist/esm/hooks/useDatasourceTableState.js +138 -58
- package/dist/esm/ui/datasource-table-view/datasourceTableView.js +8 -2
- package/dist/esm/ui/issue-like-table/column-picker/index.js +17 -7
- package/dist/esm/ui/issue-like-table/column-picker/messages.js +8 -0
- package/dist/esm/ui/issue-like-table/index.js +65 -24
- package/dist/esm/ui/issue-like-table/styled.js +1 -1
- package/dist/esm/ui/jira-issues-modal/modal/index.js +14 -13
- package/dist/esm/version.json +1 -1
- package/dist/types/hooks/useDatasourceTableState.d.ts +14 -3
- package/dist/types/ui/issue-like-table/column-picker/index.d.ts +1 -1
- package/dist/types/ui/issue-like-table/column-picker/messages.d.ts +7 -0
- package/dist/types/ui/issue-like-table/column-picker/types.d.ts +2 -0
- package/dist/types/ui/issue-like-table/index.d.ts +1 -1
- package/dist/types/ui/issue-like-table/types.d.ts +3 -1
- package/dist/types-ts4.5/hooks/useDatasourceTableState.d.ts +14 -3
- package/dist/types-ts4.5/ui/issue-like-table/column-picker/index.d.ts +1 -1
- package/dist/types-ts4.5/ui/issue-like-table/column-picker/messages.d.ts +7 -0
- package/dist/types-ts4.5/ui/issue-like-table/column-picker/types.d.ts +2 -0
- package/dist/types-ts4.5/ui/issue-like-table/index.d.ts +1 -1
- package/dist/types-ts4.5/ui/issue-like-table/types.d.ts +3 -1
- package/examples-helpers/buildIssueLikeTable.tsx +11 -3
- package/examples-helpers/buildJiraIssuesTable.tsx +7 -2
- package/package.json +2 -2
|
@@ -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 = (
|
|
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
|
|
20
|
+
const loadDatasourceDetails = useCallback(async () => {
|
|
21
|
+
if (!parameters) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
16
24
|
const result = await getDatasourceDetails(datasourceId, {
|
|
17
25
|
parameters
|
|
18
26
|
});
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
pageSize: 10,
|
|
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 =>
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
@@ -2,15 +2,20 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
|
2
2
|
/** @jsx jsx */
|
|
3
3
|
import { useCallback, useEffect, useState } from 'react';
|
|
4
4
|
import { jsx } from '@emotion/react';
|
|
5
|
+
import { useIntl } from 'react-intl-next';
|
|
5
6
|
import Button from '@atlaskit/button/standard-button';
|
|
6
7
|
import BoardIcon from '@atlaskit/icon/glyph/board';
|
|
7
8
|
import ChevronDownIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
8
9
|
import { CheckboxOption, PopupSelect } from '@atlaskit/select';
|
|
10
|
+
import { columnPickerMessages } from './messages';
|
|
9
11
|
export const ColumnPicker = ({
|
|
12
|
+
isDatasourceLoading,
|
|
10
13
|
columns,
|
|
11
14
|
selectedColumnKeys,
|
|
12
|
-
onSelectedColumnKeysChange
|
|
15
|
+
onSelectedColumnKeysChange,
|
|
16
|
+
onOpen
|
|
13
17
|
}) => {
|
|
18
|
+
const intl = useIntl();
|
|
14
19
|
const [allOptions, setAllOptions] = useState([]);
|
|
15
20
|
const mapColumnToOption = useCallback(({
|
|
16
21
|
key,
|
|
@@ -42,7 +47,7 @@ export const ColumnPicker = ({
|
|
|
42
47
|
});
|
|
43
48
|
onSelectedColumnKeysChange(selectedValues);
|
|
44
49
|
}, [columns, onSelectedColumnKeysChange]);
|
|
45
|
-
const
|
|
50
|
+
const sortSelectedColumnsTop = useCallback(() => {
|
|
46
51
|
if (!allOptions.length) {
|
|
47
52
|
return;
|
|
48
53
|
}
|
|
@@ -50,6 +55,10 @@ export const ColumnPicker = ({
|
|
|
50
55
|
const sortedOptions = [...selectedOptions, ...nonSelectedOptions];
|
|
51
56
|
sortedOptions.length > 0 && setAllOptions(sortedOptions);
|
|
52
57
|
}, [allOptions, selectedOptions]);
|
|
58
|
+
const handleOpen = useCallback(() => {
|
|
59
|
+
onOpen && void onOpen();
|
|
60
|
+
void sortSelectedColumnsTop();
|
|
61
|
+
}, [onOpen, sortSelectedColumnsTop]);
|
|
53
62
|
return jsx(PopupSelect, {
|
|
54
63
|
classNamePrefix: 'column-picker-popup',
|
|
55
64
|
testId: 'column-picker-popup',
|
|
@@ -58,14 +67,14 @@ export const ColumnPicker = ({
|
|
|
58
67
|
},
|
|
59
68
|
options: allOptions,
|
|
60
69
|
value: selectedOptions,
|
|
61
|
-
onOpen:
|
|
70
|
+
onOpen: handleOpen,
|
|
62
71
|
closeMenuOnSelect: false,
|
|
63
72
|
hideSelectedOptions: false,
|
|
64
73
|
isMulti: true,
|
|
65
|
-
placeholder:
|
|
66
|
-
,
|
|
74
|
+
placeholder: intl.formatMessage(columnPickerMessages.search),
|
|
67
75
|
"aria-label": "Search for fields",
|
|
68
76
|
onChange: handleChange,
|
|
77
|
+
isLoading: allOptions.length === 0,
|
|
69
78
|
target: ({
|
|
70
79
|
isOpen,
|
|
71
80
|
...triggerProps
|
|
@@ -80,7 +89,8 @@ export const ColumnPicker = ({
|
|
|
80
89
|
})),
|
|
81
90
|
spacing: "compact",
|
|
82
91
|
appearance: "subtle",
|
|
83
|
-
testId: "column-picker-trigger-button"
|
|
92
|
+
testId: "column-picker-trigger-button",
|
|
93
|
+
isDisabled: isDatasourceLoading
|
|
84
94
|
}))
|
|
85
95
|
});
|
|
86
96
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export const columnPickerMessages = defineMessages({
|
|
3
|
+
search: {
|
|
4
|
+
id: 'linkDataSource.column-picker.search',
|
|
5
|
+
description: 'Search bar message to look for more fields',
|
|
6
|
+
defaultMessage: 'Search for fields'
|
|
7
|
+
}
|
|
8
|
+
});
|
|
@@ -79,12 +79,13 @@ function getColumnWidth(key, type) {
|
|
|
79
79
|
case 'string':
|
|
80
80
|
return BASE_WIDTH * 22;
|
|
81
81
|
default:
|
|
82
|
-
undefined;
|
|
82
|
+
return undefined;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
export const IssueLikeDataTableView = ({
|
|
86
86
|
testId,
|
|
87
87
|
onNextPage,
|
|
88
|
+
onLoadDatasourceDetails,
|
|
88
89
|
items,
|
|
89
90
|
columns,
|
|
90
91
|
renderItem = fallbackRenderType,
|
|
@@ -96,14 +97,18 @@ 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]);
|
|
105
110
|
|
|
106
|
-
// TODO seems like this component can't handle some combination of incremental data
|
|
111
|
+
// TODO seems like this component can't handle some combination of incremental data retrieval.
|
|
107
112
|
// If data comes first, then columns and then visibleColumnKeys it blows up,
|
|
108
113
|
// or some other combination.
|
|
109
114
|
|
|
@@ -135,8 +140,10 @@ export const IssueLikeDataTableView = ({
|
|
|
135
140
|
maxWidth: getColumnWidth(key, type)
|
|
136
141
|
}));
|
|
137
142
|
useEffect(() => {
|
|
138
|
-
if (
|
|
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
|
|
@@ -252,7 +270,7 @@ export const IssueLikeDataTableView = ({
|
|
|
252
270
|
const TruncatedContent = () => jsx("div", {
|
|
253
271
|
css: truncatedCellStyles
|
|
254
272
|
}, content);
|
|
255
|
-
if (onVisibleColumnKeysChange) {
|
|
273
|
+
if (onVisibleColumnKeysChange && status !== 'loading') {
|
|
256
274
|
return jsx(DraggableTableHeading, {
|
|
257
275
|
tableId: tableId,
|
|
258
276
|
key: key,
|
|
@@ -275,9 +293,11 @@ export const IssueLikeDataTableView = ({
|
|
|
275
293
|
}), onVisibleColumnKeysChange && jsx("th", {
|
|
276
294
|
css: columnPickerHeaderStyles
|
|
277
295
|
}, jsx(ColumnPicker, {
|
|
278
|
-
columns: orderedColumns,
|
|
279
|
-
selectedColumnKeys: visibleColumnKeys,
|
|
280
|
-
|
|
296
|
+
columns: hasFullSchema ? orderedColumns : [],
|
|
297
|
+
selectedColumnKeys: hasFullSchema ? visibleColumnKeys : [],
|
|
298
|
+
isDatasourceLoading: status === 'loading',
|
|
299
|
+
onSelectedColumnKeysChange: onSelectedColumnKeysChange,
|
|
300
|
+
onOpen: handlePickerOpen
|
|
281
301
|
})))), jsx("tbody", {
|
|
282
302
|
"data-testid": testId && `${testId}--body`
|
|
283
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
|
-
|
|
58
|
-
|
|
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) {
|
|
@@ -217,7 +218,7 @@ export const JiraIssuesConfigModal = props => {
|
|
|
217
218
|
}, jsx(FormattedMessage, modalMessages.cancelButtonText)), jsx(Button, {
|
|
218
219
|
appearance: "primary",
|
|
219
220
|
onClick: onInsertPressed,
|
|
220
|
-
isDisabled: !isParametersSet,
|
|
221
|
+
isDisabled: !isParametersSet || status === 'loading',
|
|
221
222
|
testId: 'jira-jql-datasource-modal--insert-button'
|
|
222
223
|
}, jsx(FormattedMessage, modalMessages.insertIssuesButtonText))))));
|
|
223
224
|
};
|
package/dist/es2019/version.json
CHANGED
|
@@ -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(
|
|
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(
|
|
16
|
+
var _useState3 = useState([]),
|
|
13
17
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
var _useState5 = useState(
|
|
18
|
+
lastRequestedFieldKeys = _useState4[0],
|
|
19
|
+
setLastRequestedFieldKeys = _useState4[1];
|
|
20
|
+
var _useState5 = useState('empty'),
|
|
17
21
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
var _useState7 = useState(
|
|
22
|
+
status = _useState6[0],
|
|
23
|
+
setStatus = _useState6[1];
|
|
24
|
+
var _useState7 = useState([]),
|
|
21
25
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var _useState9 = useState(
|
|
26
|
+
responseItems = _useState8[0],
|
|
27
|
+
setResponseItems = _useState8[1];
|
|
28
|
+
var _useState9 = useState(true),
|
|
25
29
|
_useState10 = _slicedToArray(_useState9, 2),
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
var _useState11 = useState(
|
|
30
|
+
hasNextPage = _useState10[0],
|
|
31
|
+
setHasNextPage = _useState10[1];
|
|
32
|
+
var _useState11 = useState(undefined),
|
|
29
33
|
_useState12 = _slicedToArray(_useState11, 2),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
var _useState13 = useState(
|
|
34
|
+
nextCursor = _useState12[0],
|
|
35
|
+
setNextCursor = _useState12[1];
|
|
36
|
+
var _useState13 = useState([]),
|
|
33
37
|
_useState14 = _slicedToArray(_useState13, 2),
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
47
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
}, [
|
|
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
|
|
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 =
|
|
112
|
+
_context2.next = 3;
|
|
75
113
|
break;
|
|
76
114
|
}
|
|
77
115
|
return _context2.abrupt("return");
|
|
78
|
-
case
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
pageSize:
|
|
84
|
-
pageCursor: nextCursor,
|
|
85
|
-
fields:
|
|
86
|
-
|
|
87
|
-
|
|
120
|
+
pageSize: 20,
|
|
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
|
-
|
|
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,
|
|
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,
|