@atlaskit/smart-card 23.10.0 → 23.10.2

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 (47) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/messages.js +1 -1
  3. package/dist/cjs/state/analytics/useSmartLinkAnalytics.js +47 -17
  4. package/dist/cjs/utils/analytics/analytics.js +30 -2
  5. package/dist/cjs/utils/analytics/index.js +6 -0
  6. package/dist/cjs/utils/index.js +65 -2
  7. package/dist/cjs/version.json +1 -1
  8. package/dist/cjs/view/CardWithUrl/loader.js +19 -8
  9. package/dist/cjs/view/InlineCard/ForbiddenView/index.js +40 -18
  10. package/dist/cjs/view/InlineCard/IconAndTitleLayout/index.js +5 -2
  11. package/dist/cjs/view/InlineCard/IconAndTitleLayout/styled.js +1 -1
  12. package/dist/cjs/view/InlineCard/ResolvedView/index.js +2 -2
  13. package/dist/es2019/messages.js +1 -1
  14. package/dist/es2019/state/analytics/useSmartLinkAnalytics.js +32 -1
  15. package/dist/es2019/utils/analytics/analytics.js +24 -0
  16. package/dist/es2019/utils/analytics/index.js +1 -1
  17. package/dist/es2019/utils/index.js +16 -1
  18. package/dist/es2019/version.json +1 -1
  19. package/dist/es2019/view/CardWithUrl/loader.js +16 -8
  20. package/dist/es2019/view/InlineCard/ForbiddenView/index.js +40 -19
  21. package/dist/es2019/view/InlineCard/IconAndTitleLayout/index.js +6 -2
  22. package/dist/es2019/view/InlineCard/IconAndTitleLayout/styled.js +0 -3
  23. package/dist/es2019/view/InlineCard/ResolvedView/index.js +3 -3
  24. package/dist/esm/messages.js +1 -1
  25. package/dist/esm/state/analytics/useSmartLinkAnalytics.js +48 -18
  26. package/dist/esm/utils/analytics/analytics.js +25 -0
  27. package/dist/esm/utils/analytics/index.js +1 -1
  28. package/dist/esm/utils/index.js +56 -1
  29. package/dist/esm/version.json +1 -1
  30. package/dist/esm/view/CardWithUrl/loader.js +19 -9
  31. package/dist/esm/view/InlineCard/ForbiddenView/index.js +40 -19
  32. package/dist/esm/view/InlineCard/IconAndTitleLayout/index.js +6 -2
  33. package/dist/esm/view/InlineCard/IconAndTitleLayout/styled.js +1 -1
  34. package/dist/esm/view/InlineCard/ResolvedView/index.js +3 -3
  35. package/dist/types/state/analytics/useSmartLinkAnalytics.d.ts +8 -0
  36. package/dist/types/state/flexible-ui-context/index.d.ts +2 -0
  37. package/dist/types/state/hooks/useSmartLink.d.ts +1 -0
  38. package/dist/types/utils/analytics/analytics.d.ts +1 -0
  39. package/dist/types/utils/analytics/index.d.ts +1 -1
  40. package/dist/types/utils/index.d.ts +2 -0
  41. package/dist/types/utils/mocks.d.ts +1 -0
  42. package/dist/types/utils/types.d.ts +1 -1
  43. package/dist/types/view/InlineCard/ForbiddenView/index.d.ts +3 -0
  44. package/dist/types/view/InlineCard/IconAndTitleLayout/index.d.ts +4 -0
  45. package/package.json +1 -1
  46. package/report.api.md +12 -0
  47. package/tmp/api-report-tmp.d.ts +2 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/smart-card
2
2
 
3
+ ## 23.10.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`cb819660949`](https://bitbucket.org/atlassian/atlassian-frontend/commits/cb819660949) - [ux] Add a lonzenge to restricted links.
8
+
9
+ ## 23.10.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [`d88eda329c1`](https://bitbucket.org/atlassian/atlassian-frontend/commits/d88eda329c1) - seperate chunk load errors into it's own analytics event and do retries when lazy loading smartcard-urlcardcontent fails
14
+
3
15
  ## 23.10.0
4
16
 
5
17
  ### Minor Changes
