Spaces:
Paused
Paused
| import { IconFolderPlus, IconMistOff, IconPlus } from '@tabler/icons-react'; | |
| import { ReactNode } from 'react'; | |
| import { useTranslation } from 'react-i18next'; | |
| import { | |
| CloseSidebarButton, | |
| OpenSidebarButton, | |
| } from './components/OpenCloseButton'; | |
| import Search from '../Search'; | |
| interface Props<T> { | |
| isOpen: boolean; | |
| addItemButtonTitle: string; | |
| side: 'left' | 'right'; | |
| items: T[]; | |
| itemComponent: ReactNode; | |
| folderComponent: ReactNode; | |
| footerComponent?: ReactNode; | |
| searchTerm: string; | |
| handleSearchTerm: (searchTerm: string) => void; | |
| toggleOpen: () => void; | |
| handleCreateItem: () => void; | |
| handleCreateFolder: () => void; | |
| handleDrop: (e: any) => void; | |
| } | |
| const Sidebar = <T,>({ | |
| isOpen, | |
| addItemButtonTitle, | |
| side, | |
| items, | |
| itemComponent, | |
| folderComponent, | |
| footerComponent, | |
| searchTerm, | |
| handleSearchTerm, | |
| toggleOpen, | |
| handleCreateItem, | |
| handleCreateFolder, | |
| handleDrop, | |
| }: Props<T>) => { | |
| const { t } = useTranslation('promptbar'); | |
| const allowDrop = (e: any) => { | |
| e.preventDefault(); | |
| }; | |
| const highlightDrop = (e: any) => { | |
| e.target.style.background = '#343541'; | |
| }; | |
| const removeHighlight = (e: any) => { | |
| e.target.style.background = 'none'; | |
| }; | |
| return isOpen ? ( | |
| <div> | |
| <div | |
| className={`fixed top-0 ${side}-0 z-40 flex h-full w-[260px] flex-none flex-col space-y-2 bg-[#202123] p-2 text-[14px] transition-all sm:relative sm:top-0`} | |
| > | |
| <div className="flex items-center"> | |
| <button | |
| className="text-sidebar flex w-[190px] flex-shrink-0 cursor-pointer select-none items-center gap-3 rounded-md border border-white/20 p-3 text-white transition-colors duration-200 hover:bg-gray-500/10" | |
| onClick={() => { | |
| handleCreateItem(); | |
| handleSearchTerm(''); | |
| }} | |
| > | |
| <IconPlus size={16} /> | |
| {addItemButtonTitle} | |
| </button> | |
| <button | |
| className="ml-2 flex flex-shrink-0 cursor-pointer items-center gap-3 rounded-md border border-white/20 p-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10" | |
| onClick={handleCreateFolder} | |
| > | |
| <IconFolderPlus size={16} /> | |
| </button> | |
| </div> | |
| <Search | |
| placeholder={t('Search...') || ''} | |
| searchTerm={searchTerm} | |
| onSearch={handleSearchTerm} | |
| /> | |
| <div className="flex-grow overflow-auto"> | |
| {items?.length > 0 && ( | |
| <div className="flex border-b border-white/20 pb-2"> | |
| {folderComponent} | |
| </div> | |
| )} | |
| {items?.length > 0 ? ( | |
| <div | |
| className="pt-2" | |
| onDrop={handleDrop} | |
| onDragOver={allowDrop} | |
| onDragEnter={highlightDrop} | |
| onDragLeave={removeHighlight} | |
| > | |
| {itemComponent} | |
| </div> | |
| ) : ( | |
| <div className="mt-8 select-none text-center text-white opacity-50"> | |
| <IconMistOff className="mx-auto mb-3" /> | |
| <span className="text-[14px] leading-normal"> | |
| {t('No data.')} | |
| </span> | |
| </div> | |
| )} | |
| </div> | |
| {footerComponent} | |
| </div> | |
| <CloseSidebarButton onClick={toggleOpen} side={side} /> | |
| </div> | |
| ) : ( | |
| <OpenSidebarButton onClick={toggleOpen} side={side} /> | |
| ); | |
| }; | |
| export default Sidebar; | |