@patternfly/chatbot 6.4.0-prerelease.2 → 6.4.0-prerelease.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Chatbot/Chatbot.js +1 -7
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +2 -0
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +22 -2
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +15 -9
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +40 -2
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.js +25 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +22 -0
- package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/index.js +1 -0
- package/dist/cjs/DeepThinking/DeepThinking.d.ts +18 -0
- package/dist/cjs/DeepThinking/DeepThinking.js +18 -0
- package/dist/cjs/DeepThinking/DeepThinking.test.d.ts +1 -0
- package/dist/cjs/DeepThinking/DeepThinking.test.js +48 -0
- package/dist/cjs/DeepThinking/index.d.ts +2 -0
- package/dist/cjs/DeepThinking/index.js +23 -0
- package/dist/cjs/FilePreview/FilePreview.d.ts +26 -0
- package/dist/cjs/FilePreview/FilePreview.js +26 -0
- package/dist/cjs/FilePreview/FilePreview.test.d.ts +1 -0
- package/dist/cjs/FilePreview/FilePreview.test.js +97 -0
- package/dist/cjs/FilePreview/index.d.ts +2 -0
- package/dist/cjs/FilePreview/index.js +23 -0
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +3 -3
- package/dist/cjs/Message/LinkMessage/LinkMessage.d.ts +2 -1
- package/dist/cjs/Message/LinkMessage/LinkMessage.js +7 -3
- package/dist/cjs/Message/ListMessage/ListItemMessage.d.ts +1 -1
- package/dist/cjs/Message/ListMessage/ListItemMessage.js +16 -1
- package/dist/cjs/Message/Message.d.ts +15 -0
- package/dist/cjs/Message/Message.js +129 -32
- package/dist/cjs/Message/Message.test.js +71 -0
- package/dist/cjs/Message/SuperscriptMessage/SuperscriptMessage.d.ts +3 -0
- package/dist/cjs/Message/SuperscriptMessage/SuperscriptMessage.js +5 -0
- package/dist/cjs/Message/UserFeedback/UserFeedback.d.ts +15 -1
- package/dist/cjs/Message/UserFeedback/UserFeedback.js +4 -4
- package/dist/cjs/Message/UserFeedback/UserFeedback.test.js +44 -0
- package/dist/cjs/MessageBar/MessageBar.js +19 -4
- package/dist/cjs/MessageBox/JumpButton.d.ts +5 -0
- package/dist/cjs/MessageBox/JumpButton.js +1 -1
- package/dist/cjs/MessageBox/JumpButton.test.js +4 -4
- package/dist/cjs/MessageBox/MessageBox.d.ts +9 -0
- package/dist/cjs/MessageBox/MessageBox.js +2 -2
- package/dist/cjs/MessageBox/MessageBox.test.js +2 -2
- package/dist/cjs/SourcesCard/SourcesCard.d.ts +13 -1
- package/dist/cjs/SourcesCard/SourcesCard.js +6 -6
- package/dist/cjs/SourcesCard/SourcesCard.test.js +49 -0
- package/dist/cjs/ToolResponse/ToolResponse.d.ts +30 -0
- package/dist/cjs/ToolResponse/ToolResponse.js +18 -0
- package/dist/cjs/ToolResponse/ToolResponse.test.d.ts +1 -0
- package/dist/cjs/ToolResponse/ToolResponse.test.js +60 -0
- package/dist/cjs/ToolResponse/index.d.ts +2 -0
- package/dist/cjs/ToolResponse/index.js +23 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.js +10 -1
- package/dist/css/main.css +273 -17
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/DeepThinking/package.json +1 -0
- package/dist/dynamic/FilePreview/package.json +1 -0
- package/dist/dynamic/ToolResponse/package.json +1 -0
- package/dist/esm/Chatbot/Chatbot.js +1 -7
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +2 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +22 -2
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +17 -11
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +41 -3
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.js +22 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +20 -0
- package/dist/esm/ChatbotHeader/index.d.ts +1 -0
- package/dist/esm/ChatbotHeader/index.js +1 -0
- package/dist/esm/DeepThinking/DeepThinking.d.ts +18 -0
- package/dist/esm/DeepThinking/DeepThinking.js +14 -0
- package/dist/esm/DeepThinking/DeepThinking.test.d.ts +1 -0
- package/dist/esm/DeepThinking/DeepThinking.test.js +43 -0
- package/dist/esm/DeepThinking/index.d.ts +2 -0
- package/dist/esm/DeepThinking/index.js +2 -0
- package/dist/esm/FilePreview/FilePreview.d.ts +26 -0
- package/dist/esm/FilePreview/FilePreview.js +21 -0
- package/dist/esm/FilePreview/FilePreview.test.d.ts +1 -0
- package/dist/esm/FilePreview/FilePreview.test.js +92 -0
- package/dist/esm/FilePreview/index.d.ts +2 -0
- package/dist/esm/FilePreview/index.js +2 -0
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +5 -5
- package/dist/esm/Message/LinkMessage/LinkMessage.d.ts +2 -1
- package/dist/esm/Message/LinkMessage/LinkMessage.js +7 -3
- package/dist/esm/Message/ListMessage/ListItemMessage.d.ts +1 -1
- package/dist/esm/Message/ListMessage/ListItemMessage.js +16 -1
- package/dist/esm/Message/Message.d.ts +15 -0
- package/dist/esm/Message/Message.js +129 -32
- package/dist/esm/Message/Message.test.js +71 -0
- package/dist/esm/Message/SuperscriptMessage/SuperscriptMessage.d.ts +3 -0
- package/dist/esm/Message/SuperscriptMessage/SuperscriptMessage.js +3 -0
- package/dist/esm/Message/UserFeedback/UserFeedback.d.ts +15 -1
- package/dist/esm/Message/UserFeedback/UserFeedback.js +4 -4
- package/dist/esm/Message/UserFeedback/UserFeedback.test.js +45 -1
- package/dist/esm/MessageBar/MessageBar.js +19 -4
- package/dist/esm/MessageBox/JumpButton.d.ts +5 -0
- package/dist/esm/MessageBox/JumpButton.js +1 -1
- package/dist/esm/MessageBox/JumpButton.test.js +4 -4
- package/dist/esm/MessageBox/MessageBox.d.ts +9 -0
- package/dist/esm/MessageBox/MessageBox.js +2 -2
- package/dist/esm/MessageBox/MessageBox.test.js +2 -2
- package/dist/esm/SourcesCard/SourcesCard.d.ts +13 -1
- package/dist/esm/SourcesCard/SourcesCard.js +6 -6
- package/dist/esm/SourcesCard/SourcesCard.test.js +50 -1
- package/dist/esm/ToolResponse/ToolResponse.d.ts +30 -0
- package/dist/esm/ToolResponse/ToolResponse.js +14 -0
- package/dist/esm/ToolResponse/ToolResponse.test.d.ts +1 -0
- package/dist/esm/ToolResponse/ToolResponse.test.js +55 -0
- package/dist/esm/ToolResponse/index.d.ts +2 -0
- package/dist/esm/ToolResponse/index.js +2 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.js +6 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -6
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +101 -3
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/FilePreview.tsx +33 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx +17 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +111 -85
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithSources.tsx +70 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx +135 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +28 -4
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +107 -2
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx +616 -3
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotConversationEditing.tsx +202 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderBasic.tsx +17 -3
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +36 -5
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx +12 -2
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +22 -3
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +1 -1
- package/patternfly-docs/patternfly-docs.config.js +1 -1
- package/src/Chatbot/Chatbot.scss +9 -2
- package/src/Chatbot/Chatbot.tsx +18 -31
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +5 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +28 -10
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +132 -3
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +80 -33
- package/src/ChatbotHeader/ChatbotHeaderMenu.test.tsx +1 -1
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +2 -2
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx +25 -0
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx +64 -0
- package/src/ChatbotHeader/index.ts +1 -0
- package/src/ChatbotModal/ChatbotModal.scss +1 -1
- package/src/DeepThinking/DeepThinking.scss +24 -0
- package/src/DeepThinking/DeepThinking.test.tsx +61 -0
- package/src/DeepThinking/DeepThinking.tsx +68 -0
- package/src/DeepThinking/index.ts +3 -0
- package/src/FileDetails/__snapshots__/FileDetails.test.tsx.snap +6 -9
- package/src/FileDetailsLabel/__snapshots__/FileDetailsLabel.test.tsx.snap +6 -9
- package/src/FilePreview/FilePreview.scss +22 -0
- package/src/FilePreview/FilePreview.test.tsx +112 -0
- package/src/FilePreview/FilePreview.tsx +58 -0
- package/src/FilePreview/index.ts +3 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +2 -1
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +6 -5
- package/src/Message/LinkMessage/LinkMessage.tsx +6 -2
- package/src/Message/ListMessage/ListItemMessage.tsx +5 -1
- package/src/Message/ListMessage/ListMessage.scss +17 -0
- package/src/Message/Message.scss +44 -0
- package/src/Message/Message.test.tsx +90 -0
- package/src/Message/Message.tsx +171 -46
- package/src/Message/SuperscriptMessage/SuperscriptMessage.scss +8 -0
- package/src/Message/SuperscriptMessage/SuperscriptMessage.tsx +13 -0
- package/src/Message/TextMessage/TextMessage.scss +46 -5
- package/src/Message/UserFeedback/UserFeedback.test.tsx +107 -0
- package/src/Message/UserFeedback/UserFeedback.tsx +41 -6
- package/src/MessageBar/MessageBar.tsx +23 -3
- package/src/MessageBox/JumpButton.test.tsx +4 -4
- package/src/MessageBox/JumpButton.tsx +20 -4
- package/src/MessageBox/MessageBox.test.tsx +2 -2
- package/src/MessageBox/MessageBox.tsx +22 -1
- package/src/SourcesCard/SourcesCard.scss +17 -0
- package/src/SourcesCard/SourcesCard.test.tsx +93 -0
- package/src/SourcesCard/SourcesCard.tsx +116 -80
- package/src/ToolResponse/ToolResponse.scss +36 -0
- package/src/ToolResponse/ToolResponse.test.tsx +78 -0
- package/src/ToolResponse/ToolResponse.tsx +95 -0
- package/src/ToolResponse/index.ts +3 -0
- package/src/index.ts +9 -0
- package/src/main.scss +3 -0
|
@@ -4,7 +4,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
|
4
4
|
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
|
|
5
5
|
import ChatbotConversationHistoryNav, { Conversation } from './ChatbotConversationHistoryNav';
|
|
6
6
|
import { EmptyStateStatus, Spinner } from '@patternfly/react-core';
|
|
7
|
-
import { OutlinedCommentsIcon, SearchIcon } from '@patternfly/react-icons';
|
|
7
|
+
import { BellIcon, OutlinedCommentsIcon, SearchIcon } from '@patternfly/react-icons';
|
|
8
8
|
import { ComponentType } from 'react';
|
|
9
9
|
|
|
10
10
|
const ERROR = {
|
|
@@ -348,7 +348,7 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
348
348
|
).toBeTruthy();
|
|
349
349
|
expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
|
|
350
350
|
expect(screen.getByRole('button', { name: /Loading... Reload/i })).toBeTruthy();
|
|
351
|
-
expect(screen.getByRole('textbox', { name: /
|
|
351
|
+
expect(screen.getByRole('textbox', { name: /Search previous conversations/i })).toBeTruthy();
|
|
352
352
|
expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
|
|
353
353
|
});
|
|
354
354
|
|
|
@@ -372,7 +372,7 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
372
372
|
).toBeTruthy();
|
|
373
373
|
expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
|
|
374
374
|
expect(screen.queryByRole('button', { name: /Loading... Reload/i })).toBeFalsy();
|
|
375
|
-
expect(screen.getByRole('textbox', { name: /
|
|
375
|
+
expect(screen.getByRole('textbox', { name: /Search previous conversations/i })).toBeTruthy();
|
|
376
376
|
expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
|
|
377
377
|
});
|
|
378
378
|
|
|
@@ -491,4 +491,133 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
491
491
|
const iconElement = container.querySelector('.pf-chatbot__title-icon');
|
|
492
492
|
expect(iconElement).toBeInTheDocument();
|
|
493
493
|
});
|
|
494
|
+
|
|
495
|
+
it('Passes menuProps to Menu', () => {
|
|
496
|
+
render(
|
|
497
|
+
<ChatbotConversationHistoryNav
|
|
498
|
+
onDrawerToggle={onDrawerToggle}
|
|
499
|
+
isDrawerOpen={true}
|
|
500
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
501
|
+
setIsDrawerOpen={jest.fn()}
|
|
502
|
+
conversations={initialConversations}
|
|
503
|
+
menuProps={{ className: 'test' }}
|
|
504
|
+
/>
|
|
505
|
+
);
|
|
506
|
+
|
|
507
|
+
expect(screen.getByRole('menu').parentElement?.parentElement).toHaveClass('test');
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('Passes menuContentProps to MenuContent', () => {
|
|
511
|
+
render(
|
|
512
|
+
<ChatbotConversationHistoryNav
|
|
513
|
+
onDrawerToggle={onDrawerToggle}
|
|
514
|
+
isDrawerOpen={true}
|
|
515
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
516
|
+
setIsDrawerOpen={jest.fn()}
|
|
517
|
+
conversations={initialConversations}
|
|
518
|
+
menuContentProps={{ className: 'test' }}
|
|
519
|
+
/>
|
|
520
|
+
);
|
|
521
|
+
expect(screen.getByRole('menu').parentElement).toHaveClass('test');
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
it('Passes menuListProps to MenuList when conversations is an array', () => {
|
|
525
|
+
render(
|
|
526
|
+
<ChatbotConversationHistoryNav
|
|
527
|
+
onDrawerToggle={onDrawerToggle}
|
|
528
|
+
isDrawerOpen={true}
|
|
529
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
530
|
+
setIsDrawerOpen={jest.fn()}
|
|
531
|
+
conversations={initialConversations}
|
|
532
|
+
menuListProps={{ className: 'test' }}
|
|
533
|
+
/>
|
|
534
|
+
);
|
|
535
|
+
expect(screen.getByRole('menu')).toHaveClass('test');
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
it('Passes menuListProps to MenuList when conversations is an object', () => {
|
|
539
|
+
render(
|
|
540
|
+
<ChatbotConversationHistoryNav
|
|
541
|
+
onDrawerToggle={onDrawerToggle}
|
|
542
|
+
isDrawerOpen={true}
|
|
543
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
544
|
+
setIsDrawerOpen={jest.fn()}
|
|
545
|
+
conversations={{ Today: initialConversations }}
|
|
546
|
+
menuListProps={{ Today: { className: 'test' } }}
|
|
547
|
+
/>
|
|
548
|
+
);
|
|
549
|
+
expect(screen.getByRole('menu')).toHaveClass('test');
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
it('Passes menuGroupProps to MenuGroup when conversations is an object', () => {
|
|
553
|
+
render(
|
|
554
|
+
<ChatbotConversationHistoryNav
|
|
555
|
+
onDrawerToggle={onDrawerToggle}
|
|
556
|
+
isDrawerOpen={true}
|
|
557
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
558
|
+
setIsDrawerOpen={jest.fn()}
|
|
559
|
+
conversations={{ Today: initialConversations }}
|
|
560
|
+
menuGroupProps={{ Today: { className: 'test' } }}
|
|
561
|
+
/>
|
|
562
|
+
);
|
|
563
|
+
expect(screen.getByRole('menu').parentElement).toHaveClass('test');
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it('Passes additionalProps to MenuItem', () => {
|
|
567
|
+
render(
|
|
568
|
+
<ChatbotConversationHistoryNav
|
|
569
|
+
onDrawerToggle={onDrawerToggle}
|
|
570
|
+
isDrawerOpen={true}
|
|
571
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
572
|
+
setIsDrawerOpen={jest.fn()}
|
|
573
|
+
conversations={[{ id: '1', text: 'ChatBot documentation', additionalProps: { className: 'test' } }]}
|
|
574
|
+
/>
|
|
575
|
+
);
|
|
576
|
+
expect(screen.getByRole('menuitem')).toHaveClass('test');
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
it('should be able to spread search input props when searchInputProps is passed', () => {
|
|
580
|
+
render(
|
|
581
|
+
<ChatbotConversationHistoryNav
|
|
582
|
+
onDrawerToggle={onDrawerToggle}
|
|
583
|
+
isDrawerOpen={true}
|
|
584
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
585
|
+
setIsDrawerOpen={jest.fn()}
|
|
586
|
+
conversations={initialConversations}
|
|
587
|
+
handleTextInputChange={jest.fn()}
|
|
588
|
+
searchInputProps={{ value: 'I am a sample search' }}
|
|
589
|
+
/>
|
|
590
|
+
);
|
|
591
|
+
|
|
592
|
+
expect(screen.getByRole('dialog', { name: /Chat history I am a sample search/i })).toBeInTheDocument();
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
it('overrides nav title heading level when navTitleProps.headingLevel is passed', () => {
|
|
596
|
+
render(
|
|
597
|
+
<ChatbotConversationHistoryNav
|
|
598
|
+
onDrawerToggle={onDrawerToggle}
|
|
599
|
+
isDrawerOpen={true}
|
|
600
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
601
|
+
setIsDrawerOpen={jest.fn()}
|
|
602
|
+
conversations={{ Today: initialConversations }}
|
|
603
|
+
navTitleProps={{ headingLevel: 'h1' }}
|
|
604
|
+
/>
|
|
605
|
+
);
|
|
606
|
+
expect(screen.queryByRole('heading', { name: /Chat history/i, level: 2 })).not.toBeInTheDocument();
|
|
607
|
+
expect(screen.getByRole('heading', { name: /Chat history/i, level: 1 })).toBeInTheDocument();
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
it('overrides nav title icon when navTitleIcon is passed in', () => {
|
|
611
|
+
render(
|
|
612
|
+
<ChatbotConversationHistoryNav
|
|
613
|
+
onDrawerToggle={onDrawerToggle}
|
|
614
|
+
isDrawerOpen={true}
|
|
615
|
+
displayMode={ChatbotDisplayMode.fullscreen}
|
|
616
|
+
setIsDrawerOpen={jest.fn()}
|
|
617
|
+
conversations={initialConversations}
|
|
618
|
+
navTitleIcon={<BellIcon data-testid="bell" />}
|
|
619
|
+
/>
|
|
620
|
+
);
|
|
621
|
+
expect(screen.getByTestId('bell')).toBeInTheDocument();
|
|
622
|
+
});
|
|
494
623
|
});
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// Chatbot Header - Chatbot Conversation History Nav
|
|
3
3
|
// ============================================================================
|
|
4
4
|
import type { KeyboardEvent, FunctionComponent } from 'react';
|
|
5
|
-
|
|
6
5
|
import { useRef, Fragment } from 'react';
|
|
7
6
|
|
|
8
7
|
// Import PatternFly components
|
|
9
8
|
import {
|
|
10
9
|
Button,
|
|
10
|
+
ButtonProps,
|
|
11
11
|
Drawer,
|
|
12
12
|
DrawerPanelContent,
|
|
13
13
|
DrawerContent,
|
|
@@ -18,13 +18,7 @@ import {
|
|
|
18
18
|
DrawerCloseButton,
|
|
19
19
|
DrawerContentBody,
|
|
20
20
|
SearchInput,
|
|
21
|
-
|
|
22
|
-
MenuList,
|
|
23
|
-
MenuGroup,
|
|
24
|
-
MenuItem,
|
|
25
|
-
MenuContent,
|
|
26
|
-
MenuItemProps,
|
|
27
|
-
MenuProps,
|
|
21
|
+
Title,
|
|
28
22
|
DrawerPanelContentProps,
|
|
29
23
|
DrawerContentProps,
|
|
30
24
|
DrawerContentBodyProps,
|
|
@@ -33,12 +27,22 @@ import {
|
|
|
33
27
|
DrawerCloseButtonProps,
|
|
34
28
|
DrawerPanelBodyProps,
|
|
35
29
|
SkeletonProps,
|
|
36
|
-
Title,
|
|
37
30
|
Icon,
|
|
38
|
-
|
|
31
|
+
MenuProps,
|
|
32
|
+
TitleProps,
|
|
33
|
+
MenuListProps,
|
|
34
|
+
SearchInputProps,
|
|
35
|
+
MenuList,
|
|
36
|
+
MenuGroup,
|
|
37
|
+
MenuItem,
|
|
38
|
+
Menu,
|
|
39
|
+
MenuContent,
|
|
40
|
+
MenuItemProps,
|
|
41
|
+
MenuGroupProps,
|
|
42
|
+
MenuContentProps
|
|
39
43
|
} from '@patternfly/react-core';
|
|
40
44
|
|
|
41
|
-
import { OutlinedClockIcon, OutlinedCommentAltIcon } from '@patternfly/react-icons';
|
|
45
|
+
import { OutlinedClockIcon, OutlinedCommentAltIcon, PenToSquareIcon } from '@patternfly/react-icons';
|
|
42
46
|
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
|
|
43
47
|
import ConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
|
|
44
48
|
import LoadingState from './LoadingState';
|
|
@@ -61,8 +65,10 @@ export interface Conversation {
|
|
|
61
65
|
label?: string;
|
|
62
66
|
/** Callback for when user selects item. */
|
|
63
67
|
onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
|
|
64
|
-
/** Additional props passed to
|
|
68
|
+
/** Additional props passed to menu item */
|
|
65
69
|
additionalProps?: MenuItemProps;
|
|
70
|
+
/** Custom dropdown ID to ensure uniqueness across demo instances */
|
|
71
|
+
dropdownId?: string;
|
|
66
72
|
}
|
|
67
73
|
export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
68
74
|
/** Function called to toggle drawer */
|
|
@@ -79,6 +85,10 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
79
85
|
conversations: Conversation[] | { [key: string]: Conversation[] };
|
|
80
86
|
/** Additional button props for new chat button. */
|
|
81
87
|
newChatButtonProps?: ButtonProps;
|
|
88
|
+
/** Additional props applied to conversation menu group. If conversations is an object, you should pass an object of MenuGroupProps for each group. */
|
|
89
|
+
menuGroupProps?: MenuGroupProps | { [key: string]: MenuGroupProps };
|
|
90
|
+
/** Additional props applied to conversation list. If conversations is an object, you should pass an object of MenuListProps for each group. */
|
|
91
|
+
menuListProps?: Omit<MenuListProps, 'children'> | { [key: string]: Omit<MenuListProps, 'children'> };
|
|
82
92
|
/** Text shown in blue button */
|
|
83
93
|
newChatButtonText?: string;
|
|
84
94
|
/** Callback function for when blue button is clicked. Omit to hide blue "new chat button" */
|
|
@@ -89,6 +99,8 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
89
99
|
searchInputPlaceholder?: string;
|
|
90
100
|
/** Aria label for search input */
|
|
91
101
|
searchInputAriaLabel?: string;
|
|
102
|
+
/** Additional props passed to search input */
|
|
103
|
+
searchInputProps?: SearchInputProps;
|
|
92
104
|
/** A callback for when the input value changes. Omit to hide input field */
|
|
93
105
|
handleTextInputChange?: (value: string) => void;
|
|
94
106
|
/** Display mode of chatbot */
|
|
@@ -127,6 +139,14 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
127
139
|
isCompact?: boolean;
|
|
128
140
|
/** Display title */
|
|
129
141
|
title?: string;
|
|
142
|
+
/** Icon displayed in title */
|
|
143
|
+
navTitleIcon?: React.ReactNode;
|
|
144
|
+
/** Title header level */
|
|
145
|
+
navTitleProps?: Partial<TitleProps>;
|
|
146
|
+
/** Visually hidden text that gets announced by assistive technologies. Should be used to convey the result count when the search input value changes. */
|
|
147
|
+
searchInputScreenReaderText?: string;
|
|
148
|
+
/** Additional props passed to MenuContent */
|
|
149
|
+
menuContentProps?: Omit<MenuContentProps, 'ref'>;
|
|
130
150
|
}
|
|
131
151
|
|
|
132
152
|
export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversationHistoryNavProps> = ({
|
|
@@ -136,17 +156,18 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
|
|
|
136
156
|
activeItemId,
|
|
137
157
|
onSelectActiveItem,
|
|
138
158
|
conversations,
|
|
159
|
+
menuListProps,
|
|
139
160
|
newChatButtonText = 'New chat',
|
|
140
161
|
drawerContent,
|
|
141
162
|
onNewChat,
|
|
142
163
|
newChatButtonProps,
|
|
143
164
|
searchInputPlaceholder = 'Search previous conversations...',
|
|
144
|
-
searchInputAriaLabel = '
|
|
165
|
+
searchInputAriaLabel = 'Search previous conversations',
|
|
166
|
+
searchInputProps,
|
|
145
167
|
handleTextInputChange,
|
|
146
168
|
displayMode,
|
|
147
169
|
reverseButtonOrder = false,
|
|
148
170
|
drawerActionsTestId = 'chatbot-nav-drawer-actions',
|
|
149
|
-
menuProps,
|
|
150
171
|
drawerPanelContentProps,
|
|
151
172
|
drawerContentProps,
|
|
152
173
|
drawerContentBodyProps,
|
|
@@ -161,6 +182,12 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
|
|
|
161
182
|
noResultsState,
|
|
162
183
|
isCompact,
|
|
163
184
|
title = 'Chat history',
|
|
185
|
+
navTitleProps,
|
|
186
|
+
navTitleIcon = <OutlinedClockIcon />,
|
|
187
|
+
searchInputScreenReaderText,
|
|
188
|
+
menuProps,
|
|
189
|
+
menuGroupProps,
|
|
190
|
+
menuContentProps,
|
|
164
191
|
...props
|
|
165
192
|
}: ChatbotConversationHistoryNavProps) => {
|
|
166
193
|
const drawerRef = useRef<HTMLDivElement>(null);
|
|
@@ -169,11 +196,13 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
|
|
|
169
196
|
drawerRef.current && drawerRef.current.focus();
|
|
170
197
|
};
|
|
171
198
|
|
|
199
|
+
const isConversation = (item: any): item is Conversation =>
|
|
200
|
+
item && typeof item === 'object' && 'id' in item && 'text' in item;
|
|
201
|
+
|
|
172
202
|
const getNavItem = (conversation: Conversation) => (
|
|
173
203
|
<MenuItem
|
|
174
204
|
className={`pf-chatbot__menu-item ${activeItemId && activeItemId === conversation.id ? 'pf-chatbot__menu-item--active' : ''}`}
|
|
175
205
|
itemId={conversation.id}
|
|
176
|
-
key={conversation.id}
|
|
177
206
|
{...(conversation.noIcon ? {} : { icon: conversation.icon ?? <OutlinedCommentAltIcon /> })}
|
|
178
207
|
/* eslint-disable indent */
|
|
179
208
|
{...(conversation.menuItems
|
|
@@ -189,30 +218,37 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
|
|
|
189
218
|
}
|
|
190
219
|
: {})}
|
|
191
220
|
{...conversation.additionalProps}
|
|
192
|
-
/* eslint-enable indent */
|
|
193
221
|
>
|
|
194
222
|
{conversation.text}
|
|
195
223
|
</MenuItem>
|
|
196
224
|
);
|
|
197
225
|
|
|
198
|
-
const
|
|
226
|
+
const buildConversations = () => {
|
|
199
227
|
if (Array.isArray(conversations)) {
|
|
200
|
-
// Render for array of MenuItemObject
|
|
201
228
|
return (
|
|
202
|
-
<MenuList>
|
|
203
|
-
{conversations.map((conversation) =>
|
|
204
|
-
|
|
205
|
-
|
|
229
|
+
<MenuList {...menuListProps}>
|
|
230
|
+
{conversations.map((conversation) => {
|
|
231
|
+
if (isConversation(conversation)) {
|
|
232
|
+
return <Fragment key={conversation.id}>{getNavItem(conversation)}</Fragment>;
|
|
233
|
+
} else {
|
|
234
|
+
return conversation;
|
|
235
|
+
}
|
|
236
|
+
})}
|
|
206
237
|
</MenuList>
|
|
207
238
|
);
|
|
208
239
|
} else {
|
|
209
|
-
// Render for object with NavItemObject arrays as values
|
|
210
240
|
return (
|
|
211
241
|
<>
|
|
212
242
|
{Object.keys(conversations).map((navGroup) => (
|
|
213
|
-
<MenuGroup
|
|
214
|
-
|
|
215
|
-
|
|
243
|
+
<MenuGroup
|
|
244
|
+
className="pf-chatbot__menu-item-header"
|
|
245
|
+
label={navGroup}
|
|
246
|
+
key={navGroup}
|
|
247
|
+
labelHeadingLevel="h3"
|
|
248
|
+
{...menuGroupProps?.[navGroup]}
|
|
249
|
+
>
|
|
250
|
+
<MenuList {...menuListProps?.[navGroup]}>
|
|
251
|
+
{conversations[navGroup].map((conversation: Conversation) => (
|
|
216
252
|
<Fragment key={conversation.id}>{getNavItem(conversation)}</Fragment>
|
|
217
253
|
))}
|
|
218
254
|
</MenuList>
|
|
@@ -240,7 +276,7 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
|
|
|
240
276
|
}
|
|
241
277
|
return (
|
|
242
278
|
<Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId} {...menuProps}>
|
|
243
|
-
<MenuContent>{
|
|
279
|
+
<MenuContent {...menuContentProps}>{buildConversations()}</MenuContent>
|
|
244
280
|
</Menu>
|
|
245
281
|
);
|
|
246
282
|
};
|
|
@@ -262,26 +298,37 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
|
|
|
262
298
|
>
|
|
263
299
|
<DrawerCloseButton onClick={onDrawerToggle} {...drawerCloseButtonProps} />
|
|
264
300
|
{onNewChat && (
|
|
265
|
-
<Button
|
|
301
|
+
<Button
|
|
302
|
+
size={isCompact ? 'sm' : undefined}
|
|
303
|
+
onClick={onNewChat}
|
|
304
|
+
icon={<PenToSquareIcon />}
|
|
305
|
+
{...newChatButtonProps}
|
|
306
|
+
>
|
|
266
307
|
{newChatButtonText}
|
|
267
308
|
</Button>
|
|
268
309
|
)}
|
|
269
310
|
</DrawerActions>
|
|
270
311
|
</DrawerHead>
|
|
271
|
-
<div className="pf-
|
|
272
|
-
<
|
|
312
|
+
<div className="pf-chatbot__heading-container">
|
|
313
|
+
<div className="pf-chatbot__title-container">
|
|
273
314
|
<Icon size="lg" className="pf-chatbot__title-icon">
|
|
274
|
-
|
|
315
|
+
{navTitleIcon}
|
|
275
316
|
</Icon>
|
|
276
|
-
{
|
|
277
|
-
|
|
317
|
+
<Title className="pf-chatbot__title" headingLevel="h2" {...navTitleProps}>
|
|
318
|
+
{title}
|
|
319
|
+
</Title>
|
|
320
|
+
</div>
|
|
278
321
|
{!isLoading && handleTextInputChange && (
|
|
279
322
|
<div className="pf-chatbot__input">
|
|
280
323
|
<SearchInput
|
|
281
324
|
aria-label={searchInputAriaLabel}
|
|
282
325
|
onChange={(_event, value) => handleTextInputChange(value)}
|
|
283
326
|
placeholder={searchInputPlaceholder}
|
|
327
|
+
{...searchInputProps}
|
|
284
328
|
/>
|
|
329
|
+
{searchInputScreenReaderText && (
|
|
330
|
+
<div className="pf-chatbot__filter-announcement">{searchInputScreenReaderText}</div>
|
|
331
|
+
)}
|
|
285
332
|
</div>
|
|
286
333
|
)}
|
|
287
334
|
</div>
|
|
@@ -12,7 +12,7 @@ describe('ChatbotHeaderMenu', () => {
|
|
|
12
12
|
it('should call onMenuToggle when ChatbotHeaderMenu button is clicked', () => {
|
|
13
13
|
const onMenuToggle = jest.fn();
|
|
14
14
|
render(<ChatbotHeaderMenu className="custom-header-menu" onMenuToggle={onMenuToggle} />);
|
|
15
|
-
fireEvent.click(screen.getByRole('button', { name: '
|
|
15
|
+
fireEvent.click(screen.getByRole('button', { name: 'Chat history menu' }));
|
|
16
16
|
|
|
17
17
|
expect(onMenuToggle).toHaveBeenCalled();
|
|
18
18
|
});
|
|
@@ -25,9 +25,9 @@ const ChatbotHeaderMenuBase: FunctionComponent<ChatbotHeaderMenuProps> = ({
|
|
|
25
25
|
className,
|
|
26
26
|
onMenuToggle,
|
|
27
27
|
tooltipProps,
|
|
28
|
-
menuAriaLabel = '
|
|
28
|
+
menuAriaLabel = 'Chat history menu',
|
|
29
29
|
innerRef,
|
|
30
|
-
tooltipContent = '
|
|
30
|
+
tooltipContent = 'Chat history menu',
|
|
31
31
|
isCompact,
|
|
32
32
|
...props
|
|
33
33
|
}: ChatbotHeaderMenuProps) => (
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import { ChatbotHeaderNewChatButton } from './ChatbotHeaderNewChatButton';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
|
|
5
|
+
describe('ChatbotHeaderNewChatButton', () => {
|
|
6
|
+
it('should render ChatbotHeaderNewChatButton', () => {
|
|
7
|
+
const { container } = render(
|
|
8
|
+
<ChatbotHeaderNewChatButton className="custom-header-new-chat-button" onClick={jest.fn()} />
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
expect(container.querySelector('.custom-header-new-chat-button')).toBeTruthy();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should call onClick handler when new chat button is pressed', () => {
|
|
15
|
+
const onClick = jest.fn();
|
|
16
|
+
render(<ChatbotHeaderNewChatButton className="custom-header-new-chat-button" onClick={onClick} />);
|
|
17
|
+
fireEvent.click(screen.getByRole('button', { name: 'New chat' }));
|
|
18
|
+
expect(onClick).toHaveBeenCalled();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should render button with isCompact', () => {
|
|
22
|
+
render(<ChatbotHeaderNewChatButton data-testid="new-chat-button" onClick={jest.fn()} isCompact />);
|
|
23
|
+
expect(screen.getByTestId('new-chat-button')).toHaveClass('pf-m-compact');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Ref, FunctionComponent } from 'react';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
|
|
4
|
+
import { Button, ButtonProps, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
|
|
5
|
+
import { PenToSquareIcon } from '@patternfly/react-icons/dist/esm/icons/pen-to-square-icon';
|
|
6
|
+
|
|
7
|
+
export interface ChatbotHeaderNewChatButtonProps extends ButtonProps {
|
|
8
|
+
/** Callback function for when button is clicked */
|
|
9
|
+
onClick: () => void;
|
|
10
|
+
/** Custom classname for the header component */
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Props spread to the PF Tooltip component wrapping the display mode dropdown */
|
|
13
|
+
tooltipProps?: TooltipProps;
|
|
14
|
+
/** Aria label for menu */
|
|
15
|
+
menuAriaLabel?: string;
|
|
16
|
+
/** Ref applied to menu */
|
|
17
|
+
innerRef?: React.Ref<HTMLButtonElement>;
|
|
18
|
+
/** Content used in tooltip */
|
|
19
|
+
tooltipContent?: string;
|
|
20
|
+
/** Sets button to compact styling. */
|
|
21
|
+
isCompact?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const ChatbotHeaderNewChatButtonBase: FunctionComponent<ChatbotHeaderNewChatButtonProps> = ({
|
|
25
|
+
className,
|
|
26
|
+
onClick,
|
|
27
|
+
tooltipProps,
|
|
28
|
+
menuAriaLabel = 'New chat',
|
|
29
|
+
innerRef,
|
|
30
|
+
tooltipContent = 'New chat',
|
|
31
|
+
isCompact,
|
|
32
|
+
...props
|
|
33
|
+
}: ChatbotHeaderNewChatButtonProps) => (
|
|
34
|
+
<div className={`pf-chatbot__menu${className ? ` ${className}` : ''}`}>
|
|
35
|
+
<Tooltip
|
|
36
|
+
content={tooltipContent}
|
|
37
|
+
position="bottom"
|
|
38
|
+
// prevents VO announcements of both aria label and tooltip
|
|
39
|
+
aria="none"
|
|
40
|
+
{...tooltipProps}
|
|
41
|
+
>
|
|
42
|
+
<Button
|
|
43
|
+
className={`pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`}
|
|
44
|
+
variant="plain"
|
|
45
|
+
onClick={onClick}
|
|
46
|
+
aria-label={menuAriaLabel}
|
|
47
|
+
ref={innerRef}
|
|
48
|
+
icon={
|
|
49
|
+
<Icon size={isCompact ? 'lg' : 'xl'} isInline>
|
|
50
|
+
<PenToSquareIcon />
|
|
51
|
+
</Icon>
|
|
52
|
+
}
|
|
53
|
+
size={isCompact ? 'sm' : undefined}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
</Tooltip>
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
export const ChatbotHeaderNewChatButton = forwardRef(
|
|
61
|
+
(props: ChatbotHeaderNewChatButtonProps, ref: Ref<HTMLButtonElement>) => (
|
|
62
|
+
<ChatbotHeaderNewChatButtonBase innerRef={ref} {...props} />
|
|
63
|
+
)
|
|
64
|
+
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.pf-chatbot__deep-thinking {
|
|
2
|
+
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--control--read-only);
|
|
3
|
+
overflow: unset;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.pf-chatbot__deep-thinking-expandable-section {
|
|
7
|
+
--pf-v6-c-expandable-section--Gap: var(--pf-t--global--spacer--xs);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.pf-chatbot__deep-thinking-section {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: var(--pf-t--global--spacer--xs);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.pf-chatbot__deep-thinking-subheading {
|
|
17
|
+
font-size: var(--pf-t--global--font--size--body--sm);
|
|
18
|
+
font-weight: var(--pf-t--global--font--weight--body--default);
|
|
19
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.pf-chatbot__deep-thinking-body {
|
|
23
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
24
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import DeepThinking from './DeepThinking';
|
|
4
|
+
|
|
5
|
+
describe('DeepThinking', () => {
|
|
6
|
+
const defaultProps = {
|
|
7
|
+
toggleContent: 'Show thinking'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
it('should render with required props only', () => {
|
|
11
|
+
render(<DeepThinking {...defaultProps} />);
|
|
12
|
+
expect(screen.getByText('Show thinking')).toBeTruthy();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should render subheading when provided', () => {
|
|
16
|
+
const subheading = 'Thought for 3 seconds';
|
|
17
|
+
render(<DeepThinking {...defaultProps} subheading={subheading} />);
|
|
18
|
+
expect(screen.getByText(subheading)).toBeTruthy();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should render body content when provided', () => {
|
|
22
|
+
const body = "Here's why I think that";
|
|
23
|
+
render(<DeepThinking {...defaultProps} body={body} />);
|
|
24
|
+
expect(screen.getByText(body)).toBeTruthy();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should render with complex content including React elements', () => {
|
|
28
|
+
const body = (
|
|
29
|
+
<div>
|
|
30
|
+
<p>Complex body content</p>
|
|
31
|
+
<ul>
|
|
32
|
+
<li>Item 1</li>
|
|
33
|
+
<li>Item 2</li>
|
|
34
|
+
</ul>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
render(<DeepThinking {...defaultProps} body={body} />);
|
|
39
|
+
expect(screen.getByText('Complex body content')).toBeTruthy();
|
|
40
|
+
expect(screen.getByText('Item 1')).toBeTruthy();
|
|
41
|
+
expect(screen.getByText('Item 2')).toBeTruthy();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should apply custom className from cardProps', () => {
|
|
45
|
+
const { container } = render(
|
|
46
|
+
<DeepThinking {...defaultProps} cardProps={{ className: 'custom-tool-response-class' }} />
|
|
47
|
+
);
|
|
48
|
+
expect(container.querySelector('.custom-tool-response-class')).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should pass through expandableSectionProps', () => {
|
|
52
|
+
render(<DeepThinking {...defaultProps} expandableSectionProps={{ className: 'custom-expandable-class' }} />);
|
|
53
|
+
expect(document.querySelector('.custom-expandable-class')).toBeTruthy();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should not render subheading span when subheading is not provided', () => {
|
|
57
|
+
const { container } = render(<DeepThinking {...defaultProps} />);
|
|
58
|
+
const subheadingContainer = container.querySelector('.pf-chatbot__tool-response-subheading');
|
|
59
|
+
expect(subheadingContainer).toBeFalsy();
|
|
60
|
+
});
|
|
61
|
+
});
|