@atlaskit/smart-card 26.49.0 → 26.49.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 (43) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/state/hooks/use-ai-summary/ai-summary-service/index.js +39 -27
  3. package/dist/cjs/state/hooks/use-ai-summary/index.js +16 -38
  4. package/dist/cjs/utils/analytics/analytics.js +1 -1
  5. package/dist/cjs/view/FlexibleCard/components/blocks/ai-summary-block/resolved/index.js +37 -29
  6. package/dist/cjs/view/HoverCard/components/ContentContainer.js +42 -13
  7. package/dist/cjs/view/HoverCard/components/HoverCardContent.js +1 -10
  8. package/dist/cjs/view/HoverCard/components/views/resolved/index.js +63 -16
  9. package/dist/cjs/view/LinkUrl/index.js +1 -1
  10. package/dist/cjs/view/common/ai-summary/index.js +9 -3
  11. package/dist/es2019/state/hooks/use-ai-summary/ai-summary-service/index.js +14 -5
  12. package/dist/es2019/state/hooks/use-ai-summary/index.js +17 -35
  13. package/dist/es2019/utils/analytics/analytics.js +1 -1
  14. package/dist/es2019/view/FlexibleCard/components/blocks/ai-summary-block/resolved/index.js +33 -26
  15. package/dist/es2019/view/HoverCard/components/ContentContainer.js +35 -10
  16. package/dist/es2019/view/HoverCard/components/HoverCardContent.js +2 -7
  17. package/dist/es2019/view/HoverCard/components/views/resolved/index.js +56 -7
  18. package/dist/es2019/view/LinkUrl/index.js +1 -1
  19. package/dist/es2019/view/common/ai-summary/index.js +7 -3
  20. package/dist/esm/state/hooks/use-ai-summary/ai-summary-service/index.js +39 -27
  21. package/dist/esm/state/hooks/use-ai-summary/index.js +17 -39
  22. package/dist/esm/utils/analytics/analytics.js +1 -1
  23. package/dist/esm/view/FlexibleCard/components/blocks/ai-summary-block/resolved/index.js +38 -30
  24. package/dist/esm/view/HoverCard/components/ContentContainer.js +39 -13
  25. package/dist/esm/view/HoverCard/components/HoverCardContent.js +2 -11
  26. package/dist/esm/view/HoverCard/components/views/resolved/index.js +66 -18
  27. package/dist/esm/view/LinkUrl/index.js +1 -1
  28. package/dist/esm/view/common/ai-summary/index.js +9 -3
  29. package/dist/types/state/hooks/use-ai-summary/ai-summary-service/types.d.ts +3 -1
  30. package/dist/types/state/hooks/use-ai-summary/index.d.ts +0 -1
  31. package/dist/types/view/FlexibleCard/components/blocks/ai-summary-block/ai-state-indicator/types.d.ts +2 -2
  32. package/dist/types/view/FlexibleCard/components/blocks/ai-summary-block/types.d.ts +2 -3
  33. package/dist/types/view/HoverCard/components/views/resolved/types.d.ts +0 -2
  34. package/dist/types/view/HoverCard/types.d.ts +1 -1
  35. package/dist/types/view/common/ai-summary/index.d.ts +4 -0
  36. package/dist/types-ts4.5/state/hooks/use-ai-summary/ai-summary-service/types.d.ts +3 -1
  37. package/dist/types-ts4.5/state/hooks/use-ai-summary/index.d.ts +0 -1
  38. package/dist/types-ts4.5/view/FlexibleCard/components/blocks/ai-summary-block/ai-state-indicator/types.d.ts +2 -2
  39. package/dist/types-ts4.5/view/FlexibleCard/components/blocks/ai-summary-block/types.d.ts +2 -3
  40. package/dist/types-ts4.5/view/HoverCard/components/views/resolved/types.d.ts +0 -2
  41. package/dist/types-ts4.5/view/HoverCard/types.d.ts +1 -1
  42. package/dist/types-ts4.5/view/common/ai-summary/index.d.ts +4 -0
  43. package/package.json +2 -2
