@atlaskit/smart-card 45.5.0 → 45.6.1

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/extractors/flexible/actions/extract-rovo-chat-action.js +3 -1
  3. package/dist/cjs/state/hooks/use-embed-rovo-actions-footer-experiment/index.js +65 -0
  4. package/dist/cjs/state/hooks/use-smart-link-cross-product-url-wrapper/index.js +9 -3
  5. package/dist/cjs/utils/analytics/analytics.js +1 -1
  6. package/dist/cjs/view/CardWithUrl/component.js +1 -0
  7. package/dist/cjs/view/CardWithUrl/experiment-meta-event-attributes/index.js +17 -3
  8. package/dist/cjs/view/EmbedCard/components/rovo-actions-footer/index.compiled.css +3 -0
  9. package/dist/cjs/view/EmbedCard/components/rovo-actions-footer/index.js +138 -0
  10. package/dist/cjs/view/EmbedCard/index.js +2 -0
  11. package/dist/cjs/view/EmbedCard/views/ResolvedView.compiled.css +6 -0
  12. package/dist/cjs/view/EmbedCard/views/ResolvedView.js +129 -36
  13. package/dist/cjs/view/LinkUrl/index.js +1 -1
  14. package/dist/cjs/view/common/rovo-post-auth-prompts/index.js +15 -0
  15. package/dist/es2019/extractors/flexible/actions/extract-rovo-chat-action.js +3 -1
  16. package/dist/es2019/state/hooks/use-embed-rovo-actions-footer-experiment/index.js +58 -0
  17. package/dist/es2019/state/hooks/use-smart-link-cross-product-url-wrapper/index.js +9 -3
  18. package/dist/es2019/utils/analytics/analytics.js +1 -1
  19. package/dist/es2019/view/CardWithUrl/component.js +1 -0
  20. package/dist/es2019/view/CardWithUrl/experiment-meta-event-attributes/index.js +18 -2
  21. package/dist/es2019/view/EmbedCard/components/rovo-actions-footer/index.compiled.css +3 -0
  22. package/dist/es2019/view/EmbedCard/components/rovo-actions-footer/index.js +100 -0
  23. package/dist/es2019/view/EmbedCard/index.js +2 -0
  24. package/dist/es2019/view/EmbedCard/views/ResolvedView.compiled.css +6 -0
  25. package/dist/es2019/view/EmbedCard/views/ResolvedView.js +94 -13
  26. package/dist/es2019/view/LinkUrl/index.js +1 -1
  27. package/dist/es2019/view/common/rovo-post-auth-prompts/index.js +10 -0
  28. package/dist/esm/extractors/flexible/actions/extract-rovo-chat-action.js +3 -1
  29. package/dist/esm/state/hooks/use-embed-rovo-actions-footer-experiment/index.js +58 -0
  30. package/dist/esm/state/hooks/use-smart-link-cross-product-url-wrapper/index.js +9 -3
  31. package/dist/esm/utils/analytics/analytics.js +1 -1
  32. package/dist/esm/view/CardWithUrl/component.js +1 -0
  33. package/dist/esm/view/CardWithUrl/experiment-meta-event-attributes/index.js +17 -3
  34. package/dist/esm/view/EmbedCard/components/rovo-actions-footer/index.compiled.css +3 -0
  35. package/dist/esm/view/EmbedCard/components/rovo-actions-footer/index.js +129 -0
  36. package/dist/esm/view/EmbedCard/index.js +2 -0
  37. package/dist/esm/view/EmbedCard/views/ResolvedView.compiled.css +6 -0
  38. package/dist/esm/view/EmbedCard/views/ResolvedView.js +125 -36
  39. package/dist/esm/view/LinkUrl/index.js +1 -1
  40. package/dist/esm/view/common/rovo-post-auth-prompts/index.js +9 -0
  41. package/dist/types/extractors/flexible/actions/extract-rovo-chat-action.d.ts +2 -1
  42. package/dist/types/state/hooks/use-embed-rovo-actions-footer-experiment/index.d.ts +23 -0
  43. package/dist/types/view/CardWithUrl/experiment-meta-event-attributes/index.d.ts +5 -2
  44. package/dist/types/view/EmbedCard/components/rovo-actions-footer/index.d.ts +14 -0
  45. package/dist/types/view/EmbedCard/views/ResolvedView.d.ts +8 -0
  46. package/dist/types/view/common/rovo-post-auth-prompts/index.d.ts +5 -0
  47. package/package.json +14 -7
