diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx b/packages/module/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx new file mode 100644 index 000000000..21c92300f --- /dev/null +++ b/packages/module/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx @@ -0,0 +1,196 @@ +// Assisted by: Cursor +import React, { FunctionComponent, useState } from 'react'; +import { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot'; +import ChatbotConversationHistoryNav, { + Conversation +} from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'; +import { Checkbox, DropdownItem, DropdownList } from '@patternfly/react-core'; +import { ThumbtackIcon } from '@patternfly/react-icons'; + +// Sample conversations +const initialConversations: { [key: string]: Conversation[] } = { + Today: [ + { + id: '1', + text: 'Red Hat products and services', + label: 'Conversation options for "Red Hat products and services"' + } + ], + 'This month': [ + { + id: '2', + text: 'Enterprise Linux installation and setup', + label: 'Conversation options for "Enterprise Linux installation and setup"' + }, + { + id: '3', + text: 'Troubleshoot system crash', + label: 'Conversation options for "Troubleshoot system crash"' + } + ], + March: [ + { + id: '4', + text: 'Ansible security and updates', + label: 'Conversation options for "Ansible security and updates"' + }, + { + id: '5', + text: 'Red Hat certification', + label: 'Conversation options for "Red Hat certification"' + }, + { + id: '6', + text: 'Lightspeed user documentation', + label: 'Conversation options for "Lightspeed user documentation"' + } + ], + February: [ + { + id: '7', + text: 'Crashing pod assistance', + label: 'Conversation options for "Crashing pod assistance"' + }, + { + id: '8', + text: 'OpenShift AI pipelines', + label: 'Conversation options for "OpenShift AI pipelines"' + }, + { + id: '9', + text: 'Updating subscription plan', + label: 'Conversation options for "Updating subscription plan"' + }, + { + id: '10', + text: 'Red Hat licensing options', + label: 'Conversation options for "Red Hat licensing options"' + } + ], + January: [ + { + id: '11', + text: 'RHEL system performance', + label: 'Conversation options for "RHEL system performance"' + }, + { + id: '12', + text: 'Manage user accounts', + label: 'Conversation options for "Manage user accounts"' + } + ] +}; + +export const ChatbotHeaderPinDemo: FunctionComponent = () => { + const [isDrawerOpen, setIsDrawerOpen] = useState(true); + const [isCompact, setIsCompact] = useState(false); + const [pinnedConversations, setPinnedConversations] = useState>(new Set()); + const displayMode = ChatbotDisplayMode.embedded; + + const handlePinToggle = (conversationId: string) => { + setPinnedConversations((prev) => { + const newPinned = new Set(prev); + if (newPinned.has(conversationId)) { + newPinned.delete(conversationId); + } else { + newPinned.add(conversationId); + } + return newPinned; + }); + }; + + const createMenuItems = (conversationId: string) => { + const isPinned = pinnedConversations.has(conversationId); + + return [ + + handlePinToggle(conversationId)} + > + {isPinned ? 'Unpin' : 'Pin'} + + + Delete + + + Rename + + + Archive + + + ]; + }; + + // Reorganize conversations to show pinned ones at the top + const organizeConversations = () => { + const organized: { [key: string]: Conversation[] } = {}; + const pinnedItems: Conversation[] = []; + + // Collect all pinned conversations first + Object.entries(initialConversations).forEach(([_period, conversations]) => { + conversations.forEach((conv) => { + if (pinnedConversations.has(conv.id)) { + pinnedItems.push({ + ...conv, + menuItems: createMenuItems(conv.id), + icon: + }); + } + }); + }); + + // Add pinned section if there are pinned items + if (pinnedItems.length > 0) { + organized.Pinned = pinnedItems; + } + + // Add unpinned conversations + Object.entries(initialConversations).forEach(([period, conversations]) => { + const unpinnedConversations = conversations + .filter((conv) => !pinnedConversations.has(conv.id)) + .map((conv) => ({ + ...conv, + menuItems: createMenuItems(conv.id) + })); + + if (unpinnedConversations.length > 0) { + organized[period] = unpinnedConversations; + } + }); + + return organized; + }; + + const conversations = organizeConversations(); + + return ( + <> + setIsDrawerOpen(!isDrawerOpen)} + id="drawer-pin-visible" + name="drawer-pin-visible" + > + setIsCompact(!isCompact)} + id="drawer-pin-compact" + name="drawer-pin-compact" + > + setIsDrawerOpen(!isDrawerOpen)} + isDrawerOpen={isDrawerOpen} + setIsDrawerOpen={setIsDrawerOpen} + conversations={conversations} + drawerContent={
Drawer content
} + isCompact={isCompact} + /> + + ); +}; diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md b/packages/module/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md index c9befb6e4..ae4bcac7f 100644 --- a/packages/module/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +++ b/packages/module/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md @@ -68,7 +68,7 @@ import { MessageBar } from '@patternfly/chatbot/dist/dynamic/MessageBar'; import SourceDetailsMenuItem from '@patternfly/chatbot/dist/dynamic/SourceDetailsMenuItem'; import { ChatbotModal } from '@patternfly/chatbot/dist/dynamic/ChatbotModal'; import SettingsForm from '@patternfly/chatbot/dist/dynamic/Settings'; -import { BellIcon, CalendarAltIcon, ClipboardIcon, CodeIcon, UploadIcon } from '@patternfly/react-icons'; +import { BellIcon, CalendarAltIcon, ClipboardIcon, CodeIcon, ThumbtackIcon, UploadIcon } from '@patternfly/react-icons'; import { useDropzone } from 'react-dropzone'; import ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'; @@ -361,6 +361,14 @@ Actions can be added to conversations with `menuItems`. Optionally, you can also ``` +### Pinning conversations + +To help users track important conversations, add a "pin" option to the conversation action menus. This action moves a conversation to a dedicated "pinned" section at the top of the history drawer for quick access. Pinned items should contain an "unpin" option, so that users can remove pinned conversations as needed. + +```js file="./ChatbotHeaderDrawerWithPin.tsx" + +``` + ### Drawer with active conversation If you're showing a conversation that is already active, you can set the `activeItemId` prop on your `` to apply an active visual state.