@@ -23,7 +23,11 @@ export class AISummaryService {
23
23
  const path = 'chat/v1/invoke_agent/stream';
24
24
  const requestUrl = addPath(this.config.baseUrl, path);
25
25
  const response = await fetch(requestUrl, options);
26
- return readStream(response);
26
+ if (!response.ok || response.status >= 400) {
27
+ throw new Error(`Status: ${response.status}\n URL: ${this.url}\n StatusText ${response.statusText}`);
28
+ } else {
29
+ return readStream(response);
30
+ }
27
31
  });
28
32
  const defaultConfig = {
29
33
  baseUrl: '/gateway/api/assist',
@@ -42,10 +46,10 @@ export class AISummaryService {
42
46
  };
43
47
  this.url = props.url;
44
48
  }
45
- async summariseUrl(summaryStyle = 'short') {
49
+ async summariseUrl(summaryStyle = 'medium') {
46
50
  this.state = {
47
- ...this.state,
48
- status: 'loading'
51
+ status: 'loading',
52
+ content: ''
49
53
  };
50
54
  for (const subscriber of this.subscribedStateSetters) {
51
55
  subscriber(this.state);
@@ -63,12 +67,17 @@ export class AISummaryService {
63
67
  });
64
68
  }
65
69
  }
70
+
71
+ //if AI Mate service returns cached summary we get the summary text in one piece as the last message
72
+ if (chunk.type === 'FINAL_RESPONSE') {
73
+ bufferContent = chunk.message.message.content;
74
+ }
66
75
  }
67
76
  this.state = {
68
77
  status: 'done',
69
78
  content: bufferContent
70
79
  };