@@ -0,0 +1,58 @@
1
+ import { useMemo } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
+ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
5
+ import { getIsRovoChatEnabled } from '../../../utils/rovo';
6
+ import { getExtensionKey } from '../../helpers';
7
+ import { useSmartCardState } from '../../store';
8
+ const EMBED_ROVO_ACTIONS_FOOTER_ELIGIBLE_EXTENSION_KEYS = new Set(['google-object-provider', 'onedrive-object-provider', 'github-object-provider', 'gitlab-object-provider']);
9
+ const isEligibleEmbedRovoActionsFooterExtensionKey = extensionKey => extensionKey !== undefined && EMBED_ROVO_ACTIONS_FOOTER_ELIGIBLE_EXTENSION_KEYS.has(extensionKey);
10
+ export const EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY = 'platform_sl_3p_auth_rovo_embed_footer_exp';
11
+ const NOT_ENABLED_RESULT = {
12
+ isEnabled: false
13
+ };
14
+ export const isEmbedRovoActionsFooterExperimentEnabled = product => {
15
+ return product === 'CONFLUENCE' && fg('platform_sl_3p_auth_rovo_embed_footer_kill_switch') && expValEquals(EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY, 'isEnabled', true);
16
+ };
17
+ const isEmbedRovoActionsFooterKillSwitchEnabled = product => {
18
+ return product === 'CONFLUENCE' && fg('platform_sl_3p_auth_rovo_embed_footer_kill_switch');
19
+ };
20
+ const isEmbedRovoActionsFooterExperimentEnabledNoExposure = product => {
21
+ return isEmbedRovoActionsFooterKillSwitchEnabled(product) && expValEqualsNoExposure(EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY, 'isEnabled', true);
22
+ };
23
+ export const getEmbedRovoActionsFooterExperimentMeta = ({
24
+ extensionKey,
25
+ isRovoChatActionOptedIn,
26
+ isRovoChatEnabled,
27
+ product
28
+ }) => {
29
+ const isEligible = isEmbedRovoActionsFooterKillSwitchEnabled(product) && isRovoChatEnabled && isRovoChatActionOptedIn && isEligibleEmbedRovoActionsFooterExtensionKey(extensionKey);
30
+ if (!isEligible) {
31
+ return undefined;
32
+ }
33
+ return {
34
+ [EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY]: {
35
+ isEligible: true,
36
+ isTreatment: isEmbedRovoActionsFooterExperimentEnabledNoExposure(product)
37
+ }
38
+ };
39
+ };
40
+ const useEmbedRovoActionsFooterExperiment = (url, actionOptions, rovoOptions, product) => {
41
+ var _actionOptions$rovoCh, _actionOptions$rovoCh2;
42
+ const isRovoChatEnabled = getIsRovoChatEnabled(rovoOptions);
43
+ const cardState = useSmartCardState(url !== null && url !== void 0 ? url : '');
44
+ const extensionKey = getExtensionKey(cardState.details);
45
+ const isRovoChatActionOptedIn = (_actionOptions$rovoCh = actionOptions === null || actionOptions === void 0 ? void 0 : (_actionOptions$rovoCh2 = actionOptions.rovoChatAction) === null || _actionOptions$rovoCh2 === void 0 ? void 0 : _actionOptions$rovoCh2.optIn) !== null && _actionOptions$rovoCh !== void 0 ? _actionOptions$rovoCh : false;
46
+ return useMemo(() => {
47
+ if (!isRovoChatEnabled || !url || !isRovoChatActionOptedIn || !extensionKey) {
48
+ return NOT_ENABLED_RESULT;
49
+ }
50
+ if (!isEligibleEmbedRovoActionsFooterExtensionKey(extensionKey)) {
51
+ return NOT_ENABLED_RESULT;
52
+ }
53
+ return {
54
+ isEnabled: isEmbedRovoActionsFooterExperimentEnabled(product)
55
+ };
56
+ }, [isRovoChatEnabled, extensionKey, url, isRovoChatActionOptedIn, product]);
57
+ };
58
+ export default useEmbedRovoActionsFooterExperiment;
@@ -24,9 +24,11 @@ export const useSmartLinkCrossProductUrlWrapper = ({
24
24
  // xpcProduct takes precedence over product — it identifies the host product for XPC analytics
25
25
  // without affecting link resolution (which uses the `product` prop separately).
26
26
  const effectiveProduct = xpcProduct !== null && xpcProduct !== void 0 ? xpcProduct : product;
27
+ const effectiveBridge = bridgeProduct !== null && bridgeProduct !== void 0 ? bridgeProduct : SMART_LINKS_XPC_BRIDGE;
28
+ const effectiveProductForWrapper = (_effectiveProduct$toL = effectiveProduct === null || effectiveProduct === void 0 ? void 0 : effectiveProduct.toLowerCase()) !== null && _effectiveProduct$toL !== void 0 ? _effectiveProduct$toL : 'unknown';
27
29
  const wrapUrl = useCrossProductUrlWrapper({
28
- bridge: bridgeProduct !== null && bridgeProduct !== void 0 ? bridgeProduct : SMART_LINKS_XPC_BRIDGE,
29
- product: (_effectiveProduct$toL = effectiveProduct === null || effectiveProduct === void 0 ? void 0 : effectiveProduct.toLowerCase()) !== null && _effectiveProduct$toL !== void 0 ? _effectiveProduct$toL : 'unknown',
30
+ bridge: effectiveBridge,
31
+ product: effectiveProductForWrapper,
30
32
  ...(xpcSubProduct ? {
31
33
  subProduct: xpcSubProduct
32
34
  } : {})
@@ -45,6 +47,10 @@ export const useSmartLinkCrossProductUrlWrapper = ({
45
47
  return url;
46
48
  }
47
49
  return wrapUrl(url);
48
- }, [details, effectiveProduct, wrapUrl]);
50
+ },
51
+ // Keep bridge/subproduct in the dependency array so consumers that memoize this callback
52
+ // refresh when mini-modal context updates from smartLinks to rovo-chat.
53
+ // eslint-disable-next-line react-hooks/exhaustive-deps
54
+ [details, effectiveBridge, effectiveProduct, wrapUrl, xpcSubProduct]);
49
55
  };
50
56
  export const useSmartLinkCrossProductUrlWrapperGated = functionWithFG('platform_smartlink_xpc_url_wrapping', useSmartLinkCrossProductUrlWrapper, useSmartLinkCrossProductUrlWrapperFallback);
@@ -2,7 +2,7 @@ export const ANALYTICS_CHANNEL = 'media';
2
2
  export const context = {
3
3
  componentName: 'smart-cards',
4
4
  packageName: "@atlaskit/smart-card" || '',
5
- packageVersion: "45.4.3" || ''
5
+ packageVersion: "45.6.0" || ''
6
6
  };
7
7
  export let TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
8
8
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -304,6 +304,7 @@ function Component({
304
304
  }, [appearance, reload]);
305
305
  const handleInvoke = useCallback(opts => actions.invoke(opts, appearance), [actions, appearance]);
306
306
  const experimentMetaEventAttributes = useExperimentMetaEventAttributes({
307
+ actionOptions,
307
308
  appearance,
308
309
  state
309
310
  });
@@ -1,11 +1,16 @@
1
1
  import { fg } from '@atlaskit/platform-feature-flags';
2
2
  import { useSmartLinkContext } from '../../../state';
3
3
  import { getExtensionKey } from '../../../state/helpers';
4
+ import { getEmbedRovoActionsFooterExperimentMeta } from '../../../state/hooks/use-embed-rovo-actions-footer-experiment';
5
+ import useRovoConfig from '../../../state/hooks/use-rovo-config';
4
6
  import { getSocialProofExperimentMeta, getInlineSocialProofExperimentMeta } from '../../../state/hooks/use-social-proof-experiment';
