mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-25 20:58:50 +01:00
refactor: enhance UI components with improved class handling and state management
This commit is contained in:
parent
9c5bbdaa28
commit
b9ca23c606
6 changed files with 24 additions and 19 deletions
|
|
@ -224,6 +224,7 @@ const AttachFileMenu = ({
|
|||
aria-label="Attach File Options"
|
||||
className={cn(
|
||||
'flex size-9 items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50',
|
||||
isPopoverActive && 'bg-surface-hover',
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full items-center justify-center gap-2">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { MultiSelect, MCPIcon } from '@librechat/client';
|
|||
import MCPServerStatusIcon from '~/components/MCP/MCPServerStatusIcon';
|
||||
import MCPConfigDialog from '~/components/MCP/MCPConfigDialog';
|
||||
import { useBadgeRowContext } from '~/Providers';
|
||||
import { cn } from '~/utils';
|
||||
|
||||
function MCPSelectContent() {
|
||||
const { conversationId, mcpServerManager } = useBadgeRowContext();
|
||||
|
|
@ -88,7 +89,10 @@ function MCPSelectContent() {
|
|||
className="badge-icon min-w-fit"
|
||||
selectIcon={<MCPIcon className="icon-md text-text-primary" />}
|
||||
selectItemsClassName="border border-blue-600/50 bg-blue-500/10 hover:bg-blue-700/10"
|
||||
selectClassName="group relative inline-flex items-center justify-center md:justify-start gap-1.5 rounded-full border border-border-medium text-sm font-medium transition-all md:w-full size-9 p-2 md:p-3 bg-transparent shadow-sm hover:bg-surface-hover hover:shadow-md active:shadow-inner"
|
||||
selectClassName={cn(
|
||||
'group relative inline-flex items-center justify-center md:justify-start gap-1.5 rounded-full border border-border-medium text-sm font-medium transition-all',
|
||||
'md:w-full size-9 p-2 md:p-3 bg-transparent shadow-sm hover:bg-surface-hover hover:shadow-md active:shadow-inner',
|
||||
)}
|
||||
/>
|
||||
{configDialogProps && (
|
||||
<MCPConfigDialog {...configDialogProps} conversationId={conversationId} />
|
||||
|
|
|
|||
|
|
@ -307,10 +307,11 @@ const ToolsDropdown = ({ disabled }: ToolsDropdownProps) => {
|
|||
aria-label="Tools Options"
|
||||
className={cn(
|
||||
'flex size-9 items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50',
|
||||
isPopoverActive && 'bg-surface-hover',
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full items-center justify-center gap-2">
|
||||
<Settings2 className="icon-md" strokeWidth={4} />
|
||||
<Settings2 className="size-5" />
|
||||
</div>
|
||||
</Ariakit.MenuButton>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,17 +122,6 @@ export default function SharedLinks() {
|
|||
[setQueryParams, data?.pages],
|
||||
);
|
||||
|
||||
const handleError = useCallback(
|
||||
(error: Error) => {
|
||||
console.error('DataTable error:', error);
|
||||
showToast({
|
||||
message: localize('com_ui_share_error'),
|
||||
severity: NotificationSeverity.ERROR,
|
||||
});
|
||||
},
|
||||
[showToast, localize],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data?.pages) return;
|
||||
|
||||
|
|
@ -252,7 +241,7 @@ export default function SharedLinks() {
|
|||
},
|
||||
meta: {
|
||||
className: 'w-32 sm:w-40',
|
||||
// desktopOnly: true, // WIP
|
||||
desktopOnly: true,
|
||||
},
|
||||
enableSorting: true,
|
||||
},
|
||||
|
|
@ -350,7 +339,6 @@ export default function SharedLinks() {
|
|||
isFetchingNextPage={isFetchingNextPage}
|
||||
sorting={sorting}
|
||||
onSortingChange={handleSortingChange}
|
||||
onError={handleError}
|
||||
/>
|
||||
</OGDialogContent>
|
||||
</OGDialog>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export default function OAuthSuccess() {
|
|||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-gray-50 p-8">
|
||||
<div className="w-full max-w-md rounded-lg bg-white p-8 text-center shadow-lg">
|
||||
<div className="w-full max-w-md rounded-xl bg-white p-8 text-center shadow-lg">
|
||||
<h1 className="mb-4 text-3xl font-bold text-gray-900">
|
||||
{localize('com_ui_oauth_success_title') || 'Authentication Successful'}
|
||||
</h1>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useRef } from 'react';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import {
|
||||
Select,
|
||||
SelectArrow,
|
||||
|
|
@ -61,6 +61,7 @@ export default function MultiSelect<T extends string>({
|
|||
renderItemContent,
|
||||
}: MultiSelectProps<T>) {
|
||||
const selectRef = useRef<HTMLButtonElement>(null);
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
||||
|
||||
const handleValueChange = (values: T[]) => {
|
||||
setSelectedValues(values);
|
||||
|
|
@ -71,7 +72,12 @@ export default function MultiSelect<T extends string>({
|
|||
|
||||
return (
|
||||
<div className={className}>
|
||||
<SelectProvider value={selectedValues} setValue={handleValueChange}>
|
||||
<SelectProvider
|
||||
value={selectedValues}
|
||||
setValue={handleValueChange}
|
||||
open={isPopoverOpen}
|
||||
setOpen={setIsPopoverOpen}
|
||||
>
|
||||
{label && (
|
||||
<SelectLabel className={cn('mb-1 block text-sm text-text-primary', labelClassName)}>
|
||||
{label}
|
||||
|
|
@ -92,7 +98,12 @@ export default function MultiSelect<T extends string>({
|
|||
<span className="mr-auto hidden truncate md:block">
|
||||
{renderSelectedValues(selectedValues, placeholder)}
|
||||
</span>
|
||||
<SelectArrow className="ml-1 hidden stroke-1 text-base opacity-75 md:block" />
|
||||
<SelectArrow
|
||||
className={cn(
|
||||
'ml-1 hidden stroke-1 text-base opacity-75 transition-transform duration-300 md:block',
|
||||
isPopoverOpen && 'rotate-180',
|
||||
)}
|
||||
/>
|
||||
</Select>
|
||||
<SelectPopover
|
||||
gutter={4}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue