🖼️ style: Improve Marketplace & Sharing Dialog UI

feat: Enhance CategoryTabs and Marketplace components for better responsiveness and navigation

feat: Refactor AgentCard and AgentGrid components for improved layout and accessibility

feat: Implement animated category transitions in AgentMarketplace and update NewChat component layout

feat: Refactor UI components for improved styling and accessibility in sharing dialogs

refactor: remove GenericManagePermissionsDialog and GrantAccessDialog components

- Deleted GenericManagePermissionsDialog and GrantAccessDialog components to streamline sharing functionality.
- Updated ManagePermissionsDialog to utilize AccessRolesPicker directly.
- Introduced UnifiedPeopleSearch for improved people selection experience.
- Enhanced PublicSharingToggle with InfoHoverCard for better user guidance.
- Adjusted AgentPanel to change error status to warning for duplicate agent versions.
- Updated translations to include new keys for search and access management.

feat: Add responsive design for SelectedPrincipalsList and improve layout in GenericGrantAccessDialog

feat: Enhance styling in SelectedPrincipalsList and SearchPicker components for improved UI consistency

feat: Improve PublicSharingToggle component with enhanced styling and accessibility features

feat: Introduce InfoHoverCard component and refactor enums for better organization

feat: Implement infinite scroll for agent grids and enhance performance

- Added `useInfiniteScroll` hook to manage infinite scrolling behavior in agent grids.
- Integrated infinite scroll functionality into `AgentGrid` and `VirtualizedAgentGrid` components.
- Updated `AgentMarketplace` to pass the scroll container to the agent grid components.
- Refactored loading indicators to show a spinner instead of a "Load More" button.
- Created `VirtualizedAgentGrid` component for optimized rendering of agent cards using virtualization.
- Added performance tests for `VirtualizedAgentGrid` to ensure efficient handling of large datasets.
- Updated translations to include new messages for end-of-results scenarios.

chore: Remove unused permission-related UI localization keys

ci: Update Agent model tests to handle duplicate support_contact updates

- Modified tests to ensure that updating an agent with the same support_contact does not create a new version and returns successfully.
- Enhanced verification for partial changes in support_contact, confirming no new version is created when content remains the same.

chore: Address ESLint, clean up unused imports and improve prop definitions in various components

ci: fix tests

ci: update tests

chore: remove unused search localization keys
This commit is contained in:
Marco Beretta 2025-08-04 18:50:54 +02:00 committed by Danny Avila
parent 9585db14ba
commit d82a63642d
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
51 changed files with 2074 additions and 1311 deletions

View file

@ -1,7 +1,6 @@
import React from 'react';
import { useRecoilState } from 'recoil';
import { Switch, Label } from '@librechat/client';
import HoverCardSettings from '../HoverCardSettings';
import { Switch, Label, InfoHoverCard, ESide } from '@librechat/client';
import { useLocalize } from '~/hooks';
import store from '~/store';
@ -17,7 +16,7 @@ export default function DisplayUsernameMessages() {
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<Label className="font-light">{localize('com_nav_user_name_display')}</Label>
<HoverCardSettings side="bottom" text="com_nav_info_user_name_display" />
<InfoHoverCard side={ESide.Bottom} text={localize('com_nav_info_user_name_display')} />
</div>
<Switch
id="UsernameDisplay"

View file

@ -1,6 +1,5 @@
import React from 'react';
import { Label } from '@librechat/client';
import HoverCardSettings from '~/components/Nav/SettingsTabs/HoverCardSettings';
import { Label, InfoHoverCard, ESide } from '@librechat/client';
import { TranslationKeys, useLocalize } from '~/hooks';
interface AutoRefillSettingsProps {
@ -114,7 +113,7 @@ const AutoRefillSettings: React.FC<AutoRefillSettingsProps> = ({
{/* Left Section: Label */}
<div className="flex items-center space-x-2">
<Label className="font-light">{localize('com_nav_balance_next_refill')}</Label>
<HoverCardSettings side="bottom" text="com_nav_balance_next_refill_info" />
<InfoHoverCard side={ESide.Bottom} text={localize('com_nav_balance_next_refill_info')} />
</div>
{/* Right Section: tokenCredits Value */}

View file

@ -1,6 +1,5 @@
import React from 'react';
import { Label } from '@librechat/client';
import HoverCardSettings from '~/components/Nav/SettingsTabs/HoverCardSettings';
import { Label, InfoHoverCard, ESide } from '@librechat/client';
import { useLocalize } from '~/hooks';
interface TokenCreditsItemProps {
@ -15,7 +14,7 @@ const TokenCreditsItem: React.FC<TokenCreditsItemProps> = ({ tokenCredits }) =>
{/* Left Section: Label */}
<div className="flex items-center space-x-2">
<Label className="font-light">{localize('com_nav_balance')}</Label>
<HoverCardSettings side="bottom" text="com_nav_info_balance" />
<InfoHoverCard side={ESide.Bottom} text={localize('com_nav_info_balance')} />
</div>
{/* Right Section: tokenCredits Value */}

View file

@ -1,7 +1,6 @@
import { useRecoilState } from 'recoil';
import { Dropdown, Switch } from '@librechat/client';
import { ForkOptions } from 'librechat-data-provider';
import HoverCardSettings from '../HoverCardSettings';
import { Dropdown, Switch, InfoHoverCard, ESide } from '@librechat/client';
import { useLocalize } from '~/hooks';
import store from '~/store';
@ -36,7 +35,10 @@ export const ForkSettings = () => {
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<div>{localize('com_ui_fork_change_default')}</div>
<HoverCardSettings side="bottom" text="com_nav_info_fork_change_default" />
<InfoHoverCard
side={ESide.Bottom}
text={localize('com_nav_info_fork_change_default')}
/>
</div>
<Dropdown
value={forkSetting}
@ -53,7 +55,10 @@ export const ForkSettings = () => {
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<div>{localize('com_ui_fork_split_target_setting')}</div>
<HoverCardSettings side="bottom" text="com_nav_info_fork_split_target_setting" />
<InfoHoverCard
side={ESide.Bottom}
text={localize('com_nav_info_fork_split_target_setting')}
/>
</div>
<Switch
id="splitAtTarget"

View file

@ -1,6 +1,5 @@
import { useRecoilState } from 'recoil';
import { Switch } from '@librechat/client';
import HoverCardSettings from '../HoverCardSettings';
import { Switch, InfoHoverCard, ESide } from '@librechat/client';
import { useLocalize } from '~/hooks';
import store from '~/store';
@ -23,7 +22,7 @@ export default function SaveBadgesState({
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<div>{localize('com_nav_save_badges_state')}</div>
<HoverCardSettings side="bottom" text="com_nav_info_save_badges_state" />
<InfoHoverCard side={ESide.Bottom} text={localize('com_nav_info_save_badges_state')} />
</div>
<Switch
id="saveBadgesState"

View file

@ -1,6 +1,5 @@
import { useRecoilState } from 'recoil';
import { Switch } from '@librechat/client';
import HoverCardSettings from '../HoverCardSettings';
import { Switch, InfoHoverCard, ESide } from '@librechat/client';
import { useLocalize } from '~/hooks';
import store from '~/store';
@ -23,7 +22,7 @@ export default function SaveDraft({
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<div>{localize('com_nav_show_thinking')}</div>
<HoverCardSettings side="bottom" text="com_nav_info_show_thinking" />
<InfoHoverCard side={ESide.Bottom} text={localize('com_nav_info_show_thinking')} />
</div>
<Switch
id="showThinking"

View file

@ -1,8 +1,8 @@
import { memo } from 'react';
import { InfoHoverCard, ESide } from '@librechat/client';
import { PermissionTypes, Permissions } from 'librechat-data-provider';
import HoverCardSettings from '~/components/Nav/SettingsTabs/HoverCardSettings';
import { useLocalize, useHasAccess } from '~/hooks';
import SlashCommandSwitch from './SlashCommandSwitch';
import { useLocalize, useHasAccess } from '~/hooks';
import PlusCommandSwitch from './PlusCommandSwitch';
import AtCommandSwitch from './AtCommandSwitch';
@ -25,7 +25,7 @@ function Commands() {
<h3 className="text-lg font-medium text-text-primary">
{localize('com_nav_chat_commands')}
</h3>
<HoverCardSettings side="bottom" text="com_nav_chat_commands_info" />
<InfoHoverCard side={ESide.Bottom} text={localize('com_nav_chat_commands_info')} />
</div>
<div className="flex flex-col gap-3 text-sm text-text-primary">
<div className="pb-3">

View file

@ -1,9 +1,8 @@
import { forwardRef } from 'react';
import type { ForwardedRef } from 'react';
import { CheckIcon } from 'lucide-react';
import { Spinner, DialogButton } from '@librechat/client';
import HoverCardSettings from './HoverCardSettings';
import { Spinner, DialogButton, InfoHoverCard, ESide } from '@librechat/client';
import type { TDangerButtonProps } from '~/common';
import type { ForwardedRef } from 'react';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';
@ -37,7 +36,7 @@ const DangerButton = (props: TDangerButtonProps, ref: ForwardedRef<HTMLButtonEle
{showText && (
<div className={`flex items-center ${infoDescriptionCode ? 'space-x-2' : ''}`}>
<div>{localize(infoTextCode)}</div>
{infoDescriptionCode && <HoverCardSettings side="bottom" text={infoDescriptionCode} />}
{infoDescriptionCode && <InfoHoverCard side={ESide.Bottom} text={infoDescriptionCode} />}
</div>
)}
<DialogButton

View file

@ -1,30 +0,0 @@
import React from 'react';
import {
CircleHelpIcon,
HoverCard,
HoverCardTrigger,
HoverCardPortal,
HoverCardContent,
} from '@librechat/client';
import { useLocalize } from '~/hooks';
const HoverCardSettings = ({ side, text }) => {
const localize = useLocalize();
return (
<HoverCard openDelay={500}>
<HoverCardTrigger>
<CircleHelpIcon className="h-5 w-5 text-text-tertiary" />{' '}
</HoverCardTrigger>
<HoverCardPortal>
<HoverCardContent side={side} className="z-[999] w-80">
<div className="space-y-2">
<p className="text-sm text-text-secondary">{localize(text)}</p>
</div>
</HoverCardContent>
</HoverCardPortal>
</HoverCard>
);
};
export default HoverCardSettings;

View file

@ -1,12 +1,14 @@
import { Switch } from '@librechat/client';
import { RecoilState, useRecoilState } from 'recoil';
import HoverCardSettings from './HoverCardSettings';
import { Switch, InfoHoverCard, ESide } from '@librechat/client';
import { useLocalize } from '~/hooks';
type LocalizeFn = ReturnType<typeof useLocalize>;
type LocalizeKey = Parameters<LocalizeFn>[0];
interface ToggleSwitchProps {
stateAtom: RecoilState<boolean>;
localizationKey: string;
hoverCardText?: string;
localizationKey: LocalizeKey;
hoverCardText?: LocalizeKey;
switchId: string;
onCheckedChange?: (value: boolean) => void;
}
@ -18,21 +20,19 @@ const ToggleSwitch: React.FC<ToggleSwitchProps> = ({
switchId,
onCheckedChange,
}) => {
const [switchState, setSwitchState] = useRecoilState<boolean>(stateAtom);
const [switchState, setSwitchState] = useRecoilState(stateAtom);
const localize = useLocalize();
const handleCheckedChange = (value: boolean) => {
setSwitchState(value);
if (onCheckedChange) {
onCheckedChange(value);
}
onCheckedChange?.(value);
};
return (
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<div>{localize(localizationKey as any)}</div>
{hoverCardText && <HoverCardSettings side="bottom" text={hoverCardText} />}
<div>{localize(localizationKey)}</div>
{hoverCardText && <InfoHoverCard side={ESide.Bottom} text={localize(hoverCardText)} />}
</div>
<Switch
id={switchId}