From 0bd59c0efeed36ae499d8542a38c8fa39010b9f7 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Sun, 21 Jul 2024 19:46:43 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20style:=20update=20Assistants=20b?= =?UTF-8?q?uilder=20(#3397)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * style: update Assistant builder * fix(Eng): re-introduce old file_search info message * feat: new OGDialogTemplate; style: imporved tools + actions dialogs * style: fix alignment issue for delete tool dialog * chore: import order --------- Co-authored-by: Danny Avila --- .../Chat/Input/Files/RemoveFile.tsx | 4 +- .../Chat/Input/Files/Table/DataTable.tsx | 4 +- .../src/components/Files/DeleteIconButton.tsx | 4 +- .../Files/FileList/DataTableFile.tsx | 4 +- .../Files/FileList/FileListItem.tsx | 4 +- .../Files/FileList/FileListItem2.tsx | 4 +- .../components/Files/FileList/FilePreview.tsx | 6 +- .../Files/VectorStore/VectorStoreListItem.tsx | 4 +- .../Files/VectorStore/VectorStorePreview.tsx | 4 +- .../Prompts/Groups/DashGroupItem.tsx | 4 +- .../SidePanel/Builder/ActionsPanel.tsx | 60 +- .../SidePanel/Builder/AssistantAction.tsx | 22 +- .../SidePanel/Builder/AssistantPanel.tsx | 95 +- .../SidePanel/Builder/AssistantTool.tsx | 101 +- .../SidePanel/Builder/CapabilitiesForm.tsx | 28 +- .../src/components/SidePanel/Builder/Code.tsx | 108 +- .../SidePanel/Builder/CodeFiles.tsx | 4 +- .../SidePanel/Builder/ContextButton.tsx | 115 +- .../SidePanel/Builder/ImageVision.tsx | 5 +- .../SidePanel/Builder/Retrieval.tsx | 69 +- .../SidePanel/Parameters/OptionHover.tsx | 8 +- client/src/components/svg/NewTrashIcon.tsx | 19 - client/src/components/svg/TrashIcon.tsx | 8 +- client/src/components/svg/index.ts | 1 - client/src/components/ui/HoverCard.tsx | 32 +- client/src/components/ui/OGDialogTemplate.tsx | 95 ++ client/src/components/ui/OriginalDialog.tsx | 19 +- client/src/localization/languages/Eng.ts | 11 +- client/src/localization/languages/Tr.ts | 1189 +++++++++-------- 29 files changed, 1115 insertions(+), 916 deletions(-) delete mode 100644 client/src/components/svg/NewTrashIcon.tsx create mode 100644 client/src/components/ui/OGDialogTemplate.tsx diff --git a/client/src/components/Chat/Input/Files/RemoveFile.tsx b/client/src/components/Chat/Input/Files/RemoveFile.tsx index e9d0a6b768..31dccf4e30 100644 --- a/client/src/components/Chat/Input/Files/RemoveFile.tsx +++ b/client/src/components/Chat/Input/Files/RemoveFile.tsx @@ -2,7 +2,7 @@ export default function RemoveFile({ onRemove }: { onRemove: () => void }) { return ( diff --git a/client/src/components/Files/DeleteIconButton.tsx b/client/src/components/Files/DeleteIconButton.tsx index f887487d7a..50ac461bab 100644 --- a/client/src/components/Files/DeleteIconButton.tsx +++ b/client/src/components/Files/DeleteIconButton.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { CrossIcon, NewTrashIcon } from '~/components/svg'; +import { CrossIcon, TrashIcon } from '~/components/svg'; import { Button } from '~/components/ui'; type DeleteIconButtonProps = { @@ -10,7 +10,7 @@ export default function DeleteIconButton({ onClick }: DeleteIconButtonProps) { return (
); diff --git a/client/src/components/Files/FileList/DataTableFile.tsx b/client/src/components/Files/FileList/DataTableFile.tsx index 92e454016d..7d8e6e9118 100644 --- a/client/src/components/Files/FileList/DataTableFile.tsx +++ b/client/src/components/Files/FileList/DataTableFile.tsx @@ -32,7 +32,7 @@ import { DropdownMenuTrigger, } from '~/components/ui'; import { useDeleteFilesFromTable } from '~/hooks/Files'; -import { NewTrashIcon, Spinner } from '~/components/svg'; +import { TrashIcon, Spinner } from '~/components/svg'; import useLocalize from '~/hooks/useLocalize'; import ActionButton from '../ActionButton'; import UploadFileButton from './UploadFileButton'; @@ -112,7 +112,7 @@ export default function DataTableFile({ {isDeleting ? ( ) : ( - + )} {localize('com_ui_delete')} diff --git a/client/src/components/Files/FileList/FileListItem.tsx b/client/src/components/Files/FileList/FileListItem.tsx index 79e625c763..5760b2917b 100644 --- a/client/src/components/Files/FileList/FileListItem.tsx +++ b/client/src/components/Files/FileList/FileListItem.tsx @@ -1,6 +1,6 @@ import type { TFile } from 'librechat-data-provider'; import React from 'react'; -import { NewTrashIcon } from '~/components/svg'; +import { TrashIcon } from '~/components/svg'; import { Button } from '~/components/ui'; type FileListItemProps = { @@ -25,7 +25,7 @@ export default function FileListItem({ file, deleteFile, width = '400px' }: File className="my-0 ml-3 bg-transparent p-0 text-[#666666] hover:bg-slate-200" onClick={() => deleteFile(file._id)} > - + diff --git a/client/src/components/Files/FileList/FileListItem2.tsx b/client/src/components/Files/FileList/FileListItem2.tsx index 4941439a80..2b8ff1d6a9 100644 --- a/client/src/components/Files/FileList/FileListItem2.tsx +++ b/client/src/components/Files/FileList/FileListItem2.tsx @@ -2,7 +2,7 @@ import type { TFile } from 'librechat-data-provider'; import { FileIcon, PlusIcon } from 'lucide-react'; import React from 'react'; import { useNavigate } from 'react-router-dom'; -import { DotsIcon, NewTrashIcon } from '~/components/svg'; +import { DotsIcon, TrashIcon } from '~/components/svg'; import { Button } from '~/components/ui'; type FileListItemProps = { @@ -68,7 +68,7 @@ export default function FileListItem2({ className="w-min bg-transparent text-[#666666] hover:bg-slate-200" onClick={() => deleteFile(file._id)} > - + diff --git a/client/src/components/Files/FileList/FilePreview.tsx b/client/src/components/Files/FileList/FilePreview.tsx index 5b3b9ebf37..e0c2624b34 100644 --- a/client/src/components/Files/FileList/FilePreview.tsx +++ b/client/src/components/Files/FileList/FilePreview.tsx @@ -1,7 +1,7 @@ import { TFile } from 'librechat-data-provider/dist/types'; import React, { useState } from 'react'; import { TThread, TVectorStore } from '~/common'; -import { CheckMark, NewTrashIcon } from '~/components/svg'; +import { CheckMark, TrashIcon } from '~/components/svg'; import { Button } from '~/components/ui'; import DeleteIconButton from '../DeleteIconButton'; import VectorStoreButton from '../VectorStore/VectorStoreButton'; @@ -140,7 +140,7 @@ export default function FilePreview() { }} variant={'ghost'} > - + @@ -167,7 +167,7 @@ export default function FilePreview() { console.log('Remove from thread'); }} > - + diff --git a/client/src/components/Files/VectorStore/VectorStoreListItem.tsx b/client/src/components/Files/VectorStore/VectorStoreListItem.tsx index 7dae80f541..4b132e92a3 100644 --- a/client/src/components/Files/VectorStore/VectorStoreListItem.tsx +++ b/client/src/components/Files/VectorStore/VectorStoreListItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useNavigate } from 'react-router-dom'; import { TVectorStore } from '~/common'; -import { DotsIcon, NewTrashIcon, TrashIcon } from '~/components/svg'; +import { DotsIcon, TrashIcon, TrashIcon } from '~/components/svg'; import { Button } from '~/components/ui'; type VectorStoreListItemProps = { @@ -39,7 +39,7 @@ export default function VectorStoreListItem({ className="m-0 w-full bg-transparent p-0 text-[#666666] hover:bg-slate-200 sm:w-fit" onClick={() => deleteVectorStore(vectorStore._id)} > - + diff --git a/client/src/components/Files/VectorStore/VectorStorePreview.tsx b/client/src/components/Files/VectorStore/VectorStorePreview.tsx index dc9fd22303..74e7fe8b0a 100644 --- a/client/src/components/Files/VectorStore/VectorStorePreview.tsx +++ b/client/src/components/Files/VectorStore/VectorStorePreview.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import DeleteIconButton from '../DeleteIconButton'; import { Button } from '~/components/ui'; -import { NewTrashIcon } from '~/components/svg'; +import { TrashIcon } from '~/components/svg'; import { TFile } from 'librechat-data-provider/dist/types'; import UploadFileButton from '../FileList/UploadFileButton'; import UploadFileModal from '../FileList/UploadFileModal'; @@ -204,7 +204,7 @@ export default function VectorStorePreview() { className="my-0 ml-3 h-min bg-transparent p-0 text-[#666666] hover:bg-slate-200" onClick={() => console.log('click')} > - + diff --git a/client/src/components/Prompts/Groups/DashGroupItem.tsx b/client/src/components/Prompts/Groups/DashGroupItem.tsx index bfb8d4d6e2..1858cb2e27 100644 --- a/client/src/components/Prompts/Groups/DashGroupItem.tsx +++ b/client/src/components/Prompts/Groups/DashGroupItem.tsx @@ -18,7 +18,7 @@ import CategoryIcon from '~/components/Prompts/Groups/CategoryIcon'; import DialogTemplate from '~/components/ui/DialogTemplate'; import { RenameButton } from '~/components/Conversations'; import { useLocalize, useAuthContext } from '~/hooks'; -import { NewTrashIcon } from '~/components/svg'; +import { TrashIcon } from '~/components/svg'; import { cn } from '~/utils/'; export default function DashGroupItem({ @@ -169,7 +169,7 @@ export default function DashGroupItem({ e.stopPropagation(); }} > - + + {!!action && ( -
- +
+ + + {localize('com_ui_delete_action_confirm')} + + } + selection={{ + selectHandler: () => { + if (!assistant_id) { + return showToast({ + message: 'No assistant_id found, is the assistant created?', + status: 'error', + }); + } deleteAction.mutate({ model: assistantMap[endpoint][assistant_id].model, action_id: action.action_id, assistant_id, endpoint, }); - } + }, + selectClasses: + 'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-color duration-200 text-white', + selectText: localize('com_ui_delete'), }} - > -
- -
- - + /> + )} +
{(action ? 'Edit' : 'Add') + ' ' + 'actions'}
{localize('com_assistants_actions_info')} diff --git a/client/src/components/SidePanel/Builder/AssistantAction.tsx b/client/src/components/SidePanel/Builder/AssistantAction.tsx index 114dfdc21b..583db00674 100644 --- a/client/src/components/SidePanel/Builder/AssistantAction.tsx +++ b/client/src/components/SidePanel/Builder/AssistantAction.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react'; import type { Action } from 'librechat-data-provider'; import GearIcon from '~/components/svg/GearIcon'; @@ -8,11 +9,15 @@ export default function AssistantAction({ action: Action; onClick: () => void; }) { + const [isHovering, setIsHovering] = useState(false); + return (
setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} >
{action.metadata.domain}
-
- + {isHovering && ( + + )}
); diff --git a/client/src/components/SidePanel/Builder/AssistantPanel.tsx b/client/src/components/SidePanel/Builder/AssistantPanel.tsx index aca34fc8ea..d0dfa04e30 100644 --- a/client/src/components/SidePanel/Builder/AssistantPanel.tsx +++ b/client/src/components/SidePanel/Builder/AssistantPanel.tsx @@ -13,6 +13,7 @@ import { import type { FunctionTool, TConfig, TPlugin } from 'librechat-data-provider'; import type { AssistantForm, AssistantPanelProps } from '~/common'; import { useCreateAssistantMutation, useUpdateAssistantMutation } from '~/data-provider'; +import { cn, cardStyle, defaultTextProps, removeFocusOutlines } from '~/utils'; import { useAssistantsMapContext, useToastContext } from '~/Providers'; import { useSelectAssistant, useLocalize } from '~/hooks'; import { ToolSelectDialog } from '~/components/Tools'; @@ -24,13 +25,15 @@ import AssistantAction from './AssistantAction'; import ContextButton from './ContextButton'; import AssistantTool from './AssistantTool'; import { Spinner } from '~/components/svg'; -import { cn, cardStyle } from '~/utils/'; import Knowledge from './Knowledge'; import { Panel } from '~/common'; -const labelClass = 'mb-2 block text-xs font-bold text-gray-700 dark:text-gray-400'; -const inputClass = - 'focus:shadow-outline w-full appearance-none rounded-md border px-3 py-2 text-sm leading-tight text-gray-700 dark:text-white shadow focus:border-green-500 focus:outline-none focus:ring-0 dark:bg-gray-800 dark:border-gray-700/80'; +const labelClass = 'mb-2 text-token-text-primary block font-medium'; +const inputClass = cn( + defaultTextProps, + 'flex w-full px-3 py-2 dark:border-gray-800 dark:bg-gray-800', + removeFocusOutlines, +); export default function AssistantPanel({ // index = 0, @@ -297,7 +300,7 @@ export default function AssistantPanel({ {...field} value={field.value ?? ''} {...{ max: 32768 }} - className="focus:shadow-outline min-h-[150px] w-full resize-none resize-y appearance-none rounded-md border px-3 py-2 text-sm leading-tight text-gray-700 shadow focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700/80 dark:bg-gray-800 dark:text-white" + className={cn(inputClass, 'min-h-[100px] resize-none resize-y')} id="instructions" placeholder={localize('com_assistants_instructions_placeholder')} rows={3} @@ -357,7 +360,7 @@ export default function AssistantPanel({ ${toolsEnabled && actionsEnabled ? ' + ' : ''} ${actionsEnabled ? localize('com_assistants_actions') : ''}`} -
+
{functions.map((func, i) => ( setAction(action)} /> ); })} - {toolsEnabled && ( - - )} - {actionsEnabled && ( - - )} +
+ {toolsEnabled && ( + + )} + {actionsEnabled && ( + + )} +
@@ -415,23 +420,9 @@ export default function AssistantPanel({ createMutation={create} endpoint={endpoint} /> - {/* Secondary Select Button */} - {assistant_id && ( - - )} {/* Submit Button */} + + {isHovering && ( + + + + )}
-
+ + {localize('com_ui_delete_tool_confirm')} + + } + selection={{ + selectHandler: () => removeTool(currentTool.pluginKey), + selectClasses: + 'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-color duration-200 text-white', + selectText: localize('com_ui_delete'), + }} + /> + ); } diff --git a/client/src/components/SidePanel/Builder/CapabilitiesForm.tsx b/client/src/components/SidePanel/Builder/CapabilitiesForm.tsx index 4077adb887..efd7227cf0 100644 --- a/client/src/components/SidePanel/Builder/CapabilitiesForm.tsx +++ b/client/src/components/SidePanel/Builder/CapabilitiesForm.tsx @@ -1,9 +1,12 @@ import { useMemo } from 'react'; import { Capabilities } from 'librechat-data-provider'; +import { useFormContext, useWatch } from 'react-hook-form'; import type { TConfig, AssistantsEndpoint } from 'librechat-data-provider'; +import type { AssistantForm } from '~/common'; import ImageVision from './ImageVision'; import { useLocalize } from '~/hooks'; import Retrieval from './Retrieval'; +import CodeFiles from './CodeFiles'; import Code from './Code'; export default function CapabilitiesForm({ @@ -21,6 +24,17 @@ export default function CapabilitiesForm({ }) { const localize = useLocalize(); + const methods = useFormContext(); + const { control } = methods; + const assistant = useWatch({ control, name: 'assistant' }); + const assistant_id = useWatch({ control, name: 'id' }); + const files = useMemo(() => { + if (typeof assistant === 'string') { + return []; + } + return assistant.code_files; + }, [assistant]); + const retrievalModels = useMemo( () => new Set(assistantsConfig?.retrievalModels ?? []), [assistantsConfig], @@ -31,7 +45,7 @@ export default function CapabilitiesForm({ ); return ( -
+
- {codeEnabled && } - {imageVisionEnabled && version == 1 && } + {codeEnabled && } {retrievalEnabled && ( )} + {imageVisionEnabled && version == 1 && } + {codeEnabled && version && ( + + )}
); diff --git a/client/src/components/SidePanel/Builder/Code.tsx b/client/src/components/SidePanel/Builder/Code.tsx index 171e7f5048..c0b421cb9f 100644 --- a/client/src/components/SidePanel/Builder/Code.tsx +++ b/client/src/components/SidePanel/Builder/Code.tsx @@ -1,70 +1,66 @@ -import { useMemo } from 'react'; import { Capabilities } from 'librechat-data-provider'; -import { useFormContext, Controller, useWatch } from 'react-hook-form'; -import type { AssistantsEndpoint } from 'librechat-data-provider'; +import { useFormContext, Controller } from 'react-hook-form'; import type { AssistantForm } from '~/common'; -import { Checkbox, QuestionMark } from '~/components/ui'; +import { + Checkbox, + HoverCard, + HoverCardContent, + HoverCardPortal, + HoverCardTrigger, +} from '~/components/ui'; +import { CircleHelpIcon } from '~/components/svg'; import { useLocalize } from '~/hooks'; -import CodeFiles from './CodeFiles'; +import { ESide } from '~/common'; -export default function Code({ - version, - endpoint, -}: { - version: number | string; - endpoint: AssistantsEndpoint; -}) { +export default function Code({ version }: { version: number | string }) { const localize = useLocalize(); const methods = useFormContext(); const { control, setValue, getValues } = methods; - const assistant = useWatch({ control, name: 'assistant' }); - const assistant_id = useWatch({ control, name: 'id' }); - const files = useMemo(() => { - if (typeof assistant === 'string') { - return []; - } - return assistant.code_files; - }, [assistant]); return ( <> -
- ( - - )} - /> -