| import React, { useState } from 'react'; |
| import { useFormContext } from 'react-hook-form'; |
| import { useUpdateUserPluginsMutation } from 'librechat-data-provider/react-query'; |
| import { |
| OGDialog, |
| OGDialogTrigger, |
| Label, |
| OGDialogTemplate, |
| TrashIcon, |
| useToastContext, |
| } from '@librechat/client'; |
| import type { TPlugin } from 'librechat-data-provider'; |
| import { useLocalize } from '~/hooks'; |
| import { cn } from '~/utils'; |
|
|
| export default function AssistantTool({ |
| tool, |
| allTools, |
| assistant_id = '', |
| }: { |
| tool: string; |
| allTools: TPlugin[]; |
| assistant_id?: string; |
| }) { |
| const [isHovering, setIsHovering] = useState(false); |
| const localize = useLocalize(); |
| const { showToast } = useToastContext(); |
| const updateUserPlugins = useUpdateUserPluginsMutation(); |
| const { getValues, setValue } = useFormContext(); |
| const currentTool = allTools.find((t) => t.pluginKey === tool); |
|
|
| const removeTool = (tool: string) => { |
| if (tool) { |
| updateUserPlugins.mutate( |
| { pluginKey: tool, action: 'uninstall', auth: null, isEntityTool: true }, |
| { |
| onError: (error: unknown) => { |
| showToast({ message: `Error while deleting the tool: ${error}`, status: 'error' }); |
| }, |
| onSuccess: () => { |
| const fns = getValues('functions').filter((fn) => fn !== tool); |
| setValue('functions', fns); |
| showToast({ message: 'Tool deleted successfully', status: 'success' }); |
| }, |
| }, |
| ); |
| } |
| }; |
|
|
| if (!currentTool) { |
| return null; |
| } |
|
|
| return ( |
| <OGDialog> |
| <div |
| className={cn( |
| 'flex w-full items-center rounded-lg text-sm', |
| !assistant_id ? 'opacity-40' : '', |
| )} |
| onMouseEnter={() => setIsHovering(true)} |
| onMouseLeave={() => setIsHovering(false)} |
| > |
| <div className="flex grow items-center"> |
| {currentTool.icon && ( |
| <div className="flex h-9 w-9 items-center justify-center overflow-hidden rounded-full"> |
| <div |
| className="flex h-6 w-6 items-center justify-center overflow-hidden rounded-full bg-center bg-no-repeat dark:bg-white/20" |
| style={{ backgroundImage: `url(${currentTool.icon})`, backgroundSize: 'cover' }} |
| /> |
| </div> |
| )} |
| <div |
| className="h-9 grow px-3 py-2" |
| style={{ textOverflow: 'ellipsis', wordBreak: 'break-all', overflow: 'hidden' }} |
| > |
| {currentTool.name} |
| </div> |
| </div> |
| |
| {isHovering && ( |
| <OGDialogTrigger asChild> |
| <button |
| type="button" |
| className="flex h-9 w-9 min-w-9 items-center justify-center rounded-lg transition-colors duration-200 hover:bg-gray-200 dark:hover:bg-gray-700" |
| > |
| <TrashIcon /> |
| </button> |
| </OGDialogTrigger> |
| )} |
| </div> |
| <OGDialogTemplate |
| showCloseButton={false} |
| title={localize('com_ui_delete_tool')} |
| className="max-w-[450px]" |
| main={ |
| <Label className="text-left text-sm font-medium"> |
| {localize('com_ui_delete_tool_confirm')} |
| </Label> |
| } |
| selection={{ |
| selectHandler: () => removeTool(currentTool.pluginKey), |
| selectClasses: |
| 'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-colors duration-200 text-white', |
| selectText: localize('com_ui_delete'), |
| }} |
| /> |
| </OGDialog> |
| ); |
| } |
|
|