@atlaskit/smart-card 41.0.2 → 41.0.4
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 +18 -0
- package/dist/cjs/state/hooks/use-resolve-hyperlink/index.js +72 -0
- package/dist/cjs/state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator.js +36 -0
- package/dist/cjs/utils/analytics/analytics.js +1 -1
- package/dist/cjs/view/EmbedModal/components/link-info/index.js +3 -1
- package/dist/cjs/view/LinkUrl/Hyperlink/index.js +32 -0
- package/dist/cjs/view/LinkUrl/HyperlinkResolver/error-boundary.js +1 -0
- package/dist/cjs/view/LinkUrl/HyperlinkResolver/index.js +75 -18
- package/dist/cjs/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.js +2 -1
- package/dist/cjs/view/LinkUrl/HyperlinkResolver/unauthorize-view.js +34 -0
- package/dist/cjs/view/LinkUrl/index.js +33 -4
- package/dist/cjs/view/RelatedLinksModal/components/RelatedLinksBaseModal.js +3 -7
- package/dist/cjs/view/common/intl-provider/index.js +21 -0
- package/dist/es2019/state/hooks/use-resolve-hyperlink/index.js +60 -0
- package/dist/es2019/state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator.js +28 -0
- package/dist/es2019/utils/analytics/analytics.js +1 -1
- package/dist/es2019/view/EmbedModal/components/link-info/index.js +5 -2
- package/dist/es2019/view/LinkUrl/Hyperlink/index.js +23 -0
- package/dist/es2019/view/LinkUrl/HyperlinkResolver/error-boundary.js +1 -0
- package/dist/es2019/view/LinkUrl/HyperlinkResolver/index.js +64 -14
- package/dist/es2019/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.js +3 -1
- package/dist/es2019/view/LinkUrl/HyperlinkResolver/unauthorize-view.js +22 -0
- package/dist/es2019/view/LinkUrl/index.js +31 -4
- package/dist/es2019/view/RelatedLinksModal/components/RelatedLinksBaseModal.js +3 -7
- package/dist/es2019/view/common/intl-provider/index.js +13 -0
- package/dist/esm/state/hooks/use-resolve-hyperlink/index.js +63 -0
- package/dist/esm/state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator.js +29 -0
- package/dist/esm/utils/analytics/analytics.js +1 -1
- package/dist/esm/view/EmbedModal/components/link-info/index.js +4 -2
- package/dist/esm/view/LinkUrl/Hyperlink/index.js +25 -0
- package/dist/esm/view/LinkUrl/HyperlinkResolver/error-boundary.js +1 -0
- package/dist/esm/view/LinkUrl/HyperlinkResolver/index.js +73 -16
- package/dist/esm/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.js +3 -1
- package/dist/esm/view/LinkUrl/HyperlinkResolver/unauthorize-view.js +25 -0
- package/dist/esm/view/LinkUrl/index.js +31 -4
- package/dist/esm/view/RelatedLinksModal/components/RelatedLinksBaseModal.js +3 -7
- package/dist/esm/view/common/intl-provider/index.js +15 -0
- package/dist/types/state/hooks/use-resolve-hyperlink/index.d.ts +13 -0
- package/dist/types/state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator.d.ts +4 -0
- package/dist/types/view/LinkUrl/Hyperlink/index.d.ts +8 -0
- package/dist/types/view/LinkUrl/HyperlinkResolver/index.d.ts +2 -0
- package/dist/types/view/LinkUrl/HyperlinkResolver/unauthorize-view.d.ts +9 -0
- package/dist/types/view/common/intl-provider/index.d.ts +7 -0
- package/dist/types-ts4.5/state/hooks/use-resolve-hyperlink/index.d.ts +13 -0
- package/dist/types-ts4.5/state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator.d.ts +4 -0
- package/dist/types-ts4.5/view/LinkUrl/Hyperlink/index.d.ts +8 -0
- package/dist/types-ts4.5/view/LinkUrl/HyperlinkResolver/index.d.ts +2 -0
- package/dist/types-ts4.5/view/LinkUrl/HyperlinkResolver/unauthorize-view.d.ts +9 -0
- package/dist/types-ts4.5/view/common/intl-provider/index.d.ts +7 -0
- package/package.json +12 -17
- /package/dist/cjs/{view/LinkUrl/HyperlinkResolver/hooks → state/hooks/use-resolve-hyperlink}/useScheduledRegister.js +0 -0
- /package/dist/es2019/{view/LinkUrl/HyperlinkResolver/hooks → state/hooks/use-resolve-hyperlink}/useScheduledRegister.js +0 -0
- /package/dist/esm/{view/LinkUrl/HyperlinkResolver/hooks → state/hooks/use-resolve-hyperlink}/useScheduledRegister.js +0 -0
- /package/dist/types/{view/LinkUrl/HyperlinkResolver/hooks → state/hooks/use-resolve-hyperlink}/useScheduledRegister.d.ts +0 -0
- /package/dist/types-ts4.5/{view/LinkUrl/HyperlinkResolver/hooks → state/hooks/use-resolve-hyperlink}/useScheduledRegister.d.ts +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import AKLink from '@atlaskit/link';
|
|
4
|
+
import { withLinkClickedEvent } from '../../../utils/analytics/click';
|
|
5
|
+
const Anchor = withLinkClickedEvent('a');
|
|
6
|
+
export const LinkComponent = withLinkClickedEvent(AKLink);
|
|
7
|
+
const Hyperlink = ({
|
|
8
|
+
href,
|
|
9
|
+
children,
|
|
10
|
+
testId,
|
|
11
|
+
isLinkComponent = false,
|
|
12
|
+
...props
|
|
13
|
+
}) => {
|
|
14
|
+
const Link = isLinkComponent ? LinkComponent : Anchor;
|
|
15
|
+
return /*#__PURE__*/React.createElement(Link, _extends({}, isLinkComponent ? {
|
|
16
|
+
testId
|
|
17
|
+
} : {
|
|
18
|
+
'data-testid': testId
|
|
19
|
+
}, {
|
|
20
|
+
href: href || ''
|
|
21
|
+
}, props), children);
|
|
22
|
+
};
|
|
23
|
+
export default Hyperlink;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
3
|
+
// Remove on navx-1834-refactor-resolved-hyperlink cleanup
|
|
3
4
|
const withErrorBoundary = Component => props => {
|
|
4
5
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
5
6
|
fallback: null
|
|
@@ -1,24 +1,74 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { useCallback, useContext } from 'react';
|
|
3
|
+
import { withErrorBoundary as withReactErrorBoundary } from 'react-error-boundary';
|
|
4
|
+
import { injectIntl } from 'react-intl-next';
|
|
2
5
|
import FeatureGates from '@atlaskit/feature-gate-js-client';
|
|
6
|
+
import { extractSmartLinkProvider } from '@atlaskit/link-extractors';
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
8
|
import { SmartCardContext } from '../../../state';
|
|
9
|
+
import { getServices } from '../../../state/helpers';
|
|
10
|
+
import useResolveHyperlink from '../../../state/hooks/use-resolve-hyperlink';
|
|
11
|
+
import useResolveHyperlinkValidator, { isGoogleDomain, isSharePointDomain } from '../../../state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator';
|
|
12
|
+
import withIntlProvider from '../../common/intl-provider';
|
|
13
|
+
import Hyperlink from '../Hyperlink';
|
|
4
14
|
import withErrorBoundary from './error-boundary';
|
|
5
15
|
import { ResolveHyperlink } from './resolve-hyperlink';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
16
|
+
import HyperlinkUnauthorizedView from './unauthorize-view';
|
|
17
|
+
const HyperlinkFallbackComponent = () => null;
|
|
18
|
+
const withValidator = (Component, DefaultComponent) => props => {
|
|
19
|
+
const shouldResolveHyperlink = useResolveHyperlinkValidator(props === null || props === void 0 ? void 0 : props.href);
|
|
20
|
+
return shouldResolveHyperlink ? /*#__PURE__*/React.createElement(Component, props) : /*#__PURE__*/React.createElement(DefaultComponent, props);
|
|
13
21
|
};
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
const HyperlinkWithSmartLinkResolverInner = ({
|
|
23
|
+
onClick: onClickCallback,
|
|
24
|
+
...props
|
|
25
|
+
}) => {
|
|
26
|
+
const {
|
|
27
|
+
actions,
|
|
28
|
+
state
|
|
29
|
+
} = useResolveHyperlink({
|
|
30
|
+
href: props.href || ''
|
|
31
|
+
});
|
|
32
|
+
const services = getServices(state === null || state === void 0 ? void 0 : state.details);
|
|
33
|
+
const onClick = useCallback(e => {
|
|
34
|
+
// TODO: AI3W-1203: 3P link click analytics
|
|
35
|
+
|
|
36
|
+
onClickCallback === null || onClickCallback === void 0 ? void 0 : onClickCallback(e);
|
|
37
|
+
}, [onClickCallback]);
|
|
38
|
+
|
|
39
|
+
// TODO: AI3W-1113: Show auth button
|
|
40
|
+
const onAuthorize = fg('platform_linking_plain_hyperlink_connect_button') ?
|
|
41
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
42
|
+
useCallback(() =>
|
|
43
|
+
// TODO: Need to add hyperlink type
|
|
44
|
+
actions.authorize('inline'), [actions]) : undefined;
|
|
45
|
+
if (fg('platform_linking_plain_hyperlink_connect_button')) {
|
|
46
|
+
switch (state === null || state === void 0 ? void 0 : state.status) {
|
|
47
|
+
case 'unauthorized':
|
|
48
|
+
const provider = extractSmartLinkProvider(state === null || state === void 0 ? void 0 : state.details);
|
|
49
|
+
return /*#__PURE__*/React.createElement(HyperlinkUnauthorizedView, _extends({}, props, {
|
|
50
|
+
onAuthorize: services !== null && services !== void 0 && services.length ? onAuthorize : undefined,
|
|
51
|
+
onClick: onClick,
|
|
52
|
+
provider: provider
|
|
53
|
+
}));
|
|
54
|
+
default:
|
|
55
|
+
return /*#__PURE__*/React.createElement(Hyperlink, _extends({}, props, {
|
|
56
|
+
onClick: onClick
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
20
59
|
}
|
|
60
|
+
return /*#__PURE__*/React.createElement(Hyperlink, _extends({}, props, {
|
|
61
|
+
onClick: onClick
|
|
62
|
+
}));
|
|
21
63
|
};
|
|
64
|
+
export const HyperlinkWithSmartLinkResolver = withReactErrorBoundary(withValidator(injectIntl(withIntlProvider(HyperlinkWithSmartLinkResolverInner), {
|
|
65
|
+
enforceContext: false
|
|
66
|
+
}), Hyperlink), {
|
|
67
|
+
FallbackComponent: HyperlinkFallbackComponent
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Remove on navx-1834-refactor-resolved-hyperlink cleanup
|
|
71
|
+
|
|
22
72
|
const HyperlinkResolver = ({
|
|
23
73
|
href
|
|
24
74
|
}) => {
|
|
@@ -3,9 +3,11 @@ import uuid from 'uuid';
|
|
|
3
3
|
import { useAnalyticsEvents } from '../../../common/analytics/generated/use-analytics-events';
|
|
4
4
|
import { useSmartCardActions } from '../../../state/actions';
|
|
5
5
|
import { getDefinitionId, getExtensionKey, getResourceType } from '../../../state/helpers';
|
|
6
|
+
import { useScheduledRegister } from '../../../state/hooks/use-resolve-hyperlink/useScheduledRegister';
|
|
6
7
|
import { useSmartCardState } from '../../../state/store';
|
|
7
8
|
import * as measure from '../../../utils/performance';
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
// Remove on navx-1834-refactor-resolved-hyperlink cleanup
|
|
9
11
|
export const ResolveHyperlink = ({
|
|
10
12
|
href
|
|
11
13
|
}) => {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { useMemo } from 'react';
|
|
3
|
+
import { FormattedMessage } from 'react-intl-next';
|
|
4
|
+
import { messages } from '../../../messages';
|
|
5
|
+
import { ActionButton } from '../../InlineCard/common/action-button';
|
|
6
|
+
import Hyperlink from '../Hyperlink';
|
|
7
|
+
const HyperlinkUnauthorizedView = ({
|
|
8
|
+
onAuthorize,
|
|
9
|
+
provider,
|
|
10
|
+
...props
|
|
11
|
+
}) => {
|
|
12
|
+
const actionButton = useMemo(() => onAuthorize ? /*#__PURE__*/React.createElement(ActionButton, {
|
|
13
|
+
onClick: onAuthorize,
|
|
14
|
+
testId: "button-connect-account"
|
|
15
|
+
}, /*#__PURE__*/React.createElement(FormattedMessage, _extends({}, messages.connect_link_account_card_name, {
|
|
16
|
+
values: {
|
|
17
|
+
context: provider === null || provider === void 0 ? void 0 : provider.text
|
|
18
|
+
}
|
|
19
|
+
}))) : null, [onAuthorize, provider === null || provider === void 0 ? void 0 : provider.text]);
|
|
20
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Hyperlink, props), actionButton);
|
|
21
|
+
};
|
|
22
|
+
export default HyperlinkUnauthorizedView;
|
|
@@ -4,14 +4,16 @@ import { di } from 'react-magnetic-di';
|
|
|
4
4
|
import { withAnalyticsContext } from '@atlaskit/analytics-next';
|
|
5
5
|
import FeatureGates from '@atlaskit/feature-gate-js-client';
|
|
6
6
|
import AKLink from '@atlaskit/link';
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
8
|
import { withLinkClickedEvent } from '../../utils/analytics/click';
|
|
8
9
|
import { LinkAnalyticsContext } from '../../utils/analytics/LinkAnalyticsContext';
|
|
9
|
-
import
|
|
10
|
+
import Hyperlink from './Hyperlink';
|
|
11
|
+
import HyperlinkResolver, { HyperlinkWithSmartLinkResolver } from './HyperlinkResolver';
|
|
10
12
|
import LinkWarningModal from './LinkWarningModal';
|
|
11
13
|
import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
|
|
12
14
|
const PACKAGE_DATA = {
|
|
13
15
|
packageName: "@atlaskit/smart-card",
|
|
14
|
-
packageVersion: "41.0.
|
|
16
|
+
packageVersion: "41.0.3",
|
|
15
17
|
componentName: 'linkUrl'
|
|
16
18
|
};
|
|
17
19
|
const Anchor = withLinkClickedEvent('a');
|
|
@@ -31,8 +33,33 @@ const LinkUrl = ({
|
|
|
31
33
|
showSafetyWarningModal,
|
|
32
34
|
...linkWarningModalProps
|
|
33
35
|
} = useLinkWarningModal();
|
|
34
|
-
const Link = isLinkComponent ? LinkComponent : Anchor;
|
|
35
36
|
const resolveHyperlinkFG = FeatureGates.checkGate('platform_editor_resolve_hyperlinks_killswitch');
|
|
37
|
+
if (fg('navx-1834-refactor-resolved-hyperlink')) {
|
|
38
|
+
if (resolveHyperlinkFG) {
|
|
39
|
+
const Link = enableResolve ? HyperlinkWithSmartLinkResolver : Hyperlink;
|
|
40
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LinkAnalyticsContext, {
|
|
41
|
+
url: href,
|
|
42
|
+
display: "url"
|
|
43
|
+
}, /*#__PURE__*/React.createElement(Link, _extends({
|
|
44
|
+
href: href,
|
|
45
|
+
isLinkComponent: isLinkComponent,
|
|
46
|
+
onClick: e => {
|
|
47
|
+
if (!checkSafety) {
|
|
48
|
+
onClick && onClick(e);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Only call the onClick if the link is safe
|
|
53
|
+
if (isLinkSafe(e, href)) {
|
|
54
|
+
onClick && onClick(e);
|
|
55
|
+
} else {
|
|
56
|
+
showSafetyWarningModal(e, href);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const Link = isLinkComponent ? LinkComponent : Anchor;
|
|
36
63
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LinkAnalyticsContext, {
|
|
37
64
|
url: href,
|
|
38
65
|
display: "url"
|
|
@@ -55,7 +82,7 @@ const LinkUrl = ({
|
|
|
55
82
|
showSafetyWarningModal(e, href);
|
|
56
83
|
}
|
|
57
84
|
}
|
|
58
|
-
}, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps), enableResolve && href && resolveHyperlinkFG && /*#__PURE__*/React.createElement(HyperlinkResolver, {
|
|
85
|
+
}, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps), enableResolve && href && resolveHyperlinkFG && !fg('navx-1834-refactor-resolved-hyperlink') && /*#__PURE__*/React.createElement(HyperlinkResolver, {
|
|
59
86
|
href: href
|
|
60
87
|
}));
|
|
61
88
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* RelatedLinksBaseModal.tsx generated by @compiled/babel-plugin v0.36.1 */
|
|
2
|
-
import _extends from "@babel/runtime/helpers/extends";
|
|
3
2
|
import * as React from 'react';
|
|
4
3
|
import { ax, ix } from "@compiled/react/runtime";
|
|
5
4
|
import { useCallback, useRef } from 'react';
|
|
@@ -31,17 +30,14 @@ const RelatedLinksBaseModal = ({
|
|
|
31
30
|
});
|
|
32
31
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
33
32
|
}, [fireEvent, onClose]);
|
|
34
|
-
return /*#__PURE__*/React.createElement(ModalTransition, null, showModal && /*#__PURE__*/React.createElement(Modal,
|
|
33
|
+
return /*#__PURE__*/React.createElement(ModalTransition, null, showModal && /*#__PURE__*/React.createElement(Modal, {
|
|
35
34
|
testId: "related-links-modal",
|
|
36
35
|
onClose: closeHandler,
|
|
37
|
-
width: fixedWidth
|
|
38
|
-
}, fg('navx-1304-related-links-remove-false-autofocus') ? {} : {
|
|
39
|
-
autoFocus: false
|
|
40
|
-
}, {
|
|
36
|
+
width: fixedWidth,
|
|
41
37
|
shouldReturnFocus: false,
|
|
42
38
|
onOpenComplete: openCompleteHandler,
|
|
43
39
|
height: '504px'
|
|
44
|
-
}
|
|
40
|
+
}, /*#__PURE__*/React.createElement(ModalHeader, {
|
|
45
41
|
hasCloseButton: fg('navx-1483-a11y-close-button-in-modal-updates')
|
|
46
42
|
}, /*#__PURE__*/React.createElement(ModalTitle, null, /*#__PURE__*/React.createElement(FormattedMessage, messages.related_links_modal_title))), /*#__PURE__*/React.createElement(ModalBody, null, children), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
|
|
47
43
|
appearance: "primary",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IntlProvider } from 'react-intl-next';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HOC to wrap component with IntlProvider if not available
|
|
6
|
+
*/
|
|
7
|
+
const withIntlProvider = Component => props => {
|
|
8
|
+
const content = /*#__PURE__*/React.createElement(Component, props);
|
|
9
|
+
return props !== null && props !== void 0 && props.intl ? content : /*#__PURE__*/React.createElement(IntlProvider, {
|
|
10
|
+
locale: "en"
|
|
11
|
+
}, content);
|
|
12
|
+
};
|
|
13
|
+
export default withIntlProvider;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import uuid from 'uuid';
|
|
4
|
+
import { useAnalyticsEvents } from '../../../common/analytics/generated/use-analytics-events';
|
|
5
|
+
import * as measure from '../../../utils/performance';
|
|
6
|
+
import { useSmartCardActions } from '../../actions';
|
|
7
|
+
import { getDefinitionId, getExtensionKey, getResourceType } from '../../helpers';
|
|
8
|
+
import { useSmartCardState } from '../../store';
|
|
9
|
+
import { useScheduledRegister } from './useScheduledRegister';
|
|
10
|
+
var useResolveHyperlink = function useResolveHyperlink(_ref) {
|
|
11
|
+
var href = _ref.href;
|
|
12
|
+
var _useState = useState(function () {
|
|
13
|
+
return uuid();
|
|
14
|
+
}),
|
|
15
|
+
_useState2 = _slicedToArray(_useState, 1),
|
|
16
|
+
id = _useState2[0];
|
|
17
|
+
var state = useSmartCardState(href);
|
|
18
|
+
var definitionId = getDefinitionId(state.details);
|
|
19
|
+
var extensionKey = getExtensionKey(state.details);
|
|
20
|
+
var resourceType = getResourceType(state.details);
|
|
21
|
+
var actions = useSmartCardActions(id, href);
|
|
22
|
+
var scheduledRegister = useScheduledRegister(href, actions.register);
|
|
23
|
+
var _useAnalyticsEvents = useAnalyticsEvents(),
|
|
24
|
+
fireEvent = _useAnalyticsEvents.fireEvent;
|
|
25
|
+
useEffect(function () {
|
|
26
|
+
scheduledRegister().catch(function (error) {
|
|
27
|
+
throw error;
|
|
28
|
+
});
|
|
29
|
+
}, [scheduledRegister]);
|
|
30
|
+
useEffect(function () {
|
|
31
|
+
measure.mark(id, state.status);
|
|
32
|
+
if (state.status !== 'pending' && state.status !== 'resolving') {
|
|
33
|
+
var _state$error, _state$error2;
|
|
34
|
+
measure.create(id, state.status);
|
|
35
|
+
if (state.status === 'resolved') {
|
|
36
|
+
var _measure$getMeasure$d, _measure$getMeasure;
|
|
37
|
+
fireEvent('operational.hyperlink.resolved', {
|
|
38
|
+
definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null,
|
|
39
|
+
extensionKey: extensionKey !== null && extensionKey !== void 0 ? extensionKey : null,
|
|
40
|
+
resourceType: resourceType !== null && resourceType !== void 0 ? resourceType : null,
|
|
41
|
+
duration: (_measure$getMeasure$d = (_measure$getMeasure = measure.getMeasure(id, state.status)) === null || _measure$getMeasure === void 0 ? void 0 : _measure$getMeasure.duration) !== null && _measure$getMeasure$d !== void 0 ? _measure$getMeasure$d : null
|
|
42
|
+
});
|
|
43
|
+
} else if (((_state$error = state.error) === null || _state$error === void 0 ? void 0 : _state$error.type) !== 'ResolveUnsupportedError' && ((_state$error2 = state.error) === null || _state$error2 === void 0 ? void 0 : _state$error2.type) !== 'UnsupportedError') {
|
|
44
|
+
fireEvent('operational.hyperlink.unresolved', {
|
|
45
|
+
definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null,
|
|
46
|
+
extensionKey: extensionKey !== null && extensionKey !== void 0 ? extensionKey : null,
|
|
47
|
+
resourceType: resourceType !== null && resourceType !== void 0 ? resourceType : null,
|
|
48
|
+
reason: state.status,
|
|
49
|
+
error: state.error === undefined ? null : {
|
|
50
|
+
name: state.error.name,
|
|
51
|
+
kind: state.error.kind,
|
|
52
|
+
type: state.error.type
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}, [id, state.status, state.error, definitionId, extensionKey, resourceType, fireEvent]);
|
|
58
|
+
return {
|
|
59
|
+
state: state,
|
|
60
|
+
actions: actions
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export default useResolveHyperlink;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import FeatureGates from '@atlaskit/feature-gate-js-client';
|
|
3
|
+
import { SmartCardContext } from '@atlaskit/link-provider';
|
|
4
|
+
export var isSharePointDomain = function isSharePointDomain(href) {
|
|
5
|
+
try {
|
|
6
|
+
var hostname = new URL(href).hostname.toLowerCase();
|
|
7
|
+
return hostname.includes('sharepoint.com') || hostname.includes('onedrive.live.com');
|
|
8
|
+
} catch (_unused) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export var isGoogleDomain = function isGoogleDomain(href) {
|
|
13
|
+
try {
|
|
14
|
+
var hostname = new URL(href).hostname.toLowerCase();
|
|
15
|
+
return hostname.includes('docs.google.com') || hostname.includes('drive.google.com');
|
|
16
|
+
} catch (_unused2) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var useResolveHyperlinkValidator = function useResolveHyperlinkValidator() {
|
|
21
|
+
var href = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
22
|
+
var hasSmartCardProvider = !!useContext(SmartCardContext);
|
|
23
|
+
var isSharePointResolveEnabled = FeatureGates.getExperimentValue('platform_editor_resolve_hyperlinks_confluence', 'isEnabled', false) || FeatureGates.getExperimentValue('platform_editor_resolve_hyperlinks_jira', 'isEnabled', false);
|
|
24
|
+
var isGoogleResolveEnabled = FeatureGates.getExperimentValue('platform_editor_resolve_google_hyperlinks', 'isEnabled', false);
|
|
25
|
+
var shouldResolveSharePoint = isSharePointDomain(href) && isSharePointResolveEnabled;
|
|
26
|
+
var shouldResolveGoogle = isGoogleDomain(href) && isGoogleResolveEnabled;
|
|
27
|
+
return hasSmartCardProvider && (shouldResolveSharePoint || shouldResolveGoogle);
|
|
28
|
+
};
|
|
29
|
+
export default useResolveHyperlinkValidator;
|
|
@@ -4,7 +4,7 @@ export var ANALYTICS_CHANNEL = 'media';
|
|
|
4
4
|
export var context = {
|
|
5
5
|
componentName: 'smart-cards',
|
|
6
6
|
packageName: "@atlaskit/smart-card",
|
|
7
|
-
packageVersion: "41.0.
|
|
7
|
+
packageVersion: "41.0.3"
|
|
8
8
|
};
|
|
9
9
|
export var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
|
|
10
10
|
TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import "./index.compiled.css";
|
|
3
3
|
import { ax, ix } from "@compiled/react/runtime";
|
|
4
4
|
import React, { useMemo } from 'react';
|
|
5
|
-
import { FormattedMessage } from 'react-intl-next';
|
|
5
|
+
import { FormattedMessage, useIntl } from 'react-intl-next';
|
|
6
6
|
import Heading from '@atlaskit/heading';
|
|
7
7
|
import DownloadIcon from '@atlaskit/icon/core/download';
|
|
8
8
|
import FullscreenExitIcon from '@atlaskit/icon/core/fullscreen-exit';
|
|
@@ -38,6 +38,8 @@ var LinkInfo = function LinkInfo(_ref) {
|
|
|
38
38
|
title = _ref.title;
|
|
39
39
|
var _useModal = useModal(),
|
|
40
40
|
onClose = _useModal.onClose;
|
|
41
|
+
var _useIntl = useIntl(),
|
|
42
|
+
formatMessage = _useIntl.formatMessage;
|
|
41
43
|
var downloadButton = useMemo(function () {
|
|
42
44
|
if (onDownloadButtonClick) {
|
|
43
45
|
return /*#__PURE__*/React.createElement(LinkInfoButton, {
|
|
@@ -127,7 +129,7 @@ var LinkInfo = function LinkInfo(_ref) {
|
|
|
127
129
|
testId: "".concat(testId, "-close-tooltip")
|
|
128
130
|
}, /*#__PURE__*/React.createElement(CloseButton, {
|
|
129
131
|
onClick: onClose,
|
|
130
|
-
label: messages.preview_close
|
|
132
|
+
label: formatMessage(messages.preview_close),
|
|
131
133
|
testId: "".concat(testId, "-close-button")
|
|
132
134
|
})) : /*#__PURE__*/React.createElement(LinkInfoButton, {
|
|
133
135
|
content: /*#__PURE__*/React.createElement(FormattedMessage, messages.preview_close),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
3
|
+
var _excluded = ["href", "children", "testId", "isLinkComponent"];
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import AKLink from '@atlaskit/link';
|
|
6
|
+
import { withLinkClickedEvent } from '../../../utils/analytics/click';
|
|
7
|
+
var Anchor = withLinkClickedEvent('a');
|
|
8
|
+
export var LinkComponent = withLinkClickedEvent(AKLink);
|
|
9
|
+
var Hyperlink = function Hyperlink(_ref) {
|
|
10
|
+
var href = _ref.href,
|
|
11
|
+
children = _ref.children,
|
|
12
|
+
testId = _ref.testId,
|
|
13
|
+
_ref$isLinkComponent = _ref.isLinkComponent,
|
|
14
|
+
isLinkComponent = _ref$isLinkComponent === void 0 ? false : _ref$isLinkComponent,
|
|
15
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
16
|
+
var Link = isLinkComponent ? LinkComponent : Anchor;
|
|
17
|
+
return /*#__PURE__*/React.createElement(Link, _extends({}, isLinkComponent ? {
|
|
18
|
+
testId: testId
|
|
19
|
+
} : {
|
|
20
|
+
'data-testid': testId
|
|
21
|
+
}, {
|
|
22
|
+
href: href || ''
|
|
23
|
+
}, props), children);
|
|
24
|
+
};
|
|
25
|
+
export default Hyperlink;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
3
|
+
// Remove on navx-1834-refactor-resolved-hyperlink cleanup
|
|
3
4
|
var withErrorBoundary = function withErrorBoundary(Component) {
|
|
4
5
|
return function (props) {
|
|
5
6
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
@@ -1,26 +1,83 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
3
|
+
var _excluded = ["onClick"];
|
|
4
|
+
import React, { useCallback, useContext } from 'react';
|
|
5
|
+
import { withErrorBoundary as withReactErrorBoundary } from 'react-error-boundary';
|
|
6
|
+
import { injectIntl } from 'react-intl-next';
|
|
2
7
|
import FeatureGates from '@atlaskit/feature-gate-js-client';
|
|
8
|
+
import { extractSmartLinkProvider } from '@atlaskit/link-extractors';
|
|
9
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
10
|
import { SmartCardContext } from '../../../state';
|
|
11
|
+
import { getServices } from '../../../state/helpers';
|
|
12
|
+
import useResolveHyperlink from '../../../state/hooks/use-resolve-hyperlink';
|
|
13
|
+
import useResolveHyperlinkValidator, { isGoogleDomain, isSharePointDomain } from '../../../state/hooks/use-resolve-hyperlink/useResolveHyperlinkValidator';
|
|
14
|
+
import withIntlProvider from '../../common/intl-provider';
|
|
15
|
+
import Hyperlink from '../Hyperlink';
|
|
4
16
|
import withErrorBoundary from './error-boundary';
|
|
5
17
|
import { ResolveHyperlink } from './resolve-hyperlink';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
import HyperlinkUnauthorizedView from './unauthorize-view';
|
|
19
|
+
var HyperlinkFallbackComponent = function HyperlinkFallbackComponent() {
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
var withValidator = function withValidator(Component, DefaultComponent) {
|
|
23
|
+
return function (props) {
|
|
24
|
+
var shouldResolveHyperlink = useResolveHyperlinkValidator(props === null || props === void 0 ? void 0 : props.href);
|
|
25
|
+
return shouldResolveHyperlink ? /*#__PURE__*/React.createElement(Component, props) : /*#__PURE__*/React.createElement(DefaultComponent, props);
|
|
26
|
+
};
|
|
13
27
|
};
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
var HyperlinkWithSmartLinkResolverInner = function HyperlinkWithSmartLinkResolverInner(_ref) {
|
|
29
|
+
var onClickCallback = _ref.onClick,
|
|
30
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
31
|
+
var _useResolveHyperlink = useResolveHyperlink({
|
|
32
|
+
href: props.href || ''
|
|
33
|
+
}),
|
|
34
|
+
actions = _useResolveHyperlink.actions,
|
|
35
|
+
state = _useResolveHyperlink.state;
|
|
36
|
+
var services = getServices(state === null || state === void 0 ? void 0 : state.details);
|
|
37
|
+
var onClick = useCallback(function (e) {
|
|
38
|
+
// TODO: AI3W-1203: 3P link click analytics
|
|
39
|
+
|
|
40
|
+
onClickCallback === null || onClickCallback === void 0 || onClickCallback(e);
|
|
41
|
+
}, [onClickCallback]);
|
|
42
|
+
|
|
43
|
+
// TODO: AI3W-1113: Show auth button
|
|
44
|
+
var onAuthorize = fg('platform_linking_plain_hyperlink_connect_button') ?
|
|
45
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
46
|
+
useCallback(function () {
|
|
47
|
+
return (
|
|
48
|
+
// TODO: Need to add hyperlink type
|
|
49
|
+
actions.authorize('inline')
|
|
50
|
+
);
|
|
51
|
+
}, [actions]) : undefined;
|
|
52
|
+
if (fg('platform_linking_plain_hyperlink_connect_button')) {
|
|
53
|
+
switch (state === null || state === void 0 ? void 0 : state.status) {
|
|
54
|
+
case 'unauthorized':
|
|
55
|
+
var provider = extractSmartLinkProvider(state === null || state === void 0 ? void 0 : state.details);
|
|
56
|
+
return /*#__PURE__*/React.createElement(HyperlinkUnauthorizedView, _extends({}, props, {
|
|
57
|
+
onAuthorize: services !== null && services !== void 0 && services.length ? onAuthorize : undefined,
|
|
58
|
+
onClick: onClick,
|
|
59
|
+
provider: provider
|
|
60
|
+
}));
|
|
61
|
+
default:
|
|
62
|
+
return /*#__PURE__*/React.createElement(Hyperlink, _extends({}, props, {
|
|
63
|
+
onClick: onClick
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
20
66
|
}
|
|
67
|
+
return /*#__PURE__*/React.createElement(Hyperlink, _extends({}, props, {
|
|
68
|
+
onClick: onClick
|
|
69
|
+
}));
|
|
21
70
|
};
|
|
22
|
-
var
|
|
23
|
-
|
|
71
|
+
export var HyperlinkWithSmartLinkResolver = withReactErrorBoundary(withValidator(injectIntl(withIntlProvider(HyperlinkWithSmartLinkResolverInner), {
|
|
72
|
+
enforceContext: false
|
|
73
|
+
}), Hyperlink), {
|
|
74
|
+
FallbackComponent: HyperlinkFallbackComponent
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Remove on navx-1834-refactor-resolved-hyperlink cleanup
|
|
78
|
+
|
|
79
|
+
var HyperlinkResolver = function HyperlinkResolver(_ref2) {
|
|
80
|
+
var href = _ref2.href;
|
|
24
81
|
var hasSmartCardProvider = !!useContext(SmartCardContext);
|
|
25
82
|
var isSharePointResolveEnabled = FeatureGates.getExperimentValue('platform_editor_resolve_hyperlinks_confluence', 'isEnabled', false) || FeatureGates.getExperimentValue('platform_editor_resolve_hyperlinks_jira', 'isEnabled', false);
|
|
26
83
|
var isGoogleResolveEnabled = FeatureGates.getExperimentValue('platform_editor_resolve_google_hyperlinks', 'isEnabled', false);
|
|
@@ -4,9 +4,11 @@ import uuid from 'uuid';
|
|
|
4
4
|
import { useAnalyticsEvents } from '../../../common/analytics/generated/use-analytics-events';
|
|
5
5
|
import { useSmartCardActions } from '../../../state/actions';
|
|
6
6
|
import { getDefinitionId, getExtensionKey, getResourceType } from '../../../state/helpers';
|
|
7
|
+
import { useScheduledRegister } from '../../../state/hooks/use-resolve-hyperlink/useScheduledRegister';
|
|
7
8
|
import { useSmartCardState } from '../../../state/store';
|
|
8
9
|
import * as measure from '../../../utils/performance';
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
// Remove on navx-1834-refactor-resolved-hyperlink cleanup
|
|
10
12
|
export var ResolveHyperlink = function ResolveHyperlink(_ref) {
|
|
11
13
|
var href = _ref.href;
|
|
12
14
|
var _useState = useState(function () {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
3
|
+
var _excluded = ["onAuthorize", "provider"];
|
|
4
|
+
import React, { useMemo } from 'react';
|
|
5
|
+
import { FormattedMessage } from 'react-intl-next';
|
|
6
|
+
import { messages } from '../../../messages';
|
|
7
|
+
import { ActionButton } from '../../InlineCard/common/action-button';
|
|
8
|
+
import Hyperlink from '../Hyperlink';
|
|
9
|
+
var HyperlinkUnauthorizedView = function HyperlinkUnauthorizedView(_ref) {
|
|
10
|
+
var onAuthorize = _ref.onAuthorize,
|
|
11
|
+
provider = _ref.provider,
|
|
12
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
13
|
+
var actionButton = useMemo(function () {
|
|
14
|
+
return onAuthorize ? /*#__PURE__*/React.createElement(ActionButton, {
|
|
15
|
+
onClick: onAuthorize,
|
|
16
|
+
testId: "button-connect-account"
|
|
17
|
+
}, /*#__PURE__*/React.createElement(FormattedMessage, _extends({}, messages.connect_link_account_card_name, {
|
|
18
|
+
values: {
|
|
19
|
+
context: provider === null || provider === void 0 ? void 0 : provider.text
|
|
20
|
+
}
|
|
21
|
+
}))) : null;
|
|
22
|
+
}, [onAuthorize, provider === null || provider === void 0 ? void 0 : provider.text]);
|
|
23
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Hyperlink, props), actionButton);
|
|
24
|
+
};
|
|
25
|
+
export default HyperlinkUnauthorizedView;
|
|
@@ -7,14 +7,16 @@ import { di } from 'react-magnetic-di';
|
|
|
7
7
|
import { withAnalyticsContext } from '@atlaskit/analytics-next';
|
|
8
8
|
import FeatureGates from '@atlaskit/feature-gate-js-client';
|
|
9
9
|
import AKLink from '@atlaskit/link';
|
|
10
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
11
|
import { withLinkClickedEvent } from '../../utils/analytics/click';
|
|
11
12
|
import { LinkAnalyticsContext } from '../../utils/analytics/LinkAnalyticsContext';
|
|
12
|
-
import
|
|
13
|
+
import Hyperlink from './Hyperlink';
|
|
14
|
+
import HyperlinkResolver, { HyperlinkWithSmartLinkResolver } from './HyperlinkResolver';
|
|
13
15
|
import LinkWarningModal from './LinkWarningModal';
|
|
14
16
|
import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
|
|
15
17
|
var PACKAGE_DATA = {
|
|
16
18
|
packageName: "@atlaskit/smart-card",
|
|
17
|
-
packageVersion: "41.0.
|
|
19
|
+
packageVersion: "41.0.3",
|
|
18
20
|
componentName: 'linkUrl'
|
|
19
21
|
};
|
|
20
22
|
var Anchor = withLinkClickedEvent('a');
|
|
@@ -36,8 +38,33 @@ var LinkUrl = function LinkUrl(_ref) {
|
|
|
36
38
|
isLinkSafe = _useLinkWarningModal.isLinkSafe,
|
|
37
39
|
showSafetyWarningModal = _useLinkWarningModal.showSafetyWarningModal,
|
|
38
40
|
linkWarningModalProps = _objectWithoutProperties(_useLinkWarningModal, _excluded2);
|
|
39
|
-
var Link = isLinkComponent ? LinkComponent : Anchor;
|
|
40
41
|
var resolveHyperlinkFG = FeatureGates.checkGate('platform_editor_resolve_hyperlinks_killswitch');
|
|
42
|
+
if (fg('navx-1834-refactor-resolved-hyperlink')) {
|
|
43
|
+
if (resolveHyperlinkFG) {
|
|
44
|
+
var _Link = enableResolve ? HyperlinkWithSmartLinkResolver : Hyperlink;
|
|
45
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LinkAnalyticsContext, {
|
|
46
|
+
url: href,
|
|
47
|
+
display: "url"
|
|
48
|
+
}, /*#__PURE__*/React.createElement(_Link, _extends({
|
|
49
|
+
href: href,
|
|
50
|
+
isLinkComponent: isLinkComponent,
|
|
51
|
+
onClick: function onClick(e) {
|
|
52
|
+
if (!checkSafety) {
|
|
53
|
+
_onClick && _onClick(e);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Only call the onClick if the link is safe
|
|
58
|
+
if (isLinkSafe(e, href)) {
|
|
59
|
+
_onClick && _onClick(e);
|
|
60
|
+
} else {
|
|
61
|
+
showSafetyWarningModal(e, href);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
var Link = isLinkComponent ? LinkComponent : Anchor;
|
|
41
68
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LinkAnalyticsContext, {
|
|
42
69
|
url: href,
|
|
43
70
|
display: "url"
|
|
@@ -60,7 +87,7 @@ var LinkUrl = function LinkUrl(_ref) {
|
|
|
60
87
|
showSafetyWarningModal(e, href);
|
|
61
88
|
}
|
|
62
89
|
}
|
|
63
|
-
}, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps), enableResolve && href && resolveHyperlinkFG && /*#__PURE__*/React.createElement(HyperlinkResolver, {
|
|
90
|
+
}, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps), enableResolve && href && resolveHyperlinkFG && !fg('navx-1834-refactor-resolved-hyperlink') && /*#__PURE__*/React.createElement(HyperlinkResolver, {
|
|
64
91
|
href: href
|
|
65
92
|
}));
|
|
66
93
|
};
|