7
+ import { getIsRovoChatEnabled } from '../../../utils/rovo';
5
8
  const useExperimentMetaEventAttributes = ({
9
+ actionOptions,
6
10
  appearance,
7
11
  state
8
12
  }) => {
13
+ var _actionOptions$rovoCh, _actionOptions$rovoCh2;
9
14
  const {
10
15
  connections: {
11
16
  client: {
@@ -13,12 +18,22 @@ const useExperimentMetaEventAttributes = ({
13
18
  }
14
19
  }
15
20
  } = useSmartLinkContext();
21
+ const {
22
+ rovoOptions,
23
+ product
24
+ } = useRovoConfig();
16
25
  const {
17
26
  details,
18
27
  status
19
28
  } = state;
20
29
  const extensionKey = getExtensionKey(details);
21
- if (!fg('social-proof-3p-unauth-block-fg') && !fg('platform_sl_3p_preauth_soc_proof_inline_killswitch')) {
30
+ const embedRovoActionsFooterExperimentMeta = appearance === 'embed' && status === 'resolved' ? getEmbedRovoActionsFooterExperimentMeta({
31
+ extensionKey,
32
+ isRovoChatActionOptedIn: (_actionOptions$rovoCh = actionOptions === null || actionOptions === void 0 ? void 0 : (_actionOptions$rovoCh2 = actionOptions.rovoChatAction) === null || _actionOptions$rovoCh2 === void 0 ? void 0 : _actionOptions$rovoCh2.optIn) !== null && _actionOptions$rovoCh !== void 0 ? _actionOptions$rovoCh : false,
33
+ isRovoChatEnabled: getIsRovoChatEnabled(rovoOptions),
34
+ product
35
+ }) : undefined;
36
+ if (!embedRovoActionsFooterExperimentMeta && !fg('social-proof-3p-unauth-block-fg') && !fg('platform_sl_3p_preauth_soc_proof_inline_killswitch')) {
22
37
  return undefined;
23
38
  }
24
39
  const blockSocialProofExperimentMeta = appearance === 'block' && status === 'unauthorized' && fg('social-proof-3p-unauth-block-fg') ? getSocialProofExperimentMeta({
@@ -31,7 +46,8 @@ const useExperimentMetaEventAttributes = ({
31
46
  }) : undefined;
32
47
  const experimentMeta = {
33
48
  ...blockSocialProofExperimentMeta,
34
- ...inlineSocialProofExperimentMeta
49
+ ...inlineSocialProofExperimentMeta,
50
+ ...embedRovoActionsFooterExperimentMeta
35
51
  };
36
52
  if (Object.keys(experimentMeta).length > 0) {
37
53
  return experimentMeta;
@@ -0,0 +1,3 @@
1
+
2
+ ._zulpidpf{gap:0}._1e0c1txw{display:flex}
3
+ ._2lx2vrvc{flex-direction:row}
@@ -0,0 +1,100 @@
1
+ /* index.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import "./index.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React, { useCallback, useMemo, useState } from 'react';
5
+ import { useIntl } from 'react-intl';
6
+ import Button from '@atlaskit/button/new';
7
+ import { WidthObserver } from '@atlaskit/width-detector';
8
+ import useInvokeClientAction from '../../../../state/hooks/use-invoke-client-action';
9
+ import useRovoChat from '../../../../state/hooks/use-rovo-chat';
10
+ import { getPromptAction } from '../../../common/rovo-chat-utils';
11
+ import AIEditIcon from '../../../FlexibleCard/assets/ai-edit-icon';
12
+ const HIDE_SECONDARY_ACTIONS_WIDTH = 320;
13
+ const PRIMARY_ACTION_ICON_ONLY_WIDTH = 220;
14
+ const styles = {
15
+ actionGroup: "_zulpidpf _1e0c1txw _2lx2vrvc"
16
+ };
17
+ const RovoPromptButton = ({
18
+ hideContent = false,
19
+ icon,
20
+ onClick,
21
+ promptAction,
22
+ promptKey,
23
+ testId
24
+ }) => {
25
+ const iconBefore = useCallback(() => /*#__PURE__*/React.createElement("span", {
26
+ "aria-hidden": "true"
27
+ }, icon), [icon]);
28
+ const label = promptAction.data.name;
29
+ const handleClick = useCallback(event => onClick(event, promptAction.data, promptKey), [onClick, promptAction.data, promptKey]);
30
+ return /*#__PURE__*/React.createElement(Button, {
31
+ appearance: "subtle",
32
+ "aria-label": hideContent ? label : undefined,
33
+ iconBefore: iconBefore,
34
+ onClick: handleClick,
35
+ spacing: "compact",
36
+ testId: `${testId}-${promptKey}`
37
+ }, hideContent ? null : label);
38
+ };
39
+ const EmbedRovoActionsFooter = ({
40
+ actionData,
41
+ prompts,
42
+ testId = 'embed-rovo-actions-footer'
43
+ }) => {
44
+ const intl = useIntl();
45
+ const invoke = useInvokeClientAction({});
46
+ const {
47
+ isRovoChatEnabled,
48
+ sendPromptMessage
49
+ } = useRovoChat();
50
+ const [containerWidth, setContainerWidth] = useState(undefined);
51
+ const shouldHideSecondaryActions = containerWidth !== undefined && containerWidth < HIDE_SECONDARY_ACTIONS_WIDTH;
52
+ const shouldHidePrimaryActionContent = containerWidth !== undefined && containerWidth < PRIMARY_ACTION_ICON_ONLY_WIDTH;
53
+ const onClick = useCallback((event, promptData, promptKey) => {
54
+ event.preventDefault();
55
+ event.stopPropagation();
56
+ invoke({
57
+ ...actionData.invokeAction,
58
+ actionFn: async () => sendPromptMessage(promptData),
59
+ prompt: promptKey
60
+ });
61
+ }, [actionData.invokeAction, invoke, sendPromptMessage]);
62
+ const promptActions = useMemo(() => prompts.reduce((actions, promptKey) => {
63
+ if (shouldHideSecondaryActions && actions.length > 0) {
64
+ return actions;
65
+ }
66
+ const promptAction = getPromptAction({
67
+ promptKey,
68
+ intl,
69
+ url: actionData.url,
70
+ product: actionData.product,
71
+ iconSize: 'small'
72
+ });
73
+ if (!promptAction) {
74
+ return actions;
75
+ }
76
+ const isPrimaryAction = actions.length === 0;
77
+ actions.push( /*#__PURE__*/React.createElement(RovoPromptButton, {
78
+ hideContent: isPrimaryAction && shouldHidePrimaryActionContent,
79
+ icon: isPrimaryAction ? /*#__PURE__*/React.createElement(AIEditIcon, null) : promptAction.icon,
80
+ key: promptKey,
81
+ onClick: onClick,
82
+ promptAction: promptAction,
83
+ promptKey: promptKey,
84
+ testId: testId
85
+ }));
86
+ return actions;
87
+ }, []), [actionData.product, actionData.url, intl, onClick, prompts, shouldHidePrimaryActionContent, shouldHideSecondaryActions, testId]);
88
+ if (!isRovoChatEnabled || promptActions.length === 0) {
89
+ return null;
90
+ }
91
+ return /*#__PURE__*/React.createElement("div", {
92
+ "data-testid": testId
93
+ }, /*#__PURE__*/React.createElement(WidthObserver, {
94
+ setWidth: setContainerWidth,
95
+ offscreen: true
96
+ }), /*#__PURE__*/React.createElement("div", {
97
+ className: ax([styles.actionGroup])
98
+ }, promptActions));
99
+ };
100
+ export default EmbedRovoActionsFooter;
@@ -100,6 +100,8 @@ export const EmbedCard = /*#__PURE__*/React.forwardRef(({
100
100
  }
101
101
  if (resolvedViewProps.preview) {
102
102
  return /*#__PURE__*/React.createElement(EmbedCardResolvedView, _extends({}, resolvedViewProps, {
103
+ actionOptions: actionOptions,
104
+ details: details,
103
105
  isSelected: isSelected,
104
106
  frameStyle: frameStyle,
105
107
  inheritDimensions: inheritDimensions,
@@ -0,0 +1,6 @@
1
+ ._16jlkb7n{flex-grow:1}
2
+ ._1bah1y6m{justify-content:flex-start}
3
+ ._1e0c1txw{display:flex}
4
+ ._1tkeidpf{min-height:0}
5
+ ._2lx21bp4{flex-direction:column}
6
+ ._4t3i1osq{height:100%}
@@ -1,16 +1,89 @@
1
+ /* ResolvedView.tsx generated by @compiled/babel-plugin v0.39.1 */
1
2
  import _extends from "@babel/runtime/helpers/extends";
3
+ import "./ResolvedView.compiled.css";
4
+ import { ax, ix } from "@compiled/react/runtime";
2
5
  import React from 'react';
6
+ import Loadable from 'react-loadable';
3
7
  import LinkGlyph from '@atlaskit/icon/core/link';
4
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
+ import { componentWithFG } from '@atlaskit/platform-feature-flags-react';
5
10
  import { useThemeObserver } from '@atlaskit/tokens';
11
+ import { CardDisplay } from '../../../constants';
12
+ import extractRovoChatAction from '../../../extractors/flexible/actions/extract-rovo-chat-action';
13
+ import { getExtensionKey } from '../../../state/helpers';
14
+ import useEmbedRovoActionsFooterExperiment from '../../../state/hooks/use-embed-rovo-actions-footer-experiment';
15
+ import useRovoConfig from '../../../state/hooks/use-rovo-config';
6
16
  import { getPreviewUrlWithTheme, isProfileType } from '../../../utils';
17
+ import { getRovoPostAuthPromptKeys } from '../../common/rovo-post-auth-prompts';
7
18
  import { ExpandedFrame } from '../components/ExpandedFrame';
8
19
  import { Frame } from '../components/Frame';
9
20
  import { ImageIcon } from '../components/ImageIcon';
10
21
  import { useEmbedResolvePostMessageListener } from '../useEmbedResolvePostMessageListener';
22
+ const EmbedRovoActionsFooter = Loadable({
23
+ loader: () => import( /* webpackChunkName: "smart-card-embed-rovo-actions-footer" */'../components/rovo-actions-footer').then(module => module.default),
24
+ loading: () => null
25
+ });
26
+ EmbedRovoActionsFooter.displayName = 'lazy(EmbedRovoActionsFooter)';
27
+ const styles = {
28
+ contentWithFooter: "_1e0c1txw _2lx21bp4 _4t3i1osq _1tkeidpf",
29
+ frameWithFooter: "_16jlkb7n _1tkeidpf",
30
+ footer: "_1e0c1txw _1bah1y6m"
31
+ };
32
+ const EmbedFrameWithRovoFooter = ({
33
+ actionOptions,
34
+ details,
35
+ frame,
36
+ link,
37
+ testId
38
+ }) => {
39
+ const {
40
+ rovoOptions,
41
+ product
42
+ } = useRovoConfig();
43
+ const {
44
+ isEnabled: isEmbedRovoActionsFooterEnabled
45
+ } = useEmbedRovoActionsFooterExperiment(link, actionOptions, rovoOptions, product);
46
+ const rovoActionData = React.useMemo(() => isEmbedRovoActionsFooterEnabled && details ? extractRovoChatAction({
47
+ response: details,
48
+ rovoConfig: {
49
+ rovoOptions,
50
+ product
51
+ },
52
+ product,
53
+ actionOptions,
54
+ appearance: CardDisplay.Embed,
55
+ isEmbedRovoActionsFooterExperimentEnabled: isEmbedRovoActionsFooterEnabled
56
+ }) : undefined, [actionOptions, details, isEmbedRovoActionsFooterEnabled, product, rovoOptions]);
57
+ const prompts = React.useMemo(() => {
58
+ if (!isEmbedRovoActionsFooterEnabled) {
59
+ return [];
60
+ }
61
+ return getRovoPostAuthPromptKeys({
62
+ extensionKey: getExtensionKey(details)
63
+ });
64
+ }, [details, isEmbedRovoActionsFooterEnabled]);
65
+ const footer = React.useMemo(() => rovoActionData && prompts.length > 0 ? /*#__PURE__*/React.createElement(EmbedRovoActionsFooter, {
66
+ actionData: rovoActionData,
67
+ prompts: prompts,
68
+ testId: `${testId}-rovo-actions-footer`
69
+ }) : undefined, [prompts, rovoActionData, testId]);
70
+ return footer ? /*#__PURE__*/React.createElement("div", {
71
+ className: ax([styles.contentWithFooter])
72
+ }, /*#__PURE__*/React.createElement("div", {
73
+ className: ax([styles.frameWithFooter])
74
+ }, frame), /*#__PURE__*/React.createElement("div", {
75
+ className: ax([styles.footer])
76
+ }, footer)) : frame;
77
+ };
78
+ const EmbedFrameWithoutRovoFooter = ({
79
+ frame
80
+ }) => frame;
81
+ const EmbedFrameWithOptionalRovoFooter = componentWithFG('platform_sl_3p_auth_rovo_embed_footer_kill_switch', EmbedFrameWithRovoFooter, EmbedFrameWithoutRovoFooter);
11
82
  export const EmbedCardResolvedView = /*#__PURE__*/React.forwardRef(({
83
+ actionOptions,
12
84
  link,
13
85
  context,
86
+ details,
14
87
  onClick,
15
88
  onAuxClick,
16
89
  onContextMenu,
@@ -64,6 +137,26 @@ export const EmbedCardResolvedView = /*#__PURE__*/React.forwardRef(({
64
137
  previewUrl = getPreviewUrlWithTheme(previewUrl, themeState);
65
138
  }
66
139
  const [isMouseOver, setMouseOver] = React.useState(false);
140
+ const frame = /*#__PURE__*/React.createElement(Frame, {
141
+ url: previewUrl,
142
+ isTrusted: isTrusted,
143
+ testId: testId,
144
+ ref: embedIframeRef,
145
+ onIframeDwell: onIframeDwell,
146
+ onIframeFocus: onIframeFocus,
147
+ onIframeMouseEnter: onIframeMouseEnter,
148
+ onIframeMouseLeave: onIframeMouseLeave,
149
+ isMouseOver: isMouseOver,
150
+ title: text,
151
+ extensionKey: extensionKey
152
+ });
153
+ const frameWithFooter = /*#__PURE__*/React.createElement(EmbedFrameWithOptionalRovoFooter, {
154
+ actionOptions: actionOptions,
155
+ details: details,
156
+ frame: frame,
157
+ link: link,
158
+ testId: testId
159
+ });
67
160
  return /*#__PURE__*/React.createElement(ExpandedFrame, {
68
161
  isSelected: isSelected,
69
162
  frameStyle: frameStyle,
@@ -85,17 +178,5 @@ export const EmbedCardResolvedView = /*#__PURE__*/React.forwardRef(({
85
178
  setMouseOver(false);
86
179
  onIframeMouseLeave === null || onIframeMouseLeave === void 0 ? void 0 : onIframeMouseLeave();
87
180
  }
88
- }, /*#__PURE__*/React.createElement(Frame, {
89
- url: previewUrl,
90
- isTrusted: isTrusted,
91
- testId: testId,
92
- ref: embedIframeRef,
93
- onIframeDwell: onIframeDwell,
94
- onIframeFocus: onIframeFocus,
95
- onIframeMouseEnter: onIframeMouseEnter,
96
- onIframeMouseLeave: onIframeMouseLeave,
97
- isMouseOver: isMouseOver,
98
- title: text,
99
- extensionKey: extensionKey
100
- }));
181
+ }, frameWithFooter);
101
182
  });
@@ -9,7 +9,7 @@ import LinkWarningModal from './LinkWarningModal';
9
9
  import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
10
10
  const PACKAGE_DATA = {
11
11
  packageName: "@atlaskit/smart-card",
12
- packageVersion: "45.4.3",
12
+ packageVersion: "45.6.0",
13
13
  componentName: 'linkUrl'
14
14
  };
15
15
  const LinkUrl = ({
@@ -0,0 +1,10 @@
1
+ import { RovoChatPromptKey } from '../rovo-chat-utils';
2
+ export const getRovoPostAuthPromptKeys = ({
3
+ extensionKey
4
+ }) => {
5
+ const defaultPrompts = [RovoChatPromptKey.KEY_HIGHLIGHTS];
6
+ if (extensionKey === 'github-object-provider' || extensionKey === 'gitlab-object-provider') {
7
+ return [RovoChatPromptKey.EXPLAIN_CODE, ...defaultPrompts];
8
+ }
9
+ return [RovoChatPromptKey.SUMMARIZE_DOCUMENT, ...defaultPrompts];
10
+ };
@@ -12,6 +12,7 @@ var extractRovoChatAction = function extractRovoChatAction(_ref) {
12
12
  var actionOptions = _ref.actionOptions,
13
13
  appearance = _ref.appearance,
14
14
  id = _ref.id,
15
+ isEmbedRovoActionsFooterExperimentEnabled = _ref.isEmbedRovoActionsFooterExperimentEnabled,
15
16
  product = _ref.product,
16
17
  response = _ref.response,
17
18
  rovoConfig = _ref.rovoConfig;
@@ -27,7 +28,8 @@ var extractRovoChatAction = function extractRovoChatAction(_ref) {
27
28
  var isInlineExperimentEnabled = fg('platform_sl_3p_auth_inline_tailored_cta_killswitch') && expValEqualsNoExposure('platform_sl_3p_auth_inline_tailored_cta', 'isEnabled', true);
28
29
  var is3PAuthRovoActionEnabled = isGoogleProvider && fg('platform_sl_3p_auth_rovo_action_kill_switch');
29
30
  var is3PBlockPostAuthActionsEnabled = extensionKey !== undefined && ELIGIBLE_EXTENSION_KEYS.has(extensionKey) && (rovoConfig === null || rovoConfig === void 0 ? void 0 : rovoConfig.product) === 'CONFLUENCE';
30
- var isSupportedFeature = is3PAuthRovoActionEnabled || is3PBlockPostAuthActionsEnabled || isInlineExperimentEnabled;
31
+ var is3PEmbedPostAuthActionsEnabled = isEmbedRovoActionsFooterExperimentEnabled === true;
32
+ var isSupportedFeature = is3PAuthRovoActionEnabled || is3PBlockPostAuthActionsEnabled || isInlineExperimentEnabled || is3PEmbedPostAuthActionsEnabled;
31
33
  var isOptIn = (actionOptions === null || actionOptions === void 0 || (_actionOptions$rovoCh = actionOptions.rovoChatAction) === null || _actionOptions$rovoCh === void 0 ? void 0 : _actionOptions$rovoCh.optIn) === true;
32
34
  var url = extractSmartLinkUrl(response);
33
35
  return isSupportedFeature && isOptIn ? {
@@ -0,0 +1,58 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { useMemo } from 'react';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
+ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
6
+ import { getIsRovoChatEnabled } from '../../../utils/rovo';
7
+ import { getExtensionKey } from '../../helpers';
8
+ import { useSmartCardState } from '../../store';
9
+ var EMBED_ROVO_ACTIONS_FOOTER_ELIGIBLE_EXTENSION_KEYS = new Set(['google-object-provider', 'onedrive-object-provider', 'github-object-provider', 'gitlab-object-provider']);
10
+ var isEligibleEmbedRovoActionsFooterExtensionKey = function isEligibleEmbedRovoActionsFooterExtensionKey(extensionKey) {
11
+ return extensionKey !== undefined && EMBED_ROVO_ACTIONS_FOOTER_ELIGIBLE_EXTENSION_KEYS.has(extensionKey);
12
+ };
13
+ export var EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY = 'platform_sl_3p_auth_rovo_embed_footer_exp';
14
+ var NOT_ENABLED_RESULT = {
15
+ isEnabled: false
16
+ };
17
+ export var isEmbedRovoActionsFooterExperimentEnabled = function isEmbedRovoActionsFooterExperimentEnabled(product) {
18
+ return product === 'CONFLUENCE' && fg('platform_sl_3p_auth_rovo_embed_footer_kill_switch') && expValEquals(EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY, 'isEnabled', true);
19
+ };
20
+ var isEmbedRovoActionsFooterKillSwitchEnabled = function isEmbedRovoActionsFooterKillSwitchEnabled(product) {
21
+ return product === 'CONFLUENCE' && fg('platform_sl_3p_auth_rovo_embed_footer_kill_switch');
22
+ };
23
+ var isEmbedRovoActionsFooterExperimentEnabledNoExposure = function isEmbedRovoActionsFooterExperimentEnabledNoExposure(product) {
24
+ return isEmbedRovoActionsFooterKillSwitchEnabled(product) && expValEqualsNoExposure(EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY, 'isEnabled', true);
25
+ };
26
+ export var getEmbedRovoActionsFooterExperimentMeta = function getEmbedRovoActionsFooterExperimentMeta(_ref) {
27
+ var extensionKey = _ref.extensionKey,
28
+ isRovoChatActionOptedIn = _ref.isRovoChatActionOptedIn,
29
+ isRovoChatEnabled = _ref.isRovoChatEnabled,
30
+ product = _ref.product;
31
+ var isEligible = isEmbedRovoActionsFooterKillSwitchEnabled(product) && isRovoChatEnabled && isRovoChatActionOptedIn && isEligibleEmbedRovoActionsFooterExtensionKey(extensionKey);
32
+ if (!isEligible) {
33
+ return undefined;
34
+ }
35
+ return _defineProperty({}, EMBED_ROVO_ACTIONS_FOOTER_EXPERIMENT_KEY, {
36
+ isEligible: true,
37
+ isTreatment: isEmbedRovoActionsFooterExperimentEnabledNoExposure(product)
38
+ });
39
+ };
40
+ var useEmbedRovoActionsFooterExperiment = function useEmbedRovoActionsFooterExperiment(url, actionOptions, rovoOptions, product) {
41
+ var _actionOptions$rovoCh, _actionOptions$rovoCh2;
42
+ var isRovoChatEnabled = getIsRovoChatEnabled(rovoOptions);
43
+ var cardState = useSmartCardState(url !== null && url !== void 0 ? url : '');
44
+ var extensionKey = getExtensionKey(cardState.details);
45
+ var isRovoChatActionOptedIn = (_actionOptions$rovoCh = actionOptions === null || actionOptions === void 0 || (_actionOptions$rovoCh2 = actionOptions.rovoChatAction) === null || _actionOptions$rovoCh2 === void 0 ? void 0 : _actionOptions$rovoCh2.optIn) !== null && _actionOptions$rovoCh !== void 0 ? _actionOptions$rovoCh : false;
46
+ return useMemo(function () {
47
+ if (!isRovoChatEnabled || !url || !isRovoChatActionOptedIn || !extensionKey) {
48
+ return NOT_ENABLED_RESULT;
49
+ }
50
+ if (!isEligibleEmbedRovoActionsFooterExtensionKey(extensionKey)) {
51
+ return NOT_ENABLED_RESULT;
52
+ }
53
+ return {
54
+ isEnabled: isEmbedRovoActionsFooterExperimentEnabled(product)
55
+ };
56
+ }, [isRovoChatEnabled, extensionKey, url, isRovoChatActionOptedIn, product]);
57
+ };
58
+ export default useEmbedRovoActionsFooterExperiment;
@@ -29,9 +29,11 @@ export var useSmartLinkCrossProductUrlWrapper = function useSmartLinkCrossProduc
29
29
  // xpcProduct takes precedence over product — it identifies the host product for XPC analytics
30
30
  // without affecting link resolution (which uses the `product` prop separately).
31
31
  var effectiveProduct = xpcProduct !== null && xpcProduct !== void 0 ? xpcProduct : product;
32
+ var effectiveBridge = bridgeProduct !== null && bridgeProduct !== void 0 ? bridgeProduct : SMART_LINKS_XPC_BRIDGE;
33
+ var effectiveProductForWrapper = (_effectiveProduct$toL = effectiveProduct === null || effectiveProduct === void 0 ? void 0 : effectiveProduct.toLowerCase()) !== null && _effectiveProduct$toL !== void 0 ? _effectiveProduct$toL : 'unknown';
32
34
  var wrapUrl = useCrossProductUrlWrapper(_objectSpread({
33
- bridge: bridgeProduct !== null && bridgeProduct !== void 0 ? bridgeProduct : SMART_LINKS_XPC_BRIDGE,
34
- product: (_effectiveProduct$toL = effectiveProduct === null || effectiveProduct === void 0 ? void 0 : effectiveProduct.toLowerCase()) !== null && _effectiveProduct$toL !== void 0 ? _effectiveProduct$toL : 'unknown'
35
+ bridge: effectiveBridge,
36
+ product: effectiveProductForWrapper
35
37
  }, xpcSubProduct ? {
36
38
  subProduct: xpcSubProduct
37
39
  } : {}));
@@ -49,6 +51,10 @@ export var useSmartLinkCrossProductUrlWrapper = function useSmartLinkCrossProduc
49
51
  return url;
50
52
  }
51
53
  return wrapUrl(url);
52
- }, [details, effectiveProduct, wrapUrl]);
54
+ },
55
+ // Keep bridge/subproduct in the dependency array so consumers that memoize this callback
56
+ // refresh when mini-modal context updates from smartLinks to rovo-chat.
57
+ // eslint-disable-next-line react-hooks/exhaustive-deps
58
+ [details, effectiveBridge, effectiveProduct, wrapUrl, xpcSubProduct]);
53
59
  };
54
60
  export var useSmartLinkCrossProductUrlWrapperGated = functionWithFG('platform_smartlink_xpc_url_wrapping', useSmartLinkCrossProductUrlWrapper, useSmartLinkCrossProductUrlWrapperFallback);
@@ -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: "45.4.3" || ''
7
+ packageVersion: "45.6.0" || ''
8
8
  };
9
9
  export var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
10
10
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -306,6 +306,7 @@ function Component(_ref) {
306
306
  return actions.invoke(opts, appearance);
307
307
  }, [actions, appearance]);
308
308
  var experimentMetaEventAttributes = useExperimentMetaEventAttributes({
309
+ actionOptions: actionOptions,
309
310
  appearance: appearance,
310
311
  state: state
311
312
  });
@@ -4,16 +4,30 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  import { fg } from '@atlaskit/platform-feature-flags';
5
5
  import { useSmartLinkContext } from '../../../state';
6
6
  import { getExtensionKey } from '../../../state/helpers';
7
+ import { getEmbedRovoActionsFooterExperimentMeta } from '../../../state/hooks/use-embed-rovo-actions-footer-experiment';
8
+ import useRovoConfig from '../../../state/hooks/use-rovo-config';
7
9
  import { getSocialProofExperimentMeta, getInlineSocialProofExperimentMeta } from '../../../state/hooks/use-social-proof-experiment';
10
+ import { getIsRovoChatEnabled } from '../../../utils/rovo';
8
11
  var useExperimentMetaEventAttributes = function useExperimentMetaEventAttributes(_ref) {
9
- var appearance = _ref.appearance,
12
+ var _actionOptions$rovoCh, _actionOptions$rovoCh2;
13
+ var actionOptions = _ref.actionOptions,
14
+ appearance = _ref.appearance,
10
15
  state = _ref.state;
11
16
  var _useSmartLinkContext = useSmartLinkContext(),
12
17
  baseUriWithNoTrailingSlash = _useSmartLinkContext.connections.client.baseUrlOverride;
18
+ var _useRovoConfig = useRovoConfig(),
19
+ rovoOptions = _useRovoConfig.rovoOptions,
20
+ product = _useRovoConfig.product;
13
21
  var details = state.details,
14
22
  status = state.status;
15
23
  var extensionKey = getExtensionKey(details);
16
- if (!fg('social-proof-3p-unauth-block-fg') && !fg('platform_sl_3p_preauth_soc_proof_inline_killswitch')) {
24
+ var embedRovoActionsFooterExperimentMeta = appearance === 'embed' && status === 'resolved' ? getEmbedRovoActionsFooterExperimentMeta({
25
+ extensionKey: extensionKey,
26
+ isRovoChatActionOptedIn: (_actionOptions$rovoCh = actionOptions === null || actionOptions === void 0 || (_actionOptions$rovoCh2 = actionOptions.rovoChatAction) === null || _actionOptions$rovoCh2 === void 0 ? void 0 : _actionOptions$rovoCh2.optIn) !== null && _actionOptions$rovoCh !== void 0 ? _actionOptions$rovoCh : false,
27
+ isRovoChatEnabled: getIsRovoChatEnabled(rovoOptions),
28
+ product: product
29
+ }) : undefined;
30
+ if (!embedRovoActionsFooterExperimentMeta && !fg('social-proof-3p-unauth-block-fg') && !fg('platform_sl_3p_preauth_soc_proof_inline_killswitch')) {
17
31
  return undefined;
18
32
  }
19
33
  var blockSocialProofExperimentMeta = appearance === 'block' && status === 'unauthorized' && fg('social-proof-3p-unauth-block-fg') ? getSocialProofExperimentMeta({
@@ -24,7 +38,7 @@ var useExperimentMetaEventAttributes = function useExperimentMetaEventAttributes
24
38
  extensionKey: extensionKey,
25
39
  baseUriWithNoTrailingSlash: baseUriWithNoTrailingSlash
26
40
  }) : undefined;
27
- var experimentMeta = _objectSpread(_objectSpread({}, blockSocialProofExperimentMeta), inlineSocialProofExperimentMeta);
41
+ var experimentMeta = _objectSpread(_objectSpread(_objectSpread({}, blockSocialProofExperimentMeta), inlineSocialProofExperimentMeta), embedRovoActionsFooterExperimentMeta);
28
42
  if (Object.keys(experimentMeta).length > 0) {
29
43
  return experimentMeta;
30
44
  }
@@ -0,0 +1,3 @@
1
+
2
+ ._zulpidpf{gap:0}._1e0c1txw{display:flex}
3
+ ._2lx2vrvc{flex-direction:row}