import { useState, isValidElement, cloneElement, Children, FunctionComponent, ReactNode } from 'react'; import AttachMenu from '@patternfly/chatbot/dist/dynamic/AttachMenu'; import SourceDetailsMenuItem from '@patternfly/chatbot/dist/dynamic/SourceDetailsMenuItem'; import { Button, Divider, DropdownGroup, DropdownItem, DropdownList } from '@patternfly/react-core'; import { BellIcon, CodeIcon, ClipboardIcon, CalendarAltIcon, UploadIcon } from '@patternfly/react-icons'; import PaperclipIcon from './PaperclipIcon'; const initialMenuItems = [ } name="auth-operator" type="Pod" /> , }> Alerts }> Events }> Logs }> YAML - Status }> YAML - All contents ]; const uploadMenuItems = [ , }> Upload from computer ]; export const AttachmentMenuExample: FunctionComponent = () => { const [isOpen, setIsOpen] = useState(false); const [userFacingMenuItems, setUserFacingMenuItems] = useState([]); const onToggleClick = () => { setIsOpen(!isOpen); setUserFacingMenuItems(initialMenuItems.concat(uploadMenuItems)); }; const findMatchingElements = (elements: ReactNode[], targetValue: string) => { let matchingElements = [] as ReactNode[]; elements.forEach((element) => { if (isValidElement(element)) { // Check if the element's value matches the targetValue if (element.props.value && element.props.value.toLowerCase().includes(targetValue.toLowerCase())) { matchingElements.push(cloneElement(element, { key: element.props.value })); } // Recursively check the element's children const children = Children.toArray(element.props.children); matchingElements = matchingElements.concat(findMatchingElements(children, targetValue)); } }); return matchingElements; }; const onTextChange = (textValue: string) => { if (textValue === '') { setUserFacingMenuItems(initialMenuItems.concat(uploadMenuItems)); return; } const newMenuItems = findMatchingElements(initialMenuItems, textValue); // this is necessary because the React nodes we find traversing the recursive search // aren't correctly wrapped in a DropdownList. This leads to problems with the // auth-operator item where it winds up floating in a bad place in the DOM and never // gets removed setUserFacingMenuItems( <> {newMenuItems.length === 0 ? ( No results found ) : ( newMenuItems.map((item) => item) )} {uploadMenuItems.map((item) => item)} ); }; return ( setIsOpen(isOpen)} onOpenChangeKeys={['Escape']} // eslint-disable-next-line no-console onSelect={(_ev, value) => console.log('selected', value)} handleTextInputChange={onTextChange} popperProps={{ direction: 'up', distance: 8 }} searchInputPlaceholder="Search cluster resources..." toggle={(toggleRef) => (