@@ -135,7 +135,7 @@ var messages = (0, _reactIntlNext.defineMessages)({
135
135
  },
136
136
  invalid_permissions: {
137
137
  id: 'fabric.linking.invalid_permissions',
138
- defaultMessage: 'Restricted link',
138
+ defaultMessage: 'Restricted content',
139
139
  description: 'Message shown when a user does not have permissions to view an item'
140
140
  },
141
141
  invalid_permissions_description: {
@@ -616,6 +616,36 @@ var useSmartLinkAnalytics = function useSmartLinkAnalytics(url, dispatchAnalytic
616
616
  if (event) {
617
617
  dispatchAnalytics(applyCommonAttributes(event, commonAttributes));
618
618
  }
619
+ },
620
+
621
+ /**
622
+ * This fires an event that represents when a Smart Link renders unsuccessfuly.
623
+ * @param display Whether the card was an Inline, Block, Embed or Flexible UI.
624
+ * @param id The unique ID for this Smart Link.
625
+ * @param error: An error representing why the Smart Link render failed.
626
+ * @param errorInfo: Additional details about the error including the stack trace.
627
+ */
628
+ chunkloadFailedEvent: function chunkloadFailedEvent(_ref16) {
629
+ var display = _ref16.display,
630
+ error = _ref16.error,
631
+ errorInfo = _ref16.errorInfo,
632
+ extensionKey = _ref16.extensionKey,
633
+ definitionId = _ref16.definitionId,
634
+ resourceType = _ref16.resourceType,
635
+ destinationProduct = _ref16.destinationProduct,
636
+ destinationSubproduct = _ref16.destinationSubproduct,
637
+ location = _ref16.location;
638
+ dispatchAnalytics(applyCommonAttributes((0, _analytics.chunkloadFailedEvent)({
639
+ display: display,
640
+ error: error,
641
+ errorInfo: errorInfo,
642
+ extensionKey: extensionKey,
643
+ definitionId: definitionId,
644
+ resourceType: resourceType,
645
+ destinationProduct: destinationProduct,
646
+ destinationSubproduct: destinationSubproduct,
647
+ location: location
648
+ }), commonAttributes));
619
649
  }
620
650
  };
621
651
  }, [defaultId, commonAttributes, dispatchAnalytics]);