71
- } catch {
80
+ } catch (err) {
72
81
  this.state = {
73
82
  status: 'error',
74
83
  content: ''
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, useMemo } from 'react';
1
+ import { useState, useEffect } from 'react';
2
2
  import { AISummariesStore } from './ai-summary-service/store';
3
3
  import { AISummaryService } from './ai-summary-service';
4
4
  export const useAISummary = props => {
@@ -6,50 +6,32 @@ export const useAISummary = props => {
6
6
  const {
7
7
  url,
8
8
  baseUrl,
9
- product,
10
- headers
9
+ headers,
10
+ product
11
11
  } = props;
12
12
  const [state, setState] = useState(((_AISummariesStore$get = AISummariesStore.get(url)) === null || _AISummariesStore$get === void 0 ? void 0 : _AISummariesStore$get.state) || {
13
13
  status: 'ready',
14
14
  content: ''
15
15
  });
16
-
17
- // Can be used to know the summary status upon mounting a component (HoverCard UI state for example).
18
- // For other scenarios, opt for dynamic status updates via state.status.
19
- const isSummarisedOnMount = useMemo(() => {
20
- var _AISummariesStore$get2;
21
- return ((_AISummariesStore$get2 = AISummariesStore.get(url)) === null || _AISummariesStore$get2 === void 0 ? void 0 : _AISummariesStore$get2.state.status) === 'done';
22
- }, [url]);
23
16
  useEffect(() => {
24
- // Create or subscribe to an AI service only if a summary has not been previously generated.
25
- // Otherwise, use the data from the current state synchronized with a cache (AISummariesStore).
26
- if (!isSummarisedOnMount) {
27
- const aISummaryService = AISummariesStore.get(url);
28
- const isAISummaryServiceInitiated = !!aISummaryService;
29
- if (isAISummaryServiceInitiated) {
30
- //if we want to subscribe to updates from an existing AI service that has not yet provided a summary or is currently in progress.
31
- const unsubscribe = aISummaryService.subscribe(setState);
32
- return () => unsubscribe();
33
- } else {
34
- var _AISummariesStore$get3;
35
- //if we want to create a new AI service and wish to subscribe for updates
36
- AISummariesStore.set(url, new AISummaryService({
37
- url,
38
- baseUrl,
39
- product,
40
- headers
41
- }));
42
- const unsubscribe = (_AISummariesStore$get3 = AISummariesStore.get(url)) === null || _AISummariesStore$get3 === void 0 ? void 0 : _AISummariesStore$get3.subscribe(setState);
43
- return () => unsubscribe && unsubscribe();
44
- }
17
+ var _AISummariesStore$get2;
18
+ if (!AISummariesStore.get(url)) {
19
+ AISummariesStore.set(url, new AISummaryService({
20
+ url,
21
+ baseUrl,
22
+ headers,
23
+ product
24
+ }));
45
25
  }
46
- }, [isSummarisedOnMount, url, baseUrl, product, headers]);
26
+
27
+ //returns function that calls unsubscribe method
28
+ return (_AISummariesStore$get2 = AISummariesStore.get(url)) === null || _AISummariesStore$get2 === void 0 ? void 0 : _AISummariesStore$get2.subscribe(setState);
29
+ }, [url, baseUrl, headers, product]);
47
30
  const summariseUrl = () => {
48
- var _AISummariesStore$get4;
49
- return (_AISummariesStore$get4 = AISummariesStore.get(url)) === null || _AISummariesStore$get4 === void 0 ? void 0 : _AISummariesStore$get4.summariseUrl();
31
+ var _AISummariesStore$get3;
32
+ return (_AISummariesStore$get3 = AISummariesStore.get(url)) === null || _AISummariesStore$get3 === void 0 ? void 0 : _AISummariesStore$get3.summariseUrl();
50
33
  };
51
34
  return {
52
- isSummarisedOnMount,
53
35
  summariseUrl,
54
36
  state
55
37
  };
@@ -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: "26.49.0"
7
+ packageVersion: "26.49.1"
8
8
  };
9
9
  export let TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
10
10
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -1,5 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React, { useCallback, useMemo, useState } from 'react';
2
+ import React, { useCallback, useMemo, useRef, useState, useEffect } from 'react';
3
3
  import { FormattedMessage } from 'react-intl-next';
4
4
  import { Box, Inline } from '@atlaskit/primitives';
5
5
  import { ActionName, SmartLinkDirection, SmartLinkSize, SmartLinkWidth } from '../../../../../../constants';
@@ -21,40 +21,46 @@ const AISummaryBlockResolvedView = props => {
21
21
  actions = [],
22
22
  metadata,
23
23
  onActionMenuOpenChange,
24
- onAIActionChange,
25
24
  size = SmartLinkSize.Medium,
26
- testId
25
+ testId,
26
+ aiSummaryMinHeight
27
27
  } = props;
28
- const [aiState, setAIState] = useState('ready');
28
+ const metadataElements = renderElementItems(metadata);
29
29
  const {
30
30
  fireEvent
31
31
  } = useAnalyticsEvents();
32
- const metadataElements = renderElementItems(metadata);
33
32
  const context = useFlexibleUiContext();
34
33
  const url = (context === null || context === void 0 ? void 0 : context.url) || '';
35
- const aiSummary = useAISummary({
36
- url
37
- });
38
34
  const {
35
+ summariseUrl,
39
36
  state: {
40
37
  content,
41
38
  status
42
- },
43
- isSummarisedOnMount
44
- } = aiSummary;
45
- const onAIActionClick = useCallback(() => {
46
- fireEvent('ui.button.clicked.aiSummary', {});
47
- setAIState('loading');
48
- if (onAIActionChange) {
49
- onAIActionChange('loading');
50
39
  }
51
- }, [onAIActionChange, fireEvent]);
40
+ } = useAISummary({
41
+ url
42
+ });
43
+ const showAISummary = status !== 'ready' && status !== 'error';
44
+ const isSummarisedOnMountRef = useRef(status === 'done');
45
+ let isErroredOnMountRef = useRef(status === 'error');
46
+ const [showAISummaryErrorMessage, setShowAISummaryErrorMessage] = useState(false);
47
+ useEffect(() => {
48
+ if (isErroredOnMountRef.current && status === 'loading') {
49
+ isErroredOnMountRef.current = false;
50
+ setShowAISummaryErrorMessage(true);
51
+ } else {
52
+ setShowAISummaryErrorMessage(!isErroredOnMountRef.current && status === 'error');
53
+ }
54
+ }, [status]);
52
55
  const combinedActions = useMemo(() => {
53
- if (aiState === 'ready') {
56
+ if (status === 'ready' || status === 'error') {
54
57
  const aiAction = {
55
58
  content: /*#__PURE__*/React.createElement(FormattedMessage, messages.ai_summarize),
56
59
  name: ActionName.CustomAction,
57
- onClick: onAIActionClick,
60
+ onClick: () => {
61
+ fireEvent('ui.button.clicked.aiSummary', {});
62
+ summariseUrl();
63
+ },
58
64
  testId: `${testId}-ai-summary-action`,
59
65
  icon: /*#__PURE__*/React.createElement(AIIcon, {
60
66
  label: "AIIcon"
@@ -63,7 +69,7 @@ const AISummaryBlockResolvedView = props => {
63
69
  return [aiAction, ...actions];
64
70
  }
65
71
  return actions;
66
- }, [actions, aiState, onAIActionClick, testId]);
72
+ }, [actions, status, testId, summariseUrl, fireEvent]);
67
73
  const onDropdownOpenChange = useCallback(isOpen => {
68
74
  if (onActionMenuOpenChange) {
69
75
  onActionMenuOpenChange({
@@ -75,17 +81,18 @@ const AISummaryBlockResolvedView = props => {
75
81
  direction: SmartLinkDirection.Vertical,
76
82
  testId: `${testId}-resolved-view`
77
83
  }), status === 'done' && /*#__PURE__*/React.createElement(AIEventSummaryViewed, {
78
- fromCache: isSummarisedOnMount
79
- }), /*#__PURE__*/React.createElement(AISummary, {
84
+ fromCache: isSummarisedOnMountRef.current
85
+ }), showAISummary && /*#__PURE__*/React.createElement(AISummary, {
86
+ minHeight: aiSummaryMinHeight,
80
87
  content: content,
81
- showIcon: isSummarisedOnMount
88
+ showIcon: isSummarisedOnMountRef.current
82
89
  }), /*#__PURE__*/React.createElement(Inline, {
83
90
  alignBlock: "center",
84
91
  alignInline: "end",
85
92
  grow: "fill",
86
93
  spread: "space-between"
87
- }, /*#__PURE__*/React.createElement(Box, null, !isSummarisedOnMount && (aiState === 'loading' || aiState === 'done') ? /*#__PURE__*/React.createElement(AIStateIndicator, {
88
- state: aiState,
94
+ }, /*#__PURE__*/React.createElement(Box, null, !isSummarisedOnMountRef.current && (status === 'loading' || status === 'done') ? /*#__PURE__*/React.createElement(AIStateIndicator, {
95
+ state: status,
89
96
  testId: `${testId}-state-indicator`
90
97
  }) : /*#__PURE__*/React.createElement(ElementGroup, {
91
98
  width: SmartLinkWidth.FitToContent,
@@ -95,7 +102,7 @@ const AISummaryBlockResolvedView = props => {
95
102
  items: combinedActions,
96
103
  appearance: "default",
97
104
  size: size
98
- }))), status === 'error' && /*#__PURE__*/React.createElement(Inline, {
105
+ }))), showAISummaryErrorMessage && /*#__PURE__*/React.createElement(Inline, {
99
106
  grow: "fill"
100
107
  }, /*#__PURE__*/React.createElement(AIEventErrorViewed, null), /*#__PURE__*/React.createElement(AIStateIndicator, {
101
108
  state: status,
@@ -1,28 +1,53 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  /** @jsx jsx */
3
3
  import { jsx } from '@emotion/react';
4
- import React from 'react';
4
+ import React, { useState, useEffect } from 'react';
5
5
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
6
6
  import { HoverCardContainer, popupContainerStyles } from '../styled';
7
7
  import AIPrism from '../../common/ai-prism';
8
8
  import { hoverCardClassName } from './HoverCardContent';
9
+ import { useAISummary } from '../../../state/hooks/use-ai-summary';
10
+ const ConnectedAIPrismContainer = ({
11
+ children,
12
+ isAIEnabled = false,
13
+ testId,
14
+ url,
15
+ ...props
16
+ }) => {
17
+ const {
18
+ state: {
19
+ status
20
+ }
21
+ } = useAISummary({
22
+ url
23
+ });
24
+ const [showPrism, setShowPrism] = useState(status === 'loading');
25
+ useEffect(() => {
26
+ setShowPrism(status === 'loading');
27
+ }, [status]);
28
+ const container = jsx("div", _extends({
29
+ className: hoverCardClassName,
30
+ css: [HoverCardContainer, isAIEnabled && showPrism ? undefined : popupContainerStyles],
31
+ "data-testid": testId
32
+ }, props), children);
33
+ return isAIEnabled ? jsx(AIPrism, {
34
+ isVisible: showPrism,
35
+ testId: `${testId}-prism`
36
+ }, container) : container;
37
+ };
9
38
  const ContentContainer = ({
10
39
  children,
11
40
  isAIEnabled = false,
12
- showPrism = false,
13
41
  testId,
42
+ url,
14
43
  ...props
15
44
  }) => {
16
45
  if (getBooleanFF('platform.linking-platform.smart-card.hover-card-ai-summaries')) {
17
- const container = jsx("div", _extends({
18
- className: hoverCardClassName,
19
- css: [HoverCardContainer, isAIEnabled && showPrism ? undefined : popupContainerStyles],
20
- "data-testid": testId
46
+ return jsx(ConnectedAIPrismContainer, _extends({
47
+ isAIEnabled: isAIEnabled,
48
+ url: url,
49
+ testId: testId
21
50
  }, props), children);
22
- return isAIEnabled ? jsx(AIPrism, {
23
- isVisible: showPrism,
24
- testId: `${testId}-prism`
25
- }, container) : container;
26
51
  }
27
52
  return jsx("div", _extends({
28
53
  className: hoverCardClassName,
@@ -2,7 +2,7 @@
2
2
  import { jsx } from '@emotion/react';
3
3
  import { useAnalyticsEvents } from '@atlaskit/analytics-next';
4
4
  import CopyIcon from '@atlaskit/icon/glyph/copy';
5
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
6
6
  import { useSmartLinkContext } from '@atlaskit/link-provider';
7
7
  import { ActionName, CardDisplay, SmartLinkPosition, SmartLinkSize } from '../../../constants';
8
8
  import { extractMetadata } from '../../../extractors/hover/extractMetadata';
@@ -61,7 +61,6 @@ const HoverCardContent = ({
61
61
  const services = getServices(linkState.details);
62
62
  const statusRef = useRef(linkStatus);
63
63
  const analyticsRef = useRef(analytics);
64
- const [showPrism, setShowPrism] = useState(false);
65
64
  useEffect(() => {
66
65
  /**
67
66
  * Must access current analytics object value via ref because its not stable
@@ -131,9 +130,6 @@ const HoverCardContent = ({
131
130
  analytics
132
131
  };
133
132
  const onClickStopPropagation = useCallback(e => e.stopPropagation(), []);
134
- const onAIActionChange = useCallback(state => {
135
- setShowPrism(state === 'loading');
136
- }, []);
137
133
  const getCardView = cardState => {
138
134
  if (cardState.metadataStatus === 'pending') {
139
135
  return jsx(HoverCardLoadingView, {
@@ -166,7 +162,6 @@ const HoverCardContent = ({
166
162
  flexibleCardProps: flexibleCardProps,
167
163
  isAISummaryEnabled: isAISummaryEnabled,
168
164
  onActionClick: onActionClick,
169
- onAIActionChange: onAIActionChange,
170
165
  titleBlockProps: titleBlockProps
171
166
  });
172
167
  }
@@ -178,7 +173,7 @@ const HoverCardContent = ({
178
173
  onMouseLeave: onMouseLeave,
179
174
  onClick: onClickStopPropagation,
180
175
  isAIEnabled: isAISummaryEnabled,
181
- showPrism: showPrism
176
+ url: url
182
177
  }, cardView) : null;
183
178
  };
184
179
  export default HoverCardContent;
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
3
- import { ActionName, CardDisplay, ElementName, SmartLinkPosition, SmartLinkSize } from '../../../../../constants';
4
- import { FooterBlock, MetadataBlock, RelatedUrlsBlock, SnippetBlock, TitleBlock, AISummaryBlock } from '../../../../FlexibleCard/components/blocks';
3
+ import { ActionName, CardDisplay, ElementName, SmartLinkPosition, SmartLinkSize, SmartLinkDirection } from '../../../../../constants';
4
+ import { FooterBlock, MetadataBlock, RelatedUrlsBlock, SnippetBlock, TitleBlock, AISummaryBlock, CustomBlock } from '../../../../FlexibleCard/components/blocks';
5
5
  import { footerBlockCss, hiddenSnippetStyles, metadataBlockCss } from './styled';
6
6
  import FlexibleCard from '../../../../FlexibleCard';
7
7
  import { getSimulatedBetterMetadata } from '../../../utils';
@@ -11,6 +11,8 @@ import { messages } from '../../../../../messages';
11
11
  import { FormattedMessage } from 'react-intl-next';
12
12
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
13
13
  import { getCanBeDatasource } from '../../../../../state/helpers';
14
+ import { useAISummary } from '../../../../../state/hooks/use-ai-summary';
15
+ import { SmartLinkStatus } from '../../../../../constants';
14
16
  export const toFooterActions = (cardActions, onActionClick) => {
15
17
  const followAction = {
16
18
  hideIcon: true,
@@ -45,6 +47,30 @@ export const toFooterActions = (cardActions, onActionClick) => {
45
47
  });
46
48
  return [followAction, ...actions];
47
49
  };
50
+
51
+ //This component encapsulates useAISummary hook under the AI Summary FF 'platform.linking-platform.smart-card.hover-card-ai-summaries'
52
+ const ConnectedAIBlock = ({
53
+ bottomPrimary,
54
+ url,
55
+ imagePreview
56
+ }) => {
57
+ const aiSummary = useAISummary({
58
+ url
59
+ });
60
+ const aiStatus = aiSummary.state.status;
61
+ const showData = aiStatus === 'ready' || aiStatus === 'error';
62
+ return showData ? /*#__PURE__*/React.createElement(CustomBlock, {
63
+ direction: SmartLinkDirection.Vertical
64
+ }, !imagePreview && /*#__PURE__*/React.createElement(SnippetBlock, {
65
+ status: SmartLinkStatus.Resolved
66
+ }), /*#__PURE__*/React.createElement(MetadataBlock, {
67
+ primary: bottomPrimary,
68
+ size: SmartLinkSize.Large,
69
+ overrideCss: metadataBlockCss,
70
+ maxLines: 1,
71
+ status: SmartLinkStatus.Resolved
72
+ })) : null;
73
+ };
48
74
  const HoverCardResolvedView = ({
49
75
  flexibleCardProps,
50
76
  titleBlockProps,
@@ -53,7 +79,6 @@ const HoverCardResolvedView = ({
53
79
  cardActions = [],
54
80
  isAISummaryEnabled,
55
81
  onActionClick,
56
- onAIActionChange,
57
82
  extensionKey,
58
83
  url
59
84
  }) => {
@@ -88,6 +113,15 @@ const HoverCardResolvedView = ({
88
113
  var _snippetBlockRef$curr, _snippetBlockRef$curr2;
89
114
  snippetHeight.current = (_snippetBlockRef$curr = (_snippetBlockRef$curr2 = snippetBlockRef.current) === null || _snippetBlockRef$curr2 === void 0 ? void 0 : _snippetBlockRef$curr2.getBoundingClientRect().height) !== null && _snippetBlockRef$curr !== void 0 ? _snippetBlockRef$curr : 0;
90
115
  }, []);
116
+
117
+ // We want to maintain the height of the HoverCard while summarizing and pass this height to the AISummaryBlock.
118
+ // This approach will prevent any abrupt changes in the height of the HoverCard.
119
+ const connectedAIBlockHeight = React.useRef(0);
120
+ const connectedAIBlockRef = useRef(null);
121
+ const onConnectedAIBlockRender = useCallback(() => {
122
+ var _connectedAIBlockRef$, _connectedAIBlockRef$2;
123
+ connectedAIBlockHeight.current = (_connectedAIBlockRef$ = (_connectedAIBlockRef$2 = connectedAIBlockRef.current) === null || _connectedAIBlockRef$2 === void 0 ? void 0 : _connectedAIBlockRef$2.getBoundingClientRect().height) !== null && _connectedAIBlockRef$ !== void 0 ? _connectedAIBlockRef$ : 0;
124
+ }, []);
91
125
  const imagePreview = ImagePreview({
92
126
  data: data,
93
127
  fallbackElementHeight: snippetHeight.current
@@ -100,16 +134,31 @@ const HoverCardResolvedView = ({
100
134
  overrideCss: metadataBlockCss,
101
135
  maxLines: 1,
102
136
  size: SmartLinkSize.Medium
103
- }), !imagePreview && /*#__PURE__*/React.createElement(SnippetBlock, null), /*#__PURE__*/React.createElement(SnippetBlock, {
137
+ }), isAISummaryEnabled &&
138
+ /*#__PURE__*/
139
+ // All custom elements should be contained within a CustomBlock.
140
+ // Flex Container components check whether the direct child is a flex blocks. It removes anything that isn't
141
+ React.createElement(CustomBlock, {
142
+ direction: SmartLinkDirection.Vertical,
143
+ onRender: onConnectedAIBlockRender,
144
+ blockRef: connectedAIBlockRef
145
+ }, /*#__PURE__*/React.createElement(ConnectedAIBlock, {
146
+ imagePreview: !!imagePreview,
147
+ url: url,
148
+ bottomPrimary: bottomPrimary
149
+ })), !isAISummaryEnabled && !imagePreview && /*#__PURE__*/React.createElement(SnippetBlock, {
150
+ status: SmartLinkStatus.Resolved
151
+ }), /*#__PURE__*/React.createElement(SnippetBlock, {
104
152
  testId: 'hidden-snippet',
105
153
  onRender: onSnippetRender,
106
154
  blockRef: snippetBlockRef,
107
155
  overrideCss: hiddenSnippetStyles
108
- }), /*#__PURE__*/React.createElement(MetadataBlock, {
156
+ }), !isAISummaryEnabled && /*#__PURE__*/React.createElement(MetadataBlock, {
109
157
  primary: bottomPrimary,
110
158
  size: SmartLinkSize.Large,
111
159
  overrideCss: metadataBlockCss,
112
- maxLines: 1
160
+ maxLines: 1,
161
+ status: SmartLinkStatus.Resolved
113
162
  }), getBooleanFF('platform.linking-platform.smart-card.enable-hover-card-related-urls') && /*#__PURE__*/React.createElement(RelatedUrlsBlock, {
114
163
  url: url,
115
164
  size: SmartLinkSize.Small
@@ -118,7 +167,7 @@ const HoverCardResolvedView = ({
118
167
  name: ElementName.Provider
119
168
  }],
120
169
  actions: footerActions,
121
- onAIActionChange: onAIActionChange
170
+ aiSummaryMinHeight: connectedAIBlockHeight.current
122
171
  }) : /*#__PURE__*/React.createElement(FooterBlock, {
123
172
  actions: footerActions,
124
173
  size: SmartLinkSize.Large,
@@ -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: "26.49.0",
10
+ packageVersion: "26.49.1",
11
11
  componentName: 'linkUrl'
12
12
  };
13
13
  const Link = withLinkClickedEvent('a');
@@ -21,13 +21,14 @@ const AISummaryCSS = css({
21
21
  */
22
22
 
23
23
  const AISummary = ({
24
- content,
24
+ content = '',
25
25
  showIcon = false,
26
26
  iconComponent,
27
27
  overrideCss,
28
- testId = 'ai-summary'
28
+ testId = 'ai-summary',
29
+ minHeight = 0
29
30
  }) => {
30
- if (!content) {
31
+ if (!content && minHeight === 0) {
31
32
  return null;
32
33
  }
33
34
  return jsx(Markdown, {
@@ -39,6 +40,9 @@ const AISummary = ({
39
40
  overrides: {
40
41
  Icon: iconComponent !== null && iconComponent !== void 0 ? iconComponent : AITooltipIcon
41
42
  }
43
+ },
44
+ style: {
45
+ minHeight: minHeight
42
46
  }
43
47
  });
44
48
  };
@@ -44,8 +44,14 @@ export var AISummaryService = /*#__PURE__*/function () {
44
44
  return fetch(requestUrl, options);
45
45
  case 6:
46
46
  response = _context.sent;
47
+ if (!(!response.ok || response.status >= 400)) {
48
+ _context.next = 11;
49
+ break;
50
+ }
51
+ throw new Error("Status: ".concat(response.status, "\n URL: ").concat(_this.url, "\n StatusText ").concat(response.statusText));
52
+ case 11:
47
53
  return _context.abrupt("return", readStream(response));
48
- case 8:
54
+ case 12:
49
55
  case "end":
50
56
  return _context.stop();
51
57
  }
@@ -96,10 +102,11 @@ export var AISummaryService = /*#__PURE__*/function () {
96
102
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
97
103
  while (1) switch (_context2.prev = _context2.next) {
98
104
  case 0:
99
- summaryStyle = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : 'short';
100
- this.state = _objectSpread(_objectSpread({}, this.state), {}, {
101
- status: 'loading'
102
- });
105
+ summaryStyle = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : 'medium';
106
+ this.state = {
107
+ status: 'loading',
108
+ content: ''
109
+ };
103
110
  _iterator2 = _createForOfIteratorHelper(this.subscribedStateSetters);
104
111
  try {
105
112
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
@@ -126,7 +133,7 @@ export var AISummaryService = /*#__PURE__*/function () {
126
133
  return _iterator.next();
127
134
  case 15:
128
135
  if (!(_iteratorAbruptCompletion = !(_step = _context2.sent).done)) {
129
- _context2.next = 21;
136
+ _context2.next = 22;
130
137
  break;
131
138
  }
132
139
  chunk = _step.value;
@@ -146,53 +153,58 @@ export var AISummaryService = /*#__PURE__*/function () {
146
153
  _iterator3.f();
147
154
  }
148
155
  }
149
- case 18:
156
+
157
+ //if AI Mate service returns cached summary we get the summary text in one piece as the last message
158
+ if (chunk.type === 'FINAL_RESPONSE') {
159
+ bufferContent = chunk.message.message.content;
160
+ }
161
+ case 19:
150
162
  _iteratorAbruptCompletion = false;
151
163
  _context2.next = 13;
152
164
  break;
153
- case 21:
154
- _context2.next = 27;
165
+ case 22:
166
+ _context2.next = 28;
155
167
  break;
156
- case 23:
157
- _context2.prev = 23;
168
+ case 24:
169
+ _context2.prev = 24;
158
170
  _context2.t0 = _context2["catch"](11);
159
171
  _didIteratorError = true;
160
172
  _iteratorError = _context2.t0;
161
- case 27:
162
- _context2.prev = 27;
173
+ case 28:
163
174
  _context2.prev = 28;
175
+ _context2.prev = 29;
164
176
  if (!(_iteratorAbruptCompletion && _iterator.return != null)) {
165
- _context2.next = 32;
177
+ _context2.next = 33;
166
178
  break;
167
179
  }
168
- _context2.next = 32;
180
+ _context2.next = 33;
169
181
  return _iterator.return();
170
- case 32:
171
- _context2.prev = 32;
182
+ case 33:
183
+ _context2.prev = 33;
172
184
  if (!_didIteratorError) {
173
- _context2.next = 35;
185
+ _context2.next = 36;
174
186
  break;
175
187
  }
176
188
  throw _iteratorError;
177
- case 35:
178
- return _context2.finish(32);
179
189
  case 36:
180
- return _context2.finish(27);
190
+ return _context2.finish(33);
181
191
  case 37:
192
+ return _context2.finish(28);
193
+ case 38:
182
194
  this.state = {
183
195
  status: 'done',
184
196
  content: bufferContent
185
197
  };
186
- _context2.next = 43;
198
+ _context2.next = 44;
187
199
  break;
188
- case 40:
189
- _context2.prev = 40;
200
+ case 41:
201
+ _context2.prev = 41;
190
202
  _context2.t1 = _context2["catch"](4);
191
203
  this.state = {
192
204
  status: 'error',
193
205
  content: ''
194
206
  };
195
- case 43:
207
+ case 44:
196
208
  _iterator4 = _createForOfIteratorHelper(this.subscribedStateSetters);
197
209
  try {
198
210
  for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
@@ -204,11 +216,11 @@ export var AISummaryService = /*#__PURE__*/function () {
204
216
  } finally {
205
217
  _iterator4.f();
206
218
  }
207
- case 45:
219
+ case 46:
208
220
  case "end":
209
221
  return _context2.stop();
210
222
  }
211
- }, _callee2, this, [[4, 40], [11, 23, 27, 37], [28,, 32, 36]]);
223
+ }, _callee2, this, [[4, 41], [11, 24, 28, 38], [29,, 33, 37]]);
212
224
  }));
213
225
  function summariseUrl() {
214
226
  return _summariseUrl.apply(this, arguments);