@atlaskit/smart-card 20.0.6 → 20.1.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.
- package/CHANGELOG.md +41 -0
- package/dist/cjs/state/actions/constants.js +4 -2
- package/dist/cjs/state/actions/index.js +51 -19
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/BlockCard/index.js +29 -0
- package/dist/cjs/view/CardWithUrl/component.js +7 -2
- package/dist/cjs/view/CardWithUrl/loader.js +2 -0
- package/dist/cjs/view/EmbedCard/index.js +29 -0
- package/dist/cjs/view/FlexibleCard/components/common/loading-skeleton/index.js +6 -4
- package/dist/cjs/view/FlexibleCard/index.js +34 -7
- package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +27 -4
- package/dist/cjs/view/HoverCard/components/HoverCardContent.js +32 -10
- package/dist/cjs/view/HoverCard/components/HoverCardLoadingView.js +46 -0
- package/dist/cjs/view/HoverCard/styled.js +10 -4
- package/dist/cjs/view/InlineCard/index.js +29 -0
- package/dist/es2019/state/actions/constants.js +2 -1
- package/dist/es2019/state/actions/index.js +46 -18
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/BlockCard/index.js +29 -0
- package/dist/es2019/view/CardWithUrl/component.js +7 -2
- package/dist/es2019/view/CardWithUrl/loader.js +2 -0
- package/dist/es2019/view/EmbedCard/index.js +29 -0
- package/dist/es2019/view/FlexibleCard/components/common/loading-skeleton/index.js +38 -31
- package/dist/es2019/view/FlexibleCard/index.js +32 -7
- package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +27 -4
- package/dist/es2019/view/HoverCard/components/HoverCardContent.js +28 -9
- package/dist/es2019/view/HoverCard/components/HoverCardLoadingView.js +32 -0
- package/dist/es2019/view/HoverCard/styled.js +12 -1
- package/dist/es2019/view/InlineCard/index.js +29 -0
- package/dist/esm/state/actions/constants.js +2 -1
- package/dist/esm/state/actions/index.js +51 -20
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/BlockCard/index.js +29 -0
- package/dist/esm/view/CardWithUrl/component.js +7 -2
- package/dist/esm/view/CardWithUrl/loader.js +2 -0
- package/dist/esm/view/EmbedCard/index.js +29 -0
- package/dist/esm/view/FlexibleCard/components/common/loading-skeleton/index.js +6 -3
- package/dist/esm/view/FlexibleCard/index.js +33 -7
- package/dist/esm/view/HoverCard/components/HoverCardComponent.js +27 -4
- package/dist/esm/view/HoverCard/components/HoverCardContent.js +30 -10
- package/dist/esm/view/HoverCard/components/HoverCardLoadingView.js +31 -0
- package/dist/esm/view/HoverCard/styled.js +6 -3
- package/dist/esm/view/InlineCard/index.js +29 -0
- package/dist/types/state/actions/constants.d.ts +1 -0
- package/dist/types/state/actions/index.d.ts +1 -0
- package/dist/types/state/hooks/useSmartLink.d.ts +1 -0
- package/dist/types/view/BlockCard/types.d.ts +2 -0
- package/dist/types/view/Card/index.d.ts +1 -1
- package/dist/types/view/Card/types.d.ts +2 -1
- package/dist/types/view/CardWithUrl/component.d.ts +1 -1
- package/dist/types/view/CardWithUrl/types.d.ts +2 -1
- package/dist/types/view/EmbedCard/components/styled.d.ts +16 -16
- package/dist/types/view/EmbedCard/types.d.ts +2 -0
- package/dist/types/view/FlexibleCard/components/common/loading-skeleton/types.d.ts +8 -0
- package/dist/types/view/FlexibleCard/types.d.ts +9 -4
- package/dist/types/view/HoverCard/components/HoverCardLoadingView.d.ts +4 -0
- package/dist/types/view/HoverCard/styled.d.ts +3 -0
- package/dist/types/view/HoverCard/types.d.ts +7 -0
- package/dist/types/view/InlineCard/Frame/styled.d.ts +1 -1
- package/dist/types/view/InlineCard/Icon.d.ts +3 -3
- package/dist/types/view/InlineCard/IconAndTitleLayout/styled.d.ts +9 -9
- package/dist/types/view/InlineCard/ResolvingView/styled.d.ts +13 -5
- package/dist/types/view/InlineCard/styled.d.ts +8 -4
- package/dist/types/view/InlineCard/types.d.ts +2 -1
- package/dist/types/view/types.d.ts +6 -0
- package/package.json +4 -4
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
|
|
10
|
+
var _core = require("@emotion/core");
|
|
11
|
+
|
|
12
|
+
var _react = _interopRequireDefault(require("react"));
|
|
13
|
+
|
|
14
|
+
var _loadingSkeleton = _interopRequireDefault(require("../../FlexibleCard/components/common/loading-skeleton"));
|
|
15
|
+
|
|
16
|
+
var _FlexibleCard = _interopRequireDefault(require("../../FlexibleCard"));
|
|
17
|
+
|
|
18
|
+
var _blocks = require("../../FlexibleCard/components/blocks");
|
|
19
|
+
|
|
20
|
+
var _styled = require("../styled");
|
|
21
|
+
|
|
22
|
+
/** @jsx jsx */
|
|
23
|
+
var HoverCardLoadingView = function HoverCardLoadingView(_ref) {
|
|
24
|
+
var flexibleCardProps = _ref.flexibleCardProps,
|
|
25
|
+
titleBlockProps = _ref.titleBlockProps;
|
|
26
|
+
var lineHeightRem = 1.25;
|
|
27
|
+
var skeletonWidth = _styled.CARD_WIDTH_REM - 2;
|
|
28
|
+
return (0, _core.jsx)("div", {
|
|
29
|
+
css: _styled.loadingViewContainer,
|
|
30
|
+
"data-testid": "hover-card-loading-view"
|
|
31
|
+
}, (0, _core.jsx)(_FlexibleCard.default, flexibleCardProps, (0, _core.jsx)(_blocks.TitleBlock, titleBlockProps)), (0, _core.jsx)("div", {
|
|
32
|
+
css: _styled.skeletonContainer
|
|
33
|
+
}, (0, _core.jsx)("span", null), (0, _core.jsx)(_loadingSkeleton.default, {
|
|
34
|
+
width: skeletonWidth,
|
|
35
|
+
height: lineHeightRem
|
|
36
|
+
}), (0, _core.jsx)(_loadingSkeleton.default, {
|
|
37
|
+
width: skeletonWidth,
|
|
38
|
+
height: lineHeightRem * 3
|
|
39
|
+
}), (0, _core.jsx)(_loadingSkeleton.default, {
|
|
40
|
+
width: skeletonWidth,
|
|
41
|
+
height: lineHeightRem
|
|
42
|
+
})));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
var _default = HoverCardLoadingView;
|
|
46
|
+
exports.default = _default;
|
|
@@ -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.titleBlockCss = exports.metadataBlockCss = exports.footerBlockCss = exports.flexibleUiOptions = exports.HoverCardContainer = void 0;
|
|
8
|
+
exports.titleBlockCss = exports.skeletonContainer = exports.metadataBlockCss = exports.loadingViewContainer = exports.footerBlockCss = exports.flexibleUiOptions = exports.HoverCardContainer = exports.CARD_WIDTH_REM = void 0;
|
|
9
9
|
|
|
10
10
|
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ var _index = require("../../index");
|
|
|
15
15
|
|
|
16
16
|
var _constants = require("../../constants");
|
|
17
17
|
|
|
18
|
-
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
|
|
18
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
|
|
19
19
|
|
|
20
20
|
var flexibleUiOptions = {
|
|
21
21
|
hideElevation: true,
|
|
@@ -25,14 +25,20 @@ var flexibleUiOptions = {
|
|
|
25
25
|
hidePadding: true
|
|
26
26
|
};
|
|
27
27
|
exports.flexibleUiOptions = flexibleUiOptions;
|
|
28
|
+
var CARD_WIDTH_REM = 24;
|
|
29
|
+
exports.CARD_WIDTH_REM = CARD_WIDTH_REM;
|
|
28
30
|
var blockGap = '0.5rem';
|
|
29
31
|
var elementGap = '0.5rem';
|
|
30
32
|
var separatorCss = (0, _core.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n [data-separator] + [data-separator]:before {\n margin-right: ", ";\n }\n"])), elementGap);
|
|
31
|
-
var HoverCardContainer = (0, _core.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n background: none;\n border-width: 0;\n box-sizing: border-box;\n width:
|
|
33
|
+
var HoverCardContainer = (0, _core.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n background: none;\n border-width: 0;\n box-sizing: border-box;\n width: ", "rem;\n padding: 1rem;\n\n .", " {\n display: none;\n }\n"])), CARD_WIDTH_REM, _index.loadingPlaceholderClassName);
|
|
32
34
|
exports.HoverCardContainer = HoverCardContainer;
|
|
33
35
|
var titleBlockCss = (0, _core.css)(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2.default)(["\n gap: ", ";\n\n ", "\n\n // title and subtitle element group\n [data-smart-element-group] {\n // gap between title and subtitle\n gap: 0.06rem;\n\n /* subtitle element group */\n > [data-smart-element-group] {\n > span {\n margin-right: ", ";\n }\n }\n }\n"])), blockGap, separatorCss, elementGap);
|
|
34
36
|
exports.titleBlockCss = titleBlockCss;
|
|
35
37
|
var metadataBlockCss = (0, _core.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\n gap: 0px;\n\n /* primary element group */\n [data-smart-element-group]:nth-of-type(1) {\n flex-grow: 7;\n\n // a separator between text-based element\n ", "\n\n /* horizontal spacing between elements in group */\n > span {\n margin-right: ", ";\n }\n }\n /* secondary element group */\n [data-smart-element-group]:nth-of-type(2) {\n flex-grow: 3;\n /* horizontal spacing between elements in group */\n > span {\n margin-left: ", ";\n }\n }\n"])), separatorCss, elementGap, elementGap);
|
|
36
38
|
exports.metadataBlockCss = metadataBlockCss;
|
|
37
39
|
var footerBlockCss = (0, _core.css)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2.default)(["\n padding-top: 0.25rem;\n"])));
|
|
38
|
-
exports.footerBlockCss = footerBlockCss;
|
|
40
|
+
exports.footerBlockCss = footerBlockCss;
|
|
41
|
+
var loadingViewContainer = (0, _core.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n flex-direction: column;\n"])));
|
|
42
|
+
exports.loadingViewContainer = loadingViewContainer;
|
|
43
|
+
var skeletonContainer = (0, _core.css)(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n flex-direction: column;\n gap: 0.625rem;\n align-items: center;\n"])));
|
|
44
|
+
exports.skeletonContainer = skeletonContainer;
|
|
@@ -72,6 +72,7 @@ var InlineCard = function InlineCard(_ref) {
|
|
|
72
72
|
isSelected = _ref.isSelected,
|
|
73
73
|
renderers = _ref.renderers,
|
|
74
74
|
onResolve = _ref.onResolve,
|
|
75
|
+
onError = _ref.onError,
|
|
75
76
|
testId = _ref.testId,
|
|
76
77
|
inlinePreloaderStyle = _ref.inlinePreloaderStyle,
|
|
77
78
|
showHoverPreview = _ref.showHoverPreview;
|
|
@@ -111,6 +112,13 @@ var InlineCard = function InlineCard(_ref) {
|
|
|
111
112
|
}));
|
|
112
113
|
|
|
113
114
|
case 'unauthorized':
|
|
115
|
+
if (onError) {
|
|
116
|
+
onError({
|
|
117
|
+
url: url,
|
|
118
|
+
status: status
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
114
122
|
var provider = (0, _extractors.extractProvider)(cardDetails);
|
|
115
123
|
return /*#__PURE__*/_react.default.createElement(_UnauthorisedView.InlineCardUnauthorizedView, {
|
|
116
124
|
icon: provider && provider.icon,
|
|
@@ -122,6 +130,13 @@ var InlineCard = function InlineCard(_ref) {
|
|
|
122
130
|
});
|
|
123
131
|
|
|
124
132
|
case 'forbidden':
|
|
133
|
+
if (onError) {
|
|
134
|
+
onError({
|
|
135
|
+
url: url,
|
|
136
|
+
status: status
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
125
140
|
var providerForbidden = (0, _extractors.extractProvider)(cardDetails);
|
|
126
141
|
var cardMetadata = (_details$meta = details === null || details === void 0 ? void 0 : details.meta) !== null && _details$meta !== void 0 ? _details$meta : (0, _jsonld.getUnauthorizedJsonLd)().meta;
|
|
127
142
|
var requestAccessContext = (0, _context.extractRequestAccessContext)({
|
|
@@ -141,6 +156,13 @@ var InlineCard = function InlineCard(_ref) {
|
|
|
141
156
|
});
|
|
142
157
|
|
|
143
158
|
case 'not_found':
|
|
159
|
+
if (onError) {
|
|
160
|
+
onError({
|
|
161
|
+
url: url,
|
|
162
|
+
status: status
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
144
166
|
var providerNotFound = (0, _extractors.extractProvider)(cardDetails);
|
|
145
167
|
return /*#__PURE__*/_react.default.createElement(_ErroredView.InlineCardErroredView, {
|
|
146
168
|
url: url,
|
|
@@ -153,6 +175,13 @@ var InlineCard = function InlineCard(_ref) {
|
|
|
153
175
|
|
|
154
176
|
case 'fallback':
|
|
155
177
|
case 'errored':
|
|
178
|
+
if (onError) {
|
|
179
|
+
onError({
|
|
180
|
+
url: url,
|
|
181
|
+
status: status
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
156
185
|
return /*#__PURE__*/_react.default.createElement(_LinkView.CardLinkView, {
|
|
157
186
|
link: url,
|
|
158
187
|
isSelected: isSelected,
|
|
@@ -2,4 +2,5 @@ export const ANALYTICS_RESOLVING = 'resolving';
|
|
|
2
2
|
export const ANALYTICS_ERROR = 'errored';
|
|
3
3
|
export const ANALYTICS_FALLBACK = 'fallback';
|
|
4
4
|
export const ERROR_MESSAGE_OAUTH = 'Provider.authFlow is not set to OAuth2.';
|
|
5
|
-
export const ERROR_MESSAGE_FATAL = 'Fatal error resolving URL';
|
|
5
|
+
export const ERROR_MESSAGE_FATAL = 'Fatal error resolving URL';
|
|
6
|
+
export const ERROR_MESSAGE_METADATA = 'Error resolving metadata.';
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { useMemo, useCallback } from 'react';
|
|
2
2
|
import { auth } from '@atlaskit/outbound-auth-flow-client';
|
|
3
|
-
import { APIError } from '@atlaskit/linking-common';
|
|
4
3
|
import { useSmartLinkContext } from '@atlaskit/link-provider';
|
|
5
|
-
import { ACTION_PENDING, ACTION_RESOLVED, ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, cardAction } from '@atlaskit/linking-common';
|
|
4
|
+
import { ACTION_PENDING, ACTION_RESOLVED, ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, ACTION_UPDATE_METADATA_STATUS, cardAction, APIError } from '@atlaskit/linking-common';
|
|
6
5
|
import { getDefinitionId, getByDefinitionId, getServices, getStatus, getExtensionKey } from '../helpers';
|
|
7
|
-
import { ERROR_MESSAGE_OAUTH, ERROR_MESSAGE_FATAL } from './constants';
|
|
6
|
+
import { ERROR_MESSAGE_OAUTH, ERROR_MESSAGE_FATAL, ERROR_MESSAGE_METADATA } from './constants';
|
|
8
7
|
import * as measure from '../../utils/performance';
|
|
9
8
|
import { getUnauthorizedJsonLd } from '../../utils/jsonld';
|
|
10
9
|
import { addMetadataToExperience } from '../analytics';
|
|
@@ -20,14 +19,26 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
20
19
|
} = store;
|
|
21
20
|
const {
|
|
22
21
|
details,
|
|
23
|
-
status
|
|
22
|
+
status,
|
|
23
|
+
metadataStatus
|
|
24
24
|
} = getState()[url] || {
|
|
25
25
|
status: 'pending',
|
|
26
26
|
details: undefined
|
|
27
27
|
};
|
|
28
28
|
const hasAuthFlowSupported = config.authFlow !== 'disabled';
|
|
29
29
|
const hasData = !!(details && details.data);
|
|
30
|
-
const
|
|
30
|
+
const setMetadataStatus = useCallback(metadataStatus => {
|
|
31
|
+
dispatch(cardAction(ACTION_UPDATE_METADATA_STATUS, {
|
|
32
|
+
url
|
|
33
|
+
}, undefined, undefined, metadataStatus));
|
|
34
|
+
}, [dispatch, url]);
|
|
35
|
+
const handleResolvedLinkError = useCallback((url, error, response, isMetadataRequest) => {
|
|
36
|
+
// If metadata request then set metadata status, return and do not alter link status
|
|
37
|
+
if (isMetadataRequest) {
|
|
38
|
+
setMetadataStatus('errored');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
if (error.kind === 'fatal') {
|
|
32
43
|
// If there's no previous data in the store for this URL, then bail
|
|
33
44
|
// out and let the editor handle fallbacks (returns to a blue link).
|
|
@@ -64,24 +75,32 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
64
75
|
}, undefined, error));
|
|
65
76
|
}
|
|
66
77
|
}
|
|
67
|
-
}, [hasData, status, dispatch, details]);
|
|
68
|
-
const handleResolvedLinkResponse = useCallback((resourceUrl, response, isReloading = false) => {
|
|
78
|
+
}, [setMetadataStatus, hasData, status, dispatch, details]);
|
|
79
|
+
const handleResolvedLinkResponse = useCallback((resourceUrl, response, isReloading = false, isMetadataRequest) => {
|
|
69
80
|
const hostname = new URL(resourceUrl).hostname;
|
|
70
81
|
const nextStatus = response ? getStatus(response) : 'fatal'; // If we require authorization & do not have an authFlow available,
|
|
71
82
|
// throw an error and render as a normal blue link.
|
|
72
83
|
|
|
73
84
|
if ((nextStatus === 'unauthorized' || nextStatus === 'forbidden') && !hasAuthFlowSupported) {
|
|
74
|
-
handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH), response);
|
|
85
|
+
handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH), response, isMetadataRequest);
|
|
75
86
|
return;
|
|
76
87
|
} // Handle any other errors
|
|
77
88
|
|
|
78
89
|
|
|
79
90
|
if (nextStatus === 'fatal') {
|
|
80
|
-
handleResolvedLinkError(resourceUrl, new APIError('fatal', hostname, ERROR_MESSAGE_FATAL));
|
|
91
|
+
handleResolvedLinkError(resourceUrl, new APIError('fatal', hostname, ERROR_MESSAGE_FATAL), undefined, isMetadataRequest);
|
|
81
92
|
return;
|
|
82
|
-
} //
|
|
93
|
+
} // Handle errors of any other kind in the metadata request response
|
|
83
94
|
|
|
84
95
|
|
|
96
|
+
if (isMetadataRequest && nextStatus !== 'resolved') {
|
|
97
|
+
handleResolvedLinkError(resourceUrl, new APIError('error', hostname, ERROR_MESSAGE_METADATA), response, isMetadataRequest);
|
|
98
|
+
return;
|
|
99
|
+
} //if a link resolves normally, metadata will also always be resolved
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
setMetadataStatus('resolved'); // Dispatch Analytics and resolved card action - including unauthorized states.
|
|
103
|
+
|
|
85
104
|
if (isReloading) {
|
|
86
105
|
dispatch(cardAction(ACTION_RELOADING, {
|
|
87
106
|
url: resourceUrl
|
|
@@ -89,15 +108,15 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
89
108
|
} else {
|
|
90
109
|
dispatch(cardAction(ACTION_RESOLVED, {
|
|
91
110
|
url: resourceUrl
|
|
92
|
-
}, response));
|
|
111
|
+
}, response, undefined, undefined, isMetadataRequest));
|
|
93
112
|
}
|
|
94
|
-
}, [dispatch, handleResolvedLinkError, hasAuthFlowSupported]);
|
|
95
|
-
const resolve = useCallback(async (resourceUrl = url, isReloading = false) => {
|
|
113
|
+
}, [dispatch, handleResolvedLinkError, hasAuthFlowSupported, setMetadataStatus]);
|
|
114
|
+
const resolve = useCallback(async (resourceUrl = url, isReloading = false, isMetadataRequest = false) => {
|
|
96
115
|
// Request JSON-LD data for the card from ORS, iff it has extended
|
|
97
116
|
// its cache lifespan OR there is no data for it currently. Once the data
|
|
98
117
|
// has come back asynchronously, dispatch the resolved action for the card.
|
|
99
|
-
if (isReloading || !hasData) {
|
|
100
|
-
return connections.client.fetchData(resourceUrl).then(response => handleResolvedLinkResponse(resourceUrl, response, isReloading)).catch(error => handleResolvedLinkError(resourceUrl, error));
|
|
118
|
+
if (isReloading || !hasData || isMetadataRequest) {
|
|
119
|
+
return connections.client.fetchData(resourceUrl).then(response => handleResolvedLinkResponse(resourceUrl, response, isReloading, isMetadataRequest)).catch(error => handleResolvedLinkError(resourceUrl, error, undefined, isMetadataRequest));
|
|
101
120
|
} else {
|
|
102
121
|
addMetadataToExperience('smart-link-rendered', id, {
|
|
103
122
|
cached: true
|
|
@@ -109,10 +128,11 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
109
128
|
dispatch(cardAction(ACTION_PENDING, {
|
|
110
129
|
url
|
|
111
130
|
}));
|
|
131
|
+
setMetadataStatus('pending');
|
|
112
132
|
}
|
|
113
133
|
|
|
114
134
|
return resolve();
|
|
115
|
-
}, [
|
|
135
|
+
}, [details, resolve, dispatch, url, setMetadataStatus]);
|
|
116
136
|
const reload = useCallback(() => {
|
|
117
137
|
const definitionId = getDefinitionId(details);
|
|
118
138
|
|
|
@@ -122,6 +142,13 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
122
142
|
resolve(url, true);
|
|
123
143
|
}
|
|
124
144
|
}, [url, details, getState, resolve]);
|
|
145
|
+
const loadMetadata = useCallback(() => {
|
|
146
|
+
//metadataStatus will be undefined for SSR links only
|
|
147
|
+
if (metadataStatus === undefined) {
|
|
148
|
+
setMetadataStatus('pending');
|
|
149
|
+
return resolve(url, false, true);
|
|
150
|
+
}
|
|
151
|
+
}, [metadataStatus, resolve, setMetadataStatus, url]);
|
|
125
152
|
const authorize = useCallback(appearance => {
|
|
126
153
|
const definitionId = getDefinitionId(details);
|
|
127
154
|
const extensionKey = getExtensionKey(details);
|
|
@@ -187,6 +214,7 @@ export const useSmartCardActions = (id, url, analytics) => {
|
|
|
187
214
|
register,
|
|
188
215
|
reload,
|
|
189
216
|
authorize,
|
|
190
|
-
invoke
|
|
191
|
-
|
|
217
|
+
invoke,
|
|
218
|
+
loadMetadata
|
|
219
|
+
}), [register, reload, authorize, invoke, loadMetadata]);
|
|
192
220
|
};
|
package/dist/es2019/version.json
CHANGED
|
@@ -30,6 +30,7 @@ export const BlockCard = ({
|
|
|
30
30
|
renderers,
|
|
31
31
|
isSelected,
|
|
32
32
|
onResolve,
|
|
33
|
+
onError,
|
|
33
34
|
testId,
|
|
34
35
|
showActions,
|
|
35
36
|
platform
|
|
@@ -70,6 +71,13 @@ export const BlockCard = ({
|
|
|
70
71
|
}));
|
|
71
72
|
|
|
72
73
|
case 'unauthorized':
|
|
74
|
+
if (onError) {
|
|
75
|
+
onError({
|
|
76
|
+
url,
|
|
77
|
+
status
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
73
81
|
const unauthorizedViewProps = extractBlockProps(data, meta, extractorOpts);
|
|
74
82
|
return /*#__PURE__*/React.createElement(BlockCardUnauthorisedView, _extends({}, unauthorizedViewProps, {
|
|
75
83
|
isSelected: isSelected,
|
|
@@ -80,6 +88,13 @@ export const BlockCard = ({
|
|
|
80
88
|
}));
|
|
81
89
|
|
|
82
90
|
case 'forbidden':
|
|
91
|
+
if (onError) {
|
|
92
|
+
onError({
|
|
93
|
+
url,
|
|
94
|
+
status
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
83
98
|
const forbiddenViewProps = extractBlockProps(data, meta, extractorOpts);
|
|
84
99
|
const cardMetadata = (_details$meta = details === null || details === void 0 ? void 0 : details.meta) !== null && _details$meta !== void 0 ? _details$meta : getUnauthorizedJsonLd().meta;
|
|
85
100
|
const requestAccessContext = extractRequestAccessContext({
|
|
@@ -96,6 +111,13 @@ export const BlockCard = ({
|
|
|
96
111
|
}));
|
|
97
112
|
|
|
98
113
|
case 'not_found':
|
|
114
|
+
if (onError) {
|
|
115
|
+
onError({
|
|
116
|
+
url,
|
|
117
|
+
status
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
99
121
|
const notFoundViewProps = extractBlockProps(data, meta, extractorOpts);
|
|
100
122
|
return /*#__PURE__*/React.createElement(BlockCardNotFoundView, _extends({}, notFoundViewProps, {
|
|
101
123
|
isSelected: isSelected,
|
|
@@ -105,6 +127,13 @@ export const BlockCard = ({
|
|
|
105
127
|
|
|
106
128
|
case 'fallback':
|
|
107
129
|
case 'errored':
|
|
130
|
+
if (onError) {
|
|
131
|
+
onError({
|
|
132
|
+
url,
|
|
133
|
+
status
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
108
137
|
if (authFlow && authFlow === 'disabled') {
|
|
109
138
|
return /*#__PURE__*/React.createElement(CardLinkView, {
|
|
110
139
|
link: url,
|
|
@@ -20,6 +20,7 @@ export function CardWithUrlContent({
|
|
|
20
20
|
appearance,
|
|
21
21
|
dispatchAnalytics,
|
|
22
22
|
onResolve,
|
|
23
|
+
onError,
|
|
23
24
|
testId,
|
|
24
25
|
showActions,
|
|
25
26
|
inheritDimensions,
|
|
@@ -91,7 +92,7 @@ export function CardWithUrlContent({
|
|
|
91
92
|
if (isFinalState(state.status)) {
|
|
92
93
|
analytics.ui.renderSuccessEvent(appearance, state.status, id, definitionId, extensionKey);
|
|
93
94
|
}
|
|
94
|
-
}, [appearance, state.
|
|
95
|
+
}, [appearance, state.status, url, definitionId, extensionKey, analytics.ui, id]);
|
|
95
96
|
|
|
96
97
|
if (isFlexibleUi) {
|
|
97
98
|
let cardState = state;
|
|
@@ -115,7 +116,8 @@ export function CardWithUrlContent({
|
|
|
115
116
|
ui: ui,
|
|
116
117
|
url: url,
|
|
117
118
|
testId: testId,
|
|
118
|
-
onResolve: onResolve
|
|
119
|
+
onResolve: onResolve,
|
|
120
|
+
onError: onError
|
|
119
121
|
}, children);
|
|
120
122
|
} // We have to keep this last to prevent hook order from being violated
|
|
121
123
|
|
|
@@ -135,6 +137,7 @@ export function CardWithUrlContent({
|
|
|
135
137
|
handleFrameClick: handleClickWrapper,
|
|
136
138
|
isSelected: isSelected,
|
|
137
139
|
onResolve: onResolve,
|
|
140
|
+
onError: onError,
|
|
138
141
|
testId: testId,
|
|
139
142
|
inlinePreloaderStyle: inlinePreloaderStyle,
|
|
140
143
|
showHoverPreview: showHoverPreview
|
|
@@ -154,6 +157,7 @@ export function CardWithUrlContent({
|
|
|
154
157
|
handleAnalytics: dispatchAnalytics,
|
|
155
158
|
isSelected: isSelected,
|
|
156
159
|
onResolve: onResolve,
|
|
160
|
+
onError: onError,
|
|
157
161
|
testId: testId,
|
|
158
162
|
showActions: showActions,
|
|
159
163
|
platform: platform
|
|
@@ -173,6 +177,7 @@ export function CardWithUrlContent({
|
|
|
173
177
|
isFrameVisible: isFrameVisible,
|
|
174
178
|
platform: platform,
|
|
175
179
|
onResolve: onResolve,
|
|
180
|
+
onError: onError,
|
|
176
181
|
testId: testId,
|
|
177
182
|
inheritDimensions: inheritDimensions,
|
|
178
183
|
showActions: showActions,
|
|
@@ -25,6 +25,7 @@ export function CardWithURLRenderer(props) {
|
|
|
25
25
|
onClick,
|
|
26
26
|
container,
|
|
27
27
|
onResolve,
|
|
28
|
+
onError,
|
|
28
29
|
testId,
|
|
29
30
|
showActions,
|
|
30
31
|
inheritDimensions,
|
|
@@ -85,6 +86,7 @@ export function CardWithURLRenderer(props) {
|
|
|
85
86
|
dispatchAnalytics,
|
|
86
87
|
container,
|
|
87
88
|
onResolve,
|
|
89
|
+
onError,
|
|
88
90
|
testId,
|
|
89
91
|
showActions,
|
|
90
92
|
inheritDimensions,
|
|
@@ -29,6 +29,7 @@ export const EmbedCard = /*#__PURE__*/React.forwardRef(({
|
|
|
29
29
|
isFrameVisible,
|
|
30
30
|
platform,
|
|
31
31
|
onResolve,
|
|
32
|
+
onError,
|
|
32
33
|
testId,
|
|
33
34
|
inheritDimensions
|
|
34
35
|
}, iframeRef) => {
|
|
@@ -91,6 +92,13 @@ export const EmbedCard = /*#__PURE__*/React.forwardRef(({
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
case 'unauthorized':
|
|
95
|
+
if (onError) {
|
|
96
|
+
onError({
|
|
97
|
+
url,
|
|
98
|
+
status
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
94
102
|
const unauthorisedViewProps = extractEmbedProps(data, meta, platform);
|
|
95
103
|
return /*#__PURE__*/React.createElement(EmbedCardUnauthorisedView, _extends({}, unauthorisedViewProps, {
|
|
96
104
|
isSelected: isSelected,
|
|
@@ -100,6 +108,13 @@ export const EmbedCard = /*#__PURE__*/React.forwardRef(({
|
|
|
100
108
|
}));
|
|
101
109
|
|
|
102
110
|
case 'forbidden':
|
|
111
|
+
if (onError) {
|
|
112
|
+
onError({
|
|
113
|
+
url,
|
|
114
|
+
status
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
103
118
|
const forbiddenViewProps = extractEmbedProps(data, meta, platform);
|
|
104
119
|
const cardMetadata = (_details$meta = details === null || details === void 0 ? void 0 : details.meta) !== null && _details$meta !== void 0 ? _details$meta : getUnauthorizedJsonLd().meta;
|
|
105
120
|
const requestAccessContext = extractRequestAccessContext({
|
|
@@ -116,6 +131,13 @@ export const EmbedCard = /*#__PURE__*/React.forwardRef(({
|
|
|
116
131
|
}));
|
|
117
132
|
|
|
118
133
|
case 'not_found':
|
|
134
|
+
if (onError) {
|
|
135
|
+
onError({
|
|
136
|
+
url,
|
|
137
|
+
status
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
119
141
|
const notFoundViewProps = extractEmbedProps(data, meta, platform);
|
|
120
142
|
return /*#__PURE__*/React.createElement(EmbedCardNotFoundView, _extends({}, notFoundViewProps, {
|
|
121
143
|
isSelected: isSelected,
|
|
@@ -125,6 +147,13 @@ export const EmbedCard = /*#__PURE__*/React.forwardRef(({
|
|
|
125
147
|
|
|
126
148
|
case 'fallback':
|
|
127
149
|
case 'errored':
|
|
150
|
+
if (onError) {
|
|
151
|
+
onError({
|
|
152
|
+
url,
|
|
153
|
+
status
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
128
157
|
return /*#__PURE__*/React.createElement(EmbedCardErroredView, {
|
|
129
158
|
onRetry: handleErrorRetry,
|
|
130
159
|
inheritDimensions: inheritDimensions,
|
|
@@ -2,38 +2,45 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { css, jsx, keyframes } from '@emotion/core';
|
|
4
4
|
import { token } from '@atlaskit/tokens';
|
|
5
|
-
const animationNameStyles = keyframes`
|
|
6
|
-
0% { background-position: -20px 0; }
|
|
7
|
-
100% { background-position: 20px 0; }
|
|
8
|
-
`;
|
|
9
|
-
const styles = css`
|
|
10
|
-
border-radius: 2px;
|
|
11
|
-
user-select: none;
|
|
12
|
-
background: ${token('color.skeleton.subtle', '#f6f7f8')};
|
|
13
|
-
// TODO: https://product-fabric.atlassian.net/browse/DSP-4236
|
|
14
|
-
background-image: linear-gradient(
|
|
15
|
-
to right,
|
|
16
|
-
${token('color.skeleton.subtle', '#f6f7f8')} 0%,
|
|
17
|
-
${token('color.skeleton', '#edeef1')} 20%,
|
|
18
|
-
${token('color.skeleton.subtle', '#f6f7f8')} 40%,
|
|
19
|
-
${token('color.skeleton.subtle', '#f6f7f8')}100%
|
|
20
|
-
);
|
|
21
|
-
background-repeat: no-repeat;
|
|
22
|
-
background-size: 280% 100%;
|
|
23
|
-
display: inline-block;
|
|
24
|
-
|
|
25
|
-
animation-duration: 1s;
|
|
26
|
-
animation-fill-mode: forwards;
|
|
27
|
-
animation-iteration-count: infinite;
|
|
28
|
-
animation-name: ${animationNameStyles};
|
|
29
|
-
animation-timing-function: linear;
|
|
30
|
-
`;
|
|
31
5
|
|
|
32
6
|
const LoadingSkeleton = ({
|
|
33
|
-
testId
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
7
|
+
testId,
|
|
8
|
+
width,
|
|
9
|
+
height
|
|
10
|
+
}) => {
|
|
11
|
+
const animationWidth = width ? `${width}rem` : '20px';
|
|
12
|
+
const animationNameStyles = keyframes`
|
|
13
|
+
0% { background-position: -${animationWidth} 0; }
|
|
14
|
+
100% { background-position: ${animationWidth} 0; }
|
|
15
|
+
`;
|
|
16
|
+
const styles = css`
|
|
17
|
+
width: ${width}rem;
|
|
18
|
+
height: ${height}rem;
|
|
19
|
+
border-radius: 2px;
|
|
20
|
+
user-select: none;
|
|
21
|
+
background: ${token('color.skeleton.subtle', '#f6f7f8')};
|
|
22
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-4236
|
|
23
|
+
background-image: linear-gradient(
|
|
24
|
+
to right,
|
|
25
|
+
${token('color.skeleton.subtle', '#f6f7f8')} 0%,
|
|
26
|
+
${token('color.skeleton', '#edeef1')} 20%,
|
|
27
|
+
${token('color.skeleton.subtle', '#f6f7f8')} 40%,
|
|
28
|
+
${token('color.skeleton.subtle', '#f6f7f8')}100%
|
|
29
|
+
);
|
|
30
|
+
background-repeat: no-repeat;
|
|
31
|
+
background-size: 280% 100%;
|
|
32
|
+
display: inline-block;
|
|
33
|
+
|
|
34
|
+
animation-duration: 1s;
|
|
35
|
+
animation-fill-mode: forwards;
|
|
36
|
+
animation-iteration-count: infinite;
|
|
37
|
+
animation-name: ${animationNameStyles};
|
|
38
|
+
animation-timing-function: linear;
|
|
39
|
+
`;
|
|
40
|
+
return jsx("span", {
|
|
41
|
+
css: styles,
|
|
42
|
+
"data-testid": testId
|
|
43
|
+
});
|
|
44
|
+
};
|
|
38
45
|
|
|
39
46
|
export default LoadingSkeleton;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import React, { useEffect } from 'react';
|
|
3
|
+
import { SmartLinkStatus } from '../../constants';
|
|
3
4
|
import Container from './components/container';
|
|
4
5
|
import { FlexibleUiContext } from '../../state/flexible-ui-context';
|
|
5
6
|
import { getContextByStatus, getRetryOptions } from './utils';
|
|
@@ -14,12 +15,13 @@ const FlexibleCard = ({
|
|
|
14
15
|
cardState,
|
|
15
16
|
children,
|
|
16
17
|
onAuthorize,
|
|
18
|
+
onError,
|
|
19
|
+
onResolve,
|
|
17
20
|
renderers,
|
|
18
21
|
ui,
|
|
19
22
|
url,
|
|
20
23
|
onClick,
|
|
21
|
-
testId
|
|
22
|
-
onResolve
|
|
24
|
+
testId
|
|
23
25
|
}) => {
|
|
24
26
|
const {
|
|
25
27
|
status: cardType,
|
|
@@ -28,13 +30,36 @@ const FlexibleCard = ({
|
|
|
28
30
|
const status = cardType;
|
|
29
31
|
const context = getContextByStatus(url, status, details, renderers);
|
|
30
32
|
const retry = getRetryOptions(url, status, details, onAuthorize);
|
|
33
|
+
const {
|
|
34
|
+
title
|
|
35
|
+
} = context || {};
|
|
31
36
|
useEffect(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
switch (status) {
|
|
38
|
+
case SmartLinkStatus.Resolved:
|
|
39
|
+
if (onResolve) {
|
|
40
|
+
onResolve({
|
|
41
|
+
title,
|
|
42
|
+
url
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
break;
|
|
47
|
+
|
|
48
|
+
case SmartLinkStatus.Errored:
|
|
49
|
+
case SmartLinkStatus.Fallback:
|
|
50
|
+
case SmartLinkStatus.Forbidden:
|
|
51
|
+
case SmartLinkStatus.NotFound:
|
|
52
|
+
case SmartLinkStatus.Unauthorized:
|
|
53
|
+
if (onError) {
|
|
54
|
+
onError({
|
|
55
|
+
status,
|
|
56
|
+
url
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
break;
|
|
36
61
|
}
|
|
37
|
-
}, [onResolve, status, url]);
|
|
62
|
+
}, [onError, onResolve, status, title, url]);
|
|
38
63
|
return /*#__PURE__*/React.createElement(FlexibleUiContext.Provider, {
|
|
39
64
|
value: context
|
|
40
65
|
}, /*#__PURE__*/React.createElement(Container, _extends({
|