@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.
@@ -81,9 +81,9 @@ export const ColumnPicker = ({
81
81
  };
82
82
  useEffect(() => {
83
83
  if (allOptions.length) {
84
- var _pickerRef$current, _pickerRef$current$se, _pickerRef$current$se2;
84
+ var _pickerRef$current, _pickerRef$current$se, _pickerRef$current$se2, _pickerRef$current$se3;
85
85
  // necessary to refocus the search input after the loading state
86
- pickerRef === null || pickerRef === void 0 ? void 0 : (_pickerRef$current = pickerRef.current) === null || _pickerRef$current === void 0 ? void 0 : (_pickerRef$current$se = _pickerRef$current.selectRef) === null || _pickerRef$current$se === void 0 ? void 0 : (_pickerRef$current$se2 = _pickerRef$current$se.inputRef) === null || _pickerRef$current$se2 === void 0 ? void 0 : _pickerRef$current$se2.focus();
86
+ pickerRef === null || pickerRef === void 0 ? void 0 : (_pickerRef$current = pickerRef.current) === null || _pickerRef$current === void 0 ? void 0 : (_pickerRef$current$se = _pickerRef$current.selectRef) === null || _pickerRef$current$se === void 0 ? void 0 : (_pickerRef$current$se2 = _pickerRef$current$se.select) === null || _pickerRef$current$se2 === void 0 ? void 0 : (_pickerRef$current$se3 = _pickerRef$current$se2.inputRef) === null || _pickerRef$current$se3 === void 0 ? void 0 : _pickerRef$current$se3.focus();
87
87
  }
88
88
  }, [allOptions]);
89
89
  useEffect(() => {
@@ -8,6 +8,7 @@ import { DEFAULT_GET_DATASOURCE_DATA_PAGE_SIZE, useDatasourceClientExtension } f
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { useDatasourceAnalyticsEvents } from '../analytics';
10
10
  import { useDatasourceActions } from '../state';
11
+ import { useDiscoverActions } from '../state/actions';
11
12
  import useErrorLogger from './useErrorLogger';
12
13
  export var useDatasourceTableState = function useDatasourceTableState(_ref) {
13
14
  var datasourceId = _ref.datasourceId,
@@ -22,6 +23,8 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
22
23
  captureError = _useErrorLogger.captureError;
23
24
  var _useDatasourceActions = useDatasourceActions(),
24
25
  onAddItems = _useDatasourceActions.onAddItems;
26
+ var _useDiscoverActions = useDiscoverActions(),
27
+ discoverActions = _useDiscoverActions.discoverActions;
25
28
  var idFieldCount = 1;
26
29
  var keyFieldCount = 1;
27
30
  var _useState = useState([]),
@@ -208,6 +211,7 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
208
211
  _yield$getDatasourceD4,
209
212
  access,
210
213
  _destinationObjectTypes,
214
+ product,
211
215
  _extensionKey,
212
216
  auth,
213
217
  _providerName,
@@ -216,7 +220,9 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
216
220
  nextPageCursor,
217
221
  _totalCount,
218
222
  schema,
223
+ integrationKey,
219
224
  newIds,
225
+ aris,
220
226
  isUserLoadingNextPage,
221
227
  currentLoadedItemCount,
222
228
  newlyLoadedItemCount,
@@ -258,6 +264,7 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
258
264
  _yield$getDatasourceD4 = _yield$getDatasourceD3.meta;
259
265
  access = _yield$getDatasourceD4.access;
260
266
  _destinationObjectTypes = _yield$getDatasourceD4.destinationObjectTypes;
267
+ product = _yield$getDatasourceD4.product;
261
268
  _extensionKey = _yield$getDatasourceD4.extensionKey;
262
269
  auth = _yield$getDatasourceD4.auth;
263
270
  _providerName = _yield$getDatasourceD4.providerName;
@@ -267,21 +274,21 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
267
274
  _totalCount = _yield$getDatasourceD5.totalCount;
268
275
  schema = _yield$getDatasourceD5.schema;
269
276
  if (!((_currentAbortControll = currentAbortController) !== null && _currentAbortControll !== void 0 && _currentAbortControll.signal.aborted)) {
270
- _context2.next = 27;
277
+ _context2.next = 28;
271
278
  break;
272
279
  }
273
280
  throw new Error('Aborted');
274
- case 27:
281
+ case 28:
275
282
  setExtensionKey(_extensionKey);
276
283
  setProviderName(_providerName);
277
284
  if (!(access === 'unauthorized' || access === 'forbidden')) {
278
- _context2.next = 33;
285
+ _context2.next = 34;
279
286
  break;
280
287
  }
281
288
  setStatus(access);
282
289
  setAuthDetails(auth || initialEmptyArray);
283
290
  return _context2.abrupt("return");
284
- case 33:
291
+ case 34:
285
292
  setDestinationObjectTypes(_destinationObjectTypes);
286
293
  setTotalCount(_totalCount);
287
294
  setNextCursor(nextPageCursor);
@@ -292,10 +299,29 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
292
299
  return [].concat(_toConsumableArray(currentResponseItems), _toConsumableArray(items));
293
300
  });
294
301
  if (fg('enable_datasource_react_sweet_state')) {
295
- newIds = onAddItems(items);
302
+ /**
303
+ * Product is typed as any.
304
+ */
305
+ integrationKey = product;
306
+ newIds = onAddItems(items, typeof integrationKey === 'string' ? integrationKey : undefined);
296
307
  setResponseItemIds(function (currentIds) {
297
308
  return [].concat(_toConsumableArray(currentIds), _toConsumableArray(newIds));
298
309
  });
310
+ if (fg('platform-datasources-enable-two-way-sync')) {
311
+ if (typeof integrationKey === 'string') {
312
+ aris = items.reduce(function (acc, item) {
313
+ var _item$ari;
314
+ return typeof ((_item$ari = item.ari) === null || _item$ari === void 0 ? void 0 : _item$ari.data) === 'string' ? [].concat(_toConsumableArray(acc), [item.ari.data]) : acc;
315
+ }, []);
316
+ if (aris.length) {
317
+ discoverActions({
318
+ aris: aris,
319
+ integrationKey: integrationKey,
320
+ fieldKeys: fieldKeys
321
+ });
322
+ }
323
+ }
324
+ }
299
325
  }
300
326
  setHasNextPage(Boolean(nextPageCursor));
301
327
  if (fieldKeys.length > 0) {
@@ -315,39 +341,39 @@ export var useDatasourceTableState = function useDatasourceTableState(_ref) {
315
341
  });
316
342
  }
317
343
  setStatus('resolved');
318
- _context2.next = 58;
344
+ _context2.next = 59;
319
345
  break;
320
- case 46:
321
- _context2.prev = 46;
346
+ case 47:
347
+ _context2.prev = 47;
322
348
  _context2.t0 = _context2["catch"](10);
323
349
  if (!(_context2.t0.message === 'Aborted')) {
324
- _context2.next = 50;
350
+ _context2.next = 51;
325
351
  break;
326
352
  }
327
353
  return _context2.abrupt("return");
328
- case 50:
354
+ case 51:
329
355
  captureError('onNextPage', _context2.t0);
330
356
  if (!(_context2.t0 instanceof Response && _context2.t0.status === 401)) {
331
- _context2.next = 54;
357
+ _context2.next = 55;
332
358
  break;
333
359
  }
334
360
  setStatus('unauthorized');
335
361
  return _context2.abrupt("return");
336
- case 54:
362
+ case 55:
337
363
  if (!(_context2.t0 instanceof Response && _context2.t0.status === 403)) {
338
- _context2.next = 57;
364
+ _context2.next = 58;
339
365
  break;
340
366
  }
341
367
  setStatus('forbidden');
342
368
  return _context2.abrupt("return");
343
- case 57:
344
- setStatus('rejected');
345
369
  case 58:
370
+ setStatus('rejected');
371
+ case 59:
346
372
  case "end":
347
373
  return _context2.stop();
348
374
  }
