Skip to content

Commit b98a4f6

Browse files
feat: Improve UX of AI banner (kyma-project#4061)
* UX corrections and new translations added * update SVGs for AI banner * Move styles to adjust the entire banner component * Styles for better responsiveness have been added * Update kyma/environments/prod/config.yaml Co-authored-by: Mateusz Wisniewski <mwisnia97@gmail.com> * AI banner description corrected --------- Co-authored-by: mrCherry97 <mwisnia97@gmail.com>
1 parent 0ed1c99 commit b98a4f6

File tree

15 files changed

+190
-144
lines changed

15 files changed

+190
-144
lines changed

kyma/environments/dev/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ config:
7272
isEnabled: true
7373
config:
7474
feedbackLink: https://www.youtube.com/watch?v=dQw4w9WgXcQ
75+
documentationLink: https://help.sap.com/docs/btp/sap-business-technology-platform-internal/kyma-companion?locale=en-US&version=Internal&state=DRAFT
7576
model: 'gpt-4.1'
7677
queryMaxTokens: 8000
7778
TRACKING:

kyma/environments/prod/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ config:
7575
isEnabled: false
7676
config:
7777
feedbackLink: ''
78+
documentationLink: ''
7879
model: ''
7980
queryMaxTokens: 0
8081
GARDENER_LOGIN:

kyma/environments/stage/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ config:
7373
isEnabled: true
7474
config:
7575
feedbackLink: https://sapinsights.eu.qualtrics.com/jfe/form/SV_dmWATTfes5SstG6
76+
documentationLink: https://help.sap.com/docs/btp/sap-business-technology-platform-internal/kyma-companion?locale=en-US&version=Internal&state=DRAFT
7677
model: 'gpt-4.1'
7778
queryMaxTokens: 8000
7879
GARDENER_LOGIN:

public/defaultConfig.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ config:
5656
isEnabled: false
5757
config:
5858
feedbackLink: https://sapinsights.eu.qualtrics.com/jfe/preview/previewId/1fa80b40-56c3-4b20-9902-877df3da3493/SV_dmWATTfes5SstG6?Q_CHL=preview&Q_SurveyVersionID=current
59+
documentationLink: https://help.sap.com/docs/btp/sap-business-technology-platform-internal/kyma-companion?locale=en-US&version=Internal&state=DRAFT
5960
model: 'gpt-4.1'
6061
queryMaxTokens: 8000
6162
TRACKING:

public/i18n/en.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,9 +767,10 @@ kubeconfig-id:
767767
kyma-companion:
768768
banner:
769769
title: Meet Joule
770-
description: Joule is your personal, contextual assistant, ready to help with all Kyma-related questions. Ask about Kyma features, Kubernetes best practices, step-by-step instructions, and more.
770+
description: Joule in Kyma dashboard assists you with a wide range of tasks specific to Kyma and Kubernetes. You can use it, for example, to troubleshoot issues, create Functions, scale applications, or configure Ingress. As this is an experimental feature, we encourage you to explore its capabilities and share your feedback to help us improve.
771771
buttons:
772772
try-joule: Try Out Joule
773+
documentation: Documentation
773774
name: Joule
774775
feedback:
775776
title: We’d love to hear from you!

src/components/Clusters/views/ClusterOverview/ClusterOverview.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,21 @@ export function ClusterOverview() {
9595
actions={actions}
9696
content={
9797
<>
98-
<BannerCarousel
99-
children={
100-
<>
101-
{isKymaCompanionEnabled && (
102-
<AIBanner feedbackUrl={companionConfig?.feedbackLink} />
103-
)}
104-
<Injections
105-
destination="ClusterOverview"
106-
slot="banner"
107-
root=""
98+
<BannerCarousel>
99+
<>
100+
{isKymaCompanionEnabled && (
101+
<AIBanner
102+
feedbackUrl={companionConfig?.feedbackLink}
103+
documentationUrl={companionConfig?.documentationLink}
108104
/>
109-
</>
110-
}
111-
/>
105+
)}
106+
<Injections
107+
destination="ClusterOverview"
108+
slot="banner"
109+
root=""
110+
/>
111+
</>
112+
</BannerCarousel>
112113
<Injections
113114
destination="ClusterOverview"
114115
slot="details-top"

src/components/KymaCompanion/components/AIBanner/AIBanner.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ const getIllustration = (theme: ThemeType): string | undefined => {
2727
}
2828
};
2929

30-
export function AIBanner({ feedbackUrl }: { feedbackUrl: string }) {
30+
export function AIBanner({
31+
feedbackUrl,
32+
documentationUrl,
33+
}: {
34+
feedbackUrl: string;
35+
documentationUrl: string;
36+
}) {
3137
const { t } = useTranslation();
3238
const setShowCompanion = useSetRecoilState(showKymaCompanionState);
3339
const theme = useRecoilValue(themeState);
@@ -36,6 +42,7 @@ export function AIBanner({ feedbackUrl }: { feedbackUrl: string }) {
3642
return (
3743
<FeatureCardBanner
3844
id="ai-banner"
45+
className="ai-banner-card"
3946
title={t('kyma-companion.banner.title')}
4047
titleIcon={titleIcon}
4148
description={t('kyma-companion.banner.description')}
@@ -65,6 +72,15 @@ export function AIBanner({ feedbackUrl }: { feedbackUrl: string }) {
6572
>
6673
{t('feedback.give-feedback')}
6774
</Button>
75+
<Button
76+
key="ai-documentation"
77+
endIcon="inspect"
78+
onClick={() => {
79+
window.open(documentationUrl, '_blank');
80+
}}
81+
>
82+
{t('kyma-companion.banner.buttons.documentation')}
83+
</Button>
6884
</>
6985
}
7086
/>

src/shared/components/FeatureCard/BannerCarousel.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,24 @@ export default function BannerCarousel({ children }: { children: ReactNode }) {
66
const [childrenLength, setChildrenLength] = useState(0);
77
const [activeIndex, setActiveIndex] = useState(0);
88
const [isHovered, setIsHovered] = useState(false);
9-
const SCROLL_INTERVALL_MS = 6000;
9+
const [isUserChoice, setIsUserChoice] = useState(false);
10+
const SCROLL_INTERVALL_MS = 25000;
1011

1112
useEffect(() => {
1213
setChildrenLength(carouselRef?.current?.children?.length ?? 0);
1314
}, [carouselRef?.current?.children?.length]);
1415

1516
useEffect(() => {
1617
const timeoutId = setTimeout(() => {
17-
if (!isHovered) {
18+
if (!isHovered && !isUserChoice) {
1819
const newIndex = (activeIndex + 1) % childrenLength;
1920
carouselRef?.current?.navigateTo(newIndex);
2021
setActiveIndex(newIndex);
2122
}
2223
}, SCROLL_INTERVALL_MS);
2324

2425
return () => clearTimeout(timeoutId);
25-
}, [activeIndex, isHovered, childrenLength]);
26+
}, [activeIndex, isHovered, childrenLength, isUserChoice]);
2627

2728
const handleMouseEnter = () => {
2829
setIsHovered(true);
@@ -39,12 +40,16 @@ export default function BannerCarousel({ children }: { children: ReactNode }) {
3940
backgroundDesign="Transparent"
4041
pageIndicatorBackgroundDesign="Transparent"
4142
pageIndicatorBorderDesign="None"
42-
children={children}
4343
ref={carouselRef}
4444
style={childrenLength === 0 ? { display: 'none' } : {}}
45-
onNavigate={event => setActiveIndex(event.detail.selectedIndex)}
45+
onNavigate={event => {
46+
setIsUserChoice(true);
47+
setActiveIndex(event.detail.selectedIndex);
48+
}}
4649
onMouseEnter={handleMouseEnter}
4750
onMouseLeave={handleMouseLeave}
48-
/>
51+
>
52+
{children}
53+
</Carousel>
4954
);
5055
}

src/shared/components/FeatureCard/FeatureCard.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export function FeatureCardBanner({
6262
image = '',
6363
buttons,
6464
titleIcon,
65+
className = '',
6566
}: FeatureCardBannerProps) {
6667
const [hideBanner, setHideBanner] = useState(false);
6768
const hideBannerKey = `hideBanner${id}`;
@@ -98,7 +99,7 @@ export function FeatureCardBanner({
9899
};
99100
const illustration = getIllustration(image, theme);
100101
return (
101-
<div className="sap-margin-top-small">
102+
<div className={`sap-margin-top-small ${className}`}>
102103
<Card className="feature-card-container">
103104
<div className="feature-card" style={getBackgroundStyle(design)}>
104105
<Button
@@ -107,7 +108,7 @@ export function FeatureCardBanner({
107108
className="decline-button"
108109
onClick={handleToggle}
109110
/>
110-
<div className="outer-container" style={{ margin: '2rem 2.5rem' }}>
111+
<div className="outer-container">
111112
<div className="inner-container">
112113
<div style={{ width: '100%' }} className="title-container">
113114
<Title
@@ -118,7 +119,8 @@ export function FeatureCardBanner({
118119
display: 'inline-flex',
119120
}}
120121
>
121-
{title}
122+
{/* This extra span element is for the ability to add additional styles that cannot be added to the Title component. */}
123+
<span className="banner-title">{title}</span>
122124
</Title>
123125
{titleIcon && (
124126
<img

src/shared/components/FeatureCard/FeaturedCard.scss

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,48 +22,68 @@
2222
display: flex;
2323
align-items: center;
2424
justify-content: space-between;
25-
gap: 50px;
25+
padding: 32px 32px 0 32px;
2626
}
2727

2828
.inner-container {
2929
display: flex;
3030
flex-direction: column;
3131
gap: 16px;
32-
width: 100%;
32+
width: 50%;
33+
max-width: 700px;
34+
margin: 0 32px 32px 0;
35+
36+
.title-container {
37+
ui5-title {
38+
margin-right: 8px;
39+
.banner-title {
40+
font-weight: 900;
41+
}
42+
}
43+
img {
44+
width: 46px;
45+
height: 46px;
46+
}
47+
}
48+
ui5-text {
49+
font-size: 16px;
50+
font-weight: 400;
51+
line-height: 24px;
52+
}
3353

3454
.button-container {
3555
display: flex;
36-
gap: 16px;
56+
margin-top: 8px;
57+
gap: 8px;
3758
}
3859
}
3960

4061
.decline-button {
4162
position: absolute;
42-
top: 12.5px;
43-
right: 17.5px;
63+
top: 8px;
64+
right: 8px;
4465
color: var(--sapContent_IconColor);
4566
}
4667

4768
.illustration {
48-
max-height: 180px;
49-
max-width: 100%;
50-
margin-right: 4%;
69+
height: 100%;
70+
max-width: 50%;
5171
}
5272
}
5373

54-
@container (max-width: 850px) {
74+
@container (max-width: 625px) {
5575
.feature-card {
5676
.illustration {
57-
margin-right: 0%;
77+
max-width: 100%;
5878
}
59-
}
60-
}
61-
62-
@container (max-width: 625px) {
63-
.feature-card {
6479
.outer-container {
6580
flex-direction: column-reverse;
66-
gap: 16px;
81+
align-items: start;
82+
gap: 32px;
83+
84+
.inner-container {
85+
width: 100%;
86+
}
6787
}
6888
}
6989
}

0 commit comments

Comments
 (0)