@atlaskit/link-datasource 2.9.4 → 2.9.6
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 +19 -0
- package/dist/cjs/hooks/useDatasourceTableState.js +43 -17
- package/dist/cjs/state/actions/index.js +183 -0
- package/dist/cjs/state/index.js +8 -4
- package/dist/cjs/ui/issue-like-table/column-picker/index.js +1 -1
- package/dist/es2019/hooks/useDatasourceTableState.js +26 -2
- package/dist/es2019/state/actions/index.js +166 -0
- package/dist/es2019/state/index.js +11 -5
- package/dist/es2019/ui/issue-like-table/column-picker/index.js +2 -2
- package/dist/esm/hooks/useDatasourceTableState.js +43 -17
- package/dist/esm/state/actions/index.js +177 -0
- package/dist/esm/state/index.js +8 -4
- package/dist/esm/ui/issue-like-table/column-picker/index.js +1 -1
- package/dist/types/state/actions/index.d.ts +87 -0
- package/dist/types/state/index.d.ts +10 -5
- package/dist/types-ts4.5/state/actions/index.d.ts +87 -0
- package/dist/types-ts4.5/state/index.d.ts +10 -5
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlaskit/link-datasource
|
|
2
2
|
|
|
3
|
+
## 2.9.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`941edf62401ae`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/941edf62401ae) -
|
|
8
|
+
This version removes `platform.design-system-team.use-default-select-in-popup-select_46rmj`
|
|
9
|
+
feature flag. The `PopupSelect` component now uses the internal `Select` component ensure the
|
|
10
|
+
accessibility of options with group labels for assistive technologies.
|
|
11
|
+
|
|
12
|
+
## 2.9.5
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#127170](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/127170)
|
|
17
|
+
[`48d23d3dfb9a1`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/48d23d3dfb9a1) -
|
|
18
|
+
We are testing action discovery for datasources behind a feature flag. If this fix is successful
|
|
19
|
+
it will be available in a later release.
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
3
22
|
## 2.9.4
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -15,6 +15,7 @@ var _linkClientExtension = require("@atlaskit/link-client-extension");
|
|
|
15
15
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
16
16
|
var _analytics = require("../analytics");
|
|
17
17
|
var _state = require("../state");
|
|
18
|
+
var _actions = require("../state/actions");
|
|
18
19
|
var _useErrorLogger2 = _interopRequireDefault(require("./useErrorLogger"));
|
|
19
20
|
var useDatasourceTableState = exports.useDatasourceTableState = function useDatasourceTableState(_ref) {
|
|
20
21
|
var datasourceId = _ref.datasourceId,
|
|
@@ -29,6 +30,8 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
|
|
|
29
30
|
captureError = _useErrorLogger.captureError;
|
|
30
31
|
var _useDatasourceActions = (0, _state.useDatasourceActions)(),
|
|
31
32
|
onAddItems = _useDatasourceActions.onAddItems;
|
|
33
|
+
var _useDiscoverActions = (0, _actions.useDiscoverActions)(),
|
|
34
|
+
discoverActions = _useDiscoverActions.discoverActions;
|
|
32
35
|
var idFieldCount = 1;
|
|
33
36
|
var keyFieldCount = 1;
|
|
34
37
|
var _useState = (0, _react.useState)([]),
|
|
@@ -215,6 +218,7 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
|
|
|
215
218
|
_yield$getDatasourceD4,
|
|
216
219
|
access,
|
|
217
220
|
_destinationObjectTypes,
|
|
221
|
+
product,
|
|
218
222
|
_extensionKey,
|
|
219
223
|
auth,
|
|
220
224
|
_providerName,
|
|
@@ -223,7 +227,9 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
|
|
|
223
227
|
nextPageCursor,
|
|
224
228
|
_totalCount,
|
|
225
229
|
schema,
|
|
230
|
+
integrationKey,
|
|
226
231
|
newIds,
|
|
232
|
+
aris,
|
|
227
233
|
isUserLoadingNextPage,
|
|
228
234
|
currentLoadedItemCount,
|
|
229
235
|
newlyLoadedItemCount,
|
|
@@ -265,6 +271,7 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
|
|
|
265
271
|
_yield$getDatasourceD4 = _yield$getDatasourceD3.meta;
|
|
266
272
|
access = _yield$getDatasourceD4.access;
|
|
267
273
|
_destinationObjectTypes = _yield$getDatasourceD4.destinationObjectTypes;
|
|
274
|
+
product = _yield$getDatasourceD4.product;
|
|
268
275
|
_extensionKey = _yield$getDatasourceD4.extensionKey;
|
|
269
276
|
auth = _yield$getDatasourceD4.auth;
|
|
270
277
|
_providerName = _yield$getDatasourceD4.providerName;
|
|
@@ -274,21 +281,21 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
|
|
|
274
281
|
_totalCount = _yield$getDatasourceD5.totalCount;
|
|
275
282
|
schema = _yield$getDatasourceD5.schema;
|
|
276
283
|
if (!((_currentAbortControll = currentAbortController) !== null && _currentAbortControll !== void 0 && _currentAbortControll.signal.aborted)) {
|
|
277
|
-
_context2.next =
|
|
284
|
+
_context2.next = 28;
|
|
278
285
|
break;
|
|
279
286
|
}
|
|
280
287
|
throw new Error('Aborted');
|
|
281
|
-
case
|
|
288
|
+
case 28:
|
|
282
289
|
setExtensionKey(_extensionKey);
|
|
283
290
|
setProviderName(_providerName);
|
|
284
291
|
if (!(access === 'unauthorized' || access === 'forbidden')) {
|
|
285
|
-
_context2.next =
|
|
292
|
+
_context2.next = 34;
|
|
286
293
|
break;
|
|
287
294
|
}
|
|
288
295
|
setStatus(access);
|
|
289
296
|
setAuthDetails(auth || initialEmptyArray);
|
|
290
297
|
return _context2.abrupt("return");
|
|
291
|
-
case
|
|
298
|
+
case 34:
|
|
292
299
|
setDestinationObjectTypes(_destinationObjectTypes);
|
|
293
300
|
setTotalCount(_totalCount);
|
|
294
301
|
setNextCursor(nextPageCursor);
|
|
@@ -299,10 +306,29 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
|
|
|
299
306
|
return [].concat((0, _toConsumableArray2.default)(currentResponseItems), (0, _toConsumableArray2.default)(items));
|
|
300
307
|
});
|
|
301
308
|
if ((0, _platformFeatureFlags.fg)('enable_datasource_react_sweet_state')) {
|
|
302
|
-
|
|
309
|
+
/**
|
|
310
|
+
* Product is typed as any.
|
|
311
|
+
*/
|
|
312
|
+
integrationKey = product;
|
|
313
|
+
newIds = onAddItems(items, typeof integrationKey === 'string' ? integrationKey : undefined);
|
|
303
314
|
setResponseItemIds(function (currentIds) {
|
|
304
315
|
return [].concat((0, _toConsumableArray2.default)(currentIds), (0, _toConsumableArray2.default)(newIds));
|
|
305
316
|
});
|
|
317
|
+
if ((0, _platformFeatureFlags.fg)('platform-datasources-enable-two-way-sync')) {
|
|
318
|
+
if (typeof integrationKey === 'string') {
|
|
319
|
+
aris = items.reduce(function (acc, item) {
|
|
320
|
+
var _item$ari;
|
|
321
|
+
return typeof ((_item$ari = item.ari) === null || _item$ari === void 0 ? void 0 : _item$ari.data) === 'string' ? [].concat((0, _toConsumableArray2.default)(acc), [item.ari.data]) : acc;
|
|
322
|
+
}, []);
|
|
323
|
+
if (aris.length) {
|
|
324
|
+
discoverActions({
|
|
325
|
+
aris: aris,
|
|
326
|
+
integrationKey: integrationKey,
|
|
327
|
+
fieldKeys: fieldKeys
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
306
332
|
}
|
|
307
333
|
setHasNextPage(Boolean(nextPageCursor));
|
|
308
334
|
if (fieldKeys.length > 0) {
|
|
@@ -322,39 +348,39 @@ var useDatasourceTableState = exports.useDatasourceTableState = function useData
|
|
|
322
348
|
});
|
|
323
349
|
}
|
|
324
350
|
setStatus('resolved');
|
|
325
|
-
_context2.next =
|
|
351
|
+
_context2.next = 59;
|
|
326
352
|
break;
|
|
327
|
-
case
|
|
328
|
-
_context2.prev =
|
|
353
|
+
case 47:
|
|
354
|
+
_context2.prev = 47;
|
|
329
355
|
_context2.t0 = _context2["catch"](10);
|
|
330
356
|
if (!(_context2.t0.message === 'Aborted')) {
|
|
331
|
-
_context2.next =
|
|
357
|
+
_context2.next = 51;
|
|
332
358
|
break;
|
|
333
359
|
}
|
|
334
360
|
return _context2.abrupt("return");
|
|
335
|
-
case
|
|
361
|
+
case 51:
|
|
336
362
|
captureError('onNextPage', _context2.t0);
|
|
337
363
|
if (!(_context2.t0 instanceof Response && _context2.t0.status === 401)) {
|
|
338
|
-
_context2.next =
|
|
364
|
+
_context2.next = 55;
|
|
339
365
|
break;
|
|
340
366
|
}
|
|
341
367
|
setStatus('unauthorized');
|
|
342
368
|
return _context2.abrupt("return");
|
|
343
|
-
case
|
|
369
|
+
case 55:
|
|
344
370
|
if (!(_context2.t0 instanceof Response && _context2.t0.status === 403)) {
|
|
345
|
-
_context2.next =
|
|
371
|
+
_context2.next = 58;
|
|
346
372
|
break;
|
|
347
373
|
}
|
|
348
374
|
setStatus('forbidden');
|
|
349
375
|
return _context2.abrupt("return");
|
|
350
|
-
case 57:
|
|
351
|
-
setStatus('rejected');
|
|
352
376
|
case 58:
|
|
377
|
+
setStatus('rejected');
|
|
378
|
+
case 59:
|
|
353
379
|
case "end":
|
|
354
380
|
return _context2.stop();
|
|
355
381
|
}
|
|
356
|
-
}, _callee2, null, [[10,
|
|
357
|
-
})), [captureError, parameters, fieldKeys, nextCursor, responseItems, setResponseItemIds, onAddItems, getDatasourceData, datasourceId, applySchemaProperties, fireEvent, fullSchema, initialEmptyArray]);
|
|
382
|
+
}, _callee2, null, [[10, 47]]);
|
|
383
|
+
})), [captureError, parameters, fieldKeys, nextCursor, responseItems, setResponseItemIds, onAddItems, getDatasourceData, datasourceId, applySchemaProperties, fireEvent, fullSchema, initialEmptyArray, discoverActions]);
|
|
358
384
|
var reset = (0, _react.useCallback)(function (options) {
|
|
359
385
|
setResponseItems(initialEmptyArray);
|
|
360
386
|
setResponseItemIds(initialEmptyArray);
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useExecuteAtomicAction = exports.useDiscoverActions = exports.useAtomicUpdateActionSchema = exports.actions = exports.ActionsStore = void 0;
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
12
|
+
var _react = require("react");
|
|
13
|
+
var _reactSweetState = require("react-sweet-state");
|
|
14
|
+
var _linkClientExtension = require("@atlaskit/link-client-extension");
|
|
15
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17
|
+
/**
|
|
18
|
+
* Atomic actions available for an integration (by field)
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* {
|
|
22
|
+
* jira: {
|
|
23
|
+
* summary: {
|
|
24
|
+
* actionKey: 'atlassian:issue:update:summary',
|
|
25
|
+
* type: 'string',
|
|
26
|
+
* description: 'Update issue summary',
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Permissions available for a target
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* User permissions for actions on target (ARI) properties
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* {
|
|
42
|
+
* 'ari:cloud:jira:63cecfe3-16fa-4ee1-8e8d-047cc4b18980:issue/1': {
|
|
43
|
+
* summary: {
|
|
44
|
+
* isEditable: true
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
var getInitialState = function getInitialState() {
|
|
52
|
+
return {
|
|
53
|
+
actionsByIntegration: {},
|
|
54
|
+
permissions: {}
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
var actions = exports.actions = {
|
|
58
|
+
discoverActions: function discoverActions(api, request) {
|
|
59
|
+
return /*#__PURE__*/function () {
|
|
60
|
+
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
|
|
61
|
+
var setState, getState, response, _getState, currentActions, currentPermissions, actionsByIntegration, permissions;
|
|
62
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
63
|
+
while (1) switch (_context.prev = _context.next) {
|
|
64
|
+
case 0:
|
|
65
|
+
setState = _ref.setState, getState = _ref.getState;
|
|
66
|
+
_context.next = 3;
|
|
67
|
+
return api.getDatasourceActionsAndPermissions(request);
|
|
68
|
+
case 3:
|
|
69
|
+
response = _context.sent;
|
|
70
|
+
if ('permissions' in response) {
|
|
71
|
+
_getState = getState(), currentActions = _getState.actionsByIntegration, currentPermissions = _getState.permissions;
|
|
72
|
+
actionsByIntegration = response.actions.reduce(function (acc, action) {
|
|
73
|
+
return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2.default)({}, action.integrationKey, _objectSpread(_objectSpread({}, acc[action.integrationKey]), {}, (0, _defineProperty2.default)({}, action.fieldKey, {
|
|
74
|
+
actionKey: action.actionKey,
|
|
75
|
+
type: action.type
|
|
76
|
+
}))));
|
|
77
|
+
}, currentActions);
|
|
78
|
+
permissions = response.permissions.data.reduce(function (acc, permission) {
|
|
79
|
+
return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2.default)({}, permission.ari, _objectSpread(_objectSpread({}, acc[permission.ari]), {}, (0, _defineProperty2.default)({}, permission.fieldKey, {
|
|
80
|
+
isEditable: permission.isEditable
|
|
81
|
+
}))));
|
|
82
|
+
}, currentPermissions);
|
|
83
|
+
setState({
|
|
84
|
+
actionsByIntegration: actionsByIntegration,
|
|
85
|
+
permissions: permissions
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
case 5:
|
|
89
|
+
case "end":
|
|
90
|
+
return _context.stop();
|
|
91
|
+
}
|
|
92
|
+
}, _callee);
|
|
93
|
+
}));
|
|
94
|
+
return function (_x) {
|
|
95
|
+
return _ref2.apply(this, arguments);
|
|
96
|
+
};
|
|
97
|
+
}();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var ActionsStore = exports.ActionsStore = (0, _reactSweetState.createStore)({
|
|
101
|
+
name: 'actions-store',
|
|
102
|
+
initialState: getInitialState(),
|
|
103
|
+
actions: actions
|
|
104
|
+
});
|
|
105
|
+
var useActionStoreActions = (0, _reactSweetState.createActionsHook)(ActionsStore);
|
|
106
|
+
var useDiscoverActions = exports.useDiscoverActions = function useDiscoverActions() {
|
|
107
|
+
var _useDatasourceClientE = (0, _linkClientExtension.useDatasourceClientExtension)(),
|
|
108
|
+
getDatasourceActionsAndPermissions = _useDatasourceClientE.getDatasourceActionsAndPermissions;
|
|
109
|
+
var _useActionStoreAction = useActionStoreActions(),
|
|
110
|
+
discoverActions = _useActionStoreAction.discoverActions;
|
|
111
|
+
return {
|
|
112
|
+
discoverActions: (0, _react.useMemo)(function () {
|
|
113
|
+
return discoverActions.bind(null, {
|
|
114
|
+
getDatasourceActionsAndPermissions: getDatasourceActionsAndPermissions
|
|
115
|
+
});
|
|
116
|
+
}, [discoverActions, getDatasourceActionsAndPermissions])
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
var getFieldUpdateActionByAri = function getFieldUpdateActionByAri(state, _ref3) {
|
|
120
|
+
var _state$permissions$ar, _state$actionsByInteg;
|
|
121
|
+
var ari = _ref3.ari,
|
|
122
|
+
fieldKey = _ref3.fieldKey,
|
|
123
|
+
integrationKey = _ref3.integrationKey;
|
|
124
|
+
var isEditable = (_state$permissions$ar = state.permissions[ari]) === null || _state$permissions$ar === void 0 || (_state$permissions$ar = _state$permissions$ar[fieldKey]) === null || _state$permissions$ar === void 0 ? void 0 : _state$permissions$ar.isEditable;
|
|
125
|
+
if (isEditable === false) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
return (_state$actionsByInteg = state.actionsByIntegration[integrationKey]) === null || _state$actionsByInteg === void 0 ? void 0 : _state$actionsByInteg[fieldKey];
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Retrieves the action schema for a given ARI + fieldKey + integrationKey
|
|
133
|
+
*/
|
|
134
|
+
var useAtomicUpdateActionSchema = exports.useAtomicUpdateActionSchema = (0, _reactSweetState.createHook)(ActionsStore, {
|
|
135
|
+
selector: getFieldUpdateActionByAri
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Given an ARI + fieldKey + integrationKey
|
|
140
|
+
* Returns an executable action that updates a field on the entity if the user has permissions to do so
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```tsx
|
|
144
|
+
* const { execute } = useExecuteAtomicAction({ ari, fieldKey: 'summary', integrationKey: 'jira' });
|
|
145
|
+
*
|
|
146
|
+
* return <button onClick={() => execute('New summary')}>Update summary</button>;
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
var useExecuteAtomicAction = exports.useExecuteAtomicAction = function useExecuteAtomicAction(_ref4) {
|
|
150
|
+
var ari = _ref4.ari,
|
|
151
|
+
fieldKey = _ref4.fieldKey,
|
|
152
|
+
integrationKey = _ref4.integrationKey;
|
|
153
|
+
var _useAtomicUpdateActio = useAtomicUpdateActionSchema({
|
|
154
|
+
ari: ari,
|
|
155
|
+
fieldKey: fieldKey,
|
|
156
|
+
integrationKey: integrationKey
|
|
157
|
+
}),
|
|
158
|
+
_useAtomicUpdateActio2 = (0, _slicedToArray2.default)(_useAtomicUpdateActio, 1),
|
|
159
|
+
schema = _useAtomicUpdateActio2[0];
|
|
160
|
+
var _useDatasourceClientE2 = (0, _linkClientExtension.useDatasourceClientExtension)(),
|
|
161
|
+
executeAction = _useDatasourceClientE2.executeAtomicAction;
|
|
162
|
+
var execute = (0, _react.useCallback)(function (value) {
|
|
163
|
+
if (!schema) {
|
|
164
|
+
throw new Error('No action schema found.');
|
|
165
|
+
}
|
|
166
|
+
executeAction({
|
|
167
|
+
integrationKey: integrationKey,
|
|
168
|
+
actionKey: schema.actionKey,
|
|
169
|
+
parameters: {
|
|
170
|
+
inputs: (0, _defineProperty2.default)({}, fieldKey, value),
|
|
171
|
+
target: {
|
|
172
|
+
ari: ari
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}, [executeAction, integrationKey, schema, fieldKey, ari]);
|
|
177
|
+
if (!schema) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
execute: execute
|
|
182
|
+
};
|
|
183
|
+
};
|
package/dist/cjs/state/index.js
CHANGED
|
@@ -20,19 +20,22 @@ var getInitialState = function getInitialState() {
|
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
var actions = exports.actions = {
|
|
23
|
-
onAddItems: function onAddItems(items) {
|
|
23
|
+
onAddItems: function onAddItems(items, integrationKey) {
|
|
24
24
|
return function (_ref) {
|
|
25
25
|
var setState = _ref.setState,
|
|
26
26
|
getState = _ref.getState;
|
|
27
27
|
var oldItems = _objectSpread({}, getState().items);
|
|
28
28
|
var _items$reduce = items.reduce(function (_ref2, item) {
|
|
29
|
-
var _item$ari;
|
|
29
|
+
var _item$ari, _oldItems$id;
|
|
30
30
|
var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
|
|
31
31
|
ids = _ref3[0],
|
|
32
32
|
itemMap = _ref3[1];
|
|
33
33
|
var ari = typeof ((_item$ari = item['ari']) === null || _item$ari === void 0 ? void 0 : _item$ari.data) === 'string' ? item['ari'].data : undefined;
|
|
34
34
|
var id = ari !== null && ari !== void 0 ? ari : (0, _uuid.v4)();
|
|
35
|
-
return [[].concat((0, _toConsumableArray2.default)(ids), [id]), _objectSpread(_objectSpread({}, itemMap), {}, (0, _defineProperty2.default)({}, id,
|
|
35
|
+
return [[].concat((0, _toConsumableArray2.default)(ids), [id]), _objectSpread(_objectSpread({}, itemMap), {}, (0, _defineProperty2.default)({}, id, {
|
|
36
|
+
integrationKey: integrationKey,
|
|
37
|
+
data: _objectSpread(_objectSpread({}, (_oldItems$id = oldItems[id]) === null || _oldItems$id === void 0 ? void 0 : _oldItems$id.data), item)
|
|
38
|
+
}))];
|
|
36
39
|
}, [[], oldItems]),
|
|
37
40
|
_items$reduce2 = (0, _slicedToArray2.default)(_items$reduce, 2),
|
|
38
41
|
newItemIds = _items$reduce2[0],
|
|
@@ -51,8 +54,9 @@ var Store = exports.Store = (0, _reactSweetState.createStore)({
|
|
|
51
54
|
});
|
|
52
55
|
var useDatasourceItem = exports.useDatasourceItem = (0, _reactSweetState.createStateHook)(Store, {
|
|
53
56
|
selector: function selector(state, _ref4) {
|
|
57
|
+
var _state$items$id;
|
|
54
58
|
var id = _ref4.id;
|
|
55
|
-
return state.items[id];
|
|
59
|
+
return (_state$items$id = state.items[id]) === null || _state$items$id === void 0 ? void 0 : _state$items$id.data;
|
|
56
60
|
}
|
|
57
61
|
});
|
|
58
62
|
var useDatasourceActions = exports.useDatasourceActions = (0, _reactSweetState.createActionsHook)(Store);
|
|
@@ -107,7 +107,7 @@ var ColumnPicker = exports.ColumnPicker = function ColumnPicker(_ref) {
|
|
|
107
107
|
if (allOptions.length) {
|
|
108
108
|
var _pickerRef$current;
|
|
109
109
|
// necessary to refocus the search input after the loading state
|
|
110
|
-
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();
|
|
110
|
+
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.select) === null || _pickerRef$current === void 0 || (_pickerRef$current = _pickerRef$current.inputRef) === null || _pickerRef$current === void 0 || _pickerRef$current.focus();
|
|
111
111
|
}
|
|
112
112
|
}, [allOptions]);
|
|
113
113
|
(0, _react.useEffect)(function () {
|
|
@@ -4,6 +4,7 @@ import { DEFAULT_GET_DATASOURCE_DATA_PAGE_SIZE, useDatasourceClientExtension } f
|
|
|
4
4
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
5
|
import { useDatasourceAnalyticsEvents } from '../analytics';
|
|
6
6
|
import { useDatasourceActions } from '../state';
|
|
7
|
+
import { useDiscoverActions } from '../state/actions';
|
|
7
8
|
import useErrorLogger from './useErrorLogger';
|
|
8
9
|
export const useDatasourceTableState = ({
|
|
9
10
|
datasourceId,
|
|
@@ -21,6 +22,9 @@ export const useDatasourceTableState = ({
|
|
|
21
22
|
const {
|
|
22
23
|
onAddItems
|
|
23
24
|
} = useDatasourceActions();
|
|
25
|
+
const {
|
|
26
|
+
discoverActions
|
|
27
|
+
} = useDiscoverActions();
|
|
24
28
|
const idFieldCount = 1;
|
|
25
29
|
const keyFieldCount = 1;
|
|
26
30
|
const [initialEmptyArray] = useState([]);
|
|
@@ -152,6 +156,7 @@ export const useDatasourceTableState = ({
|
|
|
152
156
|
meta: {
|
|
153
157
|
access,
|
|
154
158
|
destinationObjectTypes,
|
|
159
|
+
product,
|
|
155
160
|
extensionKey,
|
|
156
161
|
auth,
|
|
157
162
|
providerName
|
|
@@ -186,8 +191,27 @@ export const useDatasourceTableState = ({
|
|
|
186
191
|
return [...currentResponseItems, ...items];
|
|
187
192
|
});
|
|
188
193
|
if (fg('enable_datasource_react_sweet_state')) {
|
|
189
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Product is typed as any.
|
|
196
|
+
*/
|
|
197
|
+
const integrationKey = product;
|
|
198
|
+
const newIds = onAddItems(items, typeof integrationKey === 'string' ? integrationKey : undefined);
|
|
190
199
|
setResponseItemIds(currentIds => [...currentIds, ...newIds]);
|
|
200
|
+
if (fg('platform-datasources-enable-two-way-sync')) {
|
|
201
|
+
if (typeof integrationKey === 'string') {
|
|
202
|
+
const aris = items.reduce((acc, item) => {
|
|
203
|
+
var _item$ari;
|
|
204
|
+
return typeof ((_item$ari = item.ari) === null || _item$ari === void 0 ? void 0 : _item$ari.data) === 'string' ? [...acc, item.ari.data] : acc;
|
|
205
|
+
}, []);
|
|
206
|
+
if (aris.length) {
|
|
207
|
+
discoverActions({
|
|
208
|
+
aris,
|
|
209
|
+
integrationKey,
|
|
210
|
+
fieldKeys
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
191
215
|
}
|
|
192
216
|
setHasNextPage(Boolean(nextPageCursor));
|
|
193
217
|
if (fieldKeys.length > 0) {
|
|
@@ -228,7 +252,7 @@ export const useDatasourceTableState = ({
|
|
|
228
252
|
}
|
|
229
253
|
setStatus('rejected');
|
|
230
254
|
}
|
|
231
|
-
}, [captureError, parameters, fieldKeys, nextCursor, responseItems, setResponseItemIds, onAddItems, getDatasourceData, datasourceId, applySchemaProperties, fireEvent, fullSchema, initialEmptyArray]);
|
|
255
|
+
}, [captureError, parameters, fieldKeys, nextCursor, responseItems, setResponseItemIds, onAddItems, getDatasourceData, datasourceId, applySchemaProperties, fireEvent, fullSchema, initialEmptyArray, discoverActions]);
|
|
232
256
|
const reset = useCallback(options => {
|
|
233
257
|
setResponseItems(initialEmptyArray);
|
|
234
258
|
setResponseItemIds(initialEmptyArray);
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import { createActionsHook, createHook, createStore } from 'react-sweet-state';
|
|
3
|
+
import { useDatasourceClientExtension } from '@atlaskit/link-client-extension';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Atomic actions available for an integration (by field)
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* {
|
|
10
|
+
* jira: {
|
|
11
|
+
* summary: {
|
|
12
|
+
* actionKey: 'atlassian:issue:update:summary',
|
|
13
|
+
* type: 'string',
|
|
14
|
+
* description: 'Update issue summary',
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Permissions available for a target
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* User permissions for actions on target (ARI) properties
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* {
|
|
30
|
+
* 'ari:cloud:jira:63cecfe3-16fa-4ee1-8e8d-047cc4b18980:issue/1': {
|
|
31
|
+
* summary: {
|
|
32
|
+
* isEditable: true
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const getInitialState = () => ({
|
|
40
|
+
actionsByIntegration: {},
|
|
41
|
+
permissions: {}
|
|
42
|
+
});
|
|
43
|
+
export const actions = {
|
|
44
|
+
discoverActions: (api, request) => async ({
|
|
45
|
+
setState,
|
|
46
|
+
getState
|
|
47
|
+
}) => {
|
|
48
|
+
const response = await api.getDatasourceActionsAndPermissions(request);
|
|
49
|
+
if ('permissions' in response) {
|
|
50
|
+
const {
|
|
51
|
+
actionsByIntegration: currentActions,
|
|
52
|
+
permissions: currentPermissions
|
|
53
|
+
} = getState();
|
|
54
|
+
const actionsByIntegration = response.actions.reduce((acc, action) => ({
|
|
55
|
+
...acc,
|
|
56
|
+
[action.integrationKey]: {
|
|
57
|
+
...acc[action.integrationKey],
|
|
58
|
+
[action.fieldKey]: {
|
|
59
|
+
actionKey: action.actionKey,
|
|
60
|
+
type: action.type
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}), currentActions);
|
|
64
|
+
const permissions = response.permissions.data.reduce((acc, permission) => ({
|
|
65
|
+
...acc,
|
|
66
|
+
[permission.ari]: {
|
|
67
|
+
...acc[permission.ari],
|
|
68
|
+
[permission.fieldKey]: {
|
|
69
|
+
isEditable: permission.isEditable
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}), currentPermissions);
|
|
73
|
+
setState({
|
|
74
|
+
actionsByIntegration,
|
|
75
|
+
permissions
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export const ActionsStore = createStore({
|
|
81
|
+
name: 'actions-store',
|
|
82
|
+
initialState: getInitialState(),
|
|
83
|
+
actions
|
|
84
|
+
});
|
|
85
|
+
const useActionStoreActions = createActionsHook(ActionsStore);
|
|
86
|
+
export const useDiscoverActions = () => {
|
|
87
|
+
const {
|
|
88
|
+
getDatasourceActionsAndPermissions
|
|
89
|
+
} = useDatasourceClientExtension();
|
|
90
|
+
const {
|
|
91
|
+
discoverActions
|
|
92
|
+
} = useActionStoreActions();
|
|
93
|
+
return {
|
|
94
|
+
discoverActions: useMemo(() => discoverActions.bind(null, {
|
|
95
|
+
getDatasourceActionsAndPermissions
|
|
96
|
+
}), [discoverActions, getDatasourceActionsAndPermissions])
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
const getFieldUpdateActionByAri = (state, {
|
|
100
|
+
ari,
|
|
101
|
+
fieldKey,
|
|
102
|
+
integrationKey
|
|
103
|
+
}) => {
|
|
104
|
+
var _state$permissions$ar, _state$permissions$ar2, _state$actionsByInteg;
|
|
105
|
+
const isEditable = (_state$permissions$ar = state.permissions[ari]) === null || _state$permissions$ar === void 0 ? void 0 : (_state$permissions$ar2 = _state$permissions$ar[fieldKey]) === null || _state$permissions$ar2 === void 0 ? void 0 : _state$permissions$ar2.isEditable;
|
|
106
|
+
if (isEditable === false) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
return (_state$actionsByInteg = state.actionsByIntegration[integrationKey]) === null || _state$actionsByInteg === void 0 ? void 0 : _state$actionsByInteg[fieldKey];
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Retrieves the action schema for a given ARI + fieldKey + integrationKey
|
|
114
|
+
*/
|
|
115
|
+
export const useAtomicUpdateActionSchema = createHook(ActionsStore, {
|
|
116
|
+
selector: getFieldUpdateActionByAri
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Given an ARI + fieldKey + integrationKey
|
|
121
|
+
* Returns an executable action that updates a field on the entity if the user has permissions to do so
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* const { execute } = useExecuteAtomicAction({ ari, fieldKey: 'summary', integrationKey: 'jira' });
|
|
126
|
+
*
|
|
127
|
+
* return <button onClick={() => execute('New summary')}>Update summary</button>;
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export const useExecuteAtomicAction = ({
|
|
131
|
+
ari,
|
|
132
|
+
fieldKey,
|
|
133
|
+
integrationKey
|
|
134
|
+
}) => {
|
|
135
|
+
const [schema] = useAtomicUpdateActionSchema({
|
|
136
|
+
ari,
|
|
137
|
+
fieldKey,
|
|
138
|
+
integrationKey
|
|
139
|
+
});
|
|
140
|
+
const {
|
|
141
|
+
executeAtomicAction: executeAction
|
|
142
|
+
} = useDatasourceClientExtension();
|
|
143
|
+
const execute = useCallback(value => {
|
|
144
|
+
if (!schema) {
|
|
145
|
+
throw new Error('No action schema found.');
|
|
146
|
+
}
|
|
147
|
+
executeAction({
|
|
148
|
+
integrationKey,
|
|
149
|
+
actionKey: schema.actionKey,
|
|
150
|
+
parameters: {
|
|
151
|
+
inputs: {
|
|
152
|
+
[fieldKey]: value
|
|
153
|
+
},
|
|
154
|
+
target: {
|
|
155
|
+
ari
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}, [executeAction, integrationKey, schema, fieldKey, ari]);
|
|
160
|
+
if (!schema) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
execute
|
|
165
|
+
};
|
|
166
|
+
};
|
|
@@ -6,7 +6,7 @@ const getInitialState = () => ({
|
|
|
6
6
|
items: {}
|
|
7
7
|
});
|
|
8
8
|
export const actions = {
|
|
9
|
-
onAddItems: items => ({
|
|
9
|
+
onAddItems: (items, integrationKey) => ({
|
|
10
10
|
setState,
|
|
11
11
|
getState
|
|
12
12
|
}) => {
|
|
@@ -14,14 +14,17 @@ export const actions = {
|
|
|
14
14
|
...getState().items
|
|
15
15
|
};
|
|
16
16
|
const [newItemIds, newItems] = items.reduce(([ids, itemMap], item) => {
|
|
17
|
-
var _item$ari;
|
|
17
|
+
var _item$ari, _oldItems$id;
|
|
18
18
|
const ari = typeof ((_item$ari = item['ari']) === null || _item$ari === void 0 ? void 0 : _item$ari.data) === 'string' ? item['ari'].data : undefined;
|
|
19
19
|
const id = ari !== null && ari !== void 0 ? ari : uuidv4();
|
|
20
20
|
return [[...ids, id], {
|
|
21
21
|
...itemMap,
|
|
22
22
|
[id]: {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
integrationKey,
|
|
24
|
+
data: {
|
|
25
|
+
...((_oldItems$id = oldItems[id]) === null || _oldItems$id === void 0 ? void 0 : _oldItems$id.data),
|
|
26
|
+
...item
|
|
27
|
+
}
|
|
25
28
|
}
|
|
26
29
|
}];
|
|
27
30
|
}, [[], oldItems]);
|
|
@@ -39,7 +42,10 @@ export const Store = createStore({
|
|
|
39
42
|
export const useDatasourceItem = createStateHook(Store, {
|
|
40
43
|
selector: (state, {
|
|
41
44
|
id
|
|
42
|
-
}) =>
|
|
45
|
+
}) => {
|
|
46
|
+
var _state$items$id;
|
|
47
|
+
return (_state$items$id = state.items[id]) === null || _state$items$id === void 0 ? void 0 : _state$items$id.data;
|
|
48
|
+
}
|
|
43
49
|
});
|
|
44
50
|
export const useDatasourceActions = createActionsHook(Store);
|
|
45
51
|
const Container = createContainer(Store);
|