From ead9e11134ef1dc063189b1d5e0cfe896c6ecd3f Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Sat, 23 Nov 2024 01:10:03 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20style:=20parameters=20panel=20up?= =?UTF-8?q?date=20(#4780)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔧 refactor: replace doubleClickHandler with onDoubleClick in slider components * 🔧 refactor: consolidate DynamicInput and DynamicInputNumber components into a single DynamicInput component; fix: UI crashing when typing a character instead of number in max context/output tokens * 🔧 style: update component styles to use bg-surface-secondary and bg-surface-tertiary for improved UI consistency --- .../Endpoints/Settings/Advanced.tsx | 10 +- .../Endpoints/Settings/AgentSettings.tsx | 2 +- .../components/Endpoints/Settings/Google.tsx | 16 +-- .../components/Endpoints/Settings/Plugins.tsx | 16 +-- .../Speech/STT/AutoSendTextSelector.tsx | 2 +- .../Speech/STT/DecibelSelector.tsx | 2 +- .../SettingsTabs/Speech/TTS/PlaybackRate.tsx | 2 +- .../SidePanel/Parameters/DynamicCheckbox.tsx | 1 - .../SidePanel/Parameters/DynamicInput.tsx | 19 +++- .../Parameters/DynamicInputNumber.tsx | 106 ------------------ .../SidePanel/Parameters/DynamicSlider.tsx | 3 +- .../SidePanel/Parameters/DynamicTags.tsx | 35 +++--- .../SidePanel/Parameters/DynamicTextarea.tsx | 4 +- .../components/SidePanel/Parameters/index.ts | 1 - client/src/components/ui/HoverCard.tsx | 2 +- client/src/components/ui/Slider.tsx | 27 ++--- .../Conversations/useParameterEffects.ts | 5 +- 17 files changed, 79 insertions(+), 174 deletions(-) delete mode 100644 client/src/components/SidePanel/Parameters/DynamicInputNumber.tsx diff --git a/client/src/components/Endpoints/Settings/Advanced.tsx b/client/src/components/Endpoints/Settings/Advanced.tsx index 0ab2a4320f..976e0bd946 100644 --- a/client/src/components/Endpoints/Settings/Advanced.tsx +++ b/client/src/components/Endpoints/Settings/Advanced.tsx @@ -146,7 +146,7 @@ export default function Settings({ disabled={readonly} value={[(temperatureValue as number) ?? 1]} onValueChange={(value) => setTemperature(value[0])} - doubleClickHandler={() => setTemperature(1)} + onDoubleClick={() => setTemperature(1)} max={2} min={0} step={0.01} @@ -184,7 +184,7 @@ export default function Settings({ disabled={readonly} value={[(topPValue as number) ?? 1]} onValueChange={(value) => setTopP(value[0])} - doubleClickHandler={() => setTopP(1)} + onDoubleClick={() => setTopP(1)} max={1} min={0} step={0.01} @@ -223,7 +223,7 @@ export default function Settings({ disabled={readonly} value={[(freqPValue as number) ?? 0]} onValueChange={(value) => setFreqP(value[0])} - doubleClickHandler={() => setFreqP(0)} + onDoubleClick={() => setFreqP(0)} max={2} min={-2} step={0.01} @@ -262,7 +262,7 @@ export default function Settings({ disabled={readonly} value={[(presPValue as number) ?? 0]} onValueChange={(value) => setPresP(value[0])} - doubleClickHandler={() => setPresP(0)} + onDoubleClick={() => setPresP(0)} max={2} min={-2} step={0.01} @@ -319,7 +319,7 @@ export default function Settings({ imageDetailNumeric[imageDetail ?? ''] ?? imageDetailNumeric[ImageDetail.auto], ]} onValueChange={(value) => setImageDetail(imageDetailValue[value[0]])} - doubleClickHandler={() => setImageDetail(ImageDetail.auto)} + onDoubleClick={() => setImageDetail(ImageDetail.auto)} max={2} min={0} step={1} diff --git a/client/src/components/Endpoints/Settings/AgentSettings.tsx b/client/src/components/Endpoints/Settings/AgentSettings.tsx index 91c148f1a4..8ba20f2508 100644 --- a/client/src/components/Endpoints/Settings/AgentSettings.tsx +++ b/client/src/components/Endpoints/Settings/AgentSettings.tsx @@ -77,7 +77,7 @@ export default function Settings({ conversation, setOption, models, readonly }: disabled={readonly} value={[temperature ?? 0]} onValueChange={(value: number[]) => setTemperature(value[0])} - doubleClickHandler={() => setTemperature(1)} + onDoubleClick={() => setTemperature(1)} max={2} min={0} step={0.01} diff --git a/client/src/components/Endpoints/Settings/Google.tsx b/client/src/components/Endpoints/Settings/Google.tsx index ab44b116c6..318eecb756 100644 --- a/client/src/components/Endpoints/Settings/Google.tsx +++ b/client/src/components/Endpoints/Settings/Google.tsx @@ -165,14 +165,14 @@ export default function Settings({ conversation, setOption, models, readonly }: disabled={readonly} value={[temperature ?? google.temperature.default]} onValueChange={(value) => setTemperature(value[0])} - doubleClickHandler={() => setTemperature(google.temperature.default)} + onDoubleClick={() => setTemperature(google.temperature.default)} max={google.temperature.max} min={google.temperature.min} step={google.temperature.step} className="flex h-4 w-full" /> - + @@ -205,14 +205,14 @@ export default function Settings({ conversation, setOption, models, readonly }: disabled={readonly} value={[topP ?? google.topP.default]} onValueChange={(value) => setTopP(value[0])} - doubleClickHandler={() => setTopP(google.topP.default)} + onDoubleClick={() => setTopP(google.topP.default)} max={google.topP.max} min={google.topP.min} step={google.topP.step} className="flex h-4 w-full" /> - + @@ -246,14 +246,14 @@ export default function Settings({ conversation, setOption, models, readonly }: disabled={readonly} value={[topK ?? google.topK.default]} onValueChange={(value) => setTopK(value[0])} - doubleClickHandler={() => setTopK(google.topK.default)} + onDoubleClick={() => setTopK(google.topK.default)} max={google.topK.max} min={google.topK.min} step={google.topK.step} className="flex h-4 w-full" /> - + @@ -286,7 +286,7 @@ export default function Settings({ conversation, setOption, models, readonly }: disabled={readonly} value={[maxOutputTokens ?? google.maxOutputTokens.default]} onValueChange={(value) => setMaxOutputTokens(value[0])} - doubleClickHandler={() => setMaxOutputTokens(google.maxOutputTokens.default)} + onDoubleClick={() => setMaxOutputTokens(google.maxOutputTokens.default)} max={google.maxOutputTokens.max} min={google.maxOutputTokens.min} step={google.maxOutputTokens.step} @@ -294,7 +294,7 @@ export default function Settings({ conversation, setOption, models, readonly }: /> diff --git a/client/src/components/Endpoints/Settings/Plugins.tsx b/client/src/components/Endpoints/Settings/Plugins.tsx index f3ac50c4d7..4d05068c07 100644 --- a/client/src/components/Endpoints/Settings/Plugins.tsx +++ b/client/src/components/Endpoints/Settings/Plugins.tsx @@ -251,14 +251,14 @@ export default function Settings({ disabled={readonly} value={[temperatureValue ?? 0.8]} onValueChange={(value) => setTemperature(value[0])} - doubleClickHandler={() => setTemperature(0.8)} + onDoubleClick={() => setTemperature(0.8)} max={2} min={0} step={0.01} className="flex h-4 w-full" /> - + @@ -291,14 +291,14 @@ export default function Settings({ disabled={readonly} value={[topPValue ?? 1]} onValueChange={(value) => setTopP(value[0])} - doubleClickHandler={() => setTopP(1)} + onDoubleClick={() => setTopP(1)} max={1} min={0} step={0.01} className="flex h-4 w-full" /> - + @@ -332,14 +332,14 @@ export default function Settings({ disabled={readonly} value={[freqPValue ?? 0]} onValueChange={(value) => setFreqP(value[0])} - doubleClickHandler={() => setFreqP(0)} + onDoubleClick={() => setFreqP(0)} max={2} min={-2} step={0.01} className="flex h-4 w-full" /> - + @@ -373,14 +373,14 @@ export default function Settings({ disabled={readonly} value={[presPValue ?? 0]} onValueChange={(value) => setPresP(value[0])} - doubleClickHandler={() => setPresP(0)} + onDoubleClick={() => setPresP(0)} max={2} min={-2} step={0.01} className="flex h-4 w-full" /> - + diff --git a/client/src/components/Nav/SettingsTabs/Speech/STT/AutoSendTextSelector.tsx b/client/src/components/Nav/SettingsTabs/Speech/STT/AutoSendTextSelector.tsx index 03d50c98bc..89a910f090 100644 --- a/client/src/components/Nav/SettingsTabs/Speech/STT/AutoSendTextSelector.tsx +++ b/client/src/components/Nav/SettingsTabs/Speech/STT/AutoSendTextSelector.tsx @@ -22,7 +22,7 @@ export default function AutoSendTextSelector() { setAutoSendText(value[0])} - doubleClickHandler={() => setAutoSendText(-1)} + onDoubleClick={() => setAutoSendText(-1)} min={-1} max={60} step={1} diff --git a/client/src/components/Nav/SettingsTabs/Speech/STT/DecibelSelector.tsx b/client/src/components/Nav/SettingsTabs/Speech/STT/DecibelSelector.tsx index 274f54b4a8..8683523e4d 100755 --- a/client/src/components/Nav/SettingsTabs/Speech/STT/DecibelSelector.tsx +++ b/client/src/components/Nav/SettingsTabs/Speech/STT/DecibelSelector.tsx @@ -21,7 +21,7 @@ export default function DecibelSelector() { setDecibelValue(value[0])} - doubleClickHandler={() => setDecibelValue(-45)} + onDoubleClick={() => setDecibelValue(-45)} min={-100} max={-30} step={1} diff --git a/client/src/components/Nav/SettingsTabs/Speech/TTS/PlaybackRate.tsx b/client/src/components/Nav/SettingsTabs/Speech/TTS/PlaybackRate.tsx index 446c67da57..3845dfe254 100755 --- a/client/src/components/Nav/SettingsTabs/Speech/TTS/PlaybackRate.tsx +++ b/client/src/components/Nav/SettingsTabs/Speech/TTS/PlaybackRate.tsx @@ -21,7 +21,7 @@ export default function DecibelSelector() { setPlaybackRate(value[0])} - doubleClickHandler={() => setPlaybackRate(null)} + onDoubleClick={() => setPlaybackRate(null)} min={0.1} max={2} step={0.1} diff --git a/client/src/components/SidePanel/Parameters/DynamicCheckbox.tsx b/client/src/components/SidePanel/Parameters/DynamicCheckbox.tsx index 98d85524a9..3e11202045 100644 --- a/client/src/components/SidePanel/Parameters/DynamicCheckbox.tsx +++ b/client/src/components/SidePanel/Parameters/DynamicCheckbox.tsx @@ -1,4 +1,3 @@ -// client/src/components/SidePanel/Parameters/DynamicCheckbox.tsx import { useMemo, useState } from 'react'; import { OptionTypes } from 'librechat-data-provider'; import type { DynamicSettingProps } from 'librechat-data-provider'; diff --git a/client/src/components/SidePanel/Parameters/DynamicInput.tsx b/client/src/components/SidePanel/Parameters/DynamicInput.tsx index e1439a8c8f..6de39f3b2f 100644 --- a/client/src/components/SidePanel/Parameters/DynamicInput.tsx +++ b/client/src/components/SidePanel/Parameters/DynamicInput.tsx @@ -1,4 +1,3 @@ -// client/src/components/SidePanel/Parameters/DynamicInput.tsx import { OptionTypes } from 'librechat-data-provider'; import type { DynamicSettingProps } from 'librechat-data-provider'; import { useLocalize, useDebouncedInput, useParameterEffects } from '~/hooks'; @@ -13,6 +12,7 @@ function DynamicInput({ settingKey, defaultValue, description = '', + type = 'string', columnSpan, setOption, optionType, @@ -46,6 +46,17 @@ function DynamicInput({ setInputValue: setLocalValue, }); + const handleInputChange = (e: React.ChangeEvent) => { + const value = e.target.value; + if (type === 'number') { + if (!isNaN(Number(value))) { + setInputValue(e); + } + } else { + setInputValue(e); + } + }; + return (
{description && ( diff --git a/client/src/components/SidePanel/Parameters/DynamicInputNumber.tsx b/client/src/components/SidePanel/Parameters/DynamicInputNumber.tsx deleted file mode 100644 index 9da1dcd699..0000000000 --- a/client/src/components/SidePanel/Parameters/DynamicInputNumber.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { OptionTypes } from 'librechat-data-provider'; -import type { DynamicSettingProps } from 'librechat-data-provider'; -import type { ValueType } from '@rc-component/mini-decimal'; -import { Label, HoverCard, InputNumber, HoverCardTrigger } from '~/components/ui'; -import { useLocalize, useDebouncedInput, useParameterEffects } from '~/hooks'; -import { cn, defaultTextProps, optionText } from '~/utils'; -import { ESide } from '~/common'; -import { useChatContext } from '~/Providers'; -import OptionHover from './OptionHover'; - -function DynamicInputNumber({ - label = '', - settingKey, - defaultValue, - description = '', - columnSpan, - setOption, - optionType, - readonly = false, - showDefault = false, - labelCode = false, - descriptionCode = false, - placeholderCode = false, - placeholder = '', - conversation, - range, - className = '', - inputClassName = '', -}: DynamicSettingProps) { - const localize = useLocalize(); - const { preset } = useChatContext(); - - const [setInputValue, inputValue, setLocalValue] = useDebouncedInput({ - optionKey: optionType !== OptionTypes.Custom ? settingKey : undefined, - initialValue: - optionType !== OptionTypes.Custom - ? (conversation?.[settingKey] as number) - : (defaultValue as number), - setter: () => ({}), - setOption, - }); - - useParameterEffects({ - preset, - settingKey, - defaultValue: typeof defaultValue === 'undefined' ? '' : defaultValue, - conversation, - inputValue, - setInputValue: setLocalValue, - }); - - return ( -
- - -
- - -
-
- {description && ( - - )} -
-
- ); -} - -export default DynamicInputNumber; diff --git a/client/src/components/SidePanel/Parameters/DynamicSlider.tsx b/client/src/components/SidePanel/Parameters/DynamicSlider.tsx index 2397ec7d6b..69f14c3c71 100644 --- a/client/src/components/SidePanel/Parameters/DynamicSlider.tsx +++ b/client/src/components/SidePanel/Parameters/DynamicSlider.tsx @@ -167,12 +167,11 @@ function DynamicSlider({ : (inputValue as number) ?? (defaultValue as number), ]} onValueChange={(value) => handleValueChange(value[0])} - doubleClickHandler={() => setInputValue(defaultValue as string | number)} + onDoubleClick={() => setInputValue(defaultValue as string | number)} max={max} min={range ? range.min : 0} step={range ? range.step ?? 1 : 1} className="flex h-4 w-full" - trackClassName="bg-surface-hover" /> {description && ( diff --git a/client/src/components/SidePanel/Parameters/DynamicTags.tsx b/client/src/components/SidePanel/Parameters/DynamicTags.tsx index 5a48be32bb..d83b8c9738 100644 --- a/client/src/components/SidePanel/Parameters/DynamicTags.tsx +++ b/client/src/components/SidePanel/Parameters/DynamicTags.tsx @@ -1,4 +1,3 @@ -// client/src/components/SidePanel/Parameters/DynamicTags.tsx import { useState, useMemo, useCallback, useRef } from 'react'; import { OptionTypes } from 'librechat-data-provider'; import type { DynamicSettingProps } from 'librechat-data-provider'; @@ -140,20 +139,24 @@ function DynamicTags({
-
- {currentTags?.map((tag: string, index: number) => ( - { - onTagRemove(index); - if (inputRef.current) { - inputRef.current.focus(); - } - }} - /> - ))} +
+ {currentTags && currentTags.length > 0 && ( +
+ {currentTags.map((tag: string, index: number) => ( + { + onTagRemove(index); + if (inputRef.current) { + inputRef.current.focus(); + } + }} + /> + ))} +
+ )} setTagText(e.target.value)} placeholder={placeholderCode ? localize(placeholder) ?? placeholder : placeholder} - className={cn(defaultTextProps, 'flex h-10 max-h-10 px-3 py-2')} + className={cn('flex h-10 max-h-10 border-none bg-surface-secondary px-3 py-2')} />
diff --git a/client/src/components/SidePanel/Parameters/DynamicTextarea.tsx b/client/src/components/SidePanel/Parameters/DynamicTextarea.tsx index ddc10d684b..83fead36ed 100644 --- a/client/src/components/SidePanel/Parameters/DynamicTextarea.tsx +++ b/client/src/components/SidePanel/Parameters/DynamicTextarea.tsx @@ -1,4 +1,3 @@ -// client/src/components/SidePanel/Parameters/DynamicTextarea.tsx import { OptionTypes } from 'librechat-data-provider'; import type { DynamicSettingProps } from 'librechat-data-provider'; import { Label, TextareaAutosize, HoverCard, HoverCardTrigger } from '~/components/ui'; @@ -78,9 +77,8 @@ function DynamicTextarea({ onChange={setInputValue} placeholder={placeholderCode ? localize(placeholder) ?? placeholder : placeholder} className={cn( - defaultTextProps, // TODO: configurable max height - 'flex max-h-[138px] min-h-[100px] w-full resize-none px-3 py-2', + 'flex max-h-[138px] min-h-[100px] w-full resize-none rounded-lg bg-surface-secondary px-3 py-2 focus:outline-none', )} /> diff --git a/client/src/components/SidePanel/Parameters/index.ts b/client/src/components/SidePanel/Parameters/index.ts index d945367c6d..159a9f3787 100644 --- a/client/src/components/SidePanel/Parameters/index.ts +++ b/client/src/components/SidePanel/Parameters/index.ts @@ -1,4 +1,3 @@ -export { default as DynamicInputNumber } from './DynamicInputNumber'; export { default as DynamicCombobox } from './DynamicCombobox'; export { default as DynamicDropdown } from './DynamicDropdown'; export { default as DynamicCheckbox } from './DynamicCheckbox'; diff --git a/client/src/components/ui/HoverCard.tsx b/client/src/components/ui/HoverCard.tsx index 3df6e905b7..5e973ed7bc 100644 --- a/client/src/components/ui/HoverCard.tsx +++ b/client/src/components/ui/HoverCard.tsx @@ -23,7 +23,7 @@ const HoverCardContent = React.forwardRef< align={align} sideOffset={sideOffset} className={cn( - 'z-50 w-64 rounded-md border border-gray-200 bg-white p-4 shadow-md outline-none animate-in fade-in-0 dark:border-gray-800 dark:bg-gray-800', + 'z-50 w-64 rounded-md border border-none bg-surface-tertiary p-4 shadow-md outline-none animate-in fade-in-0', className, )} {...props} diff --git a/client/src/components/ui/Slider.tsx b/client/src/components/ui/Slider.tsx index 36b3831c59..69874801b4 100644 --- a/client/src/components/ui/Slider.tsx +++ b/client/src/components/ui/Slider.tsx @@ -4,19 +4,20 @@ import { cn } from '~/utils'; const Slider = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - - - -)); + React.ComponentPropsWithoutRef & { onDoubleClick?: () => void } + >(({ className, onDoubleClick, ...props }, ref) => ( + + + + + + + )); Slider.displayName = SliderPrimitive.Root.displayName; export { Slider }; diff --git a/client/src/hooks/Conversations/useParameterEffects.ts b/client/src/hooks/Conversations/useParameterEffects.ts index ad45f52238..a39113342e 100644 --- a/client/src/hooks/Conversations/useParameterEffects.ts +++ b/client/src/hooks/Conversations/useParameterEffects.ts @@ -1,5 +1,5 @@ import { useEffect, useRef } from 'react'; -import type { DynamicSettingProps, TConversation, TPreset } from 'librechat-data-provider'; +import type { DynamicSettingProps, TPreset } from 'librechat-data-provider'; import { defaultDebouncedDelay } from '~/common'; function useParameterEffects({ @@ -10,9 +10,8 @@ function useParameterEffects({ inputValue, setInputValue, preventDelayedUpdate = false, -}: Pick & { +}: Pick & { preset: TPreset | null; - conversation?: TConversation | TPreset | null; inputValue: T; setInputValue: (inputValue: T) => void; preventDelayedUpdate?: boolean;