@@ -629,13 +659,13 @@ var useSmartLinkAnalytics = function useSmartLinkAnalytics(url, dispatchAnalytic
629
659
  * @param extensionKey The extensionKey of the Smart Link resovler invoked.
630
660
  * @returns
631
661
  */
632
- appAccountConnected: function appAccountConnected(_ref16) {
633
- var extensionKey = _ref16.extensionKey,
634
- definitionId = _ref16.definitionId,
635
- resourceType = _ref16.resourceType,
636
- destinationProduct = _ref16.destinationProduct,
637
- destinationSubproduct = _ref16.destinationSubproduct,
638
- location = _ref16.location;
662
+ appAccountConnected: function appAccountConnected(_ref17) {
663
+ var extensionKey = _ref17.extensionKey,
664
+ definitionId = _ref17.definitionId,
665
+ resourceType = _ref17.resourceType,
666
+ destinationProduct = _ref17.destinationProduct,
667
+ destinationSubproduct = _ref17.destinationSubproduct,
668
+ location = _ref17.location;
639
669
  return dispatchAnalytics(applyCommonAttributes((0, _analytics.trackAppAccountConnected)(_objectSpread(_objectSpread({}, commonAttributes), {}, {
640
670
  extensionKey: extensionKey,
641
671
  definitionId: definitionId,
@@ -652,9 +682,9 @@ var useSmartLinkAnalytics = function useSmartLinkAnalytics(url, dispatchAnalytic
652
682
  * @param extensionKey The extensionKey of the Smart Link resolver invoked.
653
683
  * @returns
654
684
  */
655
- appAccountAuthStarted: function appAccountAuthStarted(_ref17) {
656
- var extensionKey = _ref17.extensionKey,
657
- location = _ref17.location;
685
+ appAccountAuthStarted: function appAccountAuthStarted(_ref18) {
686
+ var extensionKey = _ref18.extensionKey,
687
+ location = _ref18.location;
658
688
  return dispatchAnalytics(applyCommonAttributes((0, _analytics.trackAppAccountAuthStarted)(_objectSpread(_objectSpread({}, commonAttributes), {}, {
659
689
  extensionKey: extensionKey,
660
690
  location: location
@@ -672,13 +702,13 @@ var useSmartLinkAnalytics = function useSmartLinkAnalytics(url, dispatchAnalytic
672
702
  * @param extensionKey The extensionKey of the Smart Link resovler invoked.
673
703
  * @returns
674
704
  */
675
- authPopupEvent: function authPopupEvent(_ref18) {
676
- var extensionKey = _ref18.extensionKey,
677
- definitionId = _ref18.definitionId,
678
- resourceType = _ref18.resourceType,
679
- destinationProduct = _ref18.destinationProduct,
680
- destinationSubproduct = _ref18.destinationSubproduct,
681
- location = _ref18.location;
705
+ authPopupEvent: function authPopupEvent(_ref19) {
706
+ var extensionKey = _ref19.extensionKey,
707
+ definitionId = _ref19.definitionId,
708
+ resourceType = _ref19.resourceType,
709
+ destinationProduct = _ref19.destinationProduct,
710
+ destinationSubproduct = _ref19.destinationSubproduct,
711
+ location = _ref19.location;
682
712
  return dispatchAnalytics(applyCommonAttributes((0, _analytics.screenAuthPopupEvent)(_objectSpread(_objectSpread({}, commonAttributes), {}, {
683
713
  extensionKey: extensionKey,
684
714
  definitionId: definitionId,
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.unresolvedEvent = exports.uiRenderSuccessEvent = exports.uiRenderFailedEvent = exports.uiLearnMoreLinkClickedEvent = exports.uiHoverCardViewedEvent = exports.uiHoverCardOpenLinkClickedEvent = exports.uiHoverCardDismissedEvent = exports.uiClosedAuthEvent = exports.uiCardClickedEvent = exports.uiAuthEvent = exports.uiAuthAlternateAccountEvent = exports.uiActionClickedEvent = exports.trackAppAccountConnected = exports.trackAppAccountAuthStarted = exports.screenAuthPopupEvent = exports.resolvedEvent = exports.invokeSucceededEvent = exports.invokeFailedEvent = exports.fireSmartLinkEvent = exports.context = exports.connectSucceededEvent = exports.connectFailedEvent = exports.SmartLinkEvents = exports.ANALYTICS_CHANNEL = void 0;
8
+ exports.unresolvedEvent = exports.uiRenderSuccessEvent = exports.uiRenderFailedEvent = exports.uiLearnMoreLinkClickedEvent = exports.uiHoverCardViewedEvent = exports.uiHoverCardOpenLinkClickedEvent = exports.uiHoverCardDismissedEvent = exports.uiClosedAuthEvent = exports.uiCardClickedEvent = exports.uiAuthEvent = exports.uiAuthAlternateAccountEvent = exports.uiActionClickedEvent = exports.trackAppAccountConnected = exports.trackAppAccountAuthStarted = exports.screenAuthPopupEvent = exports.resolvedEvent = exports.invokeSucceededEvent = exports.invokeFailedEvent = exports.fireSmartLinkEvent = exports.context = exports.connectSucceededEvent = exports.connectFailedEvent = exports.chunkloadFailedEvent = exports.SmartLinkEvents = exports.ANALYTICS_CHANNEL = void 0;
9
9
 
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
 
@@ -584,4 +584,32 @@ var uiLearnMoreLinkClickedEvent = function uiLearnMoreLinkClickedEvent() {
584
584
  };
585
585
  };
586
586
 
587
- exports.uiLearnMoreLinkClickedEvent = uiLearnMoreLinkClickedEvent;
587
+ exports.uiLearnMoreLinkClickedEvent = uiLearnMoreLinkClickedEvent;
588
+
589
+ var chunkloadFailedEvent = function chunkloadFailedEvent(_ref19) {
590
+ var display = _ref19.display,
591
+ error = _ref19.error,
592
+ errorInfo = _ref19.errorInfo,
593
+ extensionKey = _ref19.extensionKey,
594
+ definitionId = _ref19.definitionId,
595
+ destinationProduct = _ref19.destinationProduct,
596
+ destinationSubproduct = _ref19.destinationSubproduct,
597
+ location = _ref19.location;
598
+ return {
599
+ action: 'chunkLoadFailed',
600
+ actionSubject: 'smartLink',
601
+ eventType: 'operational',
602
+ attributes: _objectSpread(_objectSpread({}, context), {}, {
603
+ error: error,
604
+ errorInfo: errorInfo,
605
+ display: display,
606
+ extensionKey: extensionKey,
607
+ definitionId: definitionId,
608
+ destinationProduct: destinationProduct,
609
+ destinationSubproduct: destinationSubproduct,
610
+ location: location
611
+ })
612
+ };
613
+ };
614
+
615
+ exports.chunkloadFailedEvent = chunkloadFailedEvent;
@@ -11,6 +11,12 @@ Object.defineProperty(exports, "ANALYTICS_CHANNEL", {
11
11
  return _analytics.ANALYTICS_CHANNEL;
12
12
  }
13
13
  });
14
+ Object.defineProperty(exports, "chunkloadFailedEvent", {
15
+ enumerable: true,
16
+ get: function get() {
17
+ return _analytics.chunkloadFailedEvent;
18
+ }
19
+ });
14
20
  Object.defineProperty(exports, "connectFailedEvent", {
15
21
  enumerable: true,
16
22
  get: function get() {
@@ -7,7 +7,11 @@ var _typeof = require("@babel/runtime/helpers/typeof");
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
- exports.isSpecialKey = exports.isSpecialEvent = exports.isSpecialClick = exports.isIntersectionObserverSupported = exports.isIframe = exports.isCardWithData = exports.handleOnClick = exports.getLabelForFileType = exports.getIframeSandboxAttribute = exports.getIconForFileType = void 0;
10
+ exports.sleep = exports.isSpecialKey = exports.isSpecialEvent = exports.isSpecialClick = exports.isIntersectionObserverSupported = exports.isIframe = exports.isCardWithData = exports.importWithRetry = exports.handleOnClick = exports.getLabelForFileType = exports.getIframeSandboxAttribute = exports.getIconForFileType = void 0;
11
+
12
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
13
+
14
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
15
 
12
16
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
17
 
@@ -374,4 +378,63 @@ var isIntersectionObserverSupported = function isIntersectionObserverSupported()
374
378
  return typeof IntersectionObserver !== 'undefined';
375
379
  };
376
380
 
377
- exports.isIntersectionObserverSupported = isIntersectionObserverSupported;
381
+ exports.isIntersectionObserverSupported = isIntersectionObserverSupported;
382
+
383
+ var sleep = function sleep(ms) {
384
+ return new Promise(function (resolve) {
385
+ return setTimeout(resolve, ms);
386
+ });
387
+ };
388
+
389
+ exports.sleep = sleep;
390
+
391
+ var importWithRetry = /*#__PURE__*/function () {
392
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(importFn) {
393
+ var retries,
394
+ interval,
395
+ _args = arguments;
396
+ return _regenerator.default.wrap(function _callee$(_context) {
397
+ while (1) {
398
+ switch (_context.prev = _context.next) {
399
+ case 0:
400
+ retries = _args.length > 1 && _args[1] !== undefined ? _args[1] : 2;
401
+ interval = _args.length > 2 && _args[2] !== undefined ? _args[2] : 500;
402
+ _context.prev = 2;
403
+ _context.next = 5;
404
+ return importFn();
405
+
406
+ case 5:
407
+ return _context.abrupt("return", _context.sent);
408
+
409
+ case 8:
410
+ _context.prev = 8;
411
+ _context.t0 = _context["catch"](2);
412
+
413
+ if (!(_context.t0.name === 'ChunkLoadError' && retries > 0)) {
414
+ _context.next = 16;
415
+ break;
416
+ }
417
+
418
+ _context.next = 13;
419
+ return sleep(interval);
420
+
421
+ case 13:
422
+ return _context.abrupt("return", importWithRetry(importFn, retries - 1, interval));
423
+
424
+ case 16:
425
+ throw _context.t0;
426
+
427
+ case 17:
428
+ case "end":
429
+ return _context.stop();
430
+ }
431
+ }
432
+ }, _callee, null, [[2, 8]]);
433
+ }));
434
+
435
+ return function importWithRetry(_x) {
436
+ return _ref.apply(this, arguments);
437
+ };
438
+ }();
439
+
440
+ exports.importWithRetry = importWithRetry;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "23.10.0",
3
+ "version": "23.10.2",
4
4
  "sideEffects": false
5
5
  }
@@ -25,13 +25,17 @@ var _analytics2 = require("../../state/analytics");
25
25
 
26
26
  var _LazyFallback = require("./component-lazy/LazyFallback");
27
27
 
28
+ var _utils = require("../../utils");
29
+
28
30
  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); }
29
31
 
30
32
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || (0, _typeof2.default)(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; }
31
33
 
32
34
  var LazyCardWithUrlContent = /*#__PURE__*/(0, _react.lazy)(function () {
33
- return Promise.resolve().then(function () {
34
- return _interopRequireWildcard(require('./component-lazy/index'));
35
+ return (0, _utils.importWithRetry)(function () {
36
+ return Promise.resolve().then(function () {
37
+ return _interopRequireWildcard(require('./component-lazy/index'));
38
+ });
35
39
  });
36
40
  });
37
41
 
@@ -83,15 +87,22 @@ function CardWithURLRenderer(props) {
83
87
  }, [appearance, createAnalyticsEvent]);
84
88
  var analytics = (0, _analytics2.useSmartLinkAnalytics)(url !== null && url !== void 0 ? url : '', dispatchAnalytics, id);
85
89
  var logError = (0, _react.useCallback)(function (error, info) {
86
- var componentStack = info.componentStack; // NB: APIErrors are thrown in response to Object Resolver Service. We do not
90
+ var componentStack = info.componentStack;
91
+ var errorInfo = {
92
+ componentStack: componentStack
93
+ }; // NB: APIErrors are thrown in response to Object Resolver Service. We do not
87
94
  // fire an event for these, as they do not cover failed UI render events.
88
95
  // The rest of the errors caught here are unexpected, and correlate
89
96
  // to the reliability of the smart-card front-end components.
97
+ // Likewise, chunk loading errors are not caused by a failure of smart-card rendering.
90
98
 
91
- if (error.name !== 'APIError') {
92
- var errorInfo = {
93
- componentStack: componentStack
94
- };
99
+ if (error.name === 'ChunkLoadError') {
100
+ analytics.operational.chunkloadFailedEvent({
101
+ display: appearance,
102
+ error: error,
103
+ errorInfo: errorInfo
104
+ });
105
+ } else if (error.name !== 'APIError') {
95
106
  analytics.ui.renderFailedEvent({
96
107
  display: appearance,
97
108
  id: id,
@@ -103,7 +114,7 @@ function CardWithURLRenderer(props) {
103
114
 
104
115
 
105
116
  throw error;
106
- }, [analytics.ui, appearance, id]);
117
+ }, [analytics.operational, analytics.ui, appearance, id]);
107
118
 
108
119
  if (!url) {
109
120
  throw new Error('@atlaskit/smart-card: url property is missing.');
@@ -45,6 +45,10 @@ var _reactIntlNext = require("react-intl-next");
45
45
 
46
46
  var _styled = require("../styled");
47
47
 
48
+ var _lozenge = _interopRequireDefault(require("@atlaskit/lozenge"));
49
+
50
+ var _styled2 = require("../IconAndTitleLayout/styled");
51
+
48
52
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
49
53
 
50
54
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -61,6 +65,8 @@ var InlineCardForbiddenView = /*#__PURE__*/function (_React$Component) {
61
65
  var _super = _createSuper(InlineCardForbiddenView);
62
66
 
63
67
  function InlineCardForbiddenView() {
68
+ var _this$props, _this$props$requestAc;
69
+
64
70
  var _this;
65
71
 
66
72
  (0, _classCallCheck2.default)(this, InlineCardForbiddenView);
@@ -70,6 +76,9 @@ var InlineCardForbiddenView = /*#__PURE__*/function (_React$Component) {
70
76
  }
71
77
 
72
78
  _this = _super.call.apply(_super, [this].concat(args));
79
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", {
80
+ hasRequestAccessContextMessage: !!((_this$props = _this.props) !== null && _this$props !== void 0 && (_this$props$requestAc = _this$props.requestAccessContext) !== null && _this$props$requestAc !== void 0 && _this$props$requestAc.callToActionMessageKey)
81
+ });
73
82
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleRetry", function (event) {
74
83
  var onAuthorise = _this.props.onAuthorise;
75
84
  event.preventDefault();
@@ -78,15 +87,15 @@ var InlineCardForbiddenView = /*#__PURE__*/function (_React$Component) {
78
87
  if (onAuthorise) {
79
88
  onAuthorise();
80
89
  } else {
81
- var _this$props, _this$props$requestAc, _this$props$requestAc2;
90
+ var _this$props2, _this$props2$requestA, _this$props2$requestA2;
82
91
 
83
- (_this$props = _this.props) === null || _this$props === void 0 ? void 0 : (_this$props$requestAc = _this$props.requestAccessContext) === null || _this$props$requestAc === void 0 ? void 0 : (_this$props$requestAc2 = _this$props$requestAc.action) === null || _this$props$requestAc2 === void 0 ? void 0 : _this$props$requestAc2.promise();
92
+ (_this$props2 = _this.props) === null || _this$props2 === void 0 ? void 0 : (_this$props2$requestA = _this$props2.requestAccessContext) === null || _this$props2$requestA === void 0 ? void 0 : (_this$props2$requestA2 = _this$props2$requestA.action) === null || _this$props2$requestA2 === void 0 ? void 0 : _this$props2$requestA2.promise();
84
93
  }
85
94
  });
86
95
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderForbiddenAccessMessage", function () {
87
- var _this$props2, _this$props2$requestA;
96
+ var _this$props3, _this$props3$requestA;
88
97
 
89
- if ((_this$props2 = _this.props) !== null && _this$props2 !== void 0 && (_this$props2$requestA = _this$props2.requestAccessContext) !== null && _this$props2$requestA !== void 0 && _this$props2$requestA.callToActionMessageKey) {
98
+ if ((_this$props3 = _this.props) !== null && _this$props3 !== void 0 && (_this$props3$requestA = _this$props3.requestAccessContext) !== null && _this$props3$requestA !== void 0 && _this$props3$requestA.callToActionMessageKey) {
90
99
  var callToActionMessageKey = _this.props.requestAccessContext.callToActionMessageKey;
91
100
  return /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _messages.messages[callToActionMessageKey], {
92
101
  values: {
@@ -96,23 +105,35 @@ var InlineCardForbiddenView = /*#__PURE__*/function (_React$Component) {
96
105
  }
97
106
 
98
107
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.messages.invalid_permissions, function (formattedMessage) {
99
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, formattedMessage, ", ");
100
- }), /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.messages.try_another_account, function (formattedMessage) {
101
- return /*#__PURE__*/_react.default.createElement(_styled.LowercaseAppearance, null, formattedMessage);
108
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, formattedMessage);
102
109
  }));
103
110
  });
104
111
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderRightSide", function () {
105
- var _this$props3, _this$props3$requestA;
106
-
107
112
  var onAuthorise = _this.props.onAuthorise;
108
- var hasRequestAccessContextMessage = (_this$props3 = _this.props) === null || _this$props3 === void 0 ? void 0 : (_this$props3$requestA = _this$props3.requestAccessContext) === null || _this$props3$requestA === void 0 ? void 0 : _this$props3$requestA.callToActionMessageKey;
109
- return onAuthorise || hasRequestAccessContextMessage ? /*#__PURE__*/_react.default.createElement(_customThemeButton.default, {
110
- spacing: "none",
111
- appearance: "subtle-link",
112
- onClick: _this.handleRetry,
113
- component: _styled.IconStyledButton,
114
- testId: "button-connect-other-account"
115
- }, _this.renderForbiddenAccessMessage()) : null;
113
+
114
+ if (_this.state.hasRequestAccessContextMessage) {
115
+ return /*#__PURE__*/_react.default.createElement(_customThemeButton.default, {
116
+ spacing: "none",
117
+ appearance: "subtle-link",
118
+ onClick: _this.handleRetry,
119
+ component: _styled.IconStyledButton,
120
+ testId: "button-connect-other-account"
121
+ }, _this.renderForbiddenAccessMessage());
122
+ }
123
+
124
+ if (onAuthorise) {
125
+ return /*#__PURE__*/_react.default.createElement(_styled2.LozengeBlockWrapper, null, /*#__PURE__*/_react.default.createElement(_customThemeButton.default, {
126
+ spacing: "none",
127
+ appearance: "subtle-link",
128
+ onClick: _this.handleRetry,
129
+ component: _styled.IconStyledButton,
130
+ testId: "button-connect-other-account"
131
+ }, /*#__PURE__*/_react.default.createElement(_styled2.LozengeWrapper, null, /*#__PURE__*/_react.default.createElement(_lozenge.default, {
132
+ appearance: 'moved'
133
+ }, _this.renderForbiddenAccessMessage()))));
134
+ }
135
+
136
+ return null;
116
137
  });
117
138
  return _this;
118
139
  }
@@ -135,8 +156,9 @@ var InlineCardForbiddenView = /*#__PURE__*/function (_React$Component) {
135
156
  link: url,
136
157
  title: url,
137
158
  onClick: onClick,
159
+ titleColor: (0, _tokens.token)('color.text.subtle', _colors.N500),
138
160
  rightSide: this.renderRightSide(),
139
- titleColor: (0, _tokens.token)('color.text.subtle', _colors.N500)
161
+ rightSideSpacer: this.state.hasRequestAccessContextMessage
140
162
  }));
141
163
  }
142
164
  }]);
@@ -176,10 +176,13 @@ var IconAndTitleLayout = /*#__PURE__*/function (_React$Component) {
176
176
  href: link,
177
177
  onClick: this.handleClick,
178
178
  onKeyPress: this.handleKeyPress
179
- }, titlePart) : titlePart, rightSide ? /*#__PURE__*/_react.default.createElement(_styled2.NoLinkAppearance, null, ' - ', rightSide) : null));
179
+ }, titlePart) : titlePart, rightSide ? /*#__PURE__*/_react.default.createElement(_styled2.NoLinkAppearance, null, this.props.rightSideSpacer && ' - ', rightSide) : null));
180
180
  }
181
181
  }]);
