@atlaskit/smart-card 27.4.0 → 27.4.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 +16 -0
- package/dist/cjs/extractors/flexible/actions/extract-automation-action.js +13 -31
- package/dist/cjs/state/hooks/use-resolve/index.js +15 -120
- package/dist/cjs/state/hooks/use-response/index.js +132 -0
- package/dist/cjs/utils/analytics/analytics.js +1 -1
- package/dist/cjs/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/main.js +1 -1
- package/dist/cjs/view/FlexibleCard/components/actions/automation-action/index.js +14 -8
- package/dist/cjs/view/FlexibleCard/components/actions/automation-action/utils/index.js +19 -0
- package/dist/cjs/view/LinkUrl/index.js +1 -1
- package/dist/es2019/extractors/flexible/actions/extract-automation-action.js +13 -28
- package/dist/es2019/state/hooks/use-resolve/index.js +9 -112
- package/dist/es2019/state/hooks/use-response/index.js +126 -0
- package/dist/es2019/utils/analytics/analytics.js +1 -1
- package/dist/es2019/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/main.js +1 -1
- package/dist/es2019/view/FlexibleCard/components/actions/automation-action/index.js +16 -7
- package/dist/es2019/view/FlexibleCard/components/actions/automation-action/utils/index.js +13 -0
- package/dist/es2019/view/LinkUrl/index.js +1 -1
- package/dist/esm/extractors/flexible/actions/extract-automation-action.js +13 -30
- package/dist/esm/state/hooks/use-resolve/index.js +13 -118
- package/dist/esm/state/hooks/use-response/index.js +126 -0
- package/dist/esm/utils/analytics/analytics.js +1 -1
- package/dist/esm/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/main.js +1 -1
- package/dist/esm/view/FlexibleCard/components/actions/automation-action/index.js +14 -8
- package/dist/esm/view/FlexibleCard/components/actions/automation-action/utils/index.js +13 -0
- package/dist/esm/view/LinkUrl/index.js +1 -1
- package/dist/types/state/flexible-ui-context/types.d.ts +2 -3
- package/dist/types/state/hooks/use-response/index.d.ts +7 -0
- package/dist/types/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.d.ts +1 -1
- package/dist/types/view/FlexibleCard/components/actions/automation-action/utils/index.d.ts +7 -0
- package/dist/types-ts4.5/state/flexible-ui-context/types.d.ts +2 -3
- package/dist/types-ts4.5/state/hooks/use-response/index.d.ts +7 -0
- package/dist/types-ts4.5/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.d.ts +1 -1
- package/dist/types-ts4.5/view/FlexibleCard/components/actions/automation-action/utils/index.d.ts +7 -0
- package/package.json +3 -5
|
@@ -1,127 +1,24 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
|
-
import { unstable_batchedUpdates } from 'react-dom';
|
|
3
2
|
import { addMetadataToExperience } from '../../analytics';
|
|
4
|
-
import { ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, ACTION_RESOLVED, ACTION_UPDATE_METADATA_STATUS, APIError, cardAction, getStatus } from '@atlaskit/linking-common';
|
|
5
|
-
import { ERROR_MESSAGE_FATAL, ERROR_MESSAGE_METADATA, ERROR_MESSAGE_OAUTH } from '../../actions/constants';
|
|
6
|
-
import { getUnauthorizedJsonLd } from '../../../utils/jsonld';
|
|
7
3
|
import { SmartLinkStatus } from '../../../constants';
|
|
8
4
|
import { useSmartLinkContext } from '@atlaskit/link-provider';
|
|
5
|
+
import useResponse from '../use-response';
|
|
9
6
|
const useResolve = () => {
|
|
10
7
|
// Request JSON-LD data for the card from ORS, if it has extended
|
|
11
8
|
// its cache lifespan OR there is no data for it currently. Once the data
|
|
12
|
-
// has come back asynchronously,
|
|
9
|
+
// has come back asynchronously, call the useResponse callback to
|
|
10
|
+
// dispatch the resolved action for the card.
|
|
13
11
|
const {
|
|
14
12
|
store,
|
|
15
|
-
connections
|
|
16
|
-
config
|
|
13
|
+
connections
|
|
17
14
|
} = useSmartLinkContext();
|
|
18
15
|
const {
|
|
19
|
-
getState
|
|
20
|
-
dispatch
|
|
16
|
+
getState
|
|
21
17
|
} = store;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}, undefined, undefined, metadataStatus));
|
|
27
|
-
}, [dispatch]);
|
|
28
|
-
const handleResolvedLinkError = useCallback((url, error, response, isMetadataRequest) => {
|
|
29
|
-
const {
|
|
30
|
-
details
|
|
31
|
-
} = getState()[url] || {
|
|
32
|
-
status: SmartLinkStatus.Pending,
|
|
33
|
-
details: undefined
|
|
34
|
-
};
|
|
35
|
-
const hasData = !!(details && details.data);
|
|
36
|
-
|
|
37
|
-
// If metadata request then set metadata status, return and do not alter link status
|
|
38
|
-
if (isMetadataRequest) {
|
|
39
|
-
setMetadataStatus(url, 'errored');
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (error.kind === 'fatal') {
|
|
43
|
-
// If there's no previous data in the store for this URL, then bail
|
|
44
|
-
// out and let the editor handle fallbacks (returns to a blue link).
|
|
45
|
-
if (!hasData && status !== 'resolved') {
|
|
46
|
-
dispatch(cardAction(ACTION_ERROR, {
|
|
47
|
-
url
|
|
48
|
-
}, details, error));
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
// If we already have resolved data for this URL in the store, then
|
|
52
|
-
// simply fallback to the previous data.
|
|
53
|
-
if (hasData) {
|
|
54
|
-
dispatch(cardAction(ACTION_RESOLVED, {
|
|
55
|
-
url
|
|
56
|
-
}, details));
|
|
57
|
-
}
|
|
58
|
-
// Handle AuthErrors (user did not have access to resource) -
|
|
59
|
-
// Missing AAID in ASAP claims, or missing UserContext, or 403 from downstream
|
|
60
|
-
} else if (error.kind === 'auth') {
|
|
61
|
-
dispatch(cardAction(ACTION_RESOLVED, {
|
|
62
|
-
url
|
|
63
|
-
}, getUnauthorizedJsonLd()));
|
|
64
|
-
} else {
|
|
65
|
-
if (error.kind === 'fallback') {
|
|
66
|
-
// Fallback to blue link with smart link formatting. Not part of reliability.
|
|
67
|
-
dispatch(cardAction(ACTION_ERROR_FALLBACK, {
|
|
68
|
-
url
|
|
69
|
-
}, response, error));
|
|
70
|
-
} else {
|
|
71
|
-
// Fallback to blue link with smart link formatting. Part of reliability.
|
|
72
|
-
dispatch(cardAction(ACTION_ERROR, {
|
|
73
|
-
url
|
|
74
|
-
}, undefined, error));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}, [getState, setMetadataStatus, dispatch]);
|
|
78
|
-
const handleResolvedLinkSuccess = useCallback((resourceUrl, response, isReloading, isMetadataRequest) => {
|
|
79
|
-
//if a link resolves normally, metadata will also always be resolved
|
|
80
|
-
setMetadataStatus(resourceUrl, 'resolved');
|
|
81
|
-
// Dispatch Analytics and resolved card action - including unauthorized states.
|
|
82
|
-
if (isReloading) {
|
|
83
|
-
dispatch(cardAction(ACTION_RELOADING, {
|
|
84
|
-
url: resourceUrl
|
|
85
|
-
}, response));
|
|
86
|
-
} else {
|
|
87
|
-
dispatch(cardAction(ACTION_RESOLVED, {
|
|
88
|
-
url: resourceUrl
|
|
89
|
-
}, response, undefined, undefined, isMetadataRequest));
|
|
90
|
-
}
|
|
91
|
-
}, [setMetadataStatus, dispatch]);
|
|
92
|
-
const handleResolvedLinkResponse = useCallback((resourceUrl, response, isReloading = false, isMetadataRequest) => {
|
|
93
|
-
const hostname = new URL(resourceUrl).hostname;
|
|
94
|
-
const nextStatus = response ? getStatus(response) : 'fatal';
|
|
95
|
-
|
|
96
|
-
// If we require authorization & do not have an authFlow available,
|
|
97
|
-
// throw an error and render as a normal blue link.
|
|
98
|
-
if ((nextStatus === 'unauthorized' || nextStatus === 'forbidden') && !hasAuthFlowSupported) {
|
|
99
|
-
handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH), response, isMetadataRequest);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Handle any other errors
|
|
104
|
-
if (nextStatus === 'fatal') {
|
|
105
|
-
handleResolvedLinkError(resourceUrl, new APIError('fatal', hostname, ERROR_MESSAGE_FATAL), undefined, isMetadataRequest);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Handle errors of any other kind in the metadata request response
|
|
110
|
-
if (isMetadataRequest && nextStatus !== 'resolved') {
|
|
111
|
-
handleResolvedLinkError(resourceUrl, new APIError('error', hostname, ERROR_MESSAGE_METADATA), response, isMetadataRequest);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Using unstable_batchedUpdates because this store update happens async and trigers a rerender
|
|
117
|
-
* more info:
|
|
118
|
-
* https://github.com/facebook/react/blob/v18.2.0/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L113
|
|
119
|
-
* https://react-redux.js.org/api/batch
|
|
120
|
-
*/
|
|
121
|
-
unstable_batchedUpdates(() => {
|
|
122
|
-
handleResolvedLinkSuccess(resourceUrl, response, isReloading, isMetadataRequest);
|
|
123
|
-
});
|
|
124
|
-
}, [handleResolvedLinkError, handleResolvedLinkSuccess, hasAuthFlowSupported]);
|
|
18
|
+
const {
|
|
19
|
+
handleResolvedLinkResponse,
|
|
20
|
+
handleResolvedLinkError
|
|
21
|
+
} = useResponse();
|
|
125
22
|
return useCallback(async (url, isReloading = false, isMetadataRequest = false, id = '') => {
|
|
126
23
|
const {
|
|
127
24
|
details
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import { ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, ACTION_RESOLVED, ACTION_UPDATE_METADATA_STATUS, APIError, cardAction, getStatus } from '@atlaskit/linking-common';
|
|
3
|
+
import { SmartLinkStatus } from '../../../constants';
|
|
4
|
+
import { getUnauthorizedJsonLd } from '../../../utils/jsonld';
|
|
5
|
+
import { ERROR_MESSAGE_FATAL, ERROR_MESSAGE_METADATA, ERROR_MESSAGE_OAUTH } from '../../actions/constants';
|
|
6
|
+
import { unstable_batchedUpdates } from 'react-dom';
|
|
7
|
+
import { useSmartLinkContext } from '@atlaskit/link-provider';
|
|
8
|
+
const useResponse = () => {
|
|
9
|
+
// Takes in the JSON-LD response and dispatch the resolved action for the card.
|
|
10
|
+
// It will dispatch a successful or error action
|
|
11
|
+
const {
|
|
12
|
+
store,
|
|
13
|
+
config
|
|
14
|
+
} = useSmartLinkContext();
|
|
15
|
+
const {
|
|
16
|
+
getState,
|
|
17
|
+
dispatch
|
|
18
|
+
} = store;
|
|
19
|
+
const hasAuthFlowSupported = config.authFlow !== 'disabled';
|
|
20
|
+
const setMetadataStatus = useCallback((url, metadataStatus) => {
|
|
21
|
+
dispatch(cardAction(ACTION_UPDATE_METADATA_STATUS, {
|
|
22
|
+
url
|
|
23
|
+
}, undefined, undefined, metadataStatus));
|
|
24
|
+
}, [dispatch]);
|
|
25
|
+
const handleResolvedLinkError = useCallback((url, error, response, isMetadataRequest) => {
|
|
26
|
+
const {
|
|
27
|
+
details
|
|
28
|
+
} = getState()[url] || {
|
|
29
|
+
status: SmartLinkStatus.Pending,
|
|
30
|
+
details: undefined
|
|
31
|
+
};
|
|
32
|
+
const hasData = !!(details && details.data);
|
|
33
|
+
// If metadata request then set metadata status, return and do not alter link status
|
|
34
|
+
if (isMetadataRequest) {
|
|
35
|
+
setMetadataStatus(url, 'errored');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (error.kind === 'fatal') {
|
|
39
|
+
// If there's no previous data in the store for this URL, then bail
|
|
40
|
+
// out and let the editor handle fallbacks (returns to a blue link).
|
|
41
|
+
if (!hasData && status !== 'resolved') {
|
|
42
|
+
dispatch(cardAction(ACTION_ERROR, {
|
|
43
|
+
url
|
|
44
|
+
}, details, error));
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
// If we already have resolved data for this URL in the store, then
|
|
48
|
+
// simply fallback to the previous data.
|
|
49
|
+
if (hasData) {
|
|
50
|
+
dispatch(cardAction(ACTION_RESOLVED, {
|
|
51
|
+
url
|
|
52
|
+
}, details));
|
|
53
|
+
}
|
|
54
|
+
// Handle AuthErrors (user did not have access to resource) -
|
|
55
|
+
// Missing AAID in ASAP claims, or missing UserContext, or 403 from downstream
|
|
56
|
+
} else if (error.kind === 'auth') {
|
|
57
|
+
dispatch(cardAction(ACTION_RESOLVED, {
|
|
58
|
+
url
|
|
59
|
+
}, getUnauthorizedJsonLd()));
|
|
60
|
+
} else {
|
|
61
|
+
if (error.kind === 'fallback') {
|
|
62
|
+
// Fallback to blue link with smart link formatting. Not part of reliability.
|
|
63
|
+
dispatch(cardAction(ACTION_ERROR_FALLBACK, {
|
|
64
|
+
url
|
|
65
|
+
}, response, error));
|
|
66
|
+
} else {
|
|
67
|
+
// Fallback to blue link with smart link formatting. Part of reliability.
|
|
68
|
+
dispatch(cardAction(ACTION_ERROR, {
|
|
69
|
+
url
|
|
70
|
+
}, undefined, error));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}, [getState, setMetadataStatus, dispatch]);
|
|
74
|
+
const handleResolvedLinkSuccess = useCallback((resourceUrl, response, isReloading, isMetadataRequest) => {
|
|
75
|
+
//if a link resolves normally, metadata will also always be resolved
|
|
76
|
+
setMetadataStatus(resourceUrl, 'resolved');
|
|
77
|
+
// Dispatch Analytics and resolved card action - including unauthorized states.
|
|
78
|
+
if (isReloading) {
|
|
79
|
+
dispatch(cardAction(ACTION_RELOADING, {
|
|
80
|
+
url: resourceUrl
|
|
81
|
+
}, response));
|
|
82
|
+
} else {
|
|
83
|
+
dispatch(cardAction(ACTION_RESOLVED, {
|
|
84
|
+
url: resourceUrl
|
|
85
|
+
}, response, undefined, undefined, isMetadataRequest));
|
|
86
|
+
}
|
|
87
|
+
}, [setMetadataStatus, dispatch]);
|
|
88
|
+
const handleResolvedLinkResponse = useCallback((resourceUrl, response, isReloading = false, isMetadataRequest) => {
|
|
89
|
+
const hostname = new URL(resourceUrl).hostname;
|
|
90
|
+
const nextStatus = response ? getStatus(response) : 'fatal';
|
|
91
|
+
|
|
92
|
+
// If we require authorization & do not have an authFlow available,
|
|
93
|
+
// throw an error and render as a normal blue link.
|
|
94
|
+
if ((nextStatus === 'unauthorized' || nextStatus === 'forbidden') && !hasAuthFlowSupported) {
|
|
95
|
+
handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH), response, isMetadataRequest);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Handle any other errors
|
|
100
|
+
if (nextStatus === 'fatal') {
|
|
101
|
+
handleResolvedLinkError(resourceUrl, new APIError('fatal', hostname, ERROR_MESSAGE_FATAL), undefined, isMetadataRequest);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Handle errors of any other kind in the metadata request response
|
|
106
|
+
if (isMetadataRequest && nextStatus !== 'resolved') {
|
|
107
|
+
handleResolvedLinkError(resourceUrl, new APIError('error', hostname, ERROR_MESSAGE_METADATA), response, isMetadataRequest);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Using unstable_batchedUpdates because this store update happens async and triggers a rerender
|
|
113
|
+
* more info:
|
|
114
|
+
* https://github.com/facebook/react/blob/v18.2.0/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L113
|
|
115
|
+
* https://react-redux.js.org/api/batch
|
|
116
|
+
*/
|
|
117
|
+
unstable_batchedUpdates(() => {
|
|
118
|
+
handleResolvedLinkSuccess(resourceUrl, response, isReloading, isMetadataRequest);
|
|
119
|
+
});
|
|
120
|
+
}, [handleResolvedLinkError, handleResolvedLinkSuccess, hasAuthFlowSupported]);
|
|
121
|
+
return useMemo(() => ({
|
|
122
|
+
handleResolvedLinkError,
|
|
123
|
+
handleResolvedLinkResponse
|
|
124
|
+
}), [handleResolvedLinkError, handleResolvedLinkResponse]);
|
|
125
|
+
};
|
|
126
|
+
export default useResponse;
|
|
@@ -4,7 +4,7 @@ export const ANALYTICS_CHANNEL = 'media';
|
|
|
4
4
|
export const context = {
|
|
5
5
|
componentName: 'smart-cards',
|
|
6
6
|
packageName: "@atlaskit/smart-card",
|
|
7
|
-
packageVersion: "27.4.
|
|
7
|
+
packageVersion: "27.4.2"
|
|
8
8
|
};
|
|
9
9
|
export let TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
|
|
10
10
|
TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
|
|
@@ -40,7 +40,7 @@ export const AutomationModal = ({
|
|
|
40
40
|
emptyStateDescription: emptyStateDescription,
|
|
41
41
|
emptyStateAdminDescription: emptyStateAdminDescription,
|
|
42
42
|
onRuleInvocationSuccess: onClose,
|
|
43
|
-
|
|
43
|
+
onRuleInvocationFailure: () => setSelectedRule(undefined)
|
|
44
44
|
}, () => {
|
|
45
45
|
return /*#__PURE__*/React.createElement(Modal, {
|
|
46
46
|
onClose: onClose,
|
|
@@ -7,6 +7,7 @@ import { useFlexibleUiContext } from '../../../../../state/flexible-ui-context';
|
|
|
7
7
|
import { useSmartLinkModal } from '../../../../../state/modal';
|
|
8
8
|
import { ActionName } from '../../../../../constants';
|
|
9
9
|
import { messages } from '../../../../../messages';
|
|
10
|
+
import { getModalContent } from './utils';
|
|
10
11
|
const AutomationModal = /*#__PURE__*/lazy(() => import( /* webpackChunkName: "@atlaskit-internal_smart-card-automation-modal" */'./automation-manual-triggers/manual-triggers-modal'));
|
|
11
12
|
const AutomationAction = props => {
|
|
12
13
|
var _context$actions;
|
|
@@ -14,27 +15,34 @@ const AutomationAction = props => {
|
|
|
14
15
|
formatMessage
|
|
15
16
|
} = useIntl();
|
|
16
17
|
const modal = useSmartLinkModal();
|
|
18
|
+
const {
|
|
19
|
+
onClick: onClickCallback
|
|
20
|
+
} = props;
|
|
17
21
|
const context = useFlexibleUiContext();
|
|
18
22
|
const automationActionData = context === null || context === void 0 ? void 0 : (_context$actions = context.actions) === null || _context$actions === void 0 ? void 0 : _context$actions[ActionName.AutomationAction];
|
|
19
23
|
const automationActionOnClick = useCallback(automationActionData => {
|
|
20
24
|
const {
|
|
25
|
+
product,
|
|
26
|
+
resourceType,
|
|
21
27
|
baseAutomationUrl,
|
|
22
28
|
objectAri,
|
|
23
29
|
siteAri,
|
|
24
30
|
canManageAutomation,
|
|
25
31
|
analyticsSource,
|
|
26
|
-
modalTitle,
|
|
27
|
-
modalDescription,
|
|
28
32
|
objectName
|
|
29
33
|
} = automationActionData;
|
|
30
|
-
const
|
|
31
|
-
|
|
34
|
+
const {
|
|
35
|
+
modalTitle,
|
|
36
|
+
modalDescription
|
|
37
|
+
} = getModalContent(product, resourceType) || {};
|
|
38
|
+
const automationModalTitle = modalTitle ? /*#__PURE__*/React.createElement(FormattedMessage, modalTitle) : undefined;
|
|
39
|
+
const automationModalDescription = modalDescription ? /*#__PURE__*/React.createElement(FormattedMessage, _extends({}, modalDescription, {
|
|
32
40
|
values: {
|
|
33
41
|
name: objectName,
|
|
34
42
|
b: chunks => /*#__PURE__*/React.createElement("strong", null, chunks),
|
|
35
43
|
br: /*#__PURE__*/React.createElement("br", null)
|
|
36
44
|
}
|
|
37
|
-
}));
|
|
45
|
+
})) : undefined;
|
|
38
46
|
modal.open( /*#__PURE__*/React.createElement(AutomationModal, {
|
|
39
47
|
baseAutomationUrl: baseAutomationUrl,
|
|
40
48
|
objectAri: objectAri,
|
|
@@ -45,7 +53,8 @@ const AutomationAction = props => {
|
|
|
45
53
|
modalDescription: automationModalDescription,
|
|
46
54
|
onClose: () => modal.close()
|
|
47
55
|
}));
|
|
48
|
-
|
|
56
|
+
onClickCallback === null || onClickCallback === void 0 ? void 0 : onClickCallback();
|
|
57
|
+
}, [modal, onClickCallback]);
|
|
49
58
|
if (!automationActionData) {
|
|
50
59
|
return null;
|
|
51
60
|
}
|
|
@@ -59,7 +68,7 @@ const AutomationAction = props => {
|
|
|
59
68
|
}),
|
|
60
69
|
testId: "smart-action-automation-action",
|
|
61
70
|
tooltipMessage: automationActionTooltip
|
|
62
|
-
},
|
|
71
|
+
}, props, {
|
|
63
72
|
onClick: () => automationActionOnClick(automationActionData)
|
|
64
73
|
})));
|
|
65
74
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { messages } from '../../../../../../messages';
|
|
2
|
+
export const getModalContent = (product, resourceType) => {
|
|
3
|
+
var _modalContentMap$prod;
|
|
4
|
+
const modalContentMap = {
|
|
5
|
+
'confluence': {
|
|
6
|
+
'page': {
|
|
7
|
+
modalTitle: messages.automation_action_confluence_page_modal_title,
|
|
8
|
+
modalDescription: messages.automation_action_confluence_page_modal_description
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
return modalContentMap === null || modalContentMap === void 0 ? void 0 : (_modalContentMap$prod = modalContentMap[product]) === null || _modalContentMap$prod === void 0 ? void 0 : _modalContentMap$prod[resourceType];
|
|
13
|
+
};
|
|
@@ -7,7 +7,7 @@ import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-m
|
|
|
7
7
|
import LinkWarningModal from './LinkWarningModal';
|
|
8
8
|
const PACKAGE_DATA = {
|
|
9
9
|
packageName: "@atlaskit/smart-card",
|
|
10
|
-
packageVersion: "27.4.
|
|
10
|
+
packageVersion: "27.4.2",
|
|
11
11
|
componentName: 'linkUrl'
|
|
12
12
|
};
|
|
13
13
|
const Link = withLinkClickedEvent('a');
|
|
@@ -1,46 +1,29 @@
|
|
|
1
|
-
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
-
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
1
|
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
|
|
5
|
-
import {
|
|
6
|
-
// This action will not be enabled by default for smart cards, which is opposite of the default behavior for actions.
|
|
7
|
-
// The AutomationAction will only appear if product/resourceType combination is handled by this function.
|
|
8
|
-
var getProductData = function getProductData(meta) {
|
|
9
|
-
var _ProductData$product;
|
|
10
|
-
var tenantId = meta.tenantId;
|
|
11
|
-
var product = meta.product;
|
|
12
|
-
var resourceType = meta.resourceType;
|
|
13
|
-
var ProductData = {
|
|
14
|
-
'confluence': {
|
|
15
|
-
'page': {
|
|
16
|
-
//TODO extract to server
|
|
17
|
-
siteAri: "ari:cloud:confluence::site/".concat(tenantId),
|
|
18
|
-
//TODO Move to AutomationAction
|
|
19
|
-
modalTitle: messages.automation_action_confluence_page_modal_title,
|
|
20
|
-
modalDescription: messages.automation_action_confluence_page_modal_description
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
return ProductData === null || ProductData === void 0 || (_ProductData$product = ProductData[product]) === null || _ProductData$product === void 0 ? void 0 : _ProductData$product[resourceType];
|
|
25
|
-
};
|
|
2
|
+
import { ActionName } from '../../../constants';
|
|
26
3
|
export var extractAutomationAction = function extractAutomationAction(response) {
|
|
4
|
+
var _response$meta;
|
|
27
5
|
if (!getBooleanFF('platform.linking-platfom.smart-card.confluence.page.automation-action_xcdoi') || !response.data) {
|
|
28
6
|
return undefined;
|
|
29
7
|
}
|
|
8
|
+
if (!(response !== null && response !== void 0 && (_response$meta = response.meta) !== null && _response$meta !== void 0 && (_response$meta = _response$meta.supportedFeature) !== null && _response$meta !== void 0 && _response$meta.includes(ActionName.AutomationAction))) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
30
11
|
var data = response.data;
|
|
31
12
|
var meta = response.meta;
|
|
32
13
|
var name = data.name,
|
|
33
14
|
objectAri = data["atlassian:ari"];
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
15
|
+
var product = meta.product,
|
|
16
|
+
tenantId = meta.tenantId,
|
|
17
|
+
resourceType = meta.resourceType;
|
|
18
|
+
return {
|
|
19
|
+
product: product,
|
|
20
|
+
resourceType: resourceType,
|
|
21
|
+
siteAri: "ari:cloud:".concat(product, "::site/").concat(tenantId),
|
|
39
22
|
objectName: name,
|
|
40
23
|
objectAri: objectAri,
|
|
41
24
|
// TODO: The admin experience will be a follow up
|
|
42
25
|
canManageAutomation: false,
|
|
43
26
|
baseAutomationUrl: '',
|
|
44
27
|
analyticsSource: 'smartCard'
|
|
45
|
-
}
|
|
28
|
+
};
|
|
46
29
|
};
|
|
@@ -1,133 +1,28 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
2
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
|
-
import { unstable_batchedUpdates } from 'react-dom';
|
|
5
4
|
import { addMetadataToExperience } from '../../analytics';
|
|
6
|
-
import { ACTION_ERROR, ACTION_ERROR_FALLBACK, ACTION_RELOADING, ACTION_RESOLVED, ACTION_UPDATE_METADATA_STATUS, APIError, cardAction, getStatus } from '@atlaskit/linking-common';
|
|
7
|
-
import { ERROR_MESSAGE_FATAL, ERROR_MESSAGE_METADATA, ERROR_MESSAGE_OAUTH } from '../../actions/constants';
|
|
8
|
-
import { getUnauthorizedJsonLd } from '../../../utils/jsonld';
|
|
9
5
|
import { SmartLinkStatus } from '../../../constants';
|
|
10
6
|
import { useSmartLinkContext } from '@atlaskit/link-provider';
|
|
7
|
+
import useResponse from '../use-response';
|
|
11
8
|
var useResolve = function useResolve() {
|
|
12
9
|
// Request JSON-LD data for the card from ORS, if it has extended
|
|
13
10
|
// its cache lifespan OR there is no data for it currently. Once the data
|
|
14
|
-
// has come back asynchronously,
|
|
11
|
+
// has come back asynchronously, call the useResponse callback to
|
|
12
|
+
// dispatch the resolved action for the card.
|
|
15
13
|
var _useSmartLinkContext = useSmartLinkContext(),
|
|
16
14
|
store = _useSmartLinkContext.store,
|
|
17
|
-
connections = _useSmartLinkContext.connections
|
|
18
|
-
|
|
19
|
-
var
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
var setMetadataStatus = useCallback(function (url, metadataStatus) {
|
|
23
|
-
dispatch(cardAction(ACTION_UPDATE_METADATA_STATUS, {
|
|
24
|
-
url: url
|
|
25
|
-
}, undefined, undefined, metadataStatus));
|
|
26
|
-
}, [dispatch]);
|
|
27
|
-
var handleResolvedLinkError = useCallback(function (url, error, response, isMetadataRequest) {
|
|
28
|
-
var _ref = getState()[url] || {
|
|
29
|
-
status: SmartLinkStatus.Pending,
|
|
30
|
-
details: undefined
|
|
31
|
-
},
|
|
32
|
-
details = _ref.details;
|
|
33
|
-
var hasData = !!(details && details.data);
|
|
34
|
-
|
|
35
|
-
// If metadata request then set metadata status, return and do not alter link status
|
|
36
|
-
if (isMetadataRequest) {
|
|
37
|
-
setMetadataStatus(url, 'errored');
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (error.kind === 'fatal') {
|
|
41
|
-
// If there's no previous data in the store for this URL, then bail
|
|
42
|
-
// out and let the editor handle fallbacks (returns to a blue link).
|
|
43
|
-
if (!hasData && status !== 'resolved') {
|
|
44
|
-
dispatch(cardAction(ACTION_ERROR, {
|
|
45
|
-
url: url
|
|
46
|
-
}, details, error));
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
// If we already have resolved data for this URL in the store, then
|
|
50
|
-
// simply fallback to the previous data.
|
|
51
|
-
if (hasData) {
|
|
52
|
-
dispatch(cardAction(ACTION_RESOLVED, {
|
|
53
|
-
url: url
|
|
54
|
-
}, details));
|
|
55
|
-
}
|
|
56
|
-
// Handle AuthErrors (user did not have access to resource) -
|
|
57
|
-
// Missing AAID in ASAP claims, or missing UserContext, or 403 from downstream
|
|
58
|
-
} else if (error.kind === 'auth') {
|
|
59
|
-
dispatch(cardAction(ACTION_RESOLVED, {
|
|
60
|
-
url: url
|
|
61
|
-
}, getUnauthorizedJsonLd()));
|
|
62
|
-
} else {
|
|
63
|
-
if (error.kind === 'fallback') {
|
|
64
|
-
// Fallback to blue link with smart link formatting. Not part of reliability.
|
|
65
|
-
dispatch(cardAction(ACTION_ERROR_FALLBACK, {
|
|
66
|
-
url: url
|
|
67
|
-
}, response, error));
|
|
68
|
-
} else {
|
|
69
|
-
// Fallback to blue link with smart link formatting. Part of reliability.
|
|
70
|
-
dispatch(cardAction(ACTION_ERROR, {
|
|
71
|
-
url: url
|
|
72
|
-
}, undefined, error));
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}, [getState, setMetadataStatus, dispatch]);
|
|
76
|
-
var handleResolvedLinkSuccess = useCallback(function (resourceUrl, response, isReloading, isMetadataRequest) {
|
|
77
|
-
//if a link resolves normally, metadata will also always be resolved
|
|
78
|
-
setMetadataStatus(resourceUrl, 'resolved');
|
|
79
|
-
// Dispatch Analytics and resolved card action - including unauthorized states.
|
|
80
|
-
if (isReloading) {
|
|
81
|
-
dispatch(cardAction(ACTION_RELOADING, {
|
|
82
|
-
url: resourceUrl
|
|
83
|
-
}, response));
|
|
84
|
-
} else {
|
|
85
|
-
dispatch(cardAction(ACTION_RESOLVED, {
|
|
86
|
-
url: resourceUrl
|
|
87
|
-
}, response, undefined, undefined, isMetadataRequest));
|
|
88
|
-
}
|
|
89
|
-
}, [setMetadataStatus, dispatch]);
|
|
90
|
-
var handleResolvedLinkResponse = useCallback(function (resourceUrl, response) {
|
|
91
|
-
var isReloading = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
92
|
-
var isMetadataRequest = arguments.length > 3 ? arguments[3] : undefined;
|
|
93
|
-
var hostname = new URL(resourceUrl).hostname;
|
|
94
|
-
var nextStatus = response ? getStatus(response) : 'fatal';
|
|
95
|
-
|
|
96
|
-
// If we require authorization & do not have an authFlow available,
|
|
97
|
-
// throw an error and render as a normal blue link.
|
|
98
|
-
if ((nextStatus === 'unauthorized' || nextStatus === 'forbidden') && !hasAuthFlowSupported) {
|
|
99
|
-
handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH), response, isMetadataRequest);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Handle any other errors
|
|
104
|
-
if (nextStatus === 'fatal') {
|
|
105
|
-
handleResolvedLinkError(resourceUrl, new APIError('fatal', hostname, ERROR_MESSAGE_FATAL), undefined, isMetadataRequest);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Handle errors of any other kind in the metadata request response
|
|
110
|
-
if (isMetadataRequest && nextStatus !== 'resolved') {
|
|
111
|
-
handleResolvedLinkError(resourceUrl, new APIError('error', hostname, ERROR_MESSAGE_METADATA), response, isMetadataRequest);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Using unstable_batchedUpdates because this store update happens async and trigers a rerender
|
|
117
|
-
* more info:
|
|
118
|
-
* https://github.com/facebook/react/blob/v18.2.0/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L113
|
|
119
|
-
* https://react-redux.js.org/api/batch
|
|
120
|
-
*/
|
|
121
|
-
unstable_batchedUpdates(function () {
|
|
122
|
-
handleResolvedLinkSuccess(resourceUrl, response, isReloading, isMetadataRequest);
|
|
123
|
-
});
|
|
124
|
-
}, [handleResolvedLinkError, handleResolvedLinkSuccess, hasAuthFlowSupported]);
|
|
15
|
+
connections = _useSmartLinkContext.connections;
|
|
16
|
+
var getState = store.getState;
|
|
17
|
+
var _useResponse = useResponse(),
|
|
18
|
+
handleResolvedLinkResponse = _useResponse.handleResolvedLinkResponse,
|
|
19
|
+
handleResolvedLinkError = _useResponse.handleResolvedLinkError;
|
|
125
20
|
return useCallback( /*#__PURE__*/function () {
|
|
126
|
-
var
|
|
21
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url) {
|
|
127
22
|
var isReloading,
|
|
128
23
|
isMetadataRequest,
|
|
129
24
|
id,
|
|
130
|
-
|
|
25
|
+
_ref2,
|
|
131
26
|
details,
|
|
132
27
|
hasData,
|
|
133
28
|
_args = arguments;
|
|
@@ -137,10 +32,10 @@ var useResolve = function useResolve() {
|
|
|
137
32
|
isReloading = _args.length > 1 && _args[1] !== undefined ? _args[1] : false;
|
|
138
33
|
isMetadataRequest = _args.length > 2 && _args[2] !== undefined ? _args[2] : false;
|
|
139
34
|
id = _args.length > 3 && _args[3] !== undefined ? _args[3] : '';
|
|
140
|
-
|
|
35
|
+
_ref2 = getState()[url] || {
|
|
141
36
|
status: SmartLinkStatus.Pending,
|
|
142
37
|
details: undefined
|
|
143
|
-
}, details =
|
|
38
|
+
}, details = _ref2.details;
|
|
144
39
|
hasData = !!(details && details.data);
|
|
145
40
|
if (!(isReloading || !hasData || isMetadataRequest)) {
|
|
146
41
|
_context.next = 9;
|
|
@@ -162,7 +57,7 @@ var useResolve = function useResolve() {
|
|
|
162
57
|
}, _callee);
|
|
163
58
|
}));
|
|
164
59
|
return function (_x) {
|
|
165
|
-
return
|
|
60
|
+
return _ref.apply(this, arguments);
|
|
166
61
|
};
|
|
167
62
|
}(), [connections.client, getState, handleResolvedLinkError, handleResolvedLinkResponse]);
|
|
168
63
|
};
|