| import { useRecoilValue } from 'recoil'; |
| import { ChevronDownIcon } from 'lucide-react'; |
| import { useState, useEffect, useMemo } from 'react'; |
| import { useAvailablePluginsQuery } from 'librechat-data-provider/react-query'; |
| import { |
| Button, |
| SelectDropDown, |
| SelectDropDownPop, |
| MultiSelectDropDown, |
| useMediaQuery, |
| } from '@librechat/client'; |
| import type { TPlugin } from 'librechat-data-provider'; |
| import type { TModelSelectProps } from '~/common'; |
| import { useSetIndexOptions, useAuthContext, useLocalize } from '~/hooks'; |
| import { cn, cardStyle, selectPlugins, processPlugins } from '~/utils'; |
| import MultiSelectPop from './MultiSelectPop'; |
| import store from '~/store'; |
|
|
| export default function PluginsByIndex({ |
| conversation, |
| setOption, |
| models, |
| showAbove, |
| popover = false, |
| }: TModelSelectProps) { |
| const localize = useLocalize(); |
| const { user } = useAuthContext(); |
| const [visible, setVisibility] = useState<boolean>(true); |
| const isSmallScreen = useMediaQuery('(max-width: 640px)'); |
| const availableTools = useRecoilValue(store.availableTools); |
| const { checkPluginSelection, setTools } = useSetIndexOptions(); |
|
|
| const { data: allPlugins } = useAvailablePluginsQuery({ |
| enabled: !!user?.plugins, |
| select: selectPlugins, |
| }); |
|
|
| useEffect(() => { |
| if (isSmallScreen) { |
| setVisibility(false); |
| } |
| }, [isSmallScreen]); |
|
|
| const conversationTools: TPlugin[] = useMemo(() => { |
| if (!conversation?.tools) { |
| return []; |
| } |
| return processPlugins(conversation.tools, allPlugins?.map); |
| }, [conversation, allPlugins]); |
|
|
| const availablePlugins = useMemo(() => { |
| if (!availableTools) { |
| return []; |
| } |
|
|
| return Object.values(availableTools); |
| }, [availableTools]); |
|
|
| if (!conversation) { |
| return null; |
| } |
|
|
| const Menu = popover ? SelectDropDownPop : SelectDropDown; |
| const PluginsMenu = popover ? MultiSelectPop : MultiSelectDropDown; |
|
|
| return ( |
| <> |
| <Button |
| type="button" |
| className={cn( |
| cardStyle, |
| 'z-40 flex h-[40px] min-w-4 flex-none items-center justify-center px-3 hover:bg-white focus:ring-0 focus:ring-offset-0 dark:hover:bg-gray-700', |
| )} |
| onClick={() => setVisibility((prev) => !prev)} |
| > |
| <ChevronDownIcon |
| className={cn( |
| !visible ? '' : 'rotate-180 transform', |
| 'w-4 text-gray-600 dark:text-white', |
| )} |
| /> |
| </Button> |
| {visible && ( |
| <> |
| <Menu |
| value={conversation.model ?? ''} |
| setValue={setOption('model')} |
| availableValues={models} |
| showAbove={showAbove} |
| showLabel={false} |
| className={cn( |
| cardStyle, |
| 'z-50 flex h-[40px] w-48 min-w-48 flex-none items-center justify-center px-4 hover:cursor-pointer', |
| )} |
| /> |
| <PluginsMenu |
| showAbove={false} |
| showLabel={false} |
| setSelected={setTools} |
| value={conversationTools} |
| optionValueKey="pluginKey" |
| availableValues={availablePlugins} |
| isSelected={checkPluginSelection} |
| searchPlaceholder={localize('com_ui_select_search_plugin')} |
| /> |
| </> |
| )} |
| </> |
| ); |
| } |
|
|