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 @@ -9,18 +9,24 @@

// Drawer title
// ----------------------------------------------------------------------------
.pf-chatbot__title-container {
.pf-chatbot__heading-container {
padding-inline-start: var(--pf-t--global--spacer--lg);
padding-inline-end: var(--pf-t--global--spacer--lg);
display: flex;
flex-direction: column;
row-gap: var(--pf-t--global--spacer--sm);
}
// Drawer title icon
// ----------------------------------------------------------------------------
.pf-chatbot__title-icon {
padding-inline-end: var(--pf-t--global--spacer--md);
padding-inline-start: var(--pf-t--global--spacer--sm);
.pf-chatbot__title {
font-size: var(--pf-v6-c-title--m-h3--FontSize);
font-weight: var(--pf-v6-c-title--m-h3--FontWeight);
line-height: var(--pf-v6-c-title--m-h3--LineHeight);
}
.pf-chatbot__title-container {
display: flex;
flex-direction: row;
align-items: baseline;
justify-content: flex-start;
gap: var(--pf-t--global--spacer--gap--text-to-element--default);
}
// Drawer menu
// ----------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
import ChatbotConversationHistoryNav, { Conversation } from './ChatbotConversationHistoryNav';
import { EmptyStateStatus, Spinner } from '@patternfly/react-core';
import { OutlinedCommentsIcon, SearchIcon } from '@patternfly/react-icons';
import { BellIcon, OutlinedCommentsIcon, SearchIcon } from '@patternfly/react-icons';
import { ComponentType } from 'react';

const ERROR = {
Expand All @@ -25,13 +25,13 @@
const NO_RESULTS = {
bodyText: 'Adjust your search query and try again. Check your spelling or try a more general term.',
titleText: 'No results found',
icon: SearchIcon as ComponentType<any>

Check warning on line 28 in packages/module/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx

View workflow job for this annotation

GitHub Actions / call-build-lint-test-workflow / lint

Unexpected any. Specify a different type
};

const EMPTY_STATE = {
bodyText: 'Access timely assistance by starting a conversation with an AI model.',
titleText: 'Start a new chat',
icon: OutlinedCommentsIcon as ComponentType<any>

Check warning on line 34 in packages/module/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx

View workflow job for this annotation

GitHub Actions / call-build-lint-test-workflow / lint

Unexpected any. Specify a different type
};

const ERROR_WITHOUT_BUTTON = {
Expand Down Expand Up @@ -492,29 +492,29 @@
expect(iconElement).toBeInTheDocument();
});

it('Passes titleProps to Title', () => {
it('Passes listTitleProps to Title', () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
conversations={{ Today: initialConversations }}
titleProps={{ className: 'test' }}
listTitleProps={{ className: 'test' }}
/>
);
expect(screen.getByRole('heading', { name: /Today/i })).toHaveClass('test');
});

it('Overrides Title heading level when titleProps.headingLevel is passed', () => {
it('Overrides list title heading level when titleProps.headingLevel is passed', () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
conversations={{ Today: initialConversations }}
titleProps={{ headingLevel: 'h2' }}
listTitleProps={{ headingLevel: 'h2' }}
/>
);
expect(screen.queryByRole('heading', { name: /Today/i, level: 4 })).not.toBeInTheDocument();
Expand Down Expand Up @@ -577,4 +577,33 @@

expect(screen.getByRole('dialog', { name: /Chat history I am a sample search/i })).toBeInTheDocument();
});

it('overrides nav title heading level when navTitleProps.headingLevel is passed', () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
conversations={{ Today: initialConversations }}
navTitleProps={{ headingLevel: 'h1' }}
/>
);
expect(screen.queryByRole('heading', { name: /Chat history/i, level: 2 })).not.toBeInTheDocument();
expect(screen.getByRole('heading', { name: /Chat history/i, level: 1 })).toBeInTheDocument();
});

it('overrides nav title icon when navTitleIcon is passed in', () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
conversations={initialConversations}
navTitleIcon={<BellIcon data-testid="bell" />}
/>
);
expect(screen.getByTestId('bell')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
/** Additional button props for new chat button. */
newChatButtonProps?: ButtonProps;
/** Additional props applied to all conversation list headers */
titleProps?: Partial<TitleProps>;
listTitleProps?: Partial<TitleProps>;
/** Additional props applied to conversation list. If conversations is an object, you should pass an object of ListProps for each group. */
listProps?: ListProps | { [key: string]: ListProps };
/** Text shown in blue button */
Expand Down Expand Up @@ -135,6 +135,10 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
isCompact?: boolean;
/** Display title */
title?: string;
/** Icon displayed in title */
navTitleIcon?: React.ReactNode;
/** Title header level */
navTitleProps?: Partial<TitleProps>;
}

export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversationHistoryNavProps> = ({
Expand All @@ -144,7 +148,7 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
activeItemId,
onSelectActiveItem,
conversations,
titleProps,
listTitleProps,
listProps,
newChatButtonText = 'New chat',
drawerContent,
Expand All @@ -171,6 +175,8 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
noResultsState,
isCompact,
title = 'Chat history',
navTitleProps,
navTitleIcon = <OutlinedClockIcon />,
...props
}: ChatbotConversationHistoryNavProps) => {
const drawerRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -222,7 +228,7 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
<div>
{Object.keys(conversations).map((navGroup) => (
<section key={navGroup}>
<Title headingLevel="h4" className="pf-chatbot__conversation-list-header" {...titleProps}>
<Title headingLevel="h4" className="pf-chatbot__conversation-list-header" {...listTitleProps}>
{navGroup}
</Title>
<List className="pf-chatbot__conversation-list" isPlain {...listProps?.[navGroup]}>
Expand Down Expand Up @@ -283,13 +289,15 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
)}
</DrawerActions>
</DrawerHead>
<div className="pf-chatbot__title-container">
<Title headingLevel="h3">
<div className="pf-chatbot__heading-container">
<div className="pf-chatbot__title-container">
<Icon size="lg" className="pf-chatbot__title-icon">
<OutlinedClockIcon />
{navTitleIcon}
</Icon>
{title}
</Title>
<Title className="pf-chatbot__title" headingLevel="h2" {...navTitleProps}>
{title}
</Title>
</div>
{!isLoading && handleTextInputChange && (
<div className="pf-chatbot__input">
<SearchInput
Expand Down
Loading