Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import styles from 'uiSrc/components/side-panels/styles.module.scss'
import AiAssistant from 'uiSrc/components/side-panels/panels/ai-assistant'
import { ONBOARDING_FEATURES } from 'uiSrc/components/onboarding-features'
import { OnboardingTour } from 'uiSrc/components'
import { Text } from 'uiSrc/components/base/text'

export interface Props {
isFullScreen: boolean
Expand All @@ -25,7 +26,9 @@ const CopilotPanel = (props: Props) => {
fullSize
>
<div className={styles.titleWrapper}>
<span className={styles.title}>Redis Copilot</span>
<Text size="L" color="primary">
Redis Copilot
</Text>
</div>
</OnboardingTour>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
setExplorePanelIsPageOpen,
} from 'uiSrc/slices/panels/sidePanels'
import { RestartChat } from 'uiSrc/components/side-panels/panels/ai-assistant/components/shared'

import { Row } from 'uiSrc/components/base/layout/flex'
import { Spacer } from 'uiSrc/components/base/layout/spacer'
import { EmptyButton, PrimaryButton } from 'uiSrc/components/base/forms/buttons'
import { EraserIcon, LightBulbIcon } from 'uiSrc/components/base/icons'
Expand Down Expand Up @@ -102,18 +102,20 @@ const ExpertChatHeader = (props: Props) => {
}
>
<>
<Text>
<Text size="m" color="primary">
Open relevant tutorials to learn more about search and query.
</Text>
<Spacer size="s" />
<PrimaryButton
size="s"
onClick={handleOpenTutorials}
className={styles.openTutorialsBtn}
data-testid="ai-expert-open-tutorials"
>
Open tutorials
</PrimaryButton>
<Spacer size="l" />
<Row justify="end">
<PrimaryButton
size="s"
onClick={handleOpenTutorials}
className={styles.openTutorialsBtn}
data-testid="ai-expert-open-tutorials"
>
Open tutorials
</PrimaryButton>
</Row>
</>
</RiPopover>
</RiTooltip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cx from 'classnames'
import { isModifiedEvent } from 'uiSrc/services'

import { Row } from 'uiSrc/components/base/layout/flex'
import { RiPopover, RiTooltip } from 'uiSrc/components/base'
import { Spacer } from 'uiSrc/components/base/layout/spacer'
import { PrimaryButton } from 'uiSrc/components/base/forms/buttons'
Expand Down Expand Up @@ -99,12 +100,12 @@
<div>
{validation.title && (
<>
<Title size="XS">{validation.title}</Title>
<Title size="S">{validation.title}</Title>
<Spacer size="s" />
</>
)}
{validation.content && (
<Text size="xs">{validation.content}</Text>
<Text size="m">{validation.content}</Text>
)}
</div>
{validation.icon}
Expand Down Expand Up @@ -150,21 +151,24 @@
>
<>
{agreements}
<Spacer size="m" />
<PrimaryButton
size="s"
className={styles.agreementsAccept}
onClick={submitMessage}
onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}
type="button"
data-testid="ai-accept-agreements"
>
I accept
</PrimaryButton>
<Spacer size="l" />
<Row justify="end">
<PrimaryButton
size="s"
className={styles.agreementsAccept}
onClick={submitMessage}
onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}

Check warning on line 160 in redisinsight/ui/src/components/side-panels/panels/ai-assistant/components/shared/chat-form/ChatForm.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 160 in redisinsight/ui/src/components/side-panels/panels/ai-assistant/components/shared/chat-form/ChatForm.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
type="button"
data-testid="ai-accept-agreements"
>
I accept
</PrimaryButton>
</Row>
</>
</RiPopover>
</form>
</RiTooltip>
<Spacer size="xs" />
<Text textAlign="center" size="xs" className={styles.agreementText}>
Verify the accuracy of any information provided by Redis Copilot before
using it
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import styled from 'styled-components'
import { AiChatMessageType } from 'uiSrc/slices/interfaces/aiAssistant'

export const HistoryWrapper = styled.div`
width: 100%;
height: 100%;
`

export const HistoryContainer = styled.div`
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
padding: 8px 12px;

> :first-child {
margin-top: auto;
}
`

export const MessageWrapper = styled.div<{
messageType: AiChatMessageType
}>`
max-width: 90%;
margin: 8px 0;
align-self: ${({ messageType }) =>
messageType === AiChatMessageType.AIMessage ? 'flex-start' : 'flex-end'};
`

