@atlaskit/smart-card 16.1.0 → 16.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/dist/cjs/client/utils/environments.js +1 -1
- package/dist/cjs/extractors/block/index.js +2 -2
- package/dist/cjs/extractors/common/actions/extractPreviewAction.js +2 -2
- package/dist/cjs/index.js +42 -0
- package/dist/cjs/providers/editor/transformer.js +6 -2
- package/dist/cjs/state/actions/index.js +14 -7
- package/dist/cjs/state/analytics/index.js +32 -84
- package/dist/cjs/state/analytics/ufoExperiences.js +63 -0
- package/dist/cjs/state/analytics/useSmartLinkAnalytics.js +114 -0
- package/dist/cjs/state/hooks/useSmartLink.js +6 -6
- package/dist/cjs/utils/analytics/analytics.js +6 -6
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/BlockCard/index.js +1 -1
- package/dist/cjs/view/CardWithUrl/component-lazy/index.js +1 -1
- package/dist/cjs/view/CardWithUrl/component.js +8 -3
- package/dist/cjs/view/CardWithUrl/loader.js +106 -134
- package/dist/cjs/view/EmbedCard/index.js +1 -1
- package/dist/es2019/client/utils/environments.js +1 -1
- package/dist/es2019/extractors/block/index.js +2 -2
- package/dist/es2019/extractors/common/actions/extractPreviewAction.js +2 -2
- package/dist/es2019/index.js +1 -1
- package/dist/es2019/providers/editor/transformer.js +4 -2
- package/dist/es2019/state/actions/index.js +10 -5
- package/dist/es2019/state/analytics/index.js +2 -40
- package/dist/es2019/state/analytics/ufoExperiences.js +43 -0
- package/dist/es2019/state/analytics/useSmartLinkAnalytics.js +76 -0
- package/dist/es2019/state/hooks/useSmartLink.js +4 -5
- package/dist/es2019/utils/analytics/analytics.js +6 -6
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/BlockCard/index.js +2 -2
- package/dist/es2019/view/CardWithUrl/component-lazy/index.js +1 -1
- package/dist/es2019/view/CardWithUrl/component.js +8 -3
- package/dist/es2019/view/CardWithUrl/loader.js +83 -92
- package/dist/es2019/view/EmbedCard/index.js +2 -2
- package/dist/esm/client/utils/environments.js +1 -1
- package/dist/esm/extractors/block/index.js +2 -2
- package/dist/esm/extractors/common/actions/extractPreviewAction.js +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/providers/editor/transformer.js +6 -2
- package/dist/esm/state/actions/index.js +13 -7
- package/dist/esm/state/analytics/index.js +2 -80
- package/dist/esm/state/analytics/ufoExperiences.js +43 -0
- package/dist/esm/state/analytics/useSmartLinkAnalytics.js +102 -0
- package/dist/esm/state/hooks/useSmartLink.js +6 -6
- package/dist/esm/utils/analytics/analytics.js +6 -6
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/BlockCard/index.js +2 -2
- package/dist/esm/view/CardWithUrl/component-lazy/index.js +1 -1
- package/dist/esm/view/CardWithUrl/component.js +8 -3
- package/dist/esm/view/CardWithUrl/loader.js +101 -130
- package/dist/esm/view/EmbedCard/index.js +2 -2
- package/dist/types/extractors/block/types.d.ts +1 -1
- package/dist/types/extractors/common/actions/extractPreviewAction.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/state/analytics/index.d.ts +3 -32
- package/dist/types/state/analytics/ufoExperiences.d.ts +7 -0
- package/dist/types/state/analytics/useSmartLinkAnalytics.d.ts +31 -0
- package/dist/types/state/hooks/useSmartLink.d.ts +5 -6
- package/dist/types/utils/analytics/analytics.d.ts +3 -3
- package/dist/types/view/CardWithUrl/component-lazy/index.d.ts +1 -1
- package/dist/types/view/CardWithUrl/loader.d.ts +1 -15
- package/package.json +19 -16
|
@@ -49,7 +49,8 @@ function CardWithUrlContent(_ref) {
|
|
|
49
49
|
actions = _useSmartLink.actions,
|
|
50
50
|
config = _useSmartLink.config,
|
|
51
51
|
analytics = _useSmartLink.analytics,
|
|
52
|
-
renderers = _useSmartLink.renderers
|
|
52
|
+
renderers = _useSmartLink.renderers,
|
|
53
|
+
error = _useSmartLink.error;
|
|
53
54
|
|
|
54
55
|
var definitionId = (0, _helpers.getDefinitionId)(state.details);
|
|
55
56
|
var extensionKey = (0, _helpers.getExtensionKey)(state.details);
|
|
@@ -92,9 +93,13 @@ function CardWithUrlContent(_ref) {
|
|
|
92
93
|
|
|
93
94
|
(0, _react.useEffect)(function () {
|
|
94
95
|
if ((0, _helpers.isFinalState)(state.status)) {
|
|
95
|
-
analytics.ui.renderSuccessEvent(appearance, definitionId, extensionKey);
|
|
96
|
+
analytics.ui.renderSuccessEvent(appearance, id, definitionId, extensionKey);
|
|
96
97
|
}
|
|
97
|
-
}, [appearance, state.details, state.status, url, definitionId, extensionKey, analytics.ui]);
|
|
98
|
+
}, [appearance, state.details, state.status, url, definitionId, extensionKey, analytics.ui, id]); // We have to keep this last to prevent hook order from being violated
|
|
99
|
+
|
|
100
|
+
if (error) {
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
98
103
|
|
|
99
104
|
switch (appearance) {
|
|
100
105
|
case 'inline':
|
|
@@ -2,28 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
4
|
|
|
5
|
-
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
6
|
-
|
|
7
5
|
Object.defineProperty(exports, "__esModule", {
|
|
8
6
|
value: true
|
|
9
7
|
});
|
|
10
|
-
exports.CardWithURLRenderer =
|
|
11
|
-
|
|
12
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
13
|
-
|
|
14
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
15
|
-
|
|
16
|
-
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
|
|
17
|
-
|
|
18
|
-
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
19
|
-
|
|
20
|
-
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
8
|
+
exports.CardWithURLRenderer = CardWithURLRenderer;
|
|
21
9
|
|
|
22
|
-
var
|
|
10
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
23
11
|
|
|
24
|
-
var
|
|
12
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
25
13
|
|
|
26
|
-
var _react =
|
|
14
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
27
15
|
|
|
28
16
|
var _uuid = _interopRequireDefault(require("uuid"));
|
|
29
17
|
|
|
@@ -33,132 +21,116 @@ var _analytics = require("../../utils/analytics");
|
|
|
33
21
|
|
|
34
22
|
var _performance = require("../../utils/performance");
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
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; }
|
|
39
|
-
|
|
40
|
-
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); }; }
|
|
41
|
-
|
|
42
|
-
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; } }
|
|
24
|
+
var _reactErrorBoundary = require("react-error-boundary");
|
|
43
25
|
|
|
44
|
-
var
|
|
45
|
-
(0, _inherits2.default)(CardWithURLRenderer, _React$PureComponent);
|
|
26
|
+
var _ufoExperiences = require("../../state/analytics/ufoExperiences");
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
function CardWithURLRenderer(props) {
|
|
50
|
-
var _this;
|
|
28
|
+
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); }
|
|
51
29
|
|
|
52
|
-
|
|
53
|
-
_this = _super.call(this, props);
|
|
54
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "dispatchAnalytics", function (analyticsPayload) {
|
|
55
|
-
var _this$props = _this.props,
|
|
56
|
-
appearance = _this$props.appearance,
|
|
57
|
-
createAnalyticsEvent = _this$props.createAnalyticsEvent;
|
|
30
|
+
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; }
|
|
58
31
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
(0, _analytics.fireSmartLinkEvent)(analyticsPayload, createAnalyticsEvent);
|
|
68
|
-
});
|
|
69
|
-
_this.state = {
|
|
70
|
-
id: (0, _uuid.default)()
|
|
71
|
-
};
|
|
72
|
-
return _this;
|
|
73
|
-
}
|
|
32
|
+
var LazyCardWithUrlContent = /*#__PURE__*/(0, _react.lazy)(function () {
|
|
33
|
+
return Promise.resolve().then(function () {
|
|
34
|
+
return _interopRequireWildcard(require('./component-lazy/index'));
|
|
35
|
+
});
|
|
36
|
+
});
|
|
74
37
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
38
|
+
function CardWithURLRenderer(props) {
|
|
39
|
+
var _useState = (0, _react.useState)(function () {
|
|
40
|
+
return (0, _uuid.default)();
|
|
41
|
+
}),
|
|
42
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 1),
|
|
43
|
+
id = _useState2[0]; // Equivalent to ComponentWillMount
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
(0, _react.useState)(function () {
|
|
47
|
+
// We want to start timing of render event only once and right at the start
|
|
48
|
+
(0, _ufoExperiences.startUfoExperience)('smart-link-rendered', id);
|
|
49
|
+
});
|
|
50
|
+
(0, _react.useEffect)(function () {
|
|
51
|
+
// ComponentWillUnmount
|
|
52
|
+
return function () {
|
|
86
53
|
(0, _performance.clearMarks)(id);
|
|
87
54
|
(0, _performance.clearMeasures)(id);
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
appearance = _this$props2.appearance,
|
|
112
|
-
isSelected = _this$props2.isSelected,
|
|
113
|
-
isFrameVisible = _this$props2.isFrameVisible,
|
|
114
|
-
onClick = _this$props2.onClick,
|
|
115
|
-
container = _this$props2.container,
|
|
116
|
-
onResolve = _this$props2.onResolve,
|
|
117
|
-
testId = _this$props2.testId,
|
|
118
|
-
showActions = _this$props2.showActions,
|
|
119
|
-
inheritDimensions = _this$props2.inheritDimensions,
|
|
120
|
-
platform = _this$props2.platform,
|
|
121
|
-
embedIframeRef = _this$props2.embedIframeRef,
|
|
122
|
-
inlinePreloaderStyle = _this$props2.inlinePreloaderStyle;
|
|
123
|
-
|
|
124
|
-
if (!url) {
|
|
125
|
-
throw new Error('@atlaskit/smart-card: url property is missing.');
|
|
55
|
+
};
|
|
56
|
+
}, [id]);
|
|
57
|
+
var url = props.url,
|
|
58
|
+
appearance = props.appearance,
|
|
59
|
+
isSelected = props.isSelected,
|
|
60
|
+
isFrameVisible = props.isFrameVisible,
|
|
61
|
+
onClick = props.onClick,
|
|
62
|
+
container = props.container,
|
|
63
|
+
onResolve = props.onResolve,
|
|
64
|
+
testId = props.testId,
|
|
65
|
+
showActions = props.showActions,
|
|
66
|
+
inheritDimensions = props.inheritDimensions,
|
|
67
|
+
platform = props.platform,
|
|
68
|
+
embedIframeRef = props.embedIframeRef,
|
|
69
|
+
inlinePreloaderStyle = props.inlinePreloaderStyle,
|
|
70
|
+
createAnalyticsEvent = props.createAnalyticsEvent; // Wrapper around analytics.
|
|
71
|
+
|
|
72
|
+
var dispatchAnalytics = (0, _react.useCallback)(function (analyticsPayload) {
|
|
73
|
+
if (analyticsPayload && analyticsPayload.attributes) {
|
|
74
|
+
// Update if we haven't already set the display - possible
|
|
75
|
+
// in the case of `preview` which is rendered differently.
|
|
76
|
+
if (!analyticsPayload.attributes.display) {
|
|
77
|
+
analyticsPayload.attributes.display = appearance;
|
|
126
78
|
}
|
|
127
|
-
|
|
128
|
-
return CardWithURLRenderer.CardContent !== null ? /*#__PURE__*/_react.default.createElement(CardWithURLRenderer.CardContent, {
|
|
129
|
-
id: this.state.id,
|
|
130
|
-
url: url,
|
|
131
|
-
appearance: appearance,
|
|
132
|
-
onClick: onClick,
|
|
133
|
-
isSelected: isSelected,
|
|
134
|
-
isFrameVisible: isFrameVisible,
|
|
135
|
-
dispatchAnalytics: this.dispatchAnalytics,
|
|
136
|
-
container: container,
|
|
137
|
-
onResolve: onResolve,
|
|
138
|
-
testId: testId,
|
|
139
|
-
showActions: showActions,
|
|
140
|
-
inheritDimensions: inheritDimensions,
|
|
141
|
-
platform: platform,
|
|
142
|
-
embedIframeRef: embedIframeRef,
|
|
143
|
-
inlinePreloaderStyle: inlinePreloaderStyle
|
|
144
|
-
}) : /*#__PURE__*/_react.default.createElement(_mediaUi.CardLinkView, {
|
|
145
|
-
key: 'chunk-placeholder',
|
|
146
|
-
link: url
|
|
147
|
-
});
|
|
148
79
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
80
|
+
|
|
81
|
+
(0, _analytics.fireSmartLinkEvent)(analyticsPayload, createAnalyticsEvent);
|
|
82
|
+
}, [appearance, createAnalyticsEvent]);
|
|
83
|
+
var logError = (0, _react.useCallback)(function (error, info) {
|
|
84
|
+
var componentStack = info.componentStack; // NB: APIErrors are thrown in response to Object Resolver Service.
|
|
85
|
+
// In these cases, control is handed back to the Editor. We do not
|
|
86
|
+
// fire an event for these, as they do not cover failed UI render events.
|
|
87
|
+
|
|
88
|
+
if (error.name === 'APIError') {
|
|
89
|
+
throw error;
|
|
90
|
+
} // NB: the rest of the errors caught here are unexpected, and correlate
|
|
91
|
+
// to the reliability of the smart-card front-end components. We instrument
|
|
92
|
+
// these in order to measure our front-end reliability.
|
|
93
|
+
else {
|
|
94
|
+
var errorInfo = {
|
|
95
|
+
componentStack: componentStack
|
|
96
|
+
};
|
|
97
|
+
(0, _ufoExperiences.failUfoExperience)('smart-link-rendered', id);
|
|
98
|
+
(0, _ufoExperiences.failUfoExperience)('smart-link-authenticated', id);
|
|
99
|
+
dispatchAnalytics((0, _analytics.uiRenderFailedEvent)(appearance, error, errorInfo));
|
|
158
100
|
}
|
|
159
|
-
}]);
|
|
160
|
-
return CardWithURLRenderer;
|
|
161
|
-
}(_react.default.PureComponent);
|
|
101
|
+
}, [appearance, dispatchAnalytics, id]);
|
|
162
102
|
|
|
163
|
-
|
|
164
|
-
|
|
103
|
+
if (!url) {
|
|
104
|
+
throw new Error('@atlaskit/smart-card: url property is missing.');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return /*#__PURE__*/_react.default.createElement(_reactErrorBoundary.ErrorBoundary, {
|
|
108
|
+
FallbackComponent: ErrorFallback,
|
|
109
|
+
onError: logError
|
|
110
|
+
}, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
|
|
111
|
+
fallback: /*#__PURE__*/_react.default.createElement(_mediaUi.CardLinkView, {
|
|
112
|
+
key: 'chunk-placeholder',
|
|
113
|
+
link: url
|
|
114
|
+
})
|
|
115
|
+
}, /*#__PURE__*/_react.default.createElement(LazyCardWithUrlContent, {
|
|
116
|
+
id: id,
|
|
117
|
+
url: url,
|
|
118
|
+
appearance: appearance,
|
|
119
|
+
onClick: onClick,
|
|
120
|
+
isSelected: isSelected,
|
|
121
|
+
isFrameVisible: isFrameVisible,
|
|
122
|
+
dispatchAnalytics: dispatchAnalytics,
|
|
123
|
+
container: container,
|
|
124
|
+
onResolve: onResolve,
|
|
125
|
+
testId: testId,
|
|
126
|
+
showActions: showActions,
|
|
127
|
+
inheritDimensions: inheritDimensions,
|
|
128
|
+
platform: platform,
|
|
129
|
+
embedIframeRef: embedIframeRef,
|
|
130
|
+
inlinePreloaderStyle: inlinePreloaderStyle
|
|
131
|
+
})));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
var ErrorFallback = function ErrorFallback() {
|
|
135
|
+
return /*#__PURE__*/_react.default.createElement("span", null);
|
|
136
|
+
};
|
|
@@ -92,7 +92,7 @@ var EmbedCard = /*#__PURE__*/_react.default.forwardRef(function (_ref, iframeRef
|
|
|
92
92
|
var resolvedBlockViewProps = (0, _block.extractBlockProps)(data, meta, {
|
|
93
93
|
handleAnalytics: handleAnalytics,
|
|
94
94
|
handleInvoke: handleInvoke,
|
|
95
|
-
|
|
95
|
+
extensionKey: (0, _helpers.getExtensionKey)(details)
|
|
96
96
|
});
|
|
97
97
|
return /*#__PURE__*/_react.default.createElement(_mediaUi.BlockCardResolvedView, (0, _extends2.default)({}, resolvedBlockViewProps, {
|
|
98
98
|
isSelected: isSelected,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const devBaseUrl = 'https://api-private.dev.atlassian.com';
|
|
2
|
-
const stgBaseUrl = 'https://
|
|
2
|
+
const stgBaseUrl = 'https://commerce-components-preview.dev.atlassian.com/gateway/api';
|
|
3
3
|
const prodBaseUrl = 'https://api-private.atlassian.com';
|
|
4
4
|
export const BaseUrls = {
|
|
5
5
|
dev: devBaseUrl,
|
|
@@ -35,11 +35,11 @@ export const extractBlockActions = (props, jsonLd, opts, platform) => {
|
|
|
35
35
|
const {
|
|
36
36
|
handleInvoke,
|
|
37
37
|
handleAnalytics,
|
|
38
|
-
|
|
38
|
+
extensionKey,
|
|
39
39
|
testId
|
|
40
40
|
} = opts;
|
|
41
41
|
const actions = extractActions(jsonLd, handleInvoke);
|
|
42
|
-
const previewAction = extractPreviewAction(
|
|
42
|
+
const previewAction = extractPreviewAction(extensionKey, props, jsonLd, handleInvoke, handleAnalytics, testId, platform); // The previewAction should always be the last action
|
|
43
43
|
|
|
44
44
|
if (previewAction) {
|
|
45
45
|
actions.push(previewAction);
|
|
@@ -40,7 +40,7 @@ const getInvokeOpts = (key, action, source) => ({
|
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
export const extractPreviewAction = (
|
|
43
|
+
export const extractPreviewAction = (extensionKey = 'empty-object-provider', viewProps, jsonLd, handleInvoke, handleAnalytics, testId, platform) => {
|
|
44
44
|
// Extract metadata from view props & raw JSON-LD.
|
|
45
45
|
const metadataFromJsonLd = getMetadataFromJsonLd(jsonLd, platform);
|
|
46
46
|
const metadataFromViewProps = getMetadataFromResolvedProps(viewProps);
|
|
@@ -50,7 +50,7 @@ export const extractPreviewAction = (definitionId = 'empty-object-provider', vie
|
|
|
50
50
|
|
|
51
51
|
if (metadataFromJsonLd.src) {
|
|
52
52
|
// Build action using instrumentation hooks.
|
|
53
|
-
const key =
|
|
53
|
+
const key = extensionKey;
|
|
54
54
|
const previewAction = PreviewAction({ ...metadata,
|
|
55
55
|
testId,
|
|
56
56
|
onOpen: () => {
|
package/dist/es2019/index.js
CHANGED
|
@@ -9,5 +9,5 @@ export { embedHeaderHeight } from '@atlaskit/media-ui/embeds';
|
|
|
9
9
|
export { SmartLinkEvents } from './utils/analytics/analytics';
|
|
10
10
|
export { useSmartLinkEvents } from './view/SmartLinkEvents/useSmartLinkEvents'; // Classnames for integrators
|
|
11
11
|
|
|
12
|
-
export { contentFooterClassName, metadataListClassName, blockCardResolvingViewClassName, blockCardResolvedViewClassName, blockCardForbiddenViewClassName, blockCardIconImageClassName } from '@atlaskit/media-ui/classNames';
|
|
12
|
+
export { contentFooterClassName, metadataListClassName, blockCardResolvingViewClassName, blockCardResolvedViewClassName, blockCardForbiddenViewClassName, blockCardIconImageClassName, blockCardResolvedViewByClassName, blockCardForbiddenViewLinkClassName, blockCardContentClassName, blockCardContentHeaderClassName, blockCardContentHeaderNameClassName, blockCardNotFoundViewClassName, blockCardErroredViewClassName } from '@atlaskit/media-ui/classNames';
|
|
13
13
|
export { loadingPlaceholderClassName } from './view/CardWithUrl/component-lazy/LazyFallback';
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const isJiraRoadMap = url => url.match(/^https:\/\/.*?\/jira\/software\/(c\/)?projects\/[^\/]+?\/boards\/.*?\/roadmap\/?/);
|
|
2
2
|
|
|
3
|
-
const isPolarisView = url => url.match(/^https:\/\/.*?\/jira\/polaris\/projects\/[^\/]+?\/ideas\/view\/\d
|
|
3
|
+
const isPolarisView = url => url.match(/^https:\/\/.*?\/jira\/polaris\/projects\/[^\/]+?\/ideas\/view\/\d+$|^https:\/\/.*?\/secure\/JiraProductDiscoveryAnonymous\.jspa\?hash=\w+|^https:\/\/.*?\/jira\/polaris\/share\/\w+/);
|
|
4
|
+
|
|
5
|
+
const isJwmView = url => url.match(/^https:\/\/.*?\/jira\/core\/projects\/[^\/]+?\/(timeline|calendar)\/?/);
|
|
4
6
|
|
|
5
7
|
const isSlackMessage = url => url.match(/^https:\/\/.+?\.slack\.com\/archives\/[CG][A-Z0-9]+\/p[0-9]+(\?.*)?$/);
|
|
6
8
|
|
|
@@ -34,7 +36,7 @@ export class Transformer {
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
toAdf(url, appearance) {
|
|
37
|
-
if (isJiraRoadMap(url) || isPolarisView(url)) {
|
|
39
|
+
if (isJiraRoadMap(url) || isPolarisView(url) || isJwmView(url)) {
|
|
38
40
|
return this.buildEmbedAdf(url);
|
|
39
41
|
} else if (isSlackMessage(url)) {
|
|
40
42
|
return this.buildBlockAdf(url);
|
|
@@ -7,6 +7,7 @@ import { useSmartLinkContext } from '../context';
|
|
|
7
7
|
import * as measure from '../../utils/performance';
|
|
8
8
|
import { APIError } from '../../client/errors';
|
|
9
9
|
import { getUnauthorizedJsonLd } from '../../utils/jsonld';
|
|
10
|
+
import { addMetadataToExperience } from '../analytics';
|
|
10
11
|
export const useSmartCardActions = (id, url, analytics) => {
|
|
11
12
|
const {
|
|
12
13
|
store,
|
|
@@ -91,8 +92,12 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
91
92
|
// has come back asynchronously, dispatch the resolved action for the card.
|
|
92
93
|
if (isReloading || !hasData) {
|
|
93
94
|
return connections.client.fetchData(resourceUrl).then(response => handleResolvedLinkResponse(resourceUrl, response)).catch(error => handleResolvedLinkError(resourceUrl, error));
|
|
95
|
+
} else {
|
|
96
|
+
addMetadataToExperience('smart-link-rendered', id, {
|
|
97
|
+
cached: true
|
|
98
|
+
});
|
|
94
99
|
}
|
|
95
|
-
}, [url, hasData, connections.client, handleResolvedLinkResponse, handleResolvedLinkError]);
|
|
100
|
+
}, [url, hasData, connections.client, handleResolvedLinkResponse, handleResolvedLinkError, id]);
|
|
96
101
|
const register = useCallback(() => {
|
|
97
102
|
if (!details) {
|
|
98
103
|
dispatch(cardAction(ACTION_PENDING, {
|
|
@@ -128,10 +133,10 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
128
133
|
analytics.screen.authPopupEvent(definitionId, extensionKey);
|
|
129
134
|
auth(services[0].url).then(() => {
|
|
130
135
|
analytics.track.appAccountConnected(definitionId, extensionKey);
|
|
131
|
-
analytics.operational.connectSucceededEvent(definitionId, extensionKey);
|
|
136
|
+
analytics.operational.connectSucceededEvent(id, definitionId, extensionKey);
|
|
132
137
|
reload();
|
|
133
138
|
}, err => {
|
|
134
|
-
analytics.operational.connectFailedEvent(definitionId, extensionKey, err.type);
|
|
139
|
+
analytics.operational.connectFailedEvent(id, definitionId, extensionKey, err.type);
|
|
135
140
|
|
|
136
141
|
if (err.type === 'auth_window_closed') {
|
|
137
142
|
analytics.ui.closedAuthEvent(appearance, definitionId, extensionKey);
|
|
@@ -140,7 +145,7 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
140
145
|
reload();
|
|
141
146
|
});
|
|
142
147
|
}
|
|
143
|
-
}, [analytics.ui, analytics.screen, analytics.track, analytics.operational, reload, details, status]);
|
|
148
|
+
}, [analytics.ui, analytics.screen, analytics.track, analytics.operational, id, reload, details, status]);
|
|
144
149
|
const invoke = useCallback(async (opts, appearance) => {
|
|
145
150
|
const {
|
|
146
151
|
key,
|
|
@@ -153,7 +158,7 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
153
158
|
|
|
154
159
|
try {
|
|
155
160
|
// Begin analytics instrumentation.
|
|
156
|
-
analytics.ui.actionClickedEvent(key, action.type, source); // Invoke action - either client-side or server-side.
|
|
161
|
+
analytics.ui.actionClickedEvent(id, key, action.type, source, opts.type); // Invoke action - either client-side or server-side.
|
|
157
162
|
|
|
158
163
|
let response;
|
|
159
164
|
|
|
@@ -1,40 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export const useSmartLinkAnalytics = dispatchAnalytics => {
|
|
4
|
-
const ui = useMemo(() => ({
|
|
5
|
-
authEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiAuthEvent(display, definitionId, extensionKey)),
|
|
6
|
-
authAlternateAccountEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiAuthAlternateAccountEvent(display, definitionId, extensionKey)),
|
|
7
|
-
cardClickedEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiCardClickedEvent(display, definitionId, extensionKey)),
|
|
8
|
-
actionClickedEvent: (providerKey, actionType, display) => dispatchAnalytics(uiActionClickedEvent(providerKey, actionType, display)),
|
|
9
|
-
closedAuthEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiClosedAuthEvent(display, definitionId, extensionKey)),
|
|
10
|
-
renderSuccessEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiRenderSuccessEvent(display, definitionId, extensionKey)),
|
|
11
|
-
renderFailedEvent: (display, error, errorInfo) => dispatchAnalytics(uiRenderFailedEvent(display, error, errorInfo))
|
|
12
|
-
}), [dispatchAnalytics]);
|
|
13
|
-
const operational = useMemo(() => ({
|
|
14
|
-
resolvedEvent: (id, definitionId, extensionKey, resourceType) => dispatchAnalytics(resolvedEvent(id, definitionId, extensionKey, resourceType)),
|
|
15
|
-
unresolvedEvent: (id, status, definitionId, extensionKey, resourceType) => dispatchAnalytics(unresolvedEvent(id, status, definitionId, extensionKey, resourceType)),
|
|
16
|
-
invokeSucceededEvent: (id, providerKey, actionType, display) => dispatchAnalytics(invokeSucceededEvent(id, providerKey, actionType, display)),
|
|
17
|
-
invokeFailedEvent: (id, providerKey, actionType, display, reason) => dispatchAnalytics(invokeFailedEvent(id, providerKey, actionType, display, reason)),
|
|
18
|
-
connectSucceededEvent: (definitionId, extensionKey) => dispatchAnalytics(connectSucceededEvent(definitionId, extensionKey)),
|
|
19
|
-
connectFailedEvent: (definitionId, extensionKey, reason) => dispatchAnalytics(connectFailedEvent(definitionId, extensionKey, reason)),
|
|
20
|
-
instrument: (id, status, definitionId, extensionKey, resourceType, error) => {
|
|
21
|
-
const event = instrumentEvent(id, status, definitionId, extensionKey, resourceType, error);
|
|
22
|
-
|
|
23
|
-
if (event) {
|
|
24
|
-
dispatchAnalytics(event);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}), [dispatchAnalytics]);
|
|
28
|
-
const track = useMemo(() => ({
|
|
29
|
-
appAccountConnected: (definitionId, extensionKey) => dispatchAnalytics(trackAppAccountConnected(definitionId, extensionKey))
|
|
30
|
-
}), [dispatchAnalytics]);
|
|
31
|
-
const screen = useMemo(() => ({
|
|
32
|
-
authPopupEvent: (definitionId, extensionKey) => dispatchAnalytics(screenAuthPopupEvent(definitionId, extensionKey))
|
|
33
|
-
}), [dispatchAnalytics]);
|
|
34
|
-
return useMemo(() => ({
|
|
35
|
-
ui,
|
|
36
|
-
operational,
|
|
37
|
-
track,
|
|
38
|
-
screen
|
|
39
|
-
}), [ui, operational, track, screen]);
|
|
40
|
-
};
|
|
1
|
+
export { startUfoExperience, succeedUfoExperience, failUfoExperience, addMetadataToExperience } from './ufoExperiences';
|
|
2
|
+
export { useSmartLinkAnalytics } from './useSmartLinkAnalytics';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ConcurrentExperience, ExperiencePerformanceTypes, ExperienceTypes } from '@atlaskit/ufo';
|
|
2
|
+
const inlineExperience = {
|
|
3
|
+
platform: {
|
|
4
|
+
component: 'smart-links'
|
|
5
|
+
},
|
|
6
|
+
type: ExperienceTypes.Experience,
|
|
7
|
+
performanceType: ExperiencePerformanceTypes.InlineResult
|
|
8
|
+
};
|
|
9
|
+
const renderExperience = {
|
|
10
|
+
platform: {
|
|
11
|
+
component: 'smart-links'
|
|
12
|
+
},
|
|
13
|
+
type: ExperienceTypes.Load,
|
|
14
|
+
performanceType: ExperiencePerformanceTypes.PageSegmentLoad
|
|
15
|
+
};
|
|
16
|
+
const ufoExperiences = {
|
|
17
|
+
'smart-link-rendered': new ConcurrentExperience('smart-link-rendered', renderExperience),
|
|
18
|
+
'smart-link-authenticated': new ConcurrentExperience('smart-link-authenticated', inlineExperience),
|
|
19
|
+
'smart-link-action-invocation': new ConcurrentExperience('smart-link-action-invocation', inlineExperience)
|
|
20
|
+
};
|
|
21
|
+
export const startUfoExperience = (experienceName, id, properties) => {
|
|
22
|
+
const experience = ufoExperiences[experienceName].getInstance(id);
|
|
23
|
+
experience.start();
|
|
24
|
+
|
|
25
|
+
if (properties) {
|
|
26
|
+
experience.addMetadata(properties);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export const succeedUfoExperience = (experienceName, id, properties) => {
|
|
30
|
+
const experience = ufoExperiences[experienceName].getInstance(id);
|
|
31
|
+
experience.success({
|
|
32
|
+
metadata: properties
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
export const failUfoExperience = (experienceName, id, properties) => {
|
|
36
|
+
const experience = ufoExperiences[experienceName].getInstance(id);
|
|
37
|
+
experience.failure({
|
|
38
|
+
metadata: properties
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
export const addMetadataToExperience = (experienceName, id, properties) => {
|
|
42
|
+
ufoExperiences[experienceName].getInstance(id).addMetadata(properties);
|
|
43
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { uiAuthEvent, uiAuthAlternateAccountEvent, uiCardClickedEvent, uiActionClickedEvent, uiClosedAuthEvent, uiRenderSuccessEvent, resolvedEvent, unresolvedEvent, invokeSucceededEvent, invokeFailedEvent, connectSucceededEvent, connectFailedEvent, trackAppAccountConnected, screenAuthPopupEvent, instrumentEvent } from '../../utils/analytics';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { failUfoExperience, startUfoExperience, succeedUfoExperience } from './ufoExperiences';
|
|
4
|
+
export const useSmartLinkAnalytics = dispatchAnalytics => {
|
|
5
|
+
const ui = useMemo(() => ({
|
|
6
|
+
authEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiAuthEvent(display, definitionId, extensionKey)),
|
|
7
|
+
authAlternateAccountEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiAuthAlternateAccountEvent(display, definitionId, extensionKey)),
|
|
8
|
+
cardClickedEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiCardClickedEvent(display, definitionId, extensionKey)),
|
|
9
|
+
actionClickedEvent: (id, extensionKey, actionType, display, invokeType) => {
|
|
10
|
+
startUfoExperience('smart-link-action-invocation', id, {
|
|
11
|
+
actionType,
|
|
12
|
+
display,
|
|
13
|
+
extensionKey,
|
|
14
|
+
invokeType
|
|
15
|
+
});
|
|
16
|
+
dispatchAnalytics(uiActionClickedEvent(extensionKey, actionType, display));
|
|
17
|
+
},
|
|
18
|
+
closedAuthEvent: (display, definitionId, extensionKey) => dispatchAnalytics(uiClosedAuthEvent(display, definitionId, extensionKey)),
|
|
19
|
+
renderSuccessEvent: (display, id, definitionId, extensionKey) => {
|
|
20
|
+
succeedUfoExperience('smart-link-rendered', id, {
|
|
21
|
+
extensionKey,
|
|
22
|
+
display
|
|
23
|
+
}); // UFO will disregard this if authentication experience has not yet been started
|
|
24
|
+
|
|
25
|
+
succeedUfoExperience('smart-link-authenticated', id, {
|
|
26
|
+
display
|
|
27
|
+
});
|
|
28
|
+
dispatchAnalytics(uiRenderSuccessEvent(display, definitionId, extensionKey));
|
|
29
|
+
}
|
|
30
|
+
}), [dispatchAnalytics]);
|
|
31
|
+
const operational = useMemo(() => ({
|
|
32
|
+
resolvedEvent: (id, definitionId, extensionKey, resourceType) => dispatchAnalytics(resolvedEvent(id, definitionId, extensionKey, resourceType)),
|
|
33
|
+
unresolvedEvent: (id, status, definitionId, extensionKey, resourceType) => dispatchAnalytics(unresolvedEvent(id, status, definitionId, extensionKey, resourceType)),
|
|
34
|
+
invokeSucceededEvent: (id, providerKey, actionType, display) => {
|
|
35
|
+
succeedUfoExperience('smart-link-action-invocation', id);
|
|
36
|
+
dispatchAnalytics(invokeSucceededEvent(id, providerKey, actionType, display));
|
|
37
|
+
},
|
|
38
|
+
invokeFailedEvent: (id, providerKey, actionType, display, reason) => {
|
|
39
|
+
failUfoExperience('smart-link-action-invocation', id);
|
|
40
|
+
dispatchAnalytics(invokeFailedEvent(id, providerKey, actionType, display, reason));
|
|
41
|
+
},
|
|
42
|
+
connectSucceededEvent: (id, definitionId, extensionKey) => {
|
|
43
|
+
startUfoExperience('smart-link-authenticated', id, {
|
|
44
|
+
extensionKey,
|
|
45
|
+
status: 'success'
|
|
46
|
+
});
|
|
47
|
+
dispatchAnalytics(connectSucceededEvent(definitionId, extensionKey));
|
|
48
|
+
},
|
|
49
|
+
connectFailedEvent: (id, definitionId, extensionKey, status) => {
|
|
50
|
+
startUfoExperience('smart-link-authenticated', id, {
|
|
51
|
+
extensionKey,
|
|
52
|
+
status
|
|
53
|
+
});
|
|
54
|
+
dispatchAnalytics(connectFailedEvent(definitionId, extensionKey, status));
|
|
55
|
+
},
|
|
56
|
+
instrument: (id, status, definitionId, extensionKey, resourceType, error) => {
|
|
57
|
+
const event = instrumentEvent(id, status, definitionId, extensionKey, resourceType, error);
|
|
58
|
+
|
|
59
|
+
if (event) {
|
|
60
|
+
dispatchAnalytics(event);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}), [dispatchAnalytics]);
|
|
64
|
+
const track = useMemo(() => ({
|
|
65
|
+
appAccountConnected: (definitionId, extensionKey) => dispatchAnalytics(trackAppAccountConnected(definitionId, extensionKey))
|
|
66
|
+
}), [dispatchAnalytics]);
|
|
67
|
+
const screen = useMemo(() => ({
|
|
68
|
+
authPopupEvent: (definitionId, extensionKey) => dispatchAnalytics(screenAuthPopupEvent(definitionId, extensionKey))
|
|
69
|
+
}), [dispatchAnalytics]);
|
|
70
|
+
return useMemo(() => ({
|
|
71
|
+
ui,
|
|
72
|
+
operational,
|
|
73
|
+
track,
|
|
74
|
+
screen
|
|
75
|
+
}), [ui, operational, track, screen]);
|
|
76
|
+
};
|
|
@@ -11,12 +11,10 @@ export function useSmartLink(id, url, dispatchAnalytics) {
|
|
|
11
11
|
const config = useSmartLinkConfig();
|
|
12
12
|
const renderers = useSmartLinkRenderers(); // NB: used to propagate errors from hooks to error boundaries.
|
|
13
13
|
|
|
14
|
-
const [,
|
|
14
|
+
const [error, setError] = useState(null); // Register the current card.
|
|
15
15
|
|
|
16
16
|
const register = () => {
|
|
17
|
-
actions.register().catch(err =>
|
|
18
|
-
throw err;
|
|
19
|
-
}));
|
|
17
|
+
actions.register().catch(err => setError(err));
|
|
20
18
|
}; // AFP-2511 TODO: Fix automatic suppressions below
|
|
21
19
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
22
20
|
|
|
@@ -28,6 +26,7 @@ export function useSmartLink(id, url, dispatchAnalytics) {
|
|
|
28
26
|
actions,
|
|
29
27
|
config,
|
|
30
28
|
analytics,
|
|
31
|
-
renderers
|
|
29
|
+
renderers,
|
|
30
|
+
error
|
|
32
31
|
};
|
|
33
32
|
}
|