349
- }, _callee2, null, [[10, 46]]);
350
- })), [captureError, parameters, fieldKeys, nextCursor, responseItems, setResponseItemIds, onAddItems, getDatasourceData, datasourceId, applySchemaProperties, fireEvent, fullSchema, initialEmptyArray]);
375
+ }, _callee2, null, [[10, 47]]);
376
+ })), [captureError, parameters, fieldKeys, nextCursor, responseItems, setResponseItemIds, onAddItems, getDatasourceData, datasourceId, applySchemaProperties, fireEvent, fullSchema, initialEmptyArray, discoverActions]);
351
377
  var reset = useCallback(function (options) {
352
378
  setResponseItems(initialEmptyArray);
353
379
  setResponseItemIds(initialEmptyArray);
@@ -0,0 +1,177 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
5
+ 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; }
6
+ 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) { _defineProperty(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; }
7
+ import { useCallback, useMemo } from 'react';
8
+ import { createActionsHook, createHook, createStore } from 'react-sweet-state';
9
+ import { useDatasourceClientExtension } from '@atlaskit/link-client-extension';
10
+
11
+ /**
12
+ * Atomic actions available for an integration (by field)
13
+ * @example
14
+ * ```ts
15
+ * {
16
+ * jira: {
17
+ * summary: {
18
+ * actionKey: 'atlassian:issue:update:summary',
19
+ * type: 'string',
20
+ * description: 'Update issue summary',
21
+ * }
22
+ * }
23
+ * }
24
+ * ```
25
+ */
26
+
27
+ /**
28
+ * Permissions available for a target
29
+ */
30
+
31
+ /**
32
+ * User permissions for actions on target (ARI) properties
33
+ * @example
34
+ * ```ts
35
+ * {
36
+ * 'ari:cloud:jira:63cecfe3-16fa-4ee1-8e8d-047cc4b18980:issue/1': {
37
+ * summary: {
38
+ * isEditable: true
39
+ * }
40
+ * }
41
+ * }
42
+ * ```
43
+ */
44
+
45
+ var getInitialState = function getInitialState() {
46
+ return {
47
+ actionsByIntegration: {},
48
+ permissions: {}
49
+ };
50
+ };
51
+ export var actions = {
52
+ discoverActions: function discoverActions(api, request) {
53
+ return /*#__PURE__*/function () {
54
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
55
+ var setState, getState, response, _getState, currentActions, currentPermissions, actionsByIntegration, permissions;
56
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
57
+ while (1) switch (_context.prev = _context.next) {
58
+ case 0:
59
+ setState = _ref.setState, getState = _ref.getState;
60
+ _context.next = 3;
61
+ return api.getDatasourceActionsAndPermissions(request);
62
+ case 3:
63
+ response = _context.sent;
64
+ if ('permissions' in response) {
65
+ _getState = getState(), currentActions = _getState.actionsByIntegration, currentPermissions = _getState.permissions;
66
+ actionsByIntegration = response.actions.reduce(function (acc, action) {
67
+ return _objectSpread(_objectSpread({}, acc), {}, _defineProperty({}, action.integrationKey, _objectSpread(_objectSpread({}, acc[action.integrationKey]), {}, _defineProperty({}, action.fieldKey, {
68
+ actionKey: action.actionKey,
69
+ type: action.type
70
+ }))));
71
+ }, currentActions);
72
+ permissions = response.permissions.data.reduce(function (acc, permission) {
73
+ return _objectSpread(_objectSpread({}, acc), {}, _defineProperty({}, permission.ari, _objectSpread(_objectSpread({}, acc[permission.ari]), {}, _defineProperty({}, permission.fieldKey, {
74
+ isEditable: permission.isEditable
75
+ }))));
76
+ }, currentPermissions);
77
+ setState({
78
+ actionsByIntegration: actionsByIntegration,
79
+ permissions: permissions
80
+ });
81
+ }
82
+ case 5:
83
+ case "end":
84
+ return _context.stop();
85
+ }
86
+ }, _callee);
87
+ }));
88
+ return function (_x) {
89
+ return _ref2.apply(this, arguments);
90
+ };
91
+ }();
92
+ }
93
+ };
94
+ export var ActionsStore = createStore({
95
+ name: 'actions-store',
96
+ initialState: getInitialState(),
97
+ actions: actions
98
+ });
99
+ var useActionStoreActions = createActionsHook(ActionsStore);
100
+ export var useDiscoverActions = function useDiscoverActions() {
101
+ var _useDatasourceClientE = useDatasourceClientExtension(),
102
+ getDatasourceActionsAndPermissions = _useDatasourceClientE.getDatasourceActionsAndPermissions;
103
+ var _useActionStoreAction = useActionStoreActions(),
104
+ discoverActions = _useActionStoreAction.discoverActions;
105
+ return {
106
+ discoverActions: useMemo(function () {
107
+ return discoverActions.bind(null, {
108
+ getDatasourceActionsAndPermissions: getDatasourceActionsAndPermissions
109
+ });
110
+ }, [discoverActions, getDatasourceActionsAndPermissions])
111
+ };
112
+ };
113
+ var getFieldUpdateActionByAri = function getFieldUpdateActionByAri(state, _ref3) {
114
+ var _state$permissions$ar, _state$actionsByInteg;
115
+ var ari = _ref3.ari,
116
+ fieldKey = _ref3.fieldKey,
117
+ integrationKey = _ref3.integrationKey;
118
+ 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;
119
+ if (isEditable === false) {
120
+ return;
121
+ }
122
+ return (_state$actionsByInteg = state.actionsByIntegration[integrationKey]) === null || _state$actionsByInteg === void 0 ? void 0 : _state$actionsByInteg[fieldKey];
123
+ };
124
+
125
+ /**
126
+ * Retrieves the action schema for a given ARI + fieldKey + integrationKey
127
+ */
128
+ export var useAtomicUpdateActionSchema = createHook(ActionsStore, {
129
+ selector: getFieldUpdateActionByAri
130
+ });
131
+
132
+ /**
133
+ * Given an ARI + fieldKey + integrationKey
134
+ * Returns an executable action that updates a field on the entity if the user has permissions to do so
135
+ *
136
+ * @example
137
+ * ```tsx
138
+ * const { execute } = useExecuteAtomicAction({ ari, fieldKey: 'summary', integrationKey: 'jira' });
139
+ *
140
+ * return <button onClick={() => execute('New summary')}>Update summary</button>;
141
+ * ```
142
+ */
143
+ export var useExecuteAtomicAction = function useExecuteAtomicAction(_ref4) {
144
+ var ari = _ref4.ari,
145
+ fieldKey = _ref4.fieldKey,
146
+ integrationKey = _ref4.integrationKey;
147
+ var _useAtomicUpdateActio = useAtomicUpdateActionSchema({
148
+ ari: ari,
149
+ fieldKey: fieldKey,
150
+ integrationKey: integrationKey
151
+ }),
152
+ _useAtomicUpdateActio2 = _slicedToArray(_useAtomicUpdateActio, 1),
153
+ schema = _useAtomicUpdateActio2[0];
154
+ var _useDatasourceClientE2 = useDatasourceClientExtension(),
155
+ executeAction = _useDatasourceClientE2.executeAtomicAction;
156
+ var execute = useCallback(function (value) {
157
+ if (!schema) {
158
+ throw new Error('No action schema found.');
159
+ }
160
+ executeAction({
161
+ integrationKey: integrationKey,
162
+ actionKey: schema.actionKey,
163
+ parameters: {
164
+ inputs: _defineProperty({}, fieldKey, value),
165
+ target: {
166
+ ari: ari
167
+ }
168
+ }
169
+ });
170
+ }, [executeAction, integrationKey, schema, fieldKey, ari]);
171
+ if (!schema) {
172
+ return null;
173
+ }
174
+ return {
175
+ execute: execute
176
+ };
177
+ };
@@ -13,19 +13,22 @@ var getInitialState = function getInitialState() {
13
13
  };
