Skip to content

Commit 8a732df

Browse files
authored
feat: Add AI notice screen (#3973)
* feat: add AI notice screen * feat: add shadow to input field * feat: add some gradient to companion header * feat: add link to privacy policy
1 parent 37e329f commit 8a732df

File tree

9 files changed

+182
-14
lines changed

9 files changed

+182
-14
lines changed

public/i18n/en.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,12 @@ kyma-companion:
781781
introduction: Hi, I am your Kyma assistant! You can ask me any question, and I will try to help you to the best of my abilities. Meanwhile, you can check the suggested questions below; you may find them helpful!
782782
introduction-no-suggestions: Hi, I am your Kyma assistant! You can ask me any question, and I will try to help you to the best of my abilities. While I don't have any initial suggestions for this resource, feel free to ask me anything you'd like!
783783
placeholder: Message Joule...
784-
disclaimer: Joule is powered by generative AI, and the output must be reviewed before use. Do not enter any sensitive personal data, and avoid entering any other data you do not wish to be processed.
784+
disclaimer:
785+
tooltip: Disclaimer
786+
title: AI Notice
787+
text: "Joule is powered by generative AI and all output should be reviewed before use. Please do not enter any sensitive personal data, and avoid entering any other personal data you do not wish to be processed. Learn more in the <0>Joule Data Protection and Privacy</0>."
788+
hint: Joule uses AI. Verify results.
789+
back-conversation: Back to Conversation
785790
tabs:
786791
chat: Chat
787792
page-insights: Page Insights

src/components/KymaCompanion/components/Chat/Chat.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type ChatProps = {
3434
setIsReset: React.Dispatch<React.SetStateAction<boolean>>;
3535
error: AIError;
3636
setError: React.Dispatch<React.SetStateAction<AIError>>;
37+
hide: boolean;
3738
};
3839

3940
export const Chat = ({
@@ -45,6 +46,7 @@ export const Chat = ({
4546
setLoading,
4647
isReset,
4748
setIsReset,
49+
hide = false,
4850
}: ChatProps) => {
4951
const { t } = useTranslation();
5052
const chatRef = useRef<HTMLDivElement | null>(null);
@@ -315,6 +317,7 @@ export const Chat = ({
315317

316318
return (
317319
<FlexBox
320+
style={hide ? { display: 'none' } : undefined}
318321
direction="Column"
319322
justifyContent="SpaceBetween"
320323
className="chat-container"

src/components/KymaCompanion/components/Chat/Input/QueryInput.scss

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
--_ui5-v2-11-0_textarea_padding_top: 8px !important;
1010
--_ui5-v2-11-0_textarea_padding_bottom: 8px !important;
1111

12+
#query-input:focus::part(textarea) {
13+
box-shadow: 0px 1px 4px var(--sapLinkColor);
14+
}
15+
1216
.query-input-actions {
1317
position: absolute;
1418
right: 0.5rem;
@@ -42,7 +46,9 @@
4246
}
4347

4448
#disclaimer {
45-
font-size: 0.65rem;
49+
font-size: 11px;
50+
text-align: center;
51+
color: var(--sapContent_LabelColor);
4652
}
4753
}
4854
}

src/components/KymaCompanion/components/Chat/Input/QueryInput.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@ export default function QueryInput({
8080

8181
useEffect(() => {
8282
if (!loading && textareaRef.current) {
83-
textareaRef.current?.focus();
83+
requestAnimationFrame(() => {
84+
const innerTextarea = textareaRef.current?.shadowRoot?.querySelector(
85+
'.ui5-textarea-inner',
86+
) as HTMLElement;
87+
innerTextarea?.focus();
88+
});
8489
}
8590
}, [loading]);
8691

@@ -135,6 +140,7 @@ export default function QueryInput({
135140
<div className="outer-query-input-container sap-margin-x-small sap-margin-bottom-small sap-margin-top-tiny">
136141
<div className="query-input-container">
137142
<TextArea
143+
id="query-input"
138144
ref={textareaRef}
139145
disabled={loading}
140146
growing
@@ -174,7 +180,7 @@ export default function QueryInput({
174180
/>
175181
</div>
176182
</div>
177-
<Text id="disclaimer">{t('kyma-companion.disclaimer')}</Text>
183+
<Text id="disclaimer">{t('kyma-companion.disclaimer.hint')}</Text>
178184
</div>
179185
);
180186
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.disclaimer {
2+
height: calc(100vh - 60px - 1rem);
3+
background: var(--sapAssistant_BackgroundGradient);
4+
padding-inline: 2rem;
5+
display: flex;
6+
align-items: center;
7+
justify-content: center;
8+
9+
#content-container {
10+
padding-bottom: 60px;
11+
}
12+
13+
#disclaimer-icon {
14+
color: var(--sapContent_ContrastTextColor);
15+
height: 3rem;
16+
width: 3rem;
17+
}
18+
19+
#disclaimer-title {
20+
color: var(--sapContent_ContrastTextColor);
21+
font-size: 1.25rem;
22+
font-weight: bold;
23+
margin-top: 2rem;
24+
}
25+
26+
#disclaimer-text {
27+
color: var(--sapContent_ContrastTextColor);
28+
font-size: 1rem;
29+
text-align: center;
30+
max-width: 24rem;
31+
32+
ui5-link {
33+
color: var(--sapContent_ContrastTextColor);
34+
font-size: 1rem;
35+
text-shadow: none !important;
36+
}
37+
}
38+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Button, FlexBox, Link, Text } from '@ui5/webcomponents-react';
2+
import { useTranslation, Trans } from 'react-i18next';
3+
import JouleIcon from '../JouleIcon';
4+
import './Disclaimer.scss';
5+
6+
interface DisclaimerProps {
7+
hideDisclaimer: () => void;
8+
}
9+
10+
export default function Disclaimer({ hideDisclaimer }: DisclaimerProps) {
11+
const { t } = useTranslation();
12+
13+
return (
14+
<div className="disclaimer">
15+
<FlexBox
16+
id="content-container"
17+
direction="Column"
18+
justifyContent="Center"
19+
alignItems="Center"
20+
gap={16}
21+
>
22+
<JouleIcon size={4} />
23+
<Text id="disclaimer-title">
24+
{t('kyma-companion.disclaimer.title')}
25+
</Text>
26+
<Text id="disclaimer-text">
27+
<Trans
28+
i18nKey="kyma-companion.disclaimer.text"
29+
components={[
30+
<Link
31+
href="https://help.sap.com/docs/joule/serviceguide/data-protection-and-privacy"
32+
design="Subtle"
33+
target="_blank"
34+
/>,
35+
]}
36+
/>
37+
</Text>
38+
<Button
39+
className="sap-margin-top-small"
40+
onClick={hideDisclaimer}
41+
icon="discussion"
42+
>
43+
{t('kyma-companion.disclaimer.back-conversation')}
44+
</Button>
45+
</FlexBox>
46+
</div>
47+
);
48+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export default function JouleIcon({ size }: { size: number }) {
2+
return (
3+
<svg
4+
width={`${size}rem`}
5+
height={`${size}rem`}
6+
viewBox="0 0 122 120"
7+
fill="none"
8+
xmlns="http://www.w3.org/2000/svg"
9+
role="img"
10+
>
11+
<path
12+
fillRule="evenodd"
13+
clipRule="evenodd"
14+
d="M46.6026 37C45.3357 37 44.1364 37.5715 43.3379 38.5556L24.9405 61.23C23.7324 62.7189 23.6834 64.8368 24.8211 66.3802L61.616 116.29C62.4087 117.365 63.6647 118 65 118C66.3353 118 67.5913 117.365 68.384 116.29L105.179 66.3802C106.317 64.8368 106.268 62.7189 105.06 61.23L86.6621 38.5556C85.8636 37.5715 84.6643 37 83.3974 37H46.6026ZM88.3249 63.5392C79.643 62.0748 76.8647 55.2489 75.9469 50.9797C75.8477 50.5577 75.302 50.5825 75.2276 51.0045C73.764 59.6919 66.9425 62.4719 62.6759 63.3903C62.2543 63.4896 62.2791 64.0357 62.7008 64.1101C71.3827 65.5746 74.1609 72.4004 75.0787 76.6697C75.178 77.0917 75.7237 77.0668 75.7981 76.6449C77.2616 67.9574 84.0832 65.1774 88.3497 64.259C88.7714 64.1598 88.7466 63.6137 88.3249 63.5392Z"
15+
fill="var(--dasSplashScreenImageColor, #FFFFFF)"
16+
/>
17+
<path
18+
d="M101.542 20.3013C102.16 23.126 104.031 27.6422 109.878 28.6111C110.162 28.6604 110.179 29.0217 109.895 29.0874C107.022 29.695 102.428 31.5343 101.442 37.2822C101.392 37.5614 101.024 37.5778 100.958 37.2986C100.34 34.4739 98.4685 29.9578 92.6215 28.9888C92.3375 28.9396 92.3208 28.5783 92.6048 28.5126C95.4782 27.9049 100.072 26.0656 101.058 20.3178C101.108 20.0386 101.476 20.0222 101.542 20.3013Z"
19+
fill="var(--dasSplashScreenImageColor, #FFFFFF)"
20+
/>
21+
<path
22+
d="M42.2811 0.302036C43.1925 4.53904 45.9515 11.3133 54.5733 12.7667C54.9921 12.8406 55.0167 13.3826 54.598 13.4811C50.361 14.3925 43.5867 17.1515 42.1333 25.7733C42.0594 26.1921 41.5174 26.2167 41.4189 25.798C40.5075 21.561 37.7485 14.7867 29.1267 13.3333C28.7079 13.2594 28.6833 12.7174 29.102 12.6189C33.339 11.7075 40.1133 8.94848 41.5667 0.326668C41.6406 -0.0921059 42.1826 -0.116738 42.2811 0.302036Z"
23+
fill="var(--dasSplashScreenImageColor, #FFFFFF)"
24+
/>
25+
<path
26+
d="M16.7874 26.3048C17.395 29.1782 19.2344 33.7722 24.9822 34.7579C25.2614 34.808 25.2778 35.1755 24.9986 35.2423C22.174 35.8604 17.6578 37.7315 16.6889 43.5784C16.6396 43.8624 16.2783 43.8791 16.2126 43.5951C15.605 40.7218 13.7657 36.1277 8.01778 35.1421C7.7386 35.092 7.72218 34.7244 8.00136 34.6576C10.826 34.0395 15.3422 32.1685 16.3111 26.3215C16.3604 26.0375 16.7217 26.0208 16.7874 26.3048Z"
27+
fill="var(--dasSplashScreenImageColor, #FFFFFF)"
28+
/>
29+
</svg>
30+
);
31+
}

src/components/KymaCompanion/components/KymaCompanion.scss

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,21 @@
1010
height: 100%;
1111
width: 100%;
1212

13+
&__disclaimer-header {
14+
@extend .kyma-companion__header;
15+
background: unset !important;
16+
background-position: unset !important;
17+
background-size: unset !important;
18+
background-color: var(--sapAssistant_Color1) !important;
19+
}
20+
1321
&__header {
1422
display: flex;
1523
justify-content: space-between;
1624
align-items: center;
17-
background-color: var(--sapAssistant_Color1);
25+
background: var(--sapAssistant_BackgroundGradient);
26+
background-size: 100% 400%;
27+
background-position: 0 0;
1828
min-height: 60px;
1929
padding: 0 1rem;
2030

src/components/KymaCompanion/components/KymaCompanion.tsx

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from 'state/companion/showKymaCompanionAtom';
99
import { Chat } from './Chat/Chat';
1010
import { ChatGroup, chatGroupHelpers } from './Chat/types';
11+
import Disclaimer from './Disclaimer/Disclaimer';
1112
import './KymaCompanion.scss';
1213

1314
export interface AIError {
@@ -21,6 +22,7 @@ export default function KymaCompanion() {
2122
const [showCompanion, setShowCompanion] = useRecoilState<ShowKymaCompanion>(
2223
showKymaCompanionState,
2324
);
25+
const [showDisclaimer, setShowDisclaimer] = useState<boolean>(false);
2426
const [loading, setLoading] = useState<boolean>(false);
2527
const [isReset, setIsReset] = useState<boolean>(false);
2628
const [chatHistory, setChatHistory] = useState<ChatGroup[]>(
@@ -47,19 +49,25 @@ export default function KymaCompanion() {
4749
<Card
4850
className="kyma-companion"
4951
header={
50-
<div className="kyma-companion__header">
52+
<div
53+
className={`kyma-companion__${
54+
showDisclaimer ? 'disclaimer-' : ''
55+
}header`}
56+
>
5157
<Title level="H5" size="H5" className="title">
5258
{t('kyma-companion.name')}
5359
</Title>
5460
<div className="actions-container">
55-
<Button
56-
design="Transparent"
57-
icon="restart"
58-
disabled={loading}
59-
tooltip={t('common.buttons.reset')}
60-
className="action"
61-
onClick={() => handleRefresh()}
62-
/>
61+
{!showDisclaimer && (
62+
<Button
63+
design="Transparent"
64+
icon="restart"
65+
disabled={loading}
66+
tooltip={t('common.buttons.reset')}
67+
className="action"
68+
onClick={() => handleRefresh()}
69+
/>
70+
)}
6371
<Button
6472
design="Transparent"
6573
icon={
@@ -73,6 +81,15 @@ export default function KymaCompanion() {
7381
})
7482
}
7583
/>
84+
{!showDisclaimer && (
85+
<Button
86+
design="Transparent"
87+
icon="hint"
88+
tooltip={t('kyma-companion.disclaimer.tooltip')}
89+
className="action"
90+
onClick={() => setShowDisclaimer(true)}
91+
/>
92+
)}
7693
<Button
7794
design="Transparent"
7895
icon="decline"
@@ -95,7 +112,11 @@ export default function KymaCompanion() {
95112
setIsReset={setIsReset}
96113
error={error}
97114
setError={setError}
115+
hide={showDisclaimer}
98116
/>
117+
{showDisclaimer && (
118+
<Disclaimer hideDisclaimer={() => setShowDisclaimer(false)} />
119+
)}
99120
</Card>
100121
</div>
101122
);

0 commit comments

Comments
 (0)