182
182
  return IconAndTitleLayout;
183
183
  }(_react.default.Component);
184
184
 
185
- exports.IconAndTitleLayout = IconAndTitleLayout;
185
+ exports.IconAndTitleLayout = IconAndTitleLayout;
186
+ (0, _defineProperty2.default)(IconAndTitleLayout, "defaultProps", {
187
+ rightSideSpacer: true
188
+ });
@@ -43,7 +43,7 @@ var IconTitleWrapper = _styled.default.span(_templateObject3 || (_templateObject
43
43
 
44
44
  exports.IconTitleWrapper = IconTitleWrapper;
45
45
 
46
- var LozengeWrapper = _styled.default.span(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\n display: inline-block;\n vertical-align: 1px;\n & > span {\n margin-left: 4px;\n }\n"]))); // TODO: Replace overrides with proper AtlasKit solution.
46
+ var LozengeWrapper = _styled.default.span(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\n display: inline-block;\n vertical-align: 1px;\n"]))); // TODO: Replace overrides with proper AtlasKit solution.
47
47
 
48
48
 
49
49
  exports.LozengeWrapper = LozengeWrapper;
@@ -52,10 +52,10 @@ var InlineCardResolvedView = /*#__PURE__*/function (_React$Component) {
52
52
  return null;
53
53
  }
54
54
 
55
- return /*#__PURE__*/_react.default.createElement(_styled.LozengeWrapper, null, /*#__PURE__*/_react.default.createElement(_lozenge.default, {
55
+ return /*#__PURE__*/_react.default.createElement(_styled.LozengeBlockWrapper, null, /*#__PURE__*/_react.default.createElement(_styled.LozengeWrapper, null, /*#__PURE__*/_react.default.createElement(_lozenge.default, {
56
56
  appearance: lozenge.appearance || 'default',
57
57
  isBold: lozenge.isBold
58
- }, lozenge.text));
58
+ }, lozenge.text)));
59
59
  }
60
60
  }, {
61
61
  key: "render",
@@ -127,7 +127,7 @@ export const messages = defineMessages({
127
127
  },
128
128
  invalid_permissions: {
129
129
  id: 'fabric.linking.invalid_permissions',
130
- defaultMessage: 'Restricted link',
130
+ defaultMessage: 'Restricted content',
131
131
  description: 'Message shown when a user does not have permissions to view an item'
132
132
  },
133
133
  invalid_permissions_description: {
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
2
  import { getUrl } from '@atlaskit/linking-common';
3
- import { connectFailedEvent, connectSucceededEvent, context, instrumentEvent, invokeFailedEvent, invokeSucceededEvent, screenAuthPopupEvent, trackAppAccountAuthStarted, trackAppAccountConnected, uiActionClickedEvent, uiAuthAlternateAccountEvent, uiAuthEvent, uiCardClickedEvent, uiClosedAuthEvent, uiHoverCardDismissedEvent, uiHoverCardOpenLinkClickedEvent, uiHoverCardViewedEvent, uiLearnMoreLinkClickedEvent, uiRenderFailedEvent, uiRenderSuccessEvent } from '../../utils/analytics';
3
+ import { chunkloadFailedEvent, connectFailedEvent, connectSucceededEvent, context, instrumentEvent, invokeFailedEvent, invokeSucceededEvent, screenAuthPopupEvent, trackAppAccountAuthStarted, trackAppAccountConnected, uiActionClickedEvent, uiAuthAlternateAccountEvent, uiAuthEvent, uiCardClickedEvent, uiClosedAuthEvent, uiHoverCardDismissedEvent, uiHoverCardOpenLinkClickedEvent, uiHoverCardViewedEvent, uiLearnMoreLinkClickedEvent, uiRenderFailedEvent, uiRenderSuccessEvent } from '../../utils/analytics';
4
4
  import { failUfoExperience, startUfoExperience, succeedUfoExperience } from './ufoExperiences';
5
5
  import { getDefinitionId, getExtensionKey, getProduct, getResourceType, getSubproduct } from '../helpers';
6
6
  import { useSmartLinkContext } from '@atlaskit/link-provider';
@@ -586,6 +586,37 @@ export const useSmartLinkAnalytics = (url, dispatchAnalytics, id, defaultLocatio
586
586
  if (event) {
587
587
  dispatchAnalytics(applyCommonAttributes(event, commonAttributes));
588
588
  }
589
+ },
590
+
591
+ /**
592
+ * This fires an event that represents when a Smart Link renders unsuccessfuly.
593
+ * @param display Whether the card was an Inline, Block, Embed or Flexible UI.
594
+ * @param id The unique ID for this Smart Link.
595
+ * @param error: An error representing why the Smart Link render failed.
596
+ * @param errorInfo: Additional details about the error including the stack trace.
597
+ */
598
+ chunkloadFailedEvent: ({
599
+ display,
600
+ error,
601
+ errorInfo,
602
+ extensionKey,
603
+ definitionId,
604
+ resourceType,
605
+ destinationProduct,
606
+ destinationSubproduct,
607
+ location
608
+ }) => {
609
+ dispatchAnalytics(applyCommonAttributes(chunkloadFailedEvent({
610
+ display,
611
+ error,
612
+ errorInfo,
613
+ extensionKey,
614
+ definitionId,
615
+ resourceType,
616
+ destinationProduct,
617
+ destinationSubproduct,
618
+ location
619
+ }), commonAttributes));
589
620
  }
590
621
  }), [defaultId, commonAttributes, dispatchAnalytics]);
591
622
  /** Contains all track analytics events */
@@ -479,4 +479,28 @@ export const uiLearnMoreLinkClickedEvent = () => ({
479
479
  eventType: 'ui',
480
480
  attributes: { ...context
481
481
  }
482
+ });
483
+ export const chunkloadFailedEvent = ({
484
+ display,
485
+ error,
486
+ errorInfo,
487
+ extensionKey,
488
+ definitionId,
489
+ destinationProduct,
490
+ destinationSubproduct,
491
+ location
492
+ }) => ({
493
+ action: 'chunkLoadFailed',
494
+ actionSubject: 'smartLink',
495
+ eventType: 'operational',
496
+ attributes: { ...context,
497
+ error,
498
+ errorInfo,
499
+ display,
500
+ extensionKey,
501
+ definitionId,
502
+ destinationProduct,
503
+ destinationSubproduct,
504
+ location
505
+ }
482
506
  });
@@ -1,6 +1,6 @@
1
1
  import { getMeasure } from '../performance';
2
2
  import { resolvedEvent, unresolvedEvent } from './analytics';
3
- export { ANALYTICS_CHANNEL, context, fireSmartLinkEvent, resolvedEvent, unresolvedEvent, invokeSucceededEvent, invokeFailedEvent, connectSucceededEvent, connectFailedEvent, trackAppAccountAuthStarted, trackAppAccountConnected, uiAuthEvent, uiAuthAlternateAccountEvent, uiCardClickedEvent, uiActionClickedEvent, uiClosedAuthEvent, screenAuthPopupEvent, uiRenderSuccessEvent, uiRenderFailedEvent, uiHoverCardViewedEvent, uiHoverCardDismissedEvent, uiHoverCardOpenLinkClickedEvent, uiLearnMoreLinkClickedEvent } from './analytics';
3
+ export { ANALYTICS_CHANNEL, context, fireSmartLinkEvent, resolvedEvent, unresolvedEvent, invokeSucceededEvent, invokeFailedEvent, chunkloadFailedEvent, connectSucceededEvent, connectFailedEvent, trackAppAccountAuthStarted, trackAppAccountConnected, uiAuthEvent, uiAuthAlternateAccountEvent, uiCardClickedEvent, uiActionClickedEvent, uiClosedAuthEvent, screenAuthPopupEvent, uiRenderSuccessEvent, uiRenderFailedEvent, uiHoverCardViewedEvent, uiHoverCardDismissedEvent, uiHoverCardOpenLinkClickedEvent, uiLearnMoreLinkClickedEvent } from './analytics';
4
4
  export const instrumentEvent = ({
5
5
  id,
6
6
  status,
@@ -100,4 +100,19 @@ export const handleOnClick = handler => e => {
100
100
  e.stopPropagation();
101
101
  handler();
102
102
  };
103
- export const isIntersectionObserverSupported = () => typeof IntersectionObserver !== 'undefined';
103
+ export const isIntersectionObserverSupported = () => typeof IntersectionObserver !== 'undefined';
104
+ export const sleep = ms => {
105
+ return new Promise(resolve => setTimeout(resolve, ms));
106
+ };
107
+ export const importWithRetry = async (importFn, retries = 2, interval = 500) => {
108
+ try {
109
+ return await importFn();
110
+ } catch (error) {
111
+ if (error.name === 'ChunkLoadError' && retries > 0) {
112
+ await sleep(interval);
113
+ return importWithRetry(importFn, retries - 1, interval);
114
+ } else {
115
+ throw error;
116
+ }
117
+ }
118
+ };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "23.10.0",
3
+ "version": "23.10.2",
4
4
  "sideEffects": false
5
5
  }
@@ -5,9 +5,10 @@ import { clearMarks, clearMeasures } from '../../utils/performance';
5
5
  import { ErrorBoundary } from 'react-error-boundary';
6
6
  import { useSmartLinkAnalytics } from '../../state/analytics';
7
7
  import { LoadingCardLink } from './component-lazy/LazyFallback';
8
- const LazyCardWithUrlContent = /*#__PURE__*/lazy(() => import(
8
+ import { importWithRetry } from '../../utils';
9
+ const LazyCardWithUrlContent = /*#__PURE__*/lazy(() => importWithRetry(() => import(
9
10
  /* webpackChunkName: "@atlaskit-internal_smartcard-urlcardcontent" */
10
- './component-lazy/index'));
11
+ './component-lazy/index')));
11
12
  export function CardWithURLRenderer(props) {
12
13
  const [id] = useState(() => props.id ? props.id : uuid());
13
14
  useEffect(() => {
@@ -55,15 +56,22 @@ export function CardWithURLRenderer(props) {
55
56
  const logError = useCallback((error, info) => {
56
57
  const {
57
58
  componentStack
58
- } = info; // NB: APIErrors are thrown in response to Object Resolver Service. We do not
59
+ } = info;
60
+ const errorInfo = {
61
+ componentStack
62
+ }; // NB: APIErrors are thrown in response to Object Resolver Service. We do not
59
63
  // fire an event for these, as they do not cover failed UI render events.
60
64
  // The rest of the errors caught here are unexpected, and correlate
61
65
  // to the reliability of the smart-card front-end components.
66
+ // Likewise, chunk loading errors are not caused by a failure of smart-card rendering.
62
67
 
63
- if (error.name !== 'APIError') {
64
- const errorInfo = {
65
- componentStack
66
- };
68
+ if (error.name === 'ChunkLoadError') {
69
+ analytics.operational.chunkloadFailedEvent({
70
+ display: appearance,
71
+ error,
72
+ errorInfo
73
+ });
74
+ } else if (error.name !== 'APIError') {
67
75
  analytics.ui.renderFailedEvent({
68
76
  display: appearance,
69
77
  id,
@@ -75,7 +83,7 @@ export function CardWithURLRenderer(props) {
75
83
 
76
84
 
77
85
  throw error;
78
- }, [analytics.ui, appearance, id]);
86
+ }, [analytics.operational, analytics.ui, appearance, id]);
79
87
 
80
88
  if (!url) {
81
89
  throw new Error('@atlaskit/smart-card: url property is missing.');