14
14
  };
15
15
  export var actions = {
16
- onAddItems: function onAddItems(items) {
16
+ onAddItems: function onAddItems(items, integrationKey) {
17
17
  return function (_ref) {
18
18
  var setState = _ref.setState,
19
19
  getState = _ref.getState;
20
20
  var oldItems = _objectSpread({}, getState().items);
21
21
  var _items$reduce = items.reduce(function (_ref2, item) {
22
- var _item$ari;
22
+ var _item$ari, _oldItems$id;
23
23
  var _ref3 = _slicedToArray(_ref2, 2),
24
24
  ids = _ref3[0],
25
25
  itemMap = _ref3[1];
26
26
  var ari = typeof ((_item$ari = item['ari']) === null || _item$ari === void 0 ? void 0 : _item$ari.data) === 'string' ? item['ari'].data : undefined;
27
27
  var id = ari !== null && ari !== void 0 ? ari : uuidv4();
28
- return [[].concat(_toConsumableArray(ids), [id]), _objectSpread(_objectSpread({}, itemMap), {}, _defineProperty({}, id, _objectSpread(_objectSpread({}, oldItems[id]), item)))];
28
+ return [[].concat(_toConsumableArray(ids), [id]), _objectSpread(_objectSpread({}, itemMap), {}, _defineProperty({}, id, {
29
+ integrationKey: integrationKey,
30
+ data: _objectSpread(_objectSpread({}, (_oldItems$id = oldItems[id]) === null || _oldItems$id === void 0 ? void 0 : _oldItems$id.data), item)
31
+ }))];
29
32
  }, [[], oldItems]),
30
33
  _items$reduce2 = _slicedToArray(_items$reduce, 2),
31
34
  newItemIds = _items$reduce2[0],
@@ -44,8 +47,9 @@ export var Store = createStore({
44
47
  });
45
48
  export var useDatasourceItem = createStateHook(Store, {
46
49
  selector: function selector(state, _ref4) {
50
+ var _state$items$id;
47
51
  var id = _ref4.id;
48
- return state.items[id];
52
+ return (_state$items$id = state.items[id]) === null || _state$items$id === void 0 ? void 0 : _state$items$id.data;
49
53
  }
50
54
  });
51
55
  export var useDatasourceActions = createActionsHook(Store);
@@ -101,7 +101,7 @@ export var ColumnPicker = function ColumnPicker(_ref) {
101
101
  if (allOptions.length) {
102
102
  var _pickerRef$current;
103
103
  // necessary to refocus the search input after the loading state
104
- 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();
104
+ 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();
105
105
  }
106
106
  }, [allOptions]);
107
107
  useEffect(function () {
@@ -0,0 +1,87 @@
1
+ import { type Action } from 'react-sweet-state';
2
+ import { useDatasourceClientExtension } from '@atlaskit/link-client-extension';
3
+ import type { ActionsDiscoveryRequest, AtomicActionInterface } from '@atlaskit/linking-types';
4
+ type IntegrationKey = string;
5
+ type FieldKey = string;
6
+ /**
7
+ * Atomic actions available for an integration (by field)
8
+ * @example
9
+ * ```ts
10
+ * {
11
+ * jira: {
12
+ * summary: {
13
+ * actionKey: 'atlassian:issue:update:summary',
14
+ * type: 'string',
15
+ * description: 'Update issue summary',
16
+ * }
17
+ * }
18
+ * }
19
+ * ```
20
+ */
21
+ type IntegrationActions = Record<IntegrationKey, Record<FieldKey, Pick<AtomicActionInterface, 'actionKey' | 'type' | 'description'>>>;
22
+ /**
23
+ * Permissions available for a target
24
+ */
25
+ type TargetPermissions = Record<FieldKey, {
26
+ isEditable: boolean;
27
+ }>;
28
+ /**
29
+ * User permissions for actions on target (ARI) properties
30
+ * @example
31
+ * ```ts
32
+ * {
33
+ * 'ari:cloud:jira:63cecfe3-16fa-4ee1-8e8d-047cc4b18980:issue/1': {
34
+ * summary: {
35
+ * isEditable: true
36
+ * }
37
+ * }
38
+ * }
39
+ * ```
40
+ */
41
+ type ARI = string;
42
+ type Permissions = Record<ARI, TargetPermissions>;
43
+ export interface ActionsStoreState {
44
+ actionsByIntegration: IntegrationActions;
45
+ permissions: Permissions;
46
+ }
47
+ interface Client {
48
+ getDatasourceActionsAndPermissions: ReturnType<typeof useDatasourceClientExtension>['getDatasourceActionsAndPermissions'];
49
+ }
50
+ export declare const actions: {
51
+ discoverActions: (api: Client, request: ActionsDiscoveryRequest) => Action<ActionsStoreState>;
52
+ };
53
+ export declare const ActionsStore: import("react-sweet-state").Store<ActionsStoreState, {
54
+ discoverActions: (api: Client, request: ActionsDiscoveryRequest) => Action<ActionsStoreState>;
55
+ }>;
56
+ export declare const useDiscoverActions: () => {
57
+ discoverActions: (request: ActionsDiscoveryRequest) => void | Promise<void>;
58
+ };
59
+ /**
60
+ * Retrieves the action schema for a given ARI + fieldKey + integrationKey
61
+ */
62
+ export declare const useAtomicUpdateActionSchema: import("react-sweet-state").HookFunction<Pick<AtomicActionInterface, "actionKey" | "type" | "description"> | undefined, import("react-sweet-state").BoundActions<ActionsStoreState, {
63
+ discoverActions: (api: Client, request: ActionsDiscoveryRequest) => Action<ActionsStoreState>;
64
+ }>, {
65
+ ari: string;
66
+ fieldKey: string;
67
+ integrationKey: string;
68
+ }>;
69
+ /**
70
+ * Given an ARI + fieldKey + integrationKey
71
+ * Returns an executable action that updates a field on the entity if the user has permissions to do so
72
+ *
73
+ * @example
74
+ * ```tsx
75
+ * const { execute } = useExecuteAtomicAction({ ari, fieldKey: 'summary', integrationKey: 'jira' });
76
+ *
77
+ * return <button onClick={() => execute('New summary')}>Update summary</button>;
78
+ * ```
79
+ */
80
+ export declare const useExecuteAtomicAction: ({ ari, fieldKey, integrationKey, }: {
81
+ ari: string;
82
+ fieldKey: string;
83
+ integrationKey: string;
84
+ }) => {
85
+ execute: (value: AtomicActionInterface['type']) => void;
86
+ } | null;
87
+ export {};
@@ -1,21 +1,26 @@
1
1
  /// <reference types="react" />
2
2
  import { type Action } from 'react-sweet-state';
3
- import { type DatasourceDataResponseItem } from '@atlaskit/linking-types';
3
+ import type { DatasourceDataResponseItem } from '@atlaskit/linking-types';
4
+ type UniqueIdentifier = string;
4
5
  export interface State {
5
- items: Record<string, DatasourceDataResponseItem>;
6
+ items: Record<UniqueIdentifier, {
7
+ integrationKey: string | undefined;
8
+ data: DatasourceDataResponseItem;
9
+ }>;
6
10
  }
7
11
  export declare const actions: {
8
- onAddItems: (items: DatasourceDataResponseItem[]) => Action<State, void, string[]>;
12
+ onAddItems: (items: DatasourceDataResponseItem[], integrationKey: string | undefined) => Action<State, void, string[]>;
9
13
  };
10
14
  export declare const Store: import("react-sweet-state").Store<State, {
11
- onAddItems: (items: DatasourceDataResponseItem[]) => Action<State, void, string[]>;
15
+ onAddItems: (items: DatasourceDataResponseItem[], integrationKey: string | undefined) => Action<State, void, string[]>;
12
16
  }>;
13
17
  export declare const useDatasourceItem: import("react-sweet-state").HookStateFunction<DatasourceDataResponseItem | undefined, {
14
18
  id: string;
15
19
  }>;
16
20
  export declare const useDatasourceActions: import("react-sweet-state").HookActionsFunction<import("react-sweet-state").BoundActions<State, {
17
- onAddItems: (items: DatasourceDataResponseItem[]) => Action<State, void, string[]>;
21
+ onAddItems: (items: DatasourceDataResponseItem[], integrationKey: string | undefined) => Action<State, void, string[]>;
18
22
  }>>;
19
23
  export declare const StoreContainer: ({ children }: {
20
24
  children: JSX.Element;
21
25
  }) => JSX.Element;
26
+ export {};
@@ -0,0 +1,87 @@
1
+ import { type Action } from 'react-sweet-state';
2
+ import { useDatasourceClientExtension } from '@atlaskit/link-client-extension';
3
+ import type { ActionsDiscoveryRequest, AtomicActionInterface } from '@atlaskit/linking-types';
4
+ type IntegrationKey = string;
5
+ type FieldKey = string;
6
+ /**
7
+ * Atomic actions available for an integration (by field)
8
+ * @example
9
+ * ```ts
10
+ * {
11
+ * jira: {
12
+ * summary: {
13
+ * actionKey: 'atlassian:issue:update:summary',
14
+ * type: 'string',
15
+ * description: 'Update issue summary',
16
+ * }
17
+ * }
18
+ * }
19
+ * ```
20
+ */
21
+ type IntegrationActions = Record<IntegrationKey, Record<FieldKey, Pick<AtomicActionInterface, 'actionKey' | 'type' | 'description'>>>;
22
+ /**
23
+ * Permissions available for a target
24
+ */
25
+ type TargetPermissions = Record<FieldKey, {
26
+ isEditable: boolean;
27
+ }>;
28
+ /**
29
+ * User permissions for actions on target (ARI) properties
30
+ * @example
31
+ * ```ts
32
+ * {
33
+ * 'ari:cloud:jira:63cecfe3-16fa-4ee1-8e8d-047cc4b18980:issue/1': {
34
+ * summary: {
35
+ * isEditable: true
36
+ * }
37
+ * }
38
+ * }
39
+ * ```
40
+ */
41
+ type ARI = string;
42
+ type Permissions = Record<ARI, TargetPermissions>;
43
+ export interface ActionsStoreState {
44
+ actionsByIntegration: IntegrationActions;
45
+ permissions: Permissions;
46
+ }
47
+ interface Client {
48
+ getDatasourceActionsAndPermissions: ReturnType<typeof useDatasourceClientExtension>['getDatasourceActionsAndPermissions'];
49
+ }
50
+ export declare const actions: {
51
+ discoverActions: (api: Client, request: ActionsDiscoveryRequest) => Action<ActionsStoreState>;
52
+ };
53
+ export declare const ActionsStore: import("react-sweet-state").Store<ActionsStoreState, {
54
+ discoverActions: (api: Client, request: ActionsDiscoveryRequest) => Action<ActionsStoreState>;
55
+ }>;
56
+ export declare const useDiscoverActions: () => {
57
+ discoverActions: (request: ActionsDiscoveryRequest) => void | Promise<void>;
58
+ };
59
+ /**
60
+ * Retrieves the action schema for a given ARI + fieldKey + integrationKey
61
+ */
62
+ export declare const useAtomicUpdateActionSchema: import("react-sweet-state").HookFunction<Pick<AtomicActionInterface, "actionKey" | "type" | "description"> | undefined, import("react-sweet-state").BoundActions<ActionsStoreState, {
63
+ discoverActions: (api: Client, request: ActionsDiscoveryRequest) => Action<ActionsStoreState>;
64
+ }>, {
65
+ ari: string;
66
+ fieldKey: string;
67
+ integrationKey: string;
68
+ }>;
69
+ /**
70
+ * Given an ARI + fieldKey + integrationKey
71
+ * Returns an executable action that updates a field on the entity if the user has permissions to do so
72
+ *
73
+ * @example
74
+ * ```tsx
75
+ * const { execute } = useExecuteAtomicAction({ ari, fieldKey: 'summary', integrationKey: 'jira' });
76
+ *
77
+ * return <button onClick={() => execute('New summary')}>Update summary</button>;
78
+ * ```
79
+ */
80
+ export declare const useExecuteAtomicAction: ({ ari, fieldKey, integrationKey, }: {
81
+ ari: string;
82
+ fieldKey: string;
83
+ integrationKey: string;
84
+ }) => {
85
+ execute: (value: AtomicActionInterface['type']) => void;
86
+ } | null;
87
+ export {};
@@ -1,21 +1,26 @@
1
1
  /// <reference types="react" />
2
2
  import { type Action } from 'react-sweet-state';
3
- import { type DatasourceDataResponseItem } from '@atlaskit/linking-types';
3
+ import type { DatasourceDataResponseItem } from '@atlaskit/linking-types';
4
+ type UniqueIdentifier = string;
4
5
  export interface State {
5
- items: Record<string, DatasourceDataResponseItem>;
6
+ items: Record<UniqueIdentifier, {
7
+ integrationKey: string | undefined;
8
+ data: DatasourceDataResponseItem;
9
+ }>;
6
10
  }
7
11
  export declare const actions: {
8
- onAddItems: (items: DatasourceDataResponseItem[]) => Action<State, void, string[]>;
12
+ onAddItems: (items: DatasourceDataResponseItem[], integrationKey: string | undefined) => Action<State, void, string[]>;
9
13
  };
10
14
  export declare const Store: import("react-sweet-state").Store<State, {
11
- onAddItems: (items: DatasourceDataResponseItem[]) => Action<State, void, string[]>;
15
+ onAddItems: (items: DatasourceDataResponseItem[], integrationKey: string | undefined) => Action<State, void, string[]>;
12
16
  }>;
13
17
  export declare const useDatasourceItem: import("react-sweet-state").HookStateFunction<DatasourceDataResponseItem | undefined, {
14
18
  id: string;
15
19
  }>;
16
20
  export declare const useDatasourceActions: import("react-sweet-state").HookActionsFunction<import("react-sweet-state").BoundActions<State, {
17
- onAddItems: (items: DatasourceDataResponseItem[]) => Action<State, void, string[]>;
21
+ onAddItems: (items: DatasourceDataResponseItem[], integrationKey: string | undefined) => Action<State, void, string[]>;
18
22
  }>>;
19
23
  export declare const StoreContainer: ({ children }: {
20
24
  children: JSX.Element;
21
25
  }) => JSX.Element;
26
+ export {};