@atlaskit/smart-card 26.22.0 → 26.23.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/utils/actions/create-invoke-request.js +20 -0
  3. package/dist/cjs/utils/analytics/analytics.js +1 -1
  4. package/dist/cjs/utils/index.js +10 -1
  5. package/dist/cjs/view/FlexibleCard/components/actions/action/action-button/index.js +12 -1
  6. package/dist/cjs/view/FlexibleCard/components/actions/action/action-dropdown-item/index.js +2 -0
  7. package/dist/cjs/view/FlexibleCard/components/actions/action/index.js +4 -0
  8. package/dist/cjs/view/FlexibleCard/components/actions/action/server-action/index.js +76 -0
  9. package/dist/cjs/view/FlexibleCard/components/actions/action/server-action/types.js +5 -0
  10. package/dist/cjs/view/HoverCard/utils.js +3 -1
  11. package/dist/cjs/view/LinkUrl/index.js +1 -1
  12. package/dist/es2019/utils/actions/create-invoke-request.js +8 -0
  13. package/dist/es2019/utils/analytics/analytics.js +1 -1
  14. package/dist/es2019/utils/index.js +12 -1
  15. package/dist/es2019/view/FlexibleCard/components/actions/action/action-button/index.js +12 -1
  16. package/dist/es2019/view/FlexibleCard/components/actions/action/action-dropdown-item/index.js +2 -0
  17. package/dist/es2019/view/FlexibleCard/components/actions/action/index.js +3 -0
  18. package/dist/es2019/view/FlexibleCard/components/actions/action/server-action/index.js +38 -0
  19. package/dist/es2019/view/FlexibleCard/components/actions/action/server-action/types.js +1 -0
  20. package/dist/es2019/view/HoverCard/utils.js +9 -5
  21. package/dist/es2019/view/LinkUrl/index.js +1 -1
  22. package/dist/esm/utils/actions/create-invoke-request.js +12 -0
  23. package/dist/esm/utils/analytics/analytics.js +1 -1
  24. package/dist/esm/utils/index.js +10 -1
  25. package/dist/esm/view/FlexibleCard/components/actions/action/action-button/index.js +12 -1
  26. package/dist/esm/view/FlexibleCard/components/actions/action/action-dropdown-item/index.js +2 -0
  27. package/dist/esm/view/FlexibleCard/components/actions/action/index.js +4 -0
  28. package/dist/esm/view/FlexibleCard/components/actions/action/server-action/index.js +65 -0
  29. package/dist/esm/view/FlexibleCard/components/actions/action/server-action/types.js +1 -0
  30. package/dist/esm/view/HoverCard/utils.js +3 -1
  31. package/dist/esm/view/LinkUrl/index.js +1 -1
  32. package/dist/types/state/hooks/use-invoke/types.d.ts +14 -0
  33. package/dist/types/utils/actions/create-invoke-request.d.ts +3 -0
  34. package/dist/types/utils/index.d.ts +1 -1
  35. package/dist/types/view/FlexibleCard/components/actions/action/action-button/types.d.ts +1 -0
  36. package/dist/types/view/FlexibleCard/components/actions/action/action-dropdown-item/types.d.ts +1 -0
  37. package/dist/types/view/FlexibleCard/components/actions/action/index.d.ts +2 -2
  38. package/dist/types/view/FlexibleCard/components/actions/action/server-action/index.d.ts +4 -0
  39. package/dist/types/view/FlexibleCard/components/actions/action/server-action/types.d.ts +6 -0
  40. package/dist/types/view/FlexibleCard/components/actions/action/types.d.ts +12 -0
  41. package/dist/types-ts4.5/state/hooks/use-invoke/types.d.ts +14 -0
  42. package/dist/types-ts4.5/utils/actions/create-invoke-request.d.ts +3 -0
  43. package/dist/types-ts4.5/utils/index.d.ts +1 -1
  44. package/dist/types-ts4.5/view/FlexibleCard/components/actions/action/action-button/types.d.ts +1 -0
  45. package/dist/types-ts4.5/view/FlexibleCard/components/actions/action/action-dropdown-item/types.d.ts +1 -0
  46. package/dist/types-ts4.5/view/FlexibleCard/components/actions/action/index.d.ts +2 -2
  47. package/dist/types-ts4.5/view/FlexibleCard/components/actions/action/server-action/index.d.ts +4 -0
  48. package/dist/types-ts4.5/view/FlexibleCard/components/actions/action/server-action/types.d.ts +6 -0
  49. package/dist/types-ts4.5/view/FlexibleCard/components/actions/action/types.d.ts +12 -0
  50. package/package.json +7 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/smart-card
2
2
 
