Skip to content

Commit

Permalink
Merge pull request #346 from karthikjeeyar/drawer-action-config
Browse files Browse the repository at this point in the history
fix(ChatbotConversationHistoryNav): Make order of drawer action buttons configurable
  • Loading branch information
nicolethoen authored Dec 3, 2024
2 parents f2c4b99 + 96a5555 commit 8ae47d5
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const initialConversations: { [key: string]: Conversation[] } = {

export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
const [isOpen, setIsOpen] = React.useState(true);
const [isButtonOrderReversed, setIsbuttonOrderReversed] = React.useState(false);
const [conversations, setConversations] = React.useState<Conversation[] | { [key: string]: Conversation[] }>(
initialConversations
);
Expand Down Expand Up @@ -66,6 +67,13 @@ export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
id="drawer-visible"
name="drawer-visible"
/>
<Checkbox
label="Reverse action buttons"
isChecked={isButtonOrderReversed}
onChange={() => setIsbuttonOrderReversed(!isButtonOrderReversed)}
id="drawer-actions-visible"
name="drawer-actions-visible"
></Checkbox>
<ChatbotConversationHistoryNav
displayMode={displayMode}
onDrawerToggle={() => setIsOpen(!isOpen)}
Expand All @@ -77,6 +85,7 @@ export const ChatbotHeaderTitleDemo: React.FunctionComponent = () => {
onNewChat={() => {
setIsOpen(!isOpen);
}}
reverseButtonOrder={isButtonOrderReversed}
handleTextInputChange={(value: string) => {
if (value === '') {
setConversations(initialConversations);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ In the conversation history drawer, users can search previous chatbot conversati

They can also start new conversations via a "New chat" button. To customize the button label, use `newChatButtonText`.

Both the search input field and "New chat" buttons are optional.
Both the search input field and "New chat" buttons are optional. The `reverseButtonOrder` prop allows you to invert the positions of the Close and "New chat" buttons within the drawer when set to `true`.

```js file="./ChatbotHeaderDrawer.tsx"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@
height: 100%;
}

.pf-v6-c-drawer__actions--reversed {
flex-direction: row-reverse;
}

// Close drawer
.pf-v6-c-drawer__close {
.pf-v6-c-button {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import React from 'react';
import '@testing-library/jest-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';

import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
import ChatbotConversationHistoryNav, { Conversation } from './ChatbotConversationHistoryNav';

describe('ChatbotConversationHistoryNav', () => {
const onDrawerToggle = jest.fn();

const initialConversations: Conversation[] = [
{
id: '1',
text: 'Lightspeed documentation'
}
];

it('should open the conversation history navigation drawer', () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
conversations={initialConversations}
/>
);
expect(screen.queryByText('Lightspeed documentation')).toBeInTheDocument();
});

it('should display the conversations for grouped conversations', () => {
const groupedConversations: { [key: string]: Conversation[] } = {
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
};

render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
conversations={groupedConversations}
/>
);
expect(screen.queryByText('Chatbot extension')).toBeInTheDocument();
});

it('should apply the reversed class when reverseButtonOrder is true', () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
reverseButtonOrder
conversations={initialConversations}
/>
);

expect(screen.getByTestId('chatbot-nav-drawer-actions')).toHaveClass('pf-v6-c-drawer__actions--reversed');
});

it('should not apply the reversed class when reverseButtonOrder is false', () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
reverseButtonOrder={false}
conversations={initialConversations}
/>
);
expect(screen.getByTestId('chatbot-nav-drawer-actions')).not.toHaveClass('pf-v6-c-drawer__actions--reversed');
});

it('should invoke handleTextInputChange callback when user searches for conversations', () => {
const handleSearch = jest.fn();
const groupedConversations: { [key: string]: Conversation[] } = {
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
};

render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
reverseButtonOrder={false}
conversations={groupedConversations}
handleTextInputChange={handleSearch}
/>
);

const searchInput = screen.getByPlaceholderText(/Search/i);

fireEvent.change(searchInput, { target: { value: 'Chatbot' } });

expect(handleSearch).toHaveBeenCalledWith('Chatbot');
});

it('should close the drawer when escape key is pressed', async () => {
render(
<ChatbotConversationHistoryNav
onDrawerToggle={onDrawerToggle}
isDrawerOpen={true}
displayMode={ChatbotDisplayMode.fullscreen}
setIsDrawerOpen={jest.fn()}
reverseButtonOrder={false}
handleTextInputChange={jest.fn()}
conversations={initialConversations}
/>
);

fireEvent.keyDown(screen.getByPlaceholderText(/Search/i), {
key: 'Escape',
code: 'Escape',
keyCode: 27,
charCode: 27
});

waitFor(() => {
expect(screen.queryByText('Lightspeed documentation')).not.toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
handleTextInputChange?: (value: string) => void;
/** Display mode of chatbot */
displayMode: ChatbotDisplayMode;
/** Reverses the order of the drawer action buttons */
reverseButtonOrder?: boolean;
/** Custom test id for the drawer actions */
drawerActionsTestId?: string;
}

export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConversationHistoryNavProps> = ({
Expand All @@ -88,6 +92,8 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
searchInputAriaLabel = 'Filter menu items',
handleTextInputChange,
displayMode,
reverseButtonOrder = false,
drawerActionsTestId = 'chatbot-nav-drawer-actions',
...props
}: ChatbotConversationHistoryNavProps) => {
const drawerRef = React.useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -161,7 +167,10 @@ export const ChatbotConversationHistoryNav: React.FunctionComponent<ChatbotConve
const panelContent = (
<DrawerPanelContent focusTrap={{ enabled: true }} minSize="384px" maxSize="384px">
<DrawerHead>
<DrawerActions>
<DrawerActions
data-testid={drawerActionsTestId}
className={reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : ''}
>
<DrawerCloseButton onClick={onDrawerToggle} />
{onNewChat && <Button onClick={onNewChat}>{newChatButtonText}</Button>}
</DrawerActions>
Expand Down

0 comments on commit 8ae47d5

Please sign in to comment.