@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
|
@@ -22,6 +22,10 @@ export const HoverCardComponent = ({
|
|
|
22
22
|
const fadeOutTimeoutId = useRef();
|
|
23
23
|
const fadeInTimeoutId = useRef();
|
|
24
24
|
const cardOpenTime = useRef();
|
|
25
|
+
const mousePos = useRef({
|
|
26
|
+
x: 0,
|
|
27
|
+
y: 0
|
|
28
|
+
});
|
|
25
29
|
const renderers = useSmartLinkRenderers();
|
|
26
30
|
const linkState = useLinkState(url);
|
|
27
31
|
const hoverDisplay = 'card';
|
|
@@ -66,7 +70,17 @@ export const HoverCardComponent = ({
|
|
|
66
70
|
if (actionId === 'preview-content') {
|
|
67
71
|
hideCard();
|
|
68
72
|
}
|
|
69
|
-
}, [hideCard]);
|
|
73
|
+
}, [hideCard]);
|
|
74
|
+
const setMousePosition = useCallback(event => {
|
|
75
|
+
if (isOpen) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
mousePos.current = {
|
|
80
|
+
x: event.clientX,
|
|
81
|
+
y: event.clientY
|
|
82
|
+
};
|
|
83
|
+
}, [isOpen]); // Stop hover preview content to propagate event to parent.
|
|
70
84
|
|
|
71
85
|
const onClick = useCallback(e => e.stopPropagation(), []);
|
|
72
86
|
return jsx(Popup, {
|
|
@@ -92,10 +106,19 @@ export const HoverCardComponent = ({
|
|
|
92
106
|
renderers: renderers,
|
|
93
107
|
url: url
|
|
94
108
|
})),
|
|
95
|
-
trigger: triggerProps => jsx("span",
|
|
109
|
+
trigger: triggerProps => jsx("span", {
|
|
96
110
|
onMouseEnter: initShowCard,
|
|
97
|
-
onMouseLeave: initHideCard
|
|
98
|
-
|
|
111
|
+
onMouseLeave: initHideCard,
|
|
112
|
+
onMouseMove: setMousePosition
|
|
113
|
+
}, jsx("span", _extends({}, triggerProps, {
|
|
114
|
+
css: {
|
|
115
|
+
position: 'sticky'
|
|
116
|
+
},
|
|
117
|
+
style: {
|
|
118
|
+
left: mousePos.current.x,
|
|
119
|
+
top: mousePos.current.y
|
|
120
|
+
}
|
|
121
|
+
})), children),
|
|
99
122
|
zIndex: 511 // Temporary fix for Confluence inline comment on editor mod has z-index of 500, Jira issue view has z-index of 510
|
|
100
123
|
|
|
101
124
|
});
|
|
@@ -4,12 +4,14 @@ import React, { useCallback, useEffect, useMemo } from 'react';
|
|
|
4
4
|
import { ActionName, SmartLinkPosition, SmartLinkSize } from '../../../constants';
|
|
5
5
|
import extractPreview from '../../../extractors/flexible/extract-preview';
|
|
6
6
|
import { extractMetadata } from '../../../extractors/hover/extractMetadata';
|
|
7
|
+
import { useSmartCardActions } from '../../../state/actions';
|
|
7
8
|
import { getExtensionKey } from '../../../state/helpers';
|
|
8
9
|
import { isSpecialEvent } from '../../../utils';
|
|
9
10
|
import FlexibleCard from '../../FlexibleCard';
|
|
10
11
|
import { FooterBlock, MetadataBlock, PreviewBlock, SnippetBlock, TitleBlock } from '../../FlexibleCard/components/blocks';
|
|
11
12
|
import { flexibleUiOptions, footerBlockCss, metadataBlockCss, titleBlockCss } from '../styled';
|
|
12
13
|
import { getSimulatedMetadata, SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
|
|
14
|
+
import HoverCardLoadingView from './HoverCardLoadingView';
|
|
13
15
|
export const getOpenAction = (url, analytics, onActionClick) => ({
|
|
14
16
|
name: ActionName.CustomAction,
|
|
15
17
|
icon: /*#__PURE__*/React.createElement(ShortcutIcon, {
|
|
@@ -41,6 +43,7 @@ export const toFooterActions = (cardActions, onActionClick) => cardActions.map(a
|
|
|
41
43
|
}));
|
|
42
44
|
|
|
43
45
|
const HoverCardContent = ({
|
|
46
|
+
id = '',
|
|
44
47
|
analytics,
|
|
45
48
|
cardActions = [],
|
|
46
49
|
cardState,
|
|
@@ -51,6 +54,10 @@ const HoverCardContent = ({
|
|
|
51
54
|
}) => {
|
|
52
55
|
var _cardState$details;
|
|
53
56
|
|
|
57
|
+
const actions = useSmartCardActions(id, url, analytics);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
actions.loadMetadata();
|
|
60
|
+
}, [actions]);
|
|
54
61
|
useEffect(() => {
|
|
55
62
|
// Since hover preview only render on resolved status,
|
|
56
63
|
// there is no need to check for statuses.
|
|
@@ -73,21 +80,33 @@ const HoverCardContent = ({
|
|
|
73
80
|
} = extractMetadata(getSimulatedMetadata(extensionKey, types));
|
|
74
81
|
const titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
|
|
75
82
|
const body = data && extractPreview(data) ? /*#__PURE__*/React.createElement(PreviewBlock, null) : /*#__PURE__*/React.createElement(SnippetBlock, null);
|
|
76
|
-
|
|
77
|
-
cardState: cardState,
|
|
78
|
-
onClick: onClick,
|
|
79
|
-
onResolve: onResolve,
|
|
80
|
-
renderers: renderers,
|
|
81
|
-
ui: flexibleUiOptions,
|
|
82
|
-
url: url
|
|
83
|
-
}, /*#__PURE__*/React.createElement(TitleBlock, {
|
|
83
|
+
const titleBlockProps = {
|
|
84
84
|
actions: titleActions,
|
|
85
85
|
maxLines: titleMaxLines,
|
|
86
86
|
overrideCss: titleBlockCss,
|
|
87
87
|
size: SmartLinkSize.Large,
|
|
88
88
|
position: SmartLinkPosition.Center,
|
|
89
89
|
subtitle: subtitle
|
|
90
|
-
}
|
|
90
|
+
};
|
|
91
|
+
const flexibleCardProps = {
|
|
92
|
+
cardState: cardState,
|
|
93
|
+
onClick: onClick,
|
|
94
|
+
onResolve: onResolve,
|
|
95
|
+
renderers: renderers,
|
|
96
|
+
ui: flexibleUiOptions,
|
|
97
|
+
url: url,
|
|
98
|
+
children: {}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (cardState.metadataStatus === 'pending') {
|
|
102
|
+
return /*#__PURE__*/React.createElement(HoverCardLoadingView, {
|
|
103
|
+
flexibleCardProps: flexibleCardProps,
|
|
104
|
+
titleBlockProps: titleBlockProps
|
|
105
|
+
});
|
|
106
|
+
} // if metadataStatus is 'errored' simply render using data available (normal path)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
return /*#__PURE__*/React.createElement(FlexibleCard, flexibleCardProps, /*#__PURE__*/React.createElement(TitleBlock, titleBlockProps), /*#__PURE__*/React.createElement(MetadataBlock, {
|
|
91
110
|
primary: primary,
|
|
92
111
|
secondary: secondary,
|
|
93
112
|
size: SmartLinkSize.Large,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import LoadingSkeleton from '../../FlexibleCard/components/common/loading-skeleton';
|
|
5
|
+
import FlexibleCard from '../../FlexibleCard';
|
|
6
|
+
import { TitleBlock } from '../../FlexibleCard/components/blocks';
|
|
7
|
+
import { CARD_WIDTH_REM, loadingViewContainer, skeletonContainer } from '../styled';
|
|
8
|
+
|
|
9
|
+
const HoverCardLoadingView = ({
|
|
10
|
+
flexibleCardProps,
|
|
11
|
+
titleBlockProps
|
|
12
|
+
}) => {
|
|
13
|
+
const lineHeightRem = 1.25;
|
|
14
|
+
const skeletonWidth = CARD_WIDTH_REM - 2;
|
|
15
|
+
return jsx("div", {
|
|
16
|
+
css: loadingViewContainer,
|
|
17
|
+
"data-testid": "hover-card-loading-view"
|
|
18
|
+
}, jsx(FlexibleCard, flexibleCardProps, jsx(TitleBlock, titleBlockProps)), jsx("div", {
|
|
19
|
+
css: skeletonContainer
|
|
20
|
+
}, jsx("span", null), jsx(LoadingSkeleton, {
|
|
21
|
+
width: skeletonWidth,
|
|
22
|
+
height: lineHeightRem
|
|
23
|
+
}), jsx(LoadingSkeleton, {
|
|
24
|
+
width: skeletonWidth,
|
|
25
|
+
height: lineHeightRem * 3
|
|
26
|
+
}), jsx(LoadingSkeleton, {
|
|
27
|
+
width: skeletonWidth,
|
|
28
|
+
height: lineHeightRem
|
|
29
|
+
})));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default HoverCardLoadingView;
|
|
@@ -8,6 +8,7 @@ export const flexibleUiOptions = {
|
|
|
8
8
|
theme: SmartLinkTheme.Black,
|
|
9
9
|
hidePadding: true
|
|
10
10
|
};
|
|
11
|
+
export const CARD_WIDTH_REM = 24;
|
|
11
12
|
const blockGap = '0.5rem';
|
|
12
13
|
const elementGap = '0.5rem';
|
|
13
14
|
const separatorCss = css`
|
|
@@ -19,7 +20,7 @@ export const HoverCardContainer = css`
|
|
|
19
20
|
background: none;
|
|
20
21
|
border-width: 0;
|
|
21
22
|
box-sizing: border-box;
|
|
22
|
-
width:
|
|
23
|
+
width: ${CARD_WIDTH_REM}rem;
|
|
23
24
|
padding: 1rem;
|
|
24
25
|
|
|
25
26
|
.${loadingPlaceholderClassName} {
|
|
@@ -70,4 +71,14 @@ export const metadataBlockCss = css`
|
|
|
70
71
|
`;
|
|
71
72
|
export const footerBlockCss = css`
|
|
72
73
|
padding-top: 0.25rem;
|
|
74
|
+
`;
|
|
75
|
+
export const loadingViewContainer = css`
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
`;
|
|
79
|
+
export const skeletonContainer = css`
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-direction: column;
|
|
82
|
+
gap: 0.625rem;
|
|
83
|
+
align-items: center;
|
|
73
84
|
`;
|
|
@@ -20,6 +20,7 @@ export const InlineCard = ({
|
|
|
20
20
|
isSelected,
|
|
21
21
|
renderers,
|
|
22
22
|
onResolve,
|
|
23
|
+
onError,
|
|
23
24
|
testId,
|
|
24
25
|
inlinePreloaderStyle,
|
|
25
26
|
showHoverPreview
|
|
@@ -64,6 +65,13 @@ export const InlineCard = ({
|
|
|
64
65
|
}));
|
|
65
66
|
|
|
66
67
|
case 'unauthorized':
|
|
68
|
+
if (onError) {
|
|
69
|
+
onError({
|
|
70
|
+
url,
|
|
71
|
+
status
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
const provider = extractProvider(cardDetails);
|
|
68
76
|
return /*#__PURE__*/React.createElement(InlineCardUnauthorizedView, {
|
|
69
77
|
icon: provider && provider.icon,
|
|
@@ -75,6 +83,13 @@ export const InlineCard = ({
|
|
|
75
83
|
});
|
|
76
84
|
|
|
77
85
|
case 'forbidden':
|
|
86
|
+
if (onError) {
|
|
87
|
+
onError({
|
|
88
|
+
url,
|
|
89
|
+
status
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
78
93
|
const providerForbidden = extractProvider(cardDetails);
|
|
79
94
|
const cardMetadata = (_details$meta = details === null || details === void 0 ? void 0 : details.meta) !== null && _details$meta !== void 0 ? _details$meta : getUnauthorizedJsonLd().meta;
|
|
80
95
|
const requestAccessContext = extractRequestAccessContext({
|
|
@@ -94,6 +109,13 @@ export const InlineCard = ({
|
|
|
94
109
|
});
|
|
95
110
|
|
|
96
111
|
case 'not_found':
|
|
112
|
+
if (onError) {
|
|
113
|
+
onError({
|
|
114
|
+
url,
|
|
115
|
+
status
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
97
119
|
const providerNotFound = extractProvider(cardDetails);
|
|
98
120
|
return /*#__PURE__*/React.createElement(InlineCardErroredView, {
|
|
99
121
|
url: url,
|
|
@@ -106,6 +128,13 @@ export const InlineCard = ({
|
|
|
106
128
|
|
|
107
129
|
case 'fallback':
|
|
108
130
|
case 'errored':
|
|
131
|
+
if (onError) {
|
|
132
|
+
onError({
|
|
133
|
+
url,
|
|
134
|
+
status
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
109
138
|
return /*#__PURE__*/React.createElement(CardLinkView, {
|
|
110
139
|
link: url,
|
|
111
140
|
isSelected: isSelected,
|
|
@@ -2,4 +2,5 @@ export var ANALYTICS_RESOLVING = 'resolving';
|
|
|
2
2
|
export var ANALYTICS_ERROR = 'errored';
|
|
3
3
|
export var ANALYTICS_FALLBACK = 'fallback';
|
|
4
4
|
export var ERROR_MESSAGE_OAUTH = 'Provider.authFlow is not set to OAuth2.';
|
|
5
|
-
export var ERROR_MESSAGE_FATAL = 'Fatal error resolving URL';
|
|
5
|
+
export var ERROR_MESSAGE_FATAL = 'Fatal error resolving URL';
|
|
6
|
+
export var ERROR_MESSAGE_METADATA = 'Error resolving metadata.';
|
|
@@ -2,11 +2,10 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
|
2
2
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
3
|
import { useMemo, useCallback } from 'react';
|
|
4
4
|
import { auth } from '@atlaskit/outbound-auth-flow-client';
|
|
5
|
-
import { APIError } from '@atlaskit/linking-common';
|
|
6
5
|
import { useSmartLinkContext } from '@atlaskit/link-provider';
|
|
7
|
-
import { ACTION_PENDING, ACTION_RESOLVED, ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, cardAction } from '@atlaskit/linking-common';
|
|
6
|
+
import { ACTION_PENDING, ACTION_RESOLVED, ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, ACTION_UPDATE_METADATA_STATUS, cardAction, APIError } from '@atlaskit/linking-common';
|
|
8
7
|
import { getDefinitionId, getByDefinitionId, getServices, getStatus, getExtensionKey } from '../helpers';
|
|
9
|
-
import { ERROR_MESSAGE_OAUTH, ERROR_MESSAGE_FATAL } from './constants';
|
|
8
|
+
import { ERROR_MESSAGE_OAUTH, ERROR_MESSAGE_FATAL, ERROR_MESSAGE_METADATA } from './constants';
|
|
10
9
|
import * as measure from '../../utils/performance';
|
|
11
10
|
import { getUnauthorizedJsonLd } from '../../utils/jsonld';
|
|
12
11
|
import { addMetadataToExperience } from '../analytics';
|
|
@@ -24,11 +23,23 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
|
|
|
24
23
|
details: undefined
|
|
25
24
|
},
|
|
26
25
|
details = _ref.details,
|
|
27
|
-
status = _ref.status
|
|
26
|
+
status = _ref.status,
|
|
27
|
+
metadataStatus = _ref.metadataStatus;
|
|
28
28
|
|
|
29
29
|
var hasAuthFlowSupported = config.authFlow !== 'disabled';
|
|
30
30
|
var hasData = !!(details && details.data);
|
|
31
|
-
var
|
|
31
|
+
var setMetadataStatus = useCallback(function (metadataStatus) {
|
|
32
|
+
dispatch(cardAction(ACTION_UPDATE_METADATA_STATUS, {
|
|
33
|
+
url: url
|
|
34
|
+
}, undefined, undefined, metadataStatus));
|
|
35
|
+
}, [dispatch, url]);
|
|
36
|
+
var handleResolvedLinkError = useCallback(function (url, error, response, isMetadataRequest) {
|
|
37
|
+
// If metadata request then set metadata status, return and do not alter link status
|
|
38
|
+
if (isMetadataRequest) {
|
|
39
|
+
setMetadataStatus('errored');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
32
43
|
if (error.kind === 'fatal') {
|
|
33
44
|
// If there's no previous data in the store for this URL, then bail
|
|
34
45
|
// out and let the editor handle fallbacks (returns to a blue link).
|
|
@@ -65,25 +76,34 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
|
|
|
65
76
|
}, undefined, error));
|
|
66
77
|
}
|
|
67
78
|
}
|
|
68
|
-
}, [hasData, status, dispatch, details]);
|
|
79
|
+
}, [setMetadataStatus, hasData, status, dispatch, details]);
|
|
69
80
|
var handleResolvedLinkResponse = useCallback(function (resourceUrl, response) {
|
|
70
81
|
var isReloading = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
82
|
+
var isMetadataRequest = arguments.length > 3 ? arguments[3] : undefined;
|
|
71
83
|
var hostname = new URL(resourceUrl).hostname;
|
|
72
84
|
var nextStatus = response ? getStatus(response) : 'fatal'; // If we require authorization & do not have an authFlow available,
|
|
73
85
|
// throw an error and render as a normal blue link.
|
|
74
86
|
|
|
75
87
|
if ((nextStatus === 'unauthorized' || nextStatus === 'forbidden') && !hasAuthFlowSupported) {
|
|
76
|
-
handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH), response);
|
|
88
|
+
handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH), response, isMetadataRequest);
|
|
77
89
|
return;
|
|
78
90
|
} // Handle any other errors
|
|
79
91
|
|
|
80
92
|
|
|
81
93
|
if (nextStatus === 'fatal') {
|
|
82
|
-
handleResolvedLinkError(resourceUrl, new APIError('fatal', hostname, ERROR_MESSAGE_FATAL));
|
|
94
|
+
handleResolvedLinkError(resourceUrl, new APIError('fatal', hostname, ERROR_MESSAGE_FATAL), undefined, isMetadataRequest);
|
|
95
|
+
return;
|
|
96
|
+
} // Handle errors of any other kind in the metadata request response
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
if (isMetadataRequest && nextStatus !== 'resolved') {
|
|
100
|
+
handleResolvedLinkError(resourceUrl, new APIError('error', hostname, ERROR_MESSAGE_METADATA), response, isMetadataRequest);
|
|
83
101
|
return;
|
|
84
|
-
} //
|
|
102
|
+
} //if a link resolves normally, metadata will also always be resolved
|
|
85
103
|
|
|
86
104
|
|
|
105
|
+
setMetadataStatus('resolved'); // Dispatch Analytics and resolved card action - including unauthorized states.
|
|
106
|
+
|
|
87
107
|
if (isReloading) {
|
|
88
108
|
dispatch(cardAction(ACTION_RELOADING, {
|
|
89
109
|
url: resourceUrl
|
|
@@ -91,12 +111,13 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
|
|
|
91
111
|
} else {
|
|
92
112
|
dispatch(cardAction(ACTION_RESOLVED, {
|
|
93
113
|
url: resourceUrl
|
|
94
|
-
}, response));
|
|
114
|
+
}, response, undefined, undefined, isMetadataRequest));
|
|
95
115
|
}
|
|
96
|
-
}, [dispatch, handleResolvedLinkError, hasAuthFlowSupported]);
|
|
116
|
+
}, [dispatch, handleResolvedLinkError, hasAuthFlowSupported, setMetadataStatus]);
|
|
97
117
|
var resolve = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
98
118
|
var resourceUrl,
|
|
99
119
|
isReloading,
|
|
120
|
+
isMetadataRequest,
|
|
100
121
|
_args = arguments;
|
|
101
122
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
102
123
|
while (1) {
|
|
@@ -104,24 +125,25 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
|
|
|
104
125
|
case 0:
|
|
105
126
|
resourceUrl = _args.length > 0 && _args[0] !== undefined ? _args[0] : url;
|
|
106
127
|
isReloading = _args.length > 1 && _args[1] !== undefined ? _args[1] : false;
|
|
128
|
+
isMetadataRequest = _args.length > 2 && _args[2] !== undefined ? _args[2] : false;
|
|
107
129
|
|
|
108
|
-
if (!(isReloading || !hasData)) {
|
|
109
|
-
_context.next =
|
|
130
|
+
if (!(isReloading || !hasData || isMetadataRequest)) {
|
|
131
|
+
_context.next = 7;
|
|
110
132
|
break;
|
|
111
133
|
}
|
|
112
134
|
|
|
113
135
|
return _context.abrupt("return", connections.client.fetchData(resourceUrl).then(function (response) {
|
|
114
|
-
return handleResolvedLinkResponse(resourceUrl, response, isReloading);
|
|
136
|
+
return handleResolvedLinkResponse(resourceUrl, response, isReloading, isMetadataRequest);
|
|
115
137
|
}).catch(function (error) {
|
|
116
|
-
return handleResolvedLinkError(resourceUrl, error);
|
|
138
|
+
return handleResolvedLinkError(resourceUrl, error, undefined, isMetadataRequest);
|
|
117
139
|
}));
|
|
118
140
|
|
|
119
|
-
case
|
|
141
|
+
case 7:
|
|
120
142
|
addMetadataToExperience('smart-link-rendered', id, {
|
|
121
143
|
cached: true
|
|
122
144
|
});
|
|
123
145
|
|
|
124
|
-
case
|
|
146
|
+
case 8:
|
|
125
147
|
case "end":
|
|
126
148
|
return _context.stop();
|
|
127
149
|
}
|
|
@@ -133,10 +155,11 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
|
|
|
133
155
|
dispatch(cardAction(ACTION_PENDING, {
|
|
134
156
|
url: url
|
|
135
157
|
}));
|
|
158
|
+
setMetadataStatus('pending');
|
|
136
159
|
}
|
|
137
160
|
|
|
138
161
|
return resolve();
|
|
139
|
-
}, [
|
|
162
|
+
}, [details, resolve, dispatch, url, setMetadataStatus]);
|
|
140
163
|
var reload = useCallback(function () {
|
|
141
164
|
var definitionId = getDefinitionId(details);
|
|
142
165
|
|
|
@@ -148,6 +171,13 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
|
|
|
148
171
|
resolve(url, true);
|
|
149
172
|
}
|
|
150
173
|
}, [url, details, getState, resolve]);
|
|
174
|
+
var loadMetadata = useCallback(function () {
|
|
175
|
+
//metadataStatus will be undefined for SSR links only
|
|
176
|
+
if (metadataStatus === undefined) {
|
|
177
|
+
setMetadataStatus('pending');
|
|
178
|
+
return resolve(url, false, true);
|
|
179
|
+
}
|
|
180
|
+
}, [metadataStatus, resolve, setMetadataStatus, url]);
|
|
151
181
|
var authorize = useCallback(function (appearance) {
|
|
152
182
|
var definitionId = getDefinitionId(details);
|
|
153
183
|
var extensionKey = getExtensionKey(details);
|
|
@@ -243,7 +273,8 @@ export var useSmartCardActions = function useSmartCardActions(id, url, analytics
|
|
|
243
273
|
register: register,
|
|
244
274
|
reload: reload,
|
|
245
275
|
authorize: authorize,
|
|
246
|
-
invoke: invoke
|
|
276
|
+
invoke: invoke,
|
|
277
|
+
loadMetadata: loadMetadata
|
|
247
278
|
};
|
|
248
|
-
}, [register, reload, authorize, invoke]);
|
|
279
|
+
}, [register, reload, authorize, invoke, loadMetadata]);
|
|
249
280
|
};
|
package/dist/esm/version.json
CHANGED
|
@@ -31,6 +31,7 @@ export var BlockCard = function BlockCard(_ref) {
|
|
|
31
31
|
renderers = _ref.renderers,
|
|
32
32
|
isSelected = _ref.isSelected,
|
|
33
33
|
onResolve = _ref.onResolve,
|
|
34
|
+
onError = _ref.onError,
|
|
34
35
|
testId = _ref.testId,
|
|
35
36
|
showActions = _ref.showActions,
|
|
36
37
|
platform = _ref.platform;
|
|
@@ -68,6 +69,13 @@ export var BlockCard = function BlockCard(_ref) {
|
|
|
68
69
|
}));
|
|
69
70
|
|
|
70
71
|
case 'unauthorized':
|
|
72
|
+
if (onError) {
|
|
73
|
+
onError({
|
|
74
|
+
url: url,
|
|
75
|
+
status: status
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
var unauthorizedViewProps = extractBlockProps(data, meta, extractorOpts);
|
|
72
80
|
return /*#__PURE__*/React.createElement(BlockCardUnauthorisedView, _extends({}, unauthorizedViewProps, {
|
|
73
81
|
isSelected: isSelected,
|
|
@@ -78,6 +86,13 @@ export var BlockCard = function BlockCard(_ref) {
|
|
|
78
86
|
}));
|
|
79
87
|
|
|
80
88
|
case 'forbidden':
|
|
89
|
+
if (onError) {
|
|
90
|
+
onError({
|
|
91
|
+
url: url,
|
|
92
|
+
status: status
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
81
96
|
var forbiddenViewProps = extractBlockProps(data, meta, extractorOpts);
|
|
82
97
|
var cardMetadata = (_details$meta = details === null || details === void 0 ? void 0 : details.meta) !== null && _details$meta !== void 0 ? _details$meta : getUnauthorizedJsonLd().meta;
|
|
83
98
|
var requestAccessContext = extractRequestAccessContext({
|
|
@@ -94,6 +109,13 @@ export var BlockCard = function BlockCard(_ref) {
|
|
|
94
109
|
}));
|
|
95
110
|
|
|
96
111
|
case 'not_found':
|
|
112
|
+
if (onError) {
|
|
113
|
+
onError({
|
|
114
|
+
url: url,
|
|
115
|
+
status: status
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
97
119
|
var notFoundViewProps = extractBlockProps(data, meta, extractorOpts);
|
|
98
120
|
return /*#__PURE__*/React.createElement(BlockCardNotFoundView, _extends({}, notFoundViewProps, {
|
|
99
121
|
isSelected: isSelected,
|
|
@@ -103,6 +125,13 @@ export var BlockCard = function BlockCard(_ref) {
|
|
|
103
125
|
|
|
104
126
|
case 'fallback':
|
|
105
127
|
case 'errored':
|
|
128
|
+
if (onError) {
|
|
129
|
+
onError({
|
|
130
|
+
url: url,
|
|
131
|
+
status: status
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
106
135
|
if (authFlow && authFlow === 'disabled') {
|
|
107
136
|
return /*#__PURE__*/React.createElement(CardLinkView, {
|
|
108
137
|
link: url,
|
|
@@ -20,6 +20,7 @@ export function CardWithUrlContent(_ref) {
|
|
|
20
20
|
appearance = _ref.appearance,
|
|
21
21
|
dispatchAnalytics = _ref.dispatchAnalytics,
|
|
22
22
|
onResolve = _ref.onResolve,
|
|
23
|
+
onError = _ref.onError,
|
|
23
24
|
testId = _ref.testId,
|
|
24
25
|
showActions = _ref.showActions,
|
|
25
26
|
inheritDimensions = _ref.inheritDimensions,
|
|
@@ -97,7 +98,7 @@ export function CardWithUrlContent(_ref) {
|
|
|
97
98
|
if (isFinalState(state.status)) {
|
|
98
99
|
analytics.ui.renderSuccessEvent(appearance, state.status, id, definitionId, extensionKey);
|
|
99
100
|
}
|
|
100
|
-
}, [appearance, state.
|
|
101
|
+
}, [appearance, state.status, url, definitionId, extensionKey, analytics.ui, id]);
|
|
101
102
|
|
|
102
103
|
if (isFlexibleUi) {
|
|
103
104
|
var cardState = state;
|
|
@@ -121,7 +122,8 @@ export function CardWithUrlContent(_ref) {
|
|
|
121
122
|
ui: ui,
|
|
122
123
|
url: url,
|
|
123
124
|
testId: testId,
|
|
124
|
-
onResolve: onResolve
|
|
125
|
+
onResolve: onResolve,
|
|
126
|
+
onError: onError
|
|
125
127
|
}, children);
|
|
126
128
|
} // We have to keep this last to prevent hook order from being violated
|
|
127
129
|
|
|
@@ -141,6 +143,7 @@ export function CardWithUrlContent(_ref) {
|
|
|
141
143
|
handleFrameClick: handleClickWrapper,
|
|
142
144
|
isSelected: isSelected,
|
|
143
145
|
onResolve: onResolve,
|
|
146
|
+
onError: onError,
|
|
144
147
|
testId: testId,
|
|
145
148
|
inlinePreloaderStyle: inlinePreloaderStyle,
|
|
146
149
|
showHoverPreview: showHoverPreview
|
|
@@ -160,6 +163,7 @@ export function CardWithUrlContent(_ref) {
|
|
|
160
163
|
handleAnalytics: dispatchAnalytics,
|
|
161
164
|
isSelected: isSelected,
|
|
162
165
|
onResolve: onResolve,
|
|
166
|
+
onError: onError,
|
|
163
167
|
testId: testId,
|
|
164
168
|
showActions: showActions,
|
|
165
169
|
platform: platform
|
|
@@ -179,6 +183,7 @@ export function CardWithUrlContent(_ref) {
|
|
|
179
183
|
isFrameVisible: isFrameVisible,
|
|
180
184
|
platform: platform,
|
|
181
185
|
onResolve: onResolve,
|
|
186
|
+
onError: onError,
|
|
182
187
|
testId: testId,
|
|
183
188
|
inheritDimensions: inheritDimensions,
|
|
184
189
|
showActions: showActions,
|
|
@@ -32,6 +32,7 @@ export function CardWithURLRenderer(props) {
|
|
|
32
32
|
onClick = props.onClick,
|
|
33
33
|
container = props.container,
|
|
34
34
|
onResolve = props.onResolve,
|
|
35
|
+
onError = props.onError,
|
|
35
36
|
testId = props.testId,
|
|
36
37
|
showActions = props.showActions,
|
|
37
38
|
inheritDimensions = props.inheritDimensions,
|
|
@@ -89,6 +90,7 @@ export function CardWithURLRenderer(props) {
|
|
|
89
90
|
dispatchAnalytics: dispatchAnalytics,
|
|
90
91
|
container: container,
|
|
91
92
|
onResolve: onResolve,
|
|
93
|
+
onError: onError,
|
|
92
94
|
testId: testId,
|
|
93
95
|
showActions: showActions,
|
|
94
96
|
inheritDimensions: inheritDimensions,
|
|
@@ -30,6 +30,7 @@ export var EmbedCard = /*#__PURE__*/React.forwardRef(function (_ref, iframeRef)
|
|
|
30
30
|
isFrameVisible = _ref.isFrameVisible,
|
|
31
31
|
platform = _ref.platform,
|
|
32
32
|
onResolve = _ref.onResolve,
|
|
33
|
+
onError = _ref.onError,
|
|
33
34
|
testId = _ref.testId,
|
|
34
35
|
inheritDimensions = _ref.inheritDimensions;
|
|
35
36
|
var data = details && details.data || getEmptyJsonLd();
|
|
@@ -89,6 +90,13 @@ export var EmbedCard = /*#__PURE__*/React.forwardRef(function (_ref, iframeRef)
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
case 'unauthorized':
|
|
93
|
+
if (onError) {
|
|
94
|
+
onError({
|
|
95
|
+
url: url,
|
|
96
|
+
status: status
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
92
100
|
var unauthorisedViewProps = extractEmbedProps(data, meta, platform);
|
|
93
101
|
return /*#__PURE__*/React.createElement(EmbedCardUnauthorisedView, _extends({}, unauthorisedViewProps, {
|
|
94
102
|
isSelected: isSelected,
|
|
@@ -98,6 +106,13 @@ export var EmbedCard = /*#__PURE__*/React.forwardRef(function (_ref, iframeRef)
|
|
|
98
106
|
}));
|
|
99
107
|
|
|
100
108
|
case 'forbidden':
|
|
109
|
+
if (onError) {
|
|
110
|
+
onError({
|
|
111
|
+
url: url,
|
|
112
|
+
status: status
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
101
116
|
var forbiddenViewProps = extractEmbedProps(data, meta, platform);
|
|
102
117
|
var cardMetadata = (_details$meta = details === null || details === void 0 ? void 0 : details.meta) !== null && _details$meta !== void 0 ? _details$meta : getUnauthorizedJsonLd().meta;
|
|
103
118
|
var requestAccessContext = extractRequestAccessContext({
|
|
@@ -114,6 +129,13 @@ export var EmbedCard = /*#__PURE__*/React.forwardRef(function (_ref, iframeRef)
|
|
|
114
129
|
}));
|
|
115
130
|
|
|
116
131
|
case 'not_found':
|
|
132
|
+
if (onError) {
|
|
133
|
+
onError({
|
|
134
|
+
url: url,
|
|
135
|
+
status: status
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
117
139
|
var notFoundViewProps = extractEmbedProps(data, meta, platform);
|
|
118
140
|
return /*#__PURE__*/React.createElement(EmbedCardNotFoundView, _extends({}, notFoundViewProps, {
|
|
119
141
|
isSelected: isSelected,
|
|
@@ -123,6 +145,13 @@ export var EmbedCard = /*#__PURE__*/React.forwardRef(function (_ref, iframeRef)
|
|
|
123
145
|
|
|
124
146
|
case 'fallback':
|
|
125
147
|
case 'errored':
|
|
148
|
+
if (onError) {
|
|
149
|
+
onError({
|
|
150
|
+
url: url,
|
|
151
|
+
status: status
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
126
155
|
return /*#__PURE__*/React.createElement(EmbedCardErroredView, {
|
|
127
156
|
onRetry: handleErrorRetry,
|
|
128
157
|
inheritDimensions: inheritDimensions,
|
|
@@ -6,11 +6,14 @@ var _templateObject, _templateObject2;
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import { css, jsx, keyframes } from '@emotion/core';
|
|
8
8
|
import { token } from '@atlaskit/tokens';
|
|
9
|
-
var animationNameStyles = keyframes(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n 0% { background-position: -20px 0; }\n 100% { background-position: 20px 0; }\n"])));
|
|
10
|
-
var styles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n border-radius: 2px;\n user-select: none;\n background: ", ";\n // TODO: https://product-fabric.atlassian.net/browse/DSP-4236\n background-image: linear-gradient(\n to right,\n ", " 0%,\n ", " 20%,\n ", " 40%,\n ", "100%\n );\n background-repeat: no-repeat;\n background-size: 280% 100%;\n display: inline-block;\n\n animation-duration: 1s;\n animation-fill-mode: forwards;\n animation-iteration-count: infinite;\n animation-name: ", ";\n animation-timing-function: linear;\n"])), token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton', '#edeef1'), token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton.subtle', '#f6f7f8'), animationNameStyles);
|
|
11
9
|
|
|
12
10
|
var LoadingSkeleton = function LoadingSkeleton(_ref) {
|
|
13
|
-
var testId = _ref.testId
|
|
11
|
+
var testId = _ref.testId,
|
|
12
|
+
width = _ref.width,
|
|
13
|
+
height = _ref.height;
|
|
14
|
+
var animationWidth = width ? "".concat(width, "rem") : '20px';
|
|
15
|
+
var animationNameStyles = keyframes(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n 0% { background-position: -", " 0; }\n 100% { background-position: ", " 0; }\n "])), animationWidth, animationWidth);
|
|
16
|
+
var styles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n width: ", "rem;\n height: ", "rem;\n border-radius: 2px;\n user-select: none;\n background: ", ";\n // TODO: https://product-fabric.atlassian.net/browse/DSP-4236\n background-image: linear-gradient(\n to right,\n ", " 0%,\n ", " 20%,\n ", " 40%,\n ", "100%\n );\n background-repeat: no-repeat;\n background-size: 280% 100%;\n display: inline-block;\n\n animation-duration: 1s;\n animation-fill-mode: forwards;\n animation-iteration-count: infinite;\n animation-name: ", ";\n animation-timing-function: linear;\n "])), width, height, token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton', '#edeef1'), token('color.skeleton.subtle', '#f6f7f8'), token('color.skeleton.subtle', '#f6f7f8'), animationNameStyles);
|
|
14
17
|
return jsx("span", {
|
|
15
18
|
css: styles,
|
|
16
19
|
"data-testid": testId
|