3
+ ## 26.23.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`253d4604c50`](https://bitbucket.org/atlassian/atlassian-frontend/commits/253d4604c50) - We are testing support for allow-storage-access-by-user-activation sandbox permission on untrusted embeds behind the "platform.linking-platform.smart-card.iframes-allow-storage-access-by-user-activation" feature flag. If this is successful it will always be enabled for unstrusted embeds in a future release.
8
+
9
+ ### Patch Changes
10
+
11
+ - [`f85b3744521`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f85b3744521) - Add async action base component to flexible smart links (internal)
12
+
13
+ ## 26.22.1
14
+
15
+ ### Patch Changes
16
+
17
+ - [`419f14321f3`](https://bitbucket.org/atlassian/atlassian-frontend/commits/419f14321f3) - Adds a JiraTask check when getting a metadata for hovercard. The change is behind a FF. If this update is successful it will be available in a later release.
18
+
3
19
  ## 26.22.0
4
20
 
5
21
  ### Minor Changes
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ 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; }
10
+ 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; }
11
+ var createInvokeRequest = function createInvokeRequest(request, payload) {
12
+ return {
13
+ action: _objectSpread(_objectSpread({}, request.action), {}, {
14
+ payload: payload
15
+ }),
16
+ providerKey: request.providerKey
17
+ };
18
+ };
19
+ var _default = createInvokeRequest;
20
+ exports.default = _default;
@@ -21,7 +21,7 @@ exports.ANALYTICS_CHANNEL = ANALYTICS_CHANNEL;
21
21
  var context = {
22
22
  componentName: 'smart-cards',
23
23
  packageName: "@atlaskit/smart-card",
24
- packageVersion: "26.22.0"
24
+ packageVersion: "26.23.0"
25
25
  };
26
26
  exports.context = context;
27
27
  var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
@@ -11,6 +11,7 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
11
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
12
  var _react = _interopRequireDefault(require("react"));
13
13
  var _reactLoadable = _interopRequireDefault(require("react-loadable"));
14
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
15
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
16
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
17
  var isCardWithData = function isCardWithData(props) {
@@ -338,7 +339,15 @@ var typeToIcon = {
338
339
  }]
339
340
  };
340
341
  var getIframeSandboxAttribute = function getIframeSandboxAttribute(isTrusted) {
341
- return isTrusted ? undefined : 'allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts';
342
+ if (isTrusted) {
343
+ return undefined;
344
+ }
345
+ var sandboxPermissions = 'allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts';
346
+ var allowStorageAccess = 'allow-storage-access-by-user-activation';
347
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.iframes-allow-storage-access-by-user-activation')) {
348
+ return "".concat(sandboxPermissions, " ").concat(allowStorageAccess);
349
+ }
350
+ return sandboxPermissions;
342
351
  };
343
352
  exports.getIframeSandboxAttribute = getIframeSandboxAttribute;
344
353
  var handleOnClick = function handleOnClick(handler) {
@@ -10,6 +10,8 @@ var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/hel
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
  var _react2 = require("@emotion/react");
12
12
  var _customThemeButton = _interopRequireDefault(require("@atlaskit/button/custom-theme-button"));
13
+ var _button = require("@atlaskit/button");
14
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
15
  var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
14
16
  var _constants = require("../../../../../../constants");
15
17
  var _utils = require("../../../utils");
@@ -34,6 +36,7 @@ var ActionButton = function ActionButton(_ref) {
34
36
  content = _ref.content,
35
37
  iconAfter = _ref.iconAfter,
36
38
  iconBefore = _ref.iconBefore,
39
+ isLoading = _ref.isLoading,
37
40
  onClick = _ref.onClick,
38
41
  overrideCss = _ref.overrideCss,
39
42
  size = _ref.size,
@@ -53,7 +56,15 @@ var ActionButton = function ActionButton(_ref) {
53
56
  content: tooltipMessage,
54
57
  hideTooltipOnClick: true,
55
58
  testId: "".concat(testId, "-tooltip")
56
- }, (0, _react2.jsx)(_customThemeButton.default, {
59
+ }, (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.smart-card.follow-button') ? (0, _react2.jsx)(_button.LoadingButton, {
60
+ appearance: appearance,
61
+ iconAfter: iconAfter,
62
+ iconBefore: iconBefore,
63
+ isLoading: isLoading,
64
+ onClick: onButtonClick(onClick),
65
+ spacing: _utils.sizeToButtonSpacing[size],
66
+ testId: testId
67
+ }, content) : (0, _react2.jsx)(_customThemeButton.default, {
57
68
  appearance: appearance,
58
69
  iconAfter: iconAfter,
59
70
  iconBefore: iconBefore,
@@ -12,11 +12,13 @@ var ActionDropdownItem = function ActionDropdownItem(_ref) {
12
12
  var content = _ref.content,
13
13
  iconAfter = _ref.iconAfter,
14
14
  iconBefore = _ref.iconBefore,
15
+ isLoading = _ref.isLoading,
15
16
  onClick = _ref.onClick,
16
17
  testId = _ref.testId;
17
18
  return /*#__PURE__*/_react.default.createElement(_dropdownMenu.DropdownItem, {
18
19
  elemAfter: iconAfter,
19
20
  elemBefore: iconBefore,
21
+ isDisabled: isLoading,
20
22
  onClick: (0, _utils.handleOnClick)(onClick),
21
23
  testId: testId
22
24
  }, content);
@@ -25,6 +25,8 @@ var Action = function Action(_ref) {
25
25
  var _ref$appearance = _ref.appearance,
26
26
  appearance = _ref$appearance === void 0 ? 'subtle' : _ref$appearance,
27
27
  content = _ref.content,
28
+ _ref$isLoading = _ref.isLoading,
29
+ isLoading = _ref$isLoading === void 0 ? false : _ref$isLoading,
28
30
  onClick = _ref.onClick,
29
31
  _ref$size = _ref.size,
30
32
  size = _ref$size === void 0 ? _constants.SmartLinkSize.Medium : _ref$size,
@@ -51,6 +53,7 @@ var Action = function Action(_ref) {
51
53
  content: content,
52
54
  iconAfter: iconAfter,
53
55
  iconBefore: iconBefore,
56
+ isLoading: isLoading,
54
57
  onClick: onClick,
55
58
  testId: testId
56
59
  });
@@ -60,6 +63,7 @@ var Action = function Action(_ref) {
60
63
  content: content,
61
64
  iconAfter: iconAfter,
62
65
  iconBefore: iconBefore,
66
+ isLoading: isLoading,
63
67
  onClick: onClick,
64
68
  overrideCss: overrideCss,
65
69
  size: size,
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
12
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
14
+ var _react = _interopRequireWildcard(require("react"));
15
+ var _useInvoke = _interopRequireDefault(require("../../../../../../state/hooks/use-invoke"));
16
+ var _useResolve = _interopRequireDefault(require("../../../../../../state/hooks/use-resolve"));
17
+ var _createInvokeRequest = _interopRequireDefault(require("../../../../../../utils/actions/create-invoke-request"));
18
+ var _index = _interopRequireDefault(require("../index"));
19
+ var _excluded = ["action", "onClick"];
20
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
22
+ var ServerAction = function ServerAction(_ref) {
23
+ var action = _ref.action,
24
+ onClick = _ref.onClick,
25
+ props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
26
+ var _useState = (0, _react.useState)(false),
27
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
28
+ isLoading = _useState2[0],
29
+ setIsLoading = _useState2[1];
30
+ var invoke = (0, _useInvoke.default)();
31
+ var reload = (0, _useResolve.default)();
32
+ var handleClick = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
33
+ var request;
34
+ return _regenerator.default.wrap(function _callee$(_context) {
35
+ while (1) switch (_context.prev = _context.next) {
36
+ case 0:
37
+ if (!action) {
38
+ _context.next = 16;
39
+ break;
40
+ }
41
+ _context.prev = 1;
42
+ setIsLoading(true);
43
+ request = (0, _createInvokeRequest.default)(action);
44
+ _context.next = 6;
45
+ return invoke(request);
46
+ case 6:
47
+ setIsLoading(false);
48
+ if (!(action.reload && action.reload.url)) {
49
+ _context.next = 10;
50
+ break;
51
+ }
52
+ _context.next = 10;
53
+ return reload(action.reload.url, true, undefined, action.reload.id);
54
+ case 10:
55
+ if (onClick) {
56
+ onClick();
57
+ }
58
+ _context.next = 16;
59
+ break;
60
+ case 13:
61
+ _context.prev = 13;
62
+ _context.t0 = _context["catch"](1);
63
+ setIsLoading(false);
64
+ case 16:
65
+ case "end":
66
+ return _context.stop();
67
+ }
68
+ }, _callee, null, [[1, 13]]);
69
+ })), [action, invoke, onClick, reload]);
70
+ return /*#__PURE__*/_react.default.createElement(_index.default, (0, _extends2.default)({}, props, {
71
+ isLoading: isLoading,
72
+ onClick: handleClick
73
+ }));
74
+ };
75
+ var _default = ServerAction;
76
+ exports.default = _default;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -88,6 +88,7 @@ var getSimulatedMetadata = function getSimulatedMetadata() {
88
88
  };
89
89
  exports.getSimulatedMetadata = getSimulatedMetadata;
90
90
  var getSimulatedBetterMetadata = function getSimulatedBetterMetadata() {
91
+ var _data$Type$includes, _data$Type;
91
92
  var extensionKey = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
92
93
  var data = arguments.length > 1 ? arguments[1] : undefined;
93
94
  var types = data ? (0, _linkExtractors.extractType)(data) : undefined;
@@ -137,7 +138,8 @@ var getSimulatedBetterMetadata = function getSimulatedBetterMetadata() {
137
138
  }
138
139
  };
139
140
  case 'jira-object-provider':
140
- return _objectSpread(_objectSpread({}, defaultMetadata), {}, {
141
+ var isJiraTask = (_data$Type$includes = (_data$Type = data['@type']) === null || _data$Type === void 0 ? void 0 : _data$Type.includes('atlassian:Task')) !== null && _data$Type$includes !== void 0 ? _data$Type$includes : false;
142
+ return _objectSpread(_objectSpread({}, defaultMetadata), isJiraTask && {
141
143
  topMetadataBlock: {
142
144
  primary: [_constants.ElementName.AssignedToGroup, _constants.ElementName.State, _constants.ElementName.StoryPoints, _constants.ElementName.Priority],
143
145
  secondary: [],
@@ -18,7 +18,7 @@ var _excluded = ["href", "children", "checkSafety", "onClick", "testId"],
18
18
  _excluded2 = ["isLinkSafe", "showSafetyWarningModal"];
19
19
  var PACKAGE_DATA = {
20
20
  packageName: "@atlaskit/smart-card",
21
- packageVersion: "26.22.0",
21
+ packageVersion: "26.23.0",
22
22
  componentName: 'linkUrl'
23
23
  };
24
24
  var Link = (0, _click.withLinkClickedEvent)('a');
@@ -0,0 +1,8 @@
1
+ const createInvokeRequest = (request, payload) => ({
2
+ action: {
3
+ ...request.action,
4
+ payload
5
+ },
6
+ providerKey: request.providerKey
7
+ });
8
+ export default createInvokeRequest;
@@ -3,7 +3,7 @@ export const ANALYTICS_CHANNEL = 'media';
3
3
  export const context = {
4
4
  componentName: 'smart-cards',
5
5
  packageName: "@atlaskit/smart-card",
6
- packageVersion: "26.22.0"
6
+ packageVersion: "26.23.0"
7
7
  };
8
8
  export let TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
9
9
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import Loadable from 'react-loadable';
3
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
3
4
  export const isCardWithData = props => !!props.data;
4
5
  export const isSpecialEvent = evt => evt.isDefaultPrevented() && (isIframe() || isSpecialKey(evt) || isSpecialClick(evt));
5
6
  export const isIframe = () => window.parent !== parent;
@@ -98,7 +99,17 @@ const typeToIcon = {
98
99
  'application/sketch': ['Sketch', () => import('@atlaskit/icon-file-type/glyph/sketch/16')],
99
100
  folder: ['Folder', () => import('@atlaskit/icon-file-type/glyph/folder/16')]
100
101
  };
101
- export const getIframeSandboxAttribute = isTrusted => isTrusted ? undefined : 'allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts';
102
+ export const getIframeSandboxAttribute = isTrusted => {
103
+ if (isTrusted) {
104
+ return undefined;
105
+ }
106
+ const sandboxPermissions = 'allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts';
107
+ const allowStorageAccess = 'allow-storage-access-by-user-activation';
108
+ if (getBooleanFF('platform.linking-platform.smart-card.iframes-allow-storage-access-by-user-activation')) {
109
+ return `${sandboxPermissions} ${allowStorageAccess}`;
110
+ }
111
+ return sandboxPermissions;
112
+ };
102
113
  export const handleOnClick = handler => e => {
103
114
  e.preventDefault();
104
115
  e.stopPropagation();
@@ -2,6 +2,8 @@
2
2
  import React, { useCallback } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
4
  import Button from '@atlaskit/button/custom-theme-button';
5
+ import { LoadingButton } from '@atlaskit/button';
6
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
5
7
  import Tooltip from '@atlaskit/tooltip';
6
8
  import { SmartLinkSize } from '../../../../../../constants';
7
9
  import { sizeToButtonSpacing } from '../../../utils';
@@ -48,6 +50,7 @@ const ActionButton = ({
48
50
  content,
49
51
  iconAfter,
50
52
  iconBefore,
53
+ isLoading,
51
54
  onClick,
52
55
  overrideCss,
53
56
  size,
@@ -66,7 +69,15 @@ const ActionButton = ({
66
69
  content: tooltipMessage,
67
70
  hideTooltipOnClick: true,
68
71
  testId: `${testId}-tooltip`
69
- }, jsx(Button, {
72
+ }, getBooleanFF('platform.linking-platform.smart-card.follow-button') ? jsx(LoadingButton, {
73
+ appearance: appearance,
74
+ iconAfter: iconAfter,
75
+ iconBefore: iconBefore,
76
+ isLoading: isLoading,
77
+ onClick: onButtonClick(onClick),
78
+ spacing: sizeToButtonSpacing[size],
79
+ testId: testId
80
+ }, content) : jsx(Button, {
70
81
  appearance: appearance,
71
82
  iconAfter: iconAfter,
72
83
  iconBefore: iconBefore,
@@ -5,11 +5,13 @@ const ActionDropdownItem = ({
5
5
  content,
6
6
  iconAfter,
7
7
  iconBefore,
8
+ isLoading,
8
9
  onClick,
9
10
  testId
10
11
  }) => /*#__PURE__*/React.createElement(DropdownItem, {
11
12
  elemAfter: iconAfter,
12
13
  elemBefore: iconBefore,
14
+ isDisabled: isLoading,
13
15
  onClick: handleOnClick(onClick),
14
16
  testId: testId
15
17
  }, content);
@@ -17,6 +17,7 @@ import ActionIcon from './action-icon';
17
17
  const Action = ({
18
18
  appearance = 'subtle',
19
19
  content,
20
+ isLoading = false,
20
21
  onClick,
21
22
  size = SmartLinkSize.Medium,
22
23
  testId = 'smart-action',
@@ -41,6 +42,7 @@ const Action = ({
41
42
  content: content,
42
43
  iconAfter: iconAfter,
43
44
  iconBefore: iconBefore,
45
+ isLoading: isLoading,
44
46
  onClick: onClick,
45
47
  testId: testId
46
48
  });
@@ -50,6 +52,7 @@ const Action = ({
50
52
  content: content,
51
53
  iconAfter: iconAfter,
52
54
  iconBefore: iconBefore,
55
+ isLoading: isLoading,
53
56
  onClick: onClick,
54
57
  overrideCss: overrideCss,
55
58
  size: size,
@@ -0,0 +1,38 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React, { useCallback, useState } from 'react';
3
+ import useInvoke from '../../../../../../state/hooks/use-invoke';
4
+ import useResolve from '../../../../../../state/hooks/use-resolve';
5
+ import createInvokeRequest from '../../../../../../utils/actions/create-invoke-request';
6
+ import Action from '../index';
7
+ const ServerAction = ({
8
+ action,
9
+ onClick,
10
+ ...props
11
+ }) => {
12
+ const [isLoading, setIsLoading] = useState(false);
13
+ const invoke = useInvoke();
14
+ const reload = useResolve();
15
+ const handleClick = useCallback(async () => {
16
+ if (action) {
17
+ try {
18
+ setIsLoading(true);
19
+ const request = createInvokeRequest(action);
20
+ await invoke(request);
21
+ setIsLoading(false);
22
+ if (action.reload && action.reload.url) {
23
+ await reload(action.reload.url, true, undefined, action.reload.id);
24
+ }
25
+ if (onClick) {
26
+ onClick();
27
+ }
28
+ } catch (err) {
29
+ setIsLoading(false);
30
+ }
31
+ }
32
+ }, [action, invoke, onClick, reload]);
33
+ return /*#__PURE__*/React.createElement(Action, _extends({}, props, {
34
+ isLoading: isLoading,
35
+ onClick: handleClick
36
+ }));
37
+ };
38
+ export default ServerAction;
@@ -75,6 +75,7 @@ export const getSimulatedMetadata = (extensionKey = '', data) => {
75
75
  }
76
76
  };
77
77
  export const getSimulatedBetterMetadata = (extensionKey = '', data) => {
78
+ var _data$Type$includes, _data$Type;
78
79
  const types = data ? extractType(data) : undefined;
79
80
  const defaultMetadata = {
80
81
  topMetadataBlock: {
@@ -124,13 +125,16 @@ export const getSimulatedBetterMetadata = (extensionKey = '', data) => {
124
125
  }
125
126
  };
126
127
  case 'jira-object-provider':
128
+ const isJiraTask = (_data$Type$includes = (_data$Type = data['@type']) === null || _data$Type === void 0 ? void 0 : _data$Type.includes('atlassian:Task')) !== null && _data$Type$includes !== void 0 ? _data$Type$includes : false;
127
129
  return {
128
130
  ...defaultMetadata,
129
- topMetadataBlock: {
130
- primary: [ElementName.AssignedToGroup, ElementName.State, ElementName.StoryPoints, ElementName.Priority],
131
- secondary: [],
132
- subtitle: []
133
- }
131
+ ...(isJiraTask && {
132
+ topMetadataBlock: {
133
+ primary: [ElementName.AssignedToGroup, ElementName.State, ElementName.StoryPoints, ElementName.Priority],
134
+ secondary: [],
135
+ subtitle: []
136
+ }
137
+ })
134
138
  };
135
139
  case 'trello-object-provider':
136
140
  return {
@@ -8,7 +8,7 @@ import LinkWarningModal from './LinkWarningModal';
8
8
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
9
9
  const PACKAGE_DATA = {
10
10
  packageName: "@atlaskit/smart-card",
11
- packageVersion: "26.22.0",
11
+ packageVersion: "26.23.0",
12
12
  componentName: 'linkUrl'
13
13
  };
14
14
  const Link = withLinkClickedEvent('a');
@@ -0,0 +1,12 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ 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; }
3
+ 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; }
4
+ var createInvokeRequest = function createInvokeRequest(request, payload) {
5
+ return {
6
+ action: _objectSpread(_objectSpread({}, request.action), {}, {
7
+ payload: payload
8
+ }),
9
+ providerKey: request.providerKey
10
+ };
11
+ };
12
+ export default createInvokeRequest;
@@ -13,7 +13,7 @@ export var ANALYTICS_CHANNEL = 'media';
13
13
  export var context = {
14
14
  componentName: 'smart-cards',
15
15
  packageName: "@atlaskit/smart-card",
16
- packageVersion: "26.22.0"
16
+ packageVersion: "26.23.0"
17
17
  };
18
18
  export var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
19
19
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -3,6 +3,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
4
  import React from 'react';
5
5
  import Loadable from 'react-loadable';
6
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
6
7
  export var isCardWithData = function isCardWithData(props) {
7
8
  return !!props.data;
8
9
  };
@@ -221,7 +222,15 @@ var typeToIcon = {
221
222
  }]
222
223
  };
223
224
  export var getIframeSandboxAttribute = function getIframeSandboxAttribute(isTrusted) {
224
- return isTrusted ? undefined : 'allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts';
225
+ if (isTrusted) {
226
+ return undefined;
227
+ }
228
+ var sandboxPermissions = 'allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts';
229
+ var allowStorageAccess = 'allow-storage-access-by-user-activation';
230
+ if (getBooleanFF('platform.linking-platform.smart-card.iframes-allow-storage-access-by-user-activation')) {
231
+ return "".concat(sandboxPermissions, " ").concat(allowStorageAccess);
232
+ }
233
+ return sandboxPermissions;
225
234
  };
226
235
  export var handleOnClick = function handleOnClick(handler) {
227
236
  return function (e) {
@@ -4,6 +4,8 @@ var _templateObject, _templateObject2;
4
4
  import React, { useCallback } from 'react';
5
5
  import { css, jsx } from '@emotion/react';
6
6
  import Button from '@atlaskit/button/custom-theme-button';
7
+ import { LoadingButton } from '@atlaskit/button';
8
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
9
  import Tooltip from '@atlaskit/tooltip';
8
10
  import { SmartLinkSize } from '../../../../../../constants';
9
11
  import { sizeToButtonSpacing } from '../../../utils';
@@ -24,6 +26,7 @@ var ActionButton = function ActionButton(_ref) {
24
26
  content = _ref.content,
25
27
  iconAfter = _ref.iconAfter,
26
28
  iconBefore = _ref.iconBefore,
29
+ isLoading = _ref.isLoading,
27
30
  onClick = _ref.onClick,
28
31
  overrideCss = _ref.overrideCss,
29
32
  size = _ref.size,
@@ -43,7 +46,15 @@ var ActionButton = function ActionButton(_ref) {
43
46
  content: tooltipMessage,
44
47
  hideTooltipOnClick: true,
45
48
  testId: "".concat(testId, "-tooltip")
46
- }, jsx(Button, {
49
+ }, getBooleanFF('platform.linking-platform.smart-card.follow-button') ? jsx(LoadingButton, {
50
+ appearance: appearance,
51
+ iconAfter: iconAfter,
52
+ iconBefore: iconBefore,
53
+ isLoading: isLoading,
54
+ onClick: onButtonClick(onClick),
55
+ spacing: sizeToButtonSpacing[size],
56
+ testId: testId
57
+ }, content) : jsx(Button, {
47
58
  appearance: appearance,
48
59
  iconAfter: iconAfter,
49
60
  iconBefore: iconBefore,
@@ -5,11 +5,13 @@ var ActionDropdownItem = function ActionDropdownItem(_ref) {
5
5
  var content = _ref.content,
6
6
  iconAfter = _ref.iconAfter,
7
7
  iconBefore = _ref.iconBefore,
8
+ isLoading = _ref.isLoading,
8
9
  onClick = _ref.onClick,
9
10
  testId = _ref.testId;
10
11
  return /*#__PURE__*/React.createElement(DropdownItem, {
11
12
  elemAfter: iconAfter,
12
13
  elemBefore: iconBefore,
14
+ isDisabled: isLoading,
13
15
  onClick: handleOnClick(onClick),
14
16
  testId: testId
15
17
  }, content);
@@ -18,6 +18,8 @@ var Action = function Action(_ref) {
18
18
  var _ref$appearance = _ref.appearance,
19
19
  appearance = _ref$appearance === void 0 ? 'subtle' : _ref$appearance,
20
20
  content = _ref.content,
21
+ _ref$isLoading = _ref.isLoading,
22
+ isLoading = _ref$isLoading === void 0 ? false : _ref$isLoading,
21
23
  onClick = _ref.onClick,
22
24
  _ref$size = _ref.size,
23
25
  size = _ref$size === void 0 ? SmartLinkSize.Medium : _ref$size,
@@ -44,6 +46,7 @@ var Action = function Action(_ref) {
44
46
  content: content,
45
47
  iconAfter: iconAfter,
46
48
  iconBefore: iconBefore,
49
+ isLoading: isLoading,
47
50
  onClick: onClick,
48
51
  testId: testId
49
52
  });
@@ -53,6 +56,7 @@ var Action = function Action(_ref) {
53
56
  content: content,
54
57
  iconAfter: iconAfter,
55
58
  iconBefore: iconBefore,
59
+ isLoading: isLoading,
56
60
  onClick: onClick,
57
61
  overrideCss: overrideCss,
58
62
  size: size,
@@ -0,0 +1,65 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
5
+ var _excluded = ["action", "onClick"];
6
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
7
+ import React, { useCallback, useState } from 'react';
8
+ import useInvoke from '../../../../../../state/hooks/use-invoke';
9
+ import useResolve from '../../../../../../state/hooks/use-resolve';
10
+ import createInvokeRequest from '../../../../../../utils/actions/create-invoke-request';
11
+ import Action from '../index';
12
+ var ServerAction = function ServerAction(_ref) {
13
+ var action = _ref.action,
14
+ onClick = _ref.onClick,
15
+ props = _objectWithoutProperties(_ref, _excluded);
16
+ var _useState = useState(false),
17
+ _useState2 = _slicedToArray(_useState, 2),
18
+ isLoading = _useState2[0],
19
+ setIsLoading = _useState2[1];
20
+ var invoke = useInvoke();
21
+ var reload = useResolve();
22
+ var handleClick = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
23
+ var request;
24
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
25
+ while (1) switch (_context.prev = _context.next) {
26
+ case 0:
27
+ if (!action) {
28
+ _context.next = 16;
29
+ break;
30
+ }
31
+ _context.prev = 1;
32
+ setIsLoading(true);
33
+ request = createInvokeRequest(action);
34
+ _context.next = 6;
35
+ return invoke(request);
36
+ case 6:
37
+ setIsLoading(false);
38
+ if (!(action.reload && action.reload.url)) {
39
+ _context.next = 10;
40
+ break;
41
+ }
42
+ _context.next = 10;
43
+ return reload(action.reload.url, true, undefined, action.reload.id);
44
+ case 10:
45
+ if (onClick) {
46
+ onClick();
47
+ }
48
+ _context.next = 16;
49
+ break;
50
+ case 13:
51
+ _context.prev = 13;
52
+ _context.t0 = _context["catch"](1);
53
+ setIsLoading(false);
54
+ case 16:
55
+ case "end":
56
+ return _context.stop();
57
+ }
58
+ }, _callee, null, [[1, 13]]);
59
+ })), [action, invoke, onClick, reload]);
60
+ return /*#__PURE__*/React.createElement(Action, _extends({}, props, {
61
+ isLoading: isLoading,
62
+ onClick: handleClick
63
+ }));
64
+ };
65
+ export default ServerAction;
@@ -80,6 +80,7 @@ export var getSimulatedMetadata = function getSimulatedMetadata() {
80
80
  }
81
81
  };
82
82
  export var getSimulatedBetterMetadata = function getSimulatedBetterMetadata() {
83
+ var _data$Type$includes, _data$Type;
83
84
  var extensionKey = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
84
85
  var data = arguments.length > 1 ? arguments[1] : undefined;
85
86
  var types = data ? extractType(data) : undefined;
@@ -129,7 +130,8 @@ export var getSimulatedBetterMetadata = function getSimulatedBetterMetadata() {
129
130
  }
130
131
  };
131
132
  case 'jira-object-provider':
132
- return _objectSpread(_objectSpread({}, defaultMetadata), {}, {
133
+ var isJiraTask = (_data$Type$includes = (_data$Type = data['@type']) === null || _data$Type === void 0 ? void 0 : _data$Type.includes('atlassian:Task')) !== null && _data$Type$includes !== void 0 ? _data$Type$includes : false;
134
+ return _objectSpread(_objectSpread({}, defaultMetadata), isJiraTask && {
133
135
  topMetadataBlock: {
134
136
  primary: [ElementName.AssignedToGroup, ElementName.State, ElementName.StoryPoints, ElementName.Priority],
135
137
  secondary: [],
@@ -11,7 +11,7 @@ import LinkWarningModal from './LinkWarningModal';
11
11
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
12
12
  var PACKAGE_DATA = {
13
13
  packageName: "@atlaskit/smart-card",
14
- packageVersion: "26.22.0",
14
+ packageVersion: "26.23.0",
15
15
  componentName: 'linkUrl'
16
16
  };
17
17
  var Link = withLinkClickedEvent('a');
@@ -17,11 +17,25 @@ export type CardDetails = {
17
17
  */
18
18
  previewData?: PreviewActionData | null;
19
19
  };
20
+ /**
21
+ * Additional details to reload smart links
22
+ */
23
+ export type InvokeReloadDetails = {
24
+ /**
25
+ * An identifier for Smart Link analytics
26
+ */
27
+ id?: string;
28
+ /**
29
+ * The URL of the Smart Link
30
+ */
31
+ url?: string;
32
+ };
20
33
  /**
21
34
  * Invoke request with additional details for the component
22
35
  */
23
36
  export type InvokeRequestWithCardDetails = InvokeRequest & {
24
37
  details?: CardDetails;
38
+ reload?: InvokeReloadDetails;
25
39
  };
26
40
  /**
27
41
  * CRUD invoke requests for the component that support server actions
@@ -0,0 +1,3 @@
1
+ import type { InvokeRequest } from '@atlaskit/linking-types/smart-link-actions';
2
+ declare const createInvokeRequest: <TPayload extends object>(request: InvokeRequest, payload?: TPayload | undefined) => InvokeRequest<TPayload>;
3
+ export default createInvokeRequest;
@@ -16,7 +16,7 @@ export declare const isSpecialKey: (event: React.MouseEvent | React.KeyboardEven
16
16
  export declare const isSpecialClick: (event: React.MouseEvent) => boolean;
17
17
  export declare const getIconForFileType: (fileMimeType: string) => React.ReactNode | undefined;
18
18
  export declare const getLabelForFileType: (fileMimeType: string) => React.ReactNode | undefined;
19
- export declare const getIframeSandboxAttribute: (isTrusted: boolean) => "allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts" | undefined;
19
+ export declare const getIframeSandboxAttribute: (isTrusted: boolean) => string | undefined;
20
20
  export declare const handleOnClick: (handler: Function) => (e: React.BaseSyntheticEvent) => void;
21
21
  export declare const isIntersectionObserverSupported: () => boolean;
22
22
  export declare const sleep: (ms: number) => Promise<void>;
@@ -4,5 +4,6 @@ import { ActionProps } from '../types';
4
4
  export type ActionButtonProps = ActionProps & {
5
5
  iconAfter?: React.ReactChild;
6
6
  iconBefore?: React.ReactChild;
7
+ isLoading?: boolean;
7
8
  size: SmartLinkSize;
8
9
  };
@@ -3,6 +3,7 @@ export type ActionDropdownItemProps = {
3
3
  content?: React.ReactNode;
4
4
  iconAfter?: React.ReactNode;
5
5
  iconBefore?: React.ReactNode;
6
+ isLoading?: boolean;
6
7
  onClick: () => any;
7
8
  testId?: string;
8
9
  };
@@ -1,6 +1,6 @@
1
1
  /** @jsx jsx */
2
2
  import React from 'react';
3
- import { ActionProps } from './types';
3
+ import { ActionProps, InternalActionProps } from './types';
4
4
  /**
5
5
  * A base action that can be triggered with an on click.
6
6
  * @internal
@@ -9,5 +9,5 @@ import { ActionProps } from './types';
9
9
  * @see EditAction
10
10
  * @see CustomAction
11
11
  */
12
- declare const Action: React.FC<ActionProps>;
12
+ declare const Action: React.FC<ActionProps & InternalActionProps>;
13
13
  export default Action;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ServerActionProps } from './types';
3
+ declare const ServerAction: React.FC<ServerActionProps>;
4
+ export default ServerAction;
@@ -0,0 +1,6 @@
1
+ import { ActionProps } from '../types';
2
+ import { InvokeRequestWithCardDetails } from '../../../../../../state/hooks/use-invoke/types';
3
+ export type ServerActionProps = Omit<ActionProps, 'onClick'> & {
4
+ action?: InvokeRequestWithCardDetails;
5
+ onClick?: ActionProps['onClick'];
6
+ };
@@ -46,3 +46,15 @@ export type ActionProps = {
46
46
  */
47
47
  testId?: string;
48
48
  };
49
+ /**
50
+ * The internal props that should only be controlled by internal components
51
+ * and/or used by experiment. If there is a use case where these props/feature
52
+ * should be available as part of smart-card, please move them to ActionProps.
53
+ */
54
+ export type InternalActionProps = {
55
+ /**
56
+ * Conditionally show a spinner over the top of a button or disable a dropdown item
57
+ * while server action is executing.
58
+ */
59
+ isLoading?: boolean;
60
+ };
@@ -17,11 +17,25 @@ export type CardDetails = {
17
17
  */
18
18
  previewData?: PreviewActionData | null;
19
19
  };
20
+ /**
21
+ * Additional details to reload smart links
22
+ */
23
+ export type InvokeReloadDetails = {
24
+ /**
25
+ * An identifier for Smart Link analytics
26
+ */
27
+ id?: string;
28
+ /**
29
+ * The URL of the Smart Link
30
+ */
31
+ url?: string;
32
+ };
20
33
  /**
21
34
  * Invoke request with additional details for the component
22
35
  */
23
36
  export type InvokeRequestWithCardDetails = InvokeRequest & {
24
37
  details?: CardDetails;
38
+ reload?: InvokeReloadDetails;
25
39
  };
26
40
  /**
27
41
  * CRUD invoke requests for the component that support server actions
@@ -0,0 +1,3 @@
1
+ import type { InvokeRequest } from '@atlaskit/linking-types/smart-link-actions';
2
+ declare const createInvokeRequest: <TPayload extends object>(request: InvokeRequest, payload?: TPayload | undefined) => InvokeRequest<TPayload>;
3
+ export default createInvokeRequest;
@@ -16,7 +16,7 @@ export declare const isSpecialKey: (event: React.MouseEvent | React.KeyboardEven
16
16
  export declare const isSpecialClick: (event: React.MouseEvent) => boolean;
17
17
  export declare const getIconForFileType: (fileMimeType: string) => React.ReactNode | undefined;
18
18
  export declare const getLabelForFileType: (fileMimeType: string) => React.ReactNode | undefined;
19
- export declare const getIframeSandboxAttribute: (isTrusted: boolean) => "allow-downloads allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts" | undefined;
19
+ export declare const getIframeSandboxAttribute: (isTrusted: boolean) => string | undefined;
20
20
  export declare const handleOnClick: (handler: Function) => (e: React.BaseSyntheticEvent) => void;
21
21
  export declare const isIntersectionObserverSupported: () => boolean;
22
22
  export declare const sleep: (ms: number) => Promise<void>;
@@ -4,5 +4,6 @@ import { ActionProps } from '../types';
4
4
  export type ActionButtonProps = ActionProps & {
5
5
  iconAfter?: React.ReactChild;
6
6
  iconBefore?: React.ReactChild;
7
+ isLoading?: boolean;
7
8
  size: SmartLinkSize;
8
9
  };
@@ -3,6 +3,7 @@ export type ActionDropdownItemProps = {
3
3
  content?: React.ReactNode;
4
4
  iconAfter?: React.ReactNode;
5
5
  iconBefore?: React.ReactNode;
6
+ isLoading?: boolean;
6
7
  onClick: () => any;
7
8
  testId?: string;
8
9
  };
@@ -1,6 +1,6 @@
1
1
  /** @jsx jsx */
2
2
  import React from 'react';
3
- import { ActionProps } from './types';
3
+ import { ActionProps, InternalActionProps } from './types';
4
4
  /**
5
5
  * A base action that can be triggered with an on click.
6
6
  * @internal
@@ -9,5 +9,5 @@ import { ActionProps } from './types';
9
9
  * @see EditAction
10
10
  * @see CustomAction
11
11
  */
12
- declare const Action: React.FC<ActionProps>;
12
+ declare const Action: React.FC<ActionProps & InternalActionProps>;
13
13
  export default Action;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ServerActionProps } from './types';
3
+ declare const ServerAction: React.FC<ServerActionProps>;
4
+ export default ServerAction;
@@ -0,0 +1,6 @@
1
+ import { ActionProps } from '../types';
2
+ import { InvokeRequestWithCardDetails } from '../../../../../../state/hooks/use-invoke/types';
3
+ export type ServerActionProps = Omit<ActionProps, 'onClick'> & {
4
+ action?: InvokeRequestWithCardDetails;
5
+ onClick?: ActionProps['onClick'];
6
+ };
@@ -46,3 +46,15 @@ export type ActionProps = {
46
46
  */
47
47
  testId?: string;
48
48
  };
49
+ /**
50
+ * The internal props that should only be controlled by internal components
51
+ * and/or used by experiment. If there is a use case where these props/feature
52
+ * should be available as part of smart-card, please move them to ActionProps.
53
+ */
54
+ export type InternalActionProps = {
55
+ /**
56
+ * Conditionally show a spinner over the top of a button or disable a dropdown item
57
+ * while server action is executing.
58
+ */
59
+ isLoading?: boolean;
60
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "26.22.0",
3
+ "version": "26.23.0",
4
4
  "description": "Smart card component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -137,6 +137,9 @@
137
137
  "platform.linking-platform.smart-card.enable-block-card-clicks-opening-in-same-tab": {
138
138
  "type": "boolean"
139
139
  },
140
+ "platform.linking-platform.smart-card.follow-button": {
141
+ "type": "boolean"
142
+ },
140
143
  "platform.linking-platform.smart-card.should-call-onclick-in-warning-modal-only-when-safe": {
141
144
  "type": "boolean"
142
145
  },
@@ -148,6 +151,9 @@
148
151
  },
149
152
  "platform.linking-platform.smart-card.fix-is-trusted-pop": {
150
153
  "type": "boolean"
154
+ },
155
+ "platform.linking-platform.smart-card.iframes-allow-storage-access-by-user-activation": {
156
+ "type": "boolean"
151
157
  }
152
158
  },
153
159
  "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.1"