export const MessageContainer = styled.div<{
messageType: AiChatMessageType
hasError?: boolean
}>`
overflow-wrap: break-word;
padding: 8px 16px;
border-radius: 8px;
gap: 6px;

${({ messageType, theme }) =>
messageType === AiChatMessageType.AIMessage &&
`
background-color: ${theme.components.button.variants.primary.disabled?.bgColor};
`}

${({ messageType, theme }) =>
messageType === AiChatMessageType.HumanMessage &&
`
background-color: ${theme.components.button.variants['secondary-invert'].normal?.bgColor};
color: ${theme.components.button.variants['secondary-invert'].normal?.textColor};
`}

${({ hasError }) =>
hasError &&
`
opacity: .66;
display: flex;
`}
`
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import React, {
useEffect,
useRef,
} from 'react'
import cx from 'classnames'

import { throttle } from 'lodash'
import {
Expand All @@ -21,7 +20,12 @@ import LoadingMessage from '../loading-message'
import MarkdownMessage from '../markdown-message'
import ErrorMessage from '../error-message'

import styles from './styles.module.scss'
import {
HistoryContainer,
HistoryWrapper,
MessageContainer,
MessageWrapper,
} from './ChatHistory.styles'

export interface Props {
autoScroll?: boolean
Expand Down Expand Up @@ -113,25 +117,16 @@ const ChatHistory = (props: Props) => {

return (
<React.Fragment key={id}>
<div
className={cx({
[styles.answerWrapper]:
messageType === AiChatMessageType.AIMessage,
[styles.questionWrapper]:
messageType === AiChatMessageType.HumanMessage,
})}
>
<div
className={cx('jsx-markdown', {
[styles.answer]: messageType === AiChatMessageType.AIMessage,
[styles.question]:
messageType === AiChatMessageType.HumanMessage,
[styles.error]: !!error,
})}
<MessageWrapper as="div" messageType={messageType}>
<MessageContainer
as="div"
className="jsx-markdown"
messageType={messageType}
hasError={!!error}
data-testid={`ai-message-${messageType}_${id}`}
>
{error && (
<RiIcon type="ToastDangerIcon" className={styles.errorIcon} />
<RiIcon type="ToastDangerIcon" size="M" color="danger500" />
)}
{messageType === AiChatMessageType.HumanMessage ? (
content
Expand All @@ -144,8 +139,8 @@ const ChatHistory = (props: Props) => {
{content}
</MarkdownMessage>
)}
</div>
</div>
</MessageContainer>
</MessageWrapper>
<ErrorMessage error={error} onRestart={onRestart} />
</React.Fragment>
)
Expand All @@ -155,50 +150,51 @@ const ChatHistory = (props: Props) => {

if (isLoading) {
return (
<div className={cx(styles.wrapper, styles.loader)}>
<HistoryWrapper>
<Loader size="xl" data-testid="ai-loading-spinner" />
</div>
</HistoryWrapper>
)
}

if (history.length === 0) {
return (
<div className={styles.wrapper}>
<div className={styles.history} data-testid="ai-chat-empty-history">
<div className={styles.answerWrapper}>
<div
className={styles.answer}
<HistoryWrapper>
<HistoryContainer as="div" data-testid="ai-chat-empty-history">
<MessageWrapper as="div" messageType={AiChatMessageType.AIMessage}>
<MessageContainer
as="div"
messageType={AiChatMessageType.AIMessage}
data-testid="ai-message-initial-message"
>
{initialMessage}
</div>
</div>
</div>
</div>
</MessageContainer>
</MessageWrapper>
</HistoryContainer>
</HistoryWrapper>
)
}

const { content } = inProgressMessage || {}

return (
<div className={styles.wrapper}>
<div
ref={listRef}
className={styles.history}
data-testid="ai-chat-history"
>
<HistoryWrapper>
<HistoryContainer as="div" ref={listRef} data-testid="ai-chat-history">
{history.map(getMessage)}
{getMessage(inProgressMessage)}
{content === '' && (
<div className={styles.answerWrapper}>
<div className={styles.answer} data-testid="ai-loading-answer">
<MessageWrapper as="div" messageType={AiChatMessageType.AIMessage}>
<MessageContainer
as="div"
messageType={AiChatMessageType.AIMessage}
data-testid="ai-loading-answer"
>
<LoadingMessage />
</div>
</div>
</MessageContainer>
</MessageWrapper>
)}
<div className={styles.scrollAnchor} ref={scrollDivRef} />
</div>
</div>
<div ref={scrollDivRef} />
</HistoryContainer>
</HistoryWrapper>
)
}

Expand Down

This file was deleted.

Loading
Loading