mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 16:30:15 +01:00
🖌️ style: Minor UI Updates (#2011)
* UI Design update * Add an error icon next to the avatar. * fix * Change the style of buttons * fix: avatar
This commit is contained in:
parent
2e77813952
commit
f5a754c8be
39 changed files with 147 additions and 121 deletions
|
|
@ -105,7 +105,7 @@ function Login() {
|
|||
</h1>
|
||||
{error && (
|
||||
<div
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700"
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700 dark:bg-gray-900 dark:text-red-500"
|
||||
role="alert"
|
||||
>
|
||||
{localize(getLoginError(error))}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const LoginForm: React.FC<TLoginFormProps> = ({ onSubmit }) => {
|
|||
const renderError = (fieldName: string) => {
|
||||
const errorMessage = errors[fieldName]?.message;
|
||||
return errorMessage ? (
|
||||
<span role="alert" className="mt-1 text-sm text-black">
|
||||
<span role="alert" className="mt-1 text-sm text-black dark:text-white">
|
||||
{String(errorMessage)}
|
||||
</span>
|
||||
) : null;
|
||||
|
|
@ -44,7 +44,7 @@ const LoginForm: React.FC<TLoginFormProps> = ({ onSubmit }) => {
|
|||
pattern: { value: /\S+@\S+\.\S+/, message: localize('com_auth_email_pattern') },
|
||||
})}
|
||||
aria-invalid={!!errors.email}
|
||||
className="peer block w-full appearance-none rounded-md border border-gray-300 bg-white px-2.5 pb-2.5 pt-5 text-sm text-gray-800 focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700 dark:bg-gray-900 dark:text-white dark:focus:border-green-500"
|
||||
className="webkit-dark-styles peer block w-full appearance-none rounded-md border border-gray-300 bg-white px-2.5 pb-2.5 pt-5 text-sm text-gray-800 focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700 dark:bg-gray-900 dark:text-white dark:focus:border-green-500"
|
||||
placeholder=" "
|
||||
/>
|
||||
<label
|
||||
|
|
@ -69,7 +69,7 @@ const LoginForm: React.FC<TLoginFormProps> = ({ onSubmit }) => {
|
|||
maxLength: { value: 128, message: localize('com_auth_password_max_length') },
|
||||
})}
|
||||
aria-invalid={!!errors.password}
|
||||
className="peer block w-full appearance-none rounded-md border border-gray-300 bg-white px-2.5 pb-2.5 pt-5 text-sm text-gray-800 focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700 dark:bg-gray-900 dark:text-white dark:focus:border-green-500"
|
||||
className="webkit-dark-styles peer block w-full appearance-none rounded-md border border-gray-300 bg-white px-2.5 pb-2.5 pt-5 text-sm text-gray-800 focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700 dark:bg-gray-900 dark:text-white dark:focus:border-green-500"
|
||||
placeholder=" "
|
||||
/>
|
||||
<label
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ const Registration: React.FC = () => {
|
|||
validation,
|
||||
)}
|
||||
aria-invalid={!!errors[id]}
|
||||
className="peer block w-full appearance-none rounded-md border border-gray-300 bg-white px-2.5 pb-2.5 pt-5 text-sm text-gray-800 focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700 dark:bg-gray-900 dark:text-white dark:focus:border-green-500"
|
||||
className="webkit-dark-styles peer block w-full appearance-none rounded-md border border-gray-300 bg-white px-2.5 pb-2.5 pt-5 text-sm text-gray-800 focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700 dark:bg-gray-900 dark:text-white dark:focus:border-green-500"
|
||||
placeholder=" "
|
||||
data-testid={id}
|
||||
></input>
|
||||
|
|
@ -161,7 +161,7 @@ const Registration: React.FC = () => {
|
|||
</h1>
|
||||
{error && (
|
||||
<div
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700"
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700 dark:bg-gray-900 dark:text-red-500"
|
||||
role="alert"
|
||||
data-testid="registration-error"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ function RequestPasswordReset() {
|
|||
setBodyText(
|
||||
<span>
|
||||
{localize('com_auth_click')}{' '}
|
||||
<a className="text-green-600 hover:underline" href={resetLink}>
|
||||
<a className="font-medium text-green-500 hover:underline" href={resetLink}>
|
||||
{localize('com_auth_here')}
|
||||
</a>{' '}
|
||||
{localize('com_auth_to_reset_your_password')}
|
||||
|
|
@ -66,7 +66,7 @@ function RequestPasswordReset() {
|
|||
if (bodyText) {
|
||||
return (
|
||||
<div
|
||||
className="relative mt-4 rounded border border-green-400 bg-green-100 px-4 py-3 text-green-700"
|
||||
className="relative mt-4 rounded border border-green-400 bg-green-100 px-4 py-3 text-green-700 dark:bg-gray-900 dark:text-white"
|
||||
role="alert"
|
||||
>
|
||||
{bodyText}
|
||||
|
|
@ -150,7 +150,7 @@ function RequestPasswordReset() {
|
|||
</h1>
|
||||
{requestError && (
|
||||
<div
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700"
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700 dark:bg-gray-900 dark:text-red-500"
|
||||
role="alert"
|
||||
>
|
||||
{localize('com_auth_error_reset_password')}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ function ResetPassword() {
|
|||
{localize('com_auth_reset_password_success')}
|
||||
</h1>
|
||||
<div
|
||||
className="relative mb-8 mt-4 rounded border border-green-400 bg-green-100 px-4 py-3 text-center text-green-700"
|
||||
className="relative mb-8 mt-4 rounded border border-green-400 bg-green-100 px-4 py-3 text-center text-green-700 dark:bg-gray-900 dark:text-white"
|
||||
role="alert"
|
||||
>
|
||||
{localize('com_auth_login_with_new_password')}
|
||||
|
|
@ -66,7 +66,7 @@ function ResetPassword() {
|
|||
</h1>
|
||||
{resetError && (
|
||||
<div
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700 dark:text-red-600 "
|
||||
className="relative mt-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700 dark:bg-gray-900 dark:text-red-500"
|
||||
role="alert"
|
||||
>
|
||||
{localize('com_auth_error_invalid_reset_token')}{' '}
|
||||
|
|
@ -127,7 +127,7 @@ function ResetPassword() {
|
|||
</div>
|
||||
|
||||
{errors.password && (
|
||||
<span role="alert" className="mt-1 text-sm text-black">
|
||||
<span role="alert" className="mt-1 text-sm text-black dark:text-white">
|
||||
{/* @ts-ignore not sure why */}
|
||||
{errors.password.message}
|
||||
</span>
|
||||
|
|
@ -160,19 +160,19 @@ function ResetPassword() {
|
|||
</label>
|
||||
</div>
|
||||
{errors.confirm_password && (
|
||||
<span role="alert" className="mt-1 text-sm text-black">
|
||||
<span role="alert" className="mt-1 text-sm text-black dark:text-white">
|
||||
{/* @ts-ignore not sure why */}
|
||||
{errors.confirm_password.message}
|
||||
</span>
|
||||
)}
|
||||
{errors.token && (
|
||||
<span role="alert" className="mt-1 text-sm text-black">
|
||||
<span role="alert" className="mt-1 text-sm text-black dark:text-white">
|
||||
{/* @ts-ignore not sure why */}
|
||||
{errors.token.message}
|
||||
</span>
|
||||
)}
|
||||
{errors.userId && (
|
||||
<span role="alert" className="mt-1 text-sm text-black">
|
||||
<span role="alert" className="mt-1 text-sm text-black dark:text-white">
|
||||
{/* @ts-ignore not sure why */}
|
||||
{errors.userId.message}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import HeaderOptions from './Input/HeaderOptions';
|
|||
export default function Header() {
|
||||
const { navVisible } = useOutletContext<ContextType>();
|
||||
return (
|
||||
<div className="sticky top-0 z-10 flex h-14 w-full items-center justify-between bg-white/95 p-2 font-semibold dark:bg-gray-800/90 dark:text-white ">
|
||||
<div className="sticky top-0 z-10 flex h-14 w-full items-center justify-between bg-white p-2 font-semibold dark:bg-gray-800 dark:text-white">
|
||||
<div className="hide-scrollbar flex items-center gap-2 overflow-x-auto">
|
||||
{!navVisible && <HeaderNewChat />}
|
||||
<EndpointsMenu />
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ const EditPresetDialog = ({
|
|||
className="h-full max-w-full overflow-y-auto pb-4 sm:w-[680px] sm:pb-0 md:h-[720px] md:w-[750px] md:overflow-y-hidden lg:w-[950px] xl:h-[720px]"
|
||||
main={
|
||||
<div className="flex w-full flex-col items-center gap-2 md:h-[530px]">
|
||||
<div className="grid w-full grid-cols-5 gap-6">
|
||||
<div className="col-span-4 flex items-start justify-start gap-4">
|
||||
<div className="grid w-full">
|
||||
<div className="col-span-4 flex items-start md:flex-row justify-start flex-col gap-6 pb-4">
|
||||
<div className="flex w-full flex-col">
|
||||
<Label htmlFor="preset-name" className="mb-1 text-left text-sm font-medium">
|
||||
{localize('com_endpoint_preset_name')}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ const PresetItems: FC<{
|
|||
<div className="flex h-full grow items-center justify-end gap-2">
|
||||
<label
|
||||
htmlFor="default-preset"
|
||||
className="w-40 truncate rounded bg-transparent px-2 py-1 text-xs font-medium font-normal text-gray-600 transition-colors dark:bg-transparent dark:text-gray-300 sm:w-72"
|
||||
className="w-40 truncate rounded bg-transparent py-1 text-xs font-medium font-normal text-gray-600 transition-colors dark:bg-transparent dark:text-gray-300 sm:w-72"
|
||||
>
|
||||
{defaultPreset
|
||||
? `${localize('com_endpoint_preset_default_item')} ${defaultPreset.title}`
|
||||
|
|
@ -55,9 +55,12 @@ const PresetItems: FC<{
|
|||
<DialogTrigger asChild>
|
||||
<label
|
||||
htmlFor="file-upload"
|
||||
className="mr-1 flex h-[32px] cursor-pointer items-center rounded bg-transparent px-2 py-1 text-xs font-medium font-normal text-gray-600 transition-colors hover:bg-gray-100 hover:text-red-700 dark:bg-transparent dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-green-500"
|
||||
className="mr-1 flex h-[32px] cursor-pointer items-center rounded bg-transparent px-2 py-1 text-xs font-medium font-normal text-gray-600 transition-colors hover:bg-gray-100 hover:text-red-700 dark:bg-transparent dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-green-500 dark:hover:text-red-700"
|
||||
>
|
||||
<Trash2 className="mr-1 flex w-[22px] items-center stroke-1" />
|
||||
<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="mr-1 flex w-[22px] items-center">
|
||||
<path d="M9.293 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.707A1 1 0 0 0 13.707 4L10 .293A1 1 0 0 0 9.293 0M9.5 3.5v-2l3 3h-2a1 1 0 0 1-1-1M6.854 7.146 8 8.293l1.146-1.147a.5.5 0 1 1 .708.708L8.707 9l1.147 1.146a.5.5 0 0 1-.708.708L8 9.707l-1.146 1.147a.5.5 0 0 1-.708-.708L7.293 9 6.146 7.854a.5.5 0 1 1 .708-.708">
|
||||
</path>
|
||||
</svg>
|
||||
{localize('com_ui_clear')} {localize('com_ui_all')}
|
||||
</label>
|
||||
</DialogTrigger>
|
||||
|
|
@ -92,7 +95,7 @@ const PresetItems: FC<{
|
|||
className="pointer-none group m-1.5 flex h-8 min-w-[170px] gap-2 rounded px-5 py-2.5 !pr-3 text-sm !opacity-100 focus:ring-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 md:min-w-[240px]"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className="flex h-full grow items-center justify-end gap-2">
|
||||
<div className="text-gray-600 dark:text-gray-300 flex h-full grow items-center justify-end gap-2">
|
||||
{/* TODO: Create Preset from here */}
|
||||
{localize('com_endpoint_no_presets')}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export default function HoverButtons({
|
|||
<div className="visible mt-0 flex justify-center gap-1 self-end text-gray-400 lg:justify-start">
|
||||
<button
|
||||
className={cn(
|
||||
'hover-button rounded-md p-1 pl-0 text-gray-400 hover:text-gray-900 dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:group-hover:visible md:group-[.final-completion]:visible',
|
||||
'hover-button rounded-md p-1 text-gray-400 hover:text-gray-900 dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:group-hover:visible md:group-[.final-completion]:visible',
|
||||
isCreatedByUser ? '' : 'active',
|
||||
hideEditButton ? 'opacity-0' : '',
|
||||
isEditing ? 'active bg-gray-200 text-gray-700 dark:bg-gray-700 dark:text-gray-200' : '',
|
||||
|
|
@ -69,7 +69,7 @@ export default function HoverButtons({
|
|||
</button>
|
||||
<button
|
||||
className={cn(
|
||||
'ml-0 flex items-center gap-1.5 rounded-md p-1 pl-0 text-xs hover:text-gray-900 dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:group-hover:visible md:group-[.final-completion]:visible',
|
||||
'ml-0 flex items-center gap-1.5 rounded-md p-1 text-xs hover:text-gray-900 dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:group-hover:visible md:group-[.final-completion]:visible',
|
||||
isSubmitting && isCreatedByUser ? 'md:opacity-0 md:group-hover:opacity-100' : '',
|
||||
)}
|
||||
onClick={() => copyToClipboard(setIsCopied)}
|
||||
|
|
@ -82,7 +82,7 @@ export default function HoverButtons({
|
|||
</button>
|
||||
{regenerateEnabled ? (
|
||||
<button
|
||||
className="hover-button active rounded-md p-1 pl-0 text-gray-400 hover:text-gray-900 dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:invisible md:group-hover:visible md:group-[.final-completion]:visible"
|
||||
className="hover-button active rounded-md p-1 text-gray-400 hover:text-gray-900 dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400 md:invisible md:group-hover:visible md:group-[.final-completion]:visible"
|
||||
onClick={regenerate}
|
||||
type="button"
|
||||
title={localize('com_ui_regenerate')}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export default function Message(props: TMessageProps) {
|
|||
<div className="relative flex flex-shrink-0 flex-col items-end">
|
||||
<div>
|
||||
<div className="pt-0.5">
|
||||
<div className="flex h-6 w-6 items-center justify-center overflow-hidden rounded-full">
|
||||
<div className="gizmo-shadow-stroke flex h-5 w-5 items-center justify-center rounded-full">
|
||||
{typeof icon === 'string' && /[^\\x00-\\x7F]+/.test(icon as string) ? (
|
||||
<span className=" direction-rtl w-40 overflow-x-scroll">{icon}</span>
|
||||
) : (
|
||||
|
|
@ -70,7 +70,7 @@ export default function Message(props: TMessageProps) {
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={cn('relative flex w-full flex-col', isCreatedByUser ? '' : 'agent-turn')}
|
||||
className={cn('relative flex w-11/12 flex-col', isCreatedByUser ? '' : 'agent-turn')}
|
||||
>
|
||||
<div className="select-none font-semibold">{messageLabel}</div>
|
||||
<div className="flex-col gap-1 md:gap-3">
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ const Icon: React.FC<IconProps> = (props) => {
|
|||
button,
|
||||
model = '',
|
||||
endpoint,
|
||||
error,
|
||||
jailbreak,
|
||||
assistantName,
|
||||
} = props;
|
||||
|
|
@ -45,13 +46,18 @@ const Icon: React.FC<IconProps> = (props) => {
|
|||
>
|
||||
{!user?.avatar && !user?.username ? (
|
||||
<div
|
||||
style={{ backgroundColor: 'rgb(121, 137, 255)', width: '24px', height: '24px' }}
|
||||
className="relative flex h-9 w-9 items-center justify-center rounded-sm p-1 text-white"
|
||||
style={{
|
||||
backgroundColor: 'rgb(121, 137, 255)',
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
boxShadow: 'rgba(240, 246, 252, 0.1) 0px 0px 0px 1px',
|
||||
}}
|
||||
className="relative flex h-9 w-9 items-center justify-center rounded-full p-1 text-white"
|
||||
>
|
||||
<UserIcon />
|
||||
</div>
|
||||
) : (
|
||||
<img className="rounded-sm" src={user?.avatar || avatarSrc} alt="avatar" />
|
||||
<img className="rounded-full" src={user?.avatar || avatarSrc} alt="avatar" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -67,7 +73,7 @@ const Icon: React.FC<IconProps> = (props) => {
|
|||
}}
|
||||
className={cn('relative flex items-center justify-center', props.className ?? '')}
|
||||
>
|
||||
<img className="rounded-sm" src={props.iconURL} alt={assistantName} />
|
||||
<img className="rounded-full" src={props.iconURL} alt={assistantName} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="h-6 w-6">
|
||||
|
|
@ -156,21 +162,20 @@ const Icon: React.FC<IconProps> = (props) => {
|
|||
<div
|
||||
title={name}
|
||||
style={{
|
||||
background: bg || 'transparent',
|
||||
width: size,
|
||||
height: size,
|
||||
}}
|
||||
className={cn(
|
||||
'relative flex items-center justify-center rounded-sm text-white ',
|
||||
'relative flex items-center justify-center rounded-full text-black dark:text-white',
|
||||
props.className || '',
|
||||
)}
|
||||
>
|
||||
{icon}
|
||||
{/* {error && (
|
||||
<span className="absolute right-0 top-[20px] -mr-2 flex h-4 w-4 items-center justify-center rounded-full border border-white bg-red-500 text-[10px] text-white">
|
||||
{error && (
|
||||
<span className="absolute right-0 top-[20px] -mr-2 flex h-3 w-3 items-center justify-center rounded-full border border-white bg-red-500 text-[10px] text-white">
|
||||
!
|
||||
</span>
|
||||
)} */}
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const SaveAsPresetDialog = ({ open, onOpenChange, preset }: TEditPresetProps) =>
|
|||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogTemplate
|
||||
title={localize('com_endpoint_save_as_preset')}
|
||||
className="w-11/12 sm:w-1/4"
|
||||
className="w-11/12 sm:w-2/4"
|
||||
showCloseButton={false}
|
||||
main={
|
||||
<div className="flex w-full flex-col items-center gap-2">
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
</HoverCard>
|
||||
<div className="grid w-full grid-cols-2 items-center gap-10">
|
||||
<HoverCard openDelay={500}>
|
||||
<HoverCardTrigger className="w-[100px]">
|
||||
<HoverCardTrigger className="w-[100px] flex flex-col items-center text-center space-y-4">
|
||||
<label
|
||||
htmlFor="functions-agent"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-50"
|
||||
|
|
@ -106,7 +106,7 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
<OptionHover endpoint={conversation.endpoint ?? ''} type="func" side={ESide.Bottom} />
|
||||
</HoverCard>
|
||||
<HoverCard openDelay={500}>
|
||||
<HoverCardTrigger className="ml-[-60px] w-[100px]">
|
||||
<HoverCardTrigger className="ml-[-60px] w-[100px] flex flex-col items-center text-center space-y-4">
|
||||
<label
|
||||
htmlFor="skip-completion"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-50"
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ function OptionHover({ endpoint, type, side }: TOptionHoverProps) {
|
|||
}
|
||||
return (
|
||||
<HoverCardPortal>
|
||||
<HoverCardContent side={side} className="z-[80] w-80">
|
||||
<HoverCardContent side={side} className="z-[999] w-80">
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm text-gray-600 dark:text-gray-300">{localize(text)}</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -221,7 +221,10 @@ export default function NewConversationMenu() {
|
|||
htmlFor="file-upload"
|
||||
className="mr-1 flex h-[32px] h-auto cursor-pointer items-center rounded bg-transparent px-2 py-1 text-xs font-medium font-normal text-gray-600 transition-colors hover:bg-gray-100 hover:text-red-700 dark:bg-transparent dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-green-500"
|
||||
>
|
||||
<Trash2 className="mr-1 flex w-[22px] items-center stroke-1" />
|
||||
<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="mr-1 flex w-[22px] items-center">
|
||||
<path d="M9.293 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.707A1 1 0 0 0 13.707 4L10 .293A1 1 0 0 0 9.293 0M9.5 3.5v-2l3 3h-2a1 1 0 0 1-1-1M6.854 7.146 8 8.293l1.146-1.147a.5.5 0 1 1 .708.708L8.707 9l1.147 1.146a.5.5 0 0 1-.708.708L8 9.707l-1.146 1.147a.5.5 0 0 1-.708-.708L7.293 9 6.146 7.854a.5.5 0 1 1 .708-.708">
|
||||
</path>
|
||||
</svg>
|
||||
{localize('com_ui_clear')} {localize('com_ui_all')}
|
||||
</label>
|
||||
</DialogTrigger>
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ const SetKeyDialog = ({
|
|||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogTemplate
|
||||
title={`${localize('com_endpoint_config_key_for')} ${alternateName[endpoint] ?? endpoint}`}
|
||||
className="w-full max-w-[650px] sm:w-3/4 md:w-3/4 lg:w-3/4"
|
||||
className="w-11/12 max-w-[650px] sm:w-3/4 md:w-3/4 lg:w-3/4"
|
||||
main={
|
||||
<div className="grid w-full items-center gap-2">
|
||||
<small className="text-red-600">
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ const Plugin: React.FC<PluginProps> = ({ plugin }) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-start">
|
||||
<div className="my-2 flex flex-col items-start">
|
||||
<Disclosure>
|
||||
{({ open }) => {
|
||||
const iconProps: PluginIconProps = {
|
||||
|
|
@ -100,7 +100,7 @@ const Plugin: React.FC<PluginProps> = ({ plugin }) => {
|
|||
</Disclosure.Button>
|
||||
</div>
|
||||
|
||||
<Disclosure.Panel className="my-3 flex max-w-full flex-col gap-3">
|
||||
<Disclosure.Panel className="mt-3 flex max-w-full flex-col gap-3">
|
||||
<CodeBlock
|
||||
lang={latestPlugin ? `REQUEST TO ${latestPlugin?.toUpperCase()}` : 'REQUEST'}
|
||||
codeChildren={formatInputs(plugin.inputs ?? [])}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ export default function Message(props: TMessageProps) {
|
|||
return (
|
||||
<>
|
||||
<div {...messageProps} onWheel={handleScroll} onTouchMove={handleScroll}>
|
||||
<div className="relative m-auto flex gap-4 p-4 text-base md:max-w-2xl md:gap-6 md:py-6 lg:max-w-2xl lg:px-0 xl:max-w-3xl">
|
||||
<div className="relative m-auto flex gap-4 p-4 text-base md:max-w-2xl md:gap-4 md:py-6 lg:max-w-2xl lg:px-0 xl:max-w-3xl">
|
||||
<div className="relative flex h-[40px] w-[40px] flex-col items-end text-right text-xs md:text-sm">
|
||||
{typeof icon === 'string' && /[^\\x00-\\x7F]+/.test(icon as string) ? (
|
||||
<span className=" direction-rtl w-40 overflow-x-scroll">{icon}</span>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const ClearConvos = ({ open, onOpenChange }) => {
|
|||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogTemplate
|
||||
title={localize('com_nav_clear_conversation')}
|
||||
className="w-full max-w-[650px] sm:w-3/4 md:w-3/4 lg:w-3/4"
|
||||
className="w-11/12 max-w-[650px] sm:w-3/4 md:w-3/4 lg:w-3/4"
|
||||
headerClassName="border-none"
|
||||
description={localize('com_nav_clear_conversation_confirm_message')}
|
||||
buttons={
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ export default function ExportModal({ open, onOpenChange, conversation }) {
|
|||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogTemplate
|
||||
title="Export conversation"
|
||||
title={localize('com_nav_export_conversation')}
|
||||
className="max-w-full sm:max-w-2xl"
|
||||
main={
|
||||
<div className="flex w-full flex-col items-center gap-6">
|
||||
|
|
|
|||
|
|
@ -66,19 +66,20 @@ function NavLinks() {
|
|||
)}
|
||||
<Menu.Button
|
||||
className={cn(
|
||||
'group-ui-open:bg-gray-100 dark:group-ui-open:bg-gray-700 duration-350 mt-text-sm mb-1 flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 transition-colors hover:bg-gray-100 dark:hover:bg-gray-700',
|
||||
'group-ui-open:bg-gray-100 dark:group-ui-open:bg-gray-700 duration-350 mt-text-sm mb-1 flex w-full items-center gap-3 text-sm rounded-md px-3 py-3 transition-colors hover:bg-gray-100 dark:hover:bg-gray-700',
|
||||
open ? 'bg-gray-100 dark:bg-gray-700' : '',
|
||||
)}
|
||||
data-testid="nav-user"
|
||||
>
|
||||
<div className="-ml-0.9 -mt-0.8 h-8 w-7 flex-shrink-0">
|
||||
<div className="-ml-0.9 -mt-0.8 h-5 w-5 flex-shrink-0">
|
||||
<div className="relative flex">
|
||||
{!user?.avatar && !user?.username ? (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: 'rgb(121, 137, 255)',
|
||||
width: '28px',
|
||||
height: '28px',
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
boxShadow: 'rgba(240, 246, 252, 0.1) 0px 0px 0px 1px',
|
||||
}}
|
||||
className="relative flex h-9 w-9 items-center justify-center rounded-full p-1 text-white"
|
||||
>
|
||||
|
|
@ -90,8 +91,8 @@ function NavLinks() {
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="mt-2 grow overflow-hidden text-ellipsis whitespace-nowrap text-left text-black dark:text-white"
|
||||
style={{ marginTop: '-4px', marginLeft: '2px' }}
|
||||
className="mt-2 grow overflow-hidden text-ellipsis whitespace-nowrap text-left font-bold text-black dark:text-white"
|
||||
style={{ marginTop: '0', marginLeft: '0' }}
|
||||
>
|
||||
{user?.name || localize('com_nav_user')}
|
||||
</div>
|
||||
|
|
@ -125,7 +126,7 @@ function NavLinks() {
|
|||
<NavLink
|
||||
className="flex w-full cursor-pointer items-center gap-3 rounded-none px-3 py-3 text-sm text-black transition-colors duration-200 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700"
|
||||
svg={() => <FileText className="icon-md" />}
|
||||
text="My Files"
|
||||
text={localize('com_nav_my_files')}
|
||||
clickHandler={() => setShowFiles(true)}
|
||||
/>
|
||||
</Menu.Item>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<DialogContent
|
||||
className={cn(
|
||||
'shadow-2xl dark:bg-gray-800 dark:text-white md:min-h-[373px] md:w-[680px]',
|
||||
isSmallScreen ? 'top-44 -translate-y-0' : '',
|
||||
isSmallScreen ? 'top-20 -translate-y-0' : '',
|
||||
)}
|
||||
>
|
||||
<DialogHeader>
|
||||
|
|
|
|||
|
|
@ -125,12 +125,12 @@ function PluginStoreDialog({ isOpen, setIsOpen }: TPluginStoreDialogProps) {
|
|||
{/* The backdrop, rendered as a fixed sibling to the panel container */}
|
||||
<div className="fixed inset-0 bg-gray-600/65 transition-opacity dark:bg-black/80" />
|
||||
{/* Full-screen container to center the panel */}
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4">
|
||||
<div className="fixed inset-0 flex p-4">
|
||||
<Dialog.Panel
|
||||
className="relative w-full transform overflow-hidden overflow-y-auto rounded-lg bg-white text-left shadow-xl transition-all dark:bg-gray-800 max-sm:h-full sm:mx-7 sm:my-8 sm:max-w-2xl lg:max-w-5xl xl:max-w-7xl"
|
||||
style={{ minHeight: '610px' }}
|
||||
>
|
||||
<div className="flex items-center justify-between border-b-[1px] border-black/10 px-4 pb-4 pt-5 dark:border-white/10 sm:p-6">
|
||||
<div className="flex items-center justify-between border-b-[1px] border-black/10 p-6 pb-4 dark:border-white/10">
|
||||
<div className="flex items-center">
|
||||
<div className="text-center sm:text-left">
|
||||
<Dialog.Title className="text-lg font-medium leading-6 text-gray-800 dark:text-gray-200">
|
||||
|
|
@ -171,16 +171,18 @@ function PluginStoreDialog({ isOpen, setIsOpen }: TPluginStoreDialogProps) {
|
|||
)}
|
||||
<div className="p-4 sm:p-6 sm:pt-4">
|
||||
<div className="mt-4 flex flex-col gap-4">
|
||||
<div className="flex items-center justify-center space-x-4">
|
||||
<Search className="h-6 w-6 text-gray-500" />
|
||||
<input
|
||||
type="text"
|
||||
value={searchValue}
|
||||
onChange={handleSearch}
|
||||
placeholder={localize('com_nav_plugin_search')}
|
||||
className="w-64 rounded border border-gray-300 px-2 py-1 focus:outline-none dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<div class="relative flex items-center">
|
||||
<Search className="h-6 w-6 text-gray-500 absolute left-2" />
|
||||
<input
|
||||
type="text"
|
||||
value={searchValue}
|
||||
onChange={handleSearch}
|
||||
placeholder={localize('com_nav_plugin_search')}
|
||||
className="dark:focus:ring-offset-slate-900 rounded-md border border-gray-200 focus:border-slate-400 focus:bg-gray-50 bg-transparent shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none placeholder:text-gray-400 focus:ring-gray-400 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-500 dark:bg-gray-800 focus:dark:bg-gray-700 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-400 dark:focus:outline-none dark:focus:ring-0 dark:focus:ring-gray-400 dark:focus:ring-offset-0 flex pl-10 pr-2 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
ref={gridRef}
|
||||
className="grid grid-cols-1 grid-rows-2 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useState } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { LucideArrowUpLeft } from 'lucide-react';
|
||||
import { useLocalize } from '~/hooks';
|
||||
import {
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
|
|
@ -34,6 +35,7 @@ interface DataTableProps<TData, TValue> {
|
|||
}
|
||||
|
||||
export default function DataTable<TData, TValue>({ columns, data }: DataTableProps<TData, TValue>) {
|
||||
const localize = useLocalize();
|
||||
const [rowSelection, setRowSelection] = useState({});
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
||||
|
|
@ -139,7 +141,7 @@ export default function DataTable<TData, TValue>({ columns, data }: DataTablePro
|
|||
className="flex gap-2"
|
||||
>
|
||||
<LucideArrowUpLeft className="icon-sm" />
|
||||
Manage Files
|
||||
{localize('com_sidepanel_manage_files')}
|
||||
</Button>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { cn } from '~/utils';
|
|||
export default function CheckMark({ className = '' }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -14,7 +13,7 @@ export default function CheckMark({ className = '' }: { className?: string }) {
|
|||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.0633 5.67375C18.5196 5.98487 18.6374 6.607 18.3262 7.06331L10.8262 18.0633C10.6585 18.3093 10.3898 18.4678 10.0934 18.4956C9.79688 18.5234 9.50345 18.4176 9.29289 18.2071L4.79289 13.7071C4.40237 13.3166 4.40237 12.6834 4.79289 12.2929C5.18342 11.9023 5.81658 11.9023 6.20711 12.2929L9.85368 15.9394L16.6738 5.93664C16.9849 5.48033 17.607 5.36263 18.0633 5.67375Z" fill="currentColor">
|
||||
</path></svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import React from 'react';
|
|||
export default function Clipboard() {
|
||||
return (
|
||||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -14,8 +13,7 @@ export default function Clipboard() {
|
|||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path>
|
||||
<rect x="8" y="2" width="8" height="4" rx="1" ry="1" />
|
||||
</svg>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C10.8954 4 10 4.89543 10 6H14C14 4.89543 13.1046 4 12 4ZM8.53513 4C9.22675 2.8044 10.5194 2 12 2C13.4806 2 14.7733 2.8044 15.4649 4H17C18.6569 4 20 5.34315 20 7V19C20 20.6569 18.6569 22 17 22H7C5.34315 22 4 20.6569 4 19V7C4 5.34315 5.34315 4 7 4H8.53513ZM8 6H7C6.44772 6 6 6.44772 6 7V19C6 19.5523 6.44772 20 7 20H17C17.5523 20 18 19.5523 18 19V7C18 6.44772 17.5523 6 17 6H16C16 7.10457 15.1046 8 14 8H10C8.89543 8 8 7.10457 8 6Z" fill="currentColor">
|
||||
</path></svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import React from 'react';
|
|||
export default function EditIcon() {
|
||||
return (
|
||||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -14,8 +13,7 @@ export default function EditIcon() {
|
|||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
|
||||
</svg>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.2929 4.29291C15.0641 2.52167 17.9359 2.52167 19.7071 4.2929C21.4783 6.06414 21.4783 8.93588 19.7071 10.7071L18.7073 11.7069L11.1603 19.2539C10.7182 19.696 10.1489 19.989 9.53219 20.0918L4.1644 20.9864C3.84584 21.0395 3.52125 20.9355 3.29289 20.7071C3.06453 20.4788 2.96051 20.1542 3.0136 19.8356L3.90824 14.4678C4.01103 13.8511 4.30396 13.2818 4.7461 12.8397L13.2929 4.29291ZM13 7.41422L6.16031 14.2539C6.01293 14.4013 5.91529 14.591 5.88102 14.7966L5.21655 18.7835L9.20339 18.119C9.40898 18.0847 9.59872 17.9871 9.7461 17.8397L16.5858 11L13 7.41422ZM18 9.5858L14.4142 6.00001L14.7071 5.70712C15.6973 4.71693 17.3027 4.71693 18.2929 5.70712C19.2831 6.69731 19.2831 8.30272 18.2929 9.29291L18 9.5858Z" fill="currentColor">
|
||||
</path></svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { cn } from '~/utils';
|
|||
export default function RegenerateIcon({ className = '' }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -14,9 +13,7 @@ export default function RegenerateIcon({ className = '' }: { className?: string
|
|||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<polyline points="1 4 1 10 7 10" />
|
||||
<polyline points="23 20 23 14 17 14" />
|
||||
<path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15" />
|
||||
</svg>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 2.5C5.05228 2.5 5.5 2.94772 5.5 3.5V5.07196C7.19872 3.47759 9.48483 2.5 12 2.5C17.2467 2.5 21.5 6.75329 21.5 12C21.5 17.2467 17.2467 21.5 12 21.5C7.1307 21.5 3.11828 17.8375 2.565 13.1164C2.50071 12.5679 2.89327 12.0711 3.4418 12.0068C3.99033 11.9425 4.48712 12.3351 4.5514 12.8836C4.98798 16.6089 8.15708 19.5 12 19.5C16.1421 19.5 19.5 16.1421 19.5 12C19.5 7.85786 16.1421 4.5 12 4.5C9.7796 4.5 7.7836 5.46469 6.40954 7H9C9.55228 7 10 7.44772 10 8C10 8.55228 9.55228 9 9 9H4.5C3.96064 9 3.52101 8.57299 3.50073 8.03859C3.49983 8.01771 3.49958 7.99677 3.5 7.9758V3.5C3.5 2.94772 3.94771 2.5 4.5 2.5Z" fill="currentColor">
|
||||
</path></svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
export default function RenameIcon() {
|
||||
return (
|
||||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -12,8 +11,7 @@ export default function RenameIcon() {
|
|||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M12 20h9" />
|
||||
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
|
||||
</svg>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.2929 4.29291C15.0641 2.52167 17.9359 2.52167 19.7071 4.2929C21.4783 6.06414 21.4783 8.93588 19.7071 10.7071L18.7073 11.7069L11.1603 19.2539C10.7182 19.696 10.1489 19.989 9.53219 20.0918L4.1644 20.9864C3.84584 21.0395 3.52125 20.9355 3.29289 20.7071C3.06453 20.4788 2.96051 20.1542 3.0136 19.8356L3.90824 14.4678C4.01103 13.8511 4.30396 13.2818 4.7461 12.8397L13.2929 4.29291ZM13 7.41422L6.16031 14.2539C6.01293 14.4013 5.91529 14.591 5.88102 14.7966L5.21655 18.7835L9.20339 18.119C9.40898 18.0847 9.59872 17.9871 9.7461 17.8397L16.5858 11L13 7.41422ZM18 9.5858L14.4142 6.00001L14.7071 5.70712C15.6973 4.71693 17.3027 4.71693 18.2929 5.70712C19.2831 6.69731 19.2831 8.30272 18.2929 9.29291L18 9.5858Z" fill="currentColor">
|
||||
</path></svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
export default function TrashIcon() {
|
||||
return (
|
||||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -12,10 +11,7 @@ export default function TrashIcon() {
|
|||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||
<line x1="10" y1="11" x2="10" y2="17" />
|
||||
<line x1="14" y1="11" x2="14" y2="17" />
|
||||
</svg>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5555 4C10.099 4 9.70052 4.30906 9.58693 4.75114L9.29382 5.8919H14.715L14.4219 4.75114C14.3083 4.30906 13.9098 4 13.4533 4H10.5555ZM16.7799 5.8919L16.3589 4.25342C16.0182 2.92719 14.8226 2 13.4533 2H10.5555C9.18616 2 7.99062 2.92719 7.64985 4.25342L7.22886 5.8919H4C3.44772 5.8919 3 6.33961 3 6.8919C3 7.44418 3.44772 7.8919 4 7.8919H4.10069L5.31544 19.3172C5.47763 20.8427 6.76455 22 8.29863 22H15.7014C17.2354 22 18.5224 20.8427 18.6846 19.3172L19.8993 7.8919H20C20.5523 7.8919 21 7.44418 21 6.8919C21 6.33961 20.5523 5.8919 20 5.8919H16.7799ZM17.888 7.8919H6.11196L7.30423 19.1057C7.3583 19.6142 7.78727 20 8.29863 20H15.7014C16.2127 20 16.6417 19.6142 16.6958 19.1057L17.888 7.8919ZM10 10C10.5523 10 11 10.4477 11 11V16C11 16.5523 10.5523 17 10 17C9.44772 17 9 16.5523 9 16V11C9 10.4477 9.44772 10 10 10ZM14 10C14.5523 10 15 10.4477 15 11V16C15 16.5523 14.5523 17 14 17C13.4477 17 13 16.5523 13 16V11C13 10.4477 13.4477 10 14 10Z" fill="currentColor">
|
||||
</path></svg>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const DialogContent = React.forwardRef<
|
|||
{...props}
|
||||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="absolute right-6 top-[0.5rem] rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 dark:data-[state=open]:bg-slate-800 sm:top-[1.6rem]">
|
||||
<DialogPrimitive.Close className="absolute right-6 top-[1.6rem] rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900 dark:data-[state=open]:bg-slate-800">
|
||||
<X className="h-5 w-5 text-black dark:text-white" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
|
|
@ -72,7 +72,7 @@ DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|||
const DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col space-y-2 border-b border-black/10 p-2 text-center dark:border-white/10 sm:p-6 sm:text-left',
|
||||
'flex flex-col space-y-2 border-b border-black/10 dark:border-white/10 p-6 pb-4 text-left',
|
||||
className ?? '',
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -83,7 +83,7 @@ DialogHeader.displayName = 'DialogHeader';
|
|||
const DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col-reverse px-6 sm:flex-row sm:justify-between sm:space-x-2',
|
||||
'flex px-6 py-4 flex-row justify-between space-x-2',
|
||||
className ?? '',
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const DialogTemplate = forwardRef((props: DialogTemplateProps, ref: Ref<HTMLDivE
|
|||
className={cn('shadow-2xl dark:bg-gray-800', className || '')}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<DialogHeader className={cn('sm:pb-7', headerClassName ?? '')}>
|
||||
<DialogHeader className={cn(headerClassName ?? '')}>
|
||||
<DialogTitle className="text-lg font-medium leading-6 text-gray-800 dark:text-gray-200">
|
||||
{title}
|
||||
</DialogTitle>
|
||||
|
|
|
|||
|
|
@ -41,13 +41,12 @@ const Dropdown: FC<DropdownProps> = ({
|
|||
<Listbox.Button
|
||||
data-testid={testId}
|
||||
className={cn(
|
||||
'relative inline-flex items-center justify-between rounded-md border-gray-300 bg-white py-2 pl-3 pr-10 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700',
|
||||
|
||||
'relative inline-flex items-center justify-between rounded-md border-gray-300 bg-white py-2 pl-3 pr-8 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700',
|
||||
'w-auto',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<span className="block truncate font-medium">
|
||||
<span className="block truncate">
|
||||
{label}
|
||||
{options
|
||||
.map((o) => (typeof o === 'string' ? { value: o, display: o } : o))
|
||||
|
|
@ -58,15 +57,11 @@ const Dropdown: FC<DropdownProps> = ({
|
|||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth="1.5"
|
||||
strokeWidth="2"
|
||||
stroke="currentColor"
|
||||
className="h-5 w-5 rotate-0 transform text-gray-400 transition-transform duration-300 ease-in-out"
|
||||
className="h-4 w-5 rotate-0 transform text-gray-400 transition-transform duration-300 ease-in-out"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M19.5 8.25l-7.5 7.5-7.5-7.5"
|
||||
/>
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</span>
|
||||
</Listbox.Button>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export default function Landing() {
|
|||
<h1
|
||||
id="landing-title"
|
||||
data-testid="landing-title"
|
||||
className="mb-10 ml-auto mr-auto mt-6 flex items-center justify-center gap-2 text-center text-4xl font-semibold sm:mb-16 md:mt-[10vh]"
|
||||
className="mb-10 ml-auto mr-auto mt-6 flex items-center justify-center gap-2 dark:text-gray-600 text-center text-4xl font-semibold sm:mb-16 md:mt-[10vh]"
|
||||
>
|
||||
{config?.appTitle || 'LibreChat'}
|
||||
</h1>
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ function SelectDropDown({
|
|||
>
|
||||
<Listbox.Options
|
||||
className={cn(
|
||||
'absolute z-10 mt-2 max-h-60 w-full overflow-auto rounded border bg-white text-base text-xs ring-black/10 focus:outline-none dark:bg-gray-800 dark:ring-white/20 dark:last:border-0 md:w-[100%]',
|
||||
'absolute z-10 mt-2 max-h-60 w-full overflow-auto rounded border bg-white text-base text-xs ring-black/10 focus:outline-none dark:bg-gray-800 dark:ring-white/20 dark:border-gray-600 md:w-[100%]',
|
||||
optionsListClass ?? '',
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ export default {
|
|||
com_nav_search_placeholder: 'Nachrichten suchen',
|
||||
com_nav_setting_general: 'Allgemein',
|
||||
com_nav_setting_beta: 'Beta-Funktionen',
|
||||
com_nav_setting_data: 'Datenkontrollen',
|
||||
com_nav_setting_data: 'Daten-Kontrolle',
|
||||
com_nav_setting_account: 'Konto',
|
||||
com_nav_language: 'Sprache',
|
||||
com_nav_lang_auto: 'Automatische Erkennung',
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export default {
|
|||
com_sidepanel_select_assistant: 'Select an Assistant',
|
||||
com_sidepanel_assistant_builder: 'Assistant Builder',
|
||||
com_sidepanel_attach_files: 'Attach Files',
|
||||
com_sidepanel_manage_files: 'Manage Files',
|
||||
com_assistants_knowledge: 'Knowledge',
|
||||
com_assistants_knowledge_info:
|
||||
'If you upload files under Knowledge, conversations with your Assistant may include file contents.',
|
||||
|
|
@ -345,6 +346,7 @@ export default {
|
|||
com_nav_export_recursive_or_sequential: 'Recursive or sequential?',
|
||||
com_nav_export_recursive: 'Recursive',
|
||||
com_nav_export_conversation: 'Export conversation',
|
||||
com_nav_my_files: 'My Files',
|
||||
com_nav_theme: 'Theme',
|
||||
com_nav_theme_system: 'System',
|
||||
com_nav_theme_dark: 'Dark',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
// Russian phrases
|
||||
|
||||
export default {
|
||||
com_sidepanel_select_assistant: 'Выбрать Ассистента',
|
||||
com_sidepanel_assistant_builder: 'Конструктор Ассистента',
|
||||
com_sidepanel_attach_files: 'Прикрепить файлы',
|
||||
com_sidepanel_manage_files: 'Управление файлами',
|
||||
com_assistants_code_interpreter: 'Интерпретатор кода',
|
||||
com_assistants_code_interpreter_files:
|
||||
'Следующие файлы доступны только для Интерпретатора кода:',
|
||||
com_assistants_retrieval: 'Поиск',
|
||||
com_ui_examples: 'Примеры',
|
||||
com_ui_new_chat: 'Создать чат',
|
||||
com_ui_happy_birthday: 'Это мой первый день рождения!',
|
||||
|
|
@ -116,6 +124,7 @@ export default {
|
|||
com_auth_to_try_again: 'чтобы попробовать снова.',
|
||||
com_auth_submit_registration: 'Отправить регистрацию',
|
||||
com_auth_welcome_back: 'Добро пожаловать',
|
||||
com_auth_back_to_login: 'Вернуться к авторизации',
|
||||
com_endpoint_open_menu: 'Открыть меню',
|
||||
com_endpoint_bing_enable_sydney: 'Включить Sydney',
|
||||
com_endpoint_bing_to_enable_sydney: 'Чтобы включить Sydney',
|
||||
|
|
@ -184,7 +193,7 @@ export default {
|
|||
com_endpoint_disabled_with_tools_placeholder: 'Отключено при включённых плагинах',
|
||||
com_endpoint_plug_set_custom_instructions_for_gpt_placeholder:
|
||||
'Задайте кастомные инструкции для включения в системное сообщение. По умолчанию: нет',
|
||||
com_endpoint_import: 'Импортировать',
|
||||
com_endpoint_import: 'Импорт',
|
||||
com_endpoint_set_custom_name:
|
||||
'Задайте кастомное имя на случай, если вы сможете найти эту предустановку :)',
|
||||
com_endpoint_preset_delete_confirm: 'Вы уверены, что хотите удалить этот пресет?',
|
||||
|
|
@ -198,7 +207,7 @@ export default {
|
|||
'Произошла ошибка при удалении вашего пресета. Пожалуйста, попробуйте еще раз.',
|
||||
com_endpoint_preset_default_removed: 'больше не пресет по умолчанию.',
|
||||
com_endpoint_preset_default_item: 'По умолчанию:',
|
||||
com_endpoint_preset_default_none: 'Нет активных пресетов По умолчанию.',
|
||||
com_endpoint_preset_default_none: 'Активных пресетов по умолчанию нет.',
|
||||
com_endpoint_preset_title: 'Пресет',
|
||||
com_endpoint_preset_saved: 'Сохранено!',
|
||||
com_endpoint_preset_default: 'теперь пресет По умолчаанию.',
|
||||
|
|
@ -216,7 +225,7 @@ export default {
|
|||
com_endpoint_agent: 'Агент',
|
||||
com_endpoint_show_what_settings: 'Показать настройки {0}',
|
||||
com_endpoint_save: 'Сохранить',
|
||||
com_endpoint_export: 'Экспортировать',
|
||||
com_endpoint_export: 'Экспорт',
|
||||
com_endpoint_save_as_preset: 'Сохранить как Пресет',
|
||||
com_endpoint_presets_clear_warning:
|
||||
'Вы уверены, что хотите удалить все пресеты? Это действие необратимо и восстановление невозможно.',
|
||||
|
|
@ -268,6 +277,7 @@ export default {
|
|||
'Убедитесь что нажали на \'Create and Continue\' чтобы получить как минимум \'Vertex AI User\'. Наконец, создайте JSON-ключ чтобы импортировать его сюда.',
|
||||
com_nav_welcome_message: 'Чем я могу помочь вам сегодня?',
|
||||
com_nav_auto_scroll: 'Автоматически проматывать к самым новым сообщениям при открытии',
|
||||
com_nav_hide_panel: 'Скрыть правую боковую панель',
|
||||
com_nav_modular_chat: 'Разрешить менять точки подключения в середине разговора',
|
||||
com_nav_latex_parsing: 'Обработка LaTeX в сообщениях (может повлиять на производительность)',
|
||||
com_nav_plugin_store: 'Магазин плагинов',
|
||||
|
|
@ -284,6 +294,7 @@ export default {
|
|||
com_nav_export_recursive_or_sequential: 'Рекурсивно или последовательно?',
|
||||
com_nav_export_recursive: 'Рекурсивно',
|
||||
com_nav_export_conversation: 'Экспортировать разговор',
|
||||
com_nav_my_files: 'Мои файлы',
|
||||
com_nav_theme: 'Тема',
|
||||
com_nav_theme_system: 'Системная',
|
||||
com_nav_theme_dark: 'Темная',
|
||||
|
|
|
|||
|
|
@ -1034,16 +1034,24 @@ button {
|
|||
background-color: rgba(16, 163, 127, var(--tw-bg-opacity));
|
||||
}
|
||||
.btn-secondary {
|
||||
--tw-border-opacity: 1;
|
||||
--tw-bg-opacity: 1;
|
||||
--tw-text-opacity: 1;
|
||||
background-color: rgba(224, 231, 255, var(--tw-bg-opacity));
|
||||
color: rgba(67, 56, 202, var(--tw-text-opacity));
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
background-color: transparent;
|
||||
background-color: rgba(16, 163, 156, var(--tw-bg-opacity));
|
||||
color: rgba(255, 255, 255, var(--tw-text-opacity));
|
||||
}
|
||||
.btn-secondary:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgba(199, 210, 254, var(--tw-bg-opacity));
|
||||
border-color: rgba(0, 0, 0, 0.1);
|
||||
color: rgba(64, 65, 79, var(--tw-text-opacity));
|
||||
background-color: rgba(236, 236, 241, var(--tw-bg-opacity));
|
||||
}
|
||||
.dark .btn-secondary:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
border-color: rgba(68, 68, 68, var(--tw-border-opacity));
|
||||
color: rgba(255, 255, 240, var(--tw-text-opacity));
|
||||
background-color: rgba(47, 47, 47, var(--tw-bg-opacity));
|
||||
}
|
||||
.btn-neutral {
|
||||
--tw-bg-opacity: 1;
|
||||
|
|
@ -1064,12 +1072,12 @@ button {
|
|||
--tw-bg-opacity: 1;
|
||||
--tw-text-opacity: 1;
|
||||
background-color: transparent;
|
||||
border-color: rgba(38, 38, 38, var(--tw-border-opacity));
|
||||
border-color: rgba(68, 68, 68, var(--tw-border-opacity));
|
||||
color: rgba(255, 255, 240, var(--tw-text-opacity));
|
||||
}
|
||||
.dark .btn-neutral:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgba(23, 23, 23, var(--tw-bg-opacity));
|
||||
background-color: rgba(47, 47, 47, var(--tw-bg-opacity));
|
||||
}
|
||||
.btn-small {
|
||||
padding: 0.25rem 0.5rem;
|
||||
|
|
@ -1962,4 +1970,12 @@ html {
|
|||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.dark .webkit-dark-styles {
|
||||
-webkit-text-fill-color: #fff;
|
||||
-webkit-box-shadow: 0 0 0px 1000px #0c1015 inset;
|
||||
}
|
||||
.dark .webkit-dark-styles:focus {
|
||||
-webkit-box-shadow: 0 0 0px 1000px #0c1015 inset;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue