🖼️ 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,6 +1,6 @@
import * as React from 'react';
import { Search } from 'lucide-react';
import debounce from 'lodash/debounce';
import { Search, X } from 'lucide-react';
import * as Ariakit from '@ariakit/react';
import { Spinner, Skeleton } from '@librechat/client';
import { useLocalize } from '~/hooks';
@ -14,7 +14,7 @@ type SearchPickerProps<TOption extends { key: string }> = {
onPick: (pickedOption: TOption) => void;
placeholder?: string;
inputClassName?: string;
label: string;
label?: string;
resetValueOnHide?: boolean;
isSmallScreen?: boolean;
isLoading?: boolean;
@ -69,29 +69,21 @@ export function SearchPicker<TOption extends { key: string; value: string }>({
inputRef.current.focus();
}
};
const showClearIcon = localQuery.trim().length > 0;
const clearText = () => {
setLocalQuery('');
onQueryChange('');
debouncedOnQueryChange.cancel();
if (inputRef.current) {
inputRef.current.focus();
}
};
return (
<Ariakit.ComboboxProvider store={combobox}>
<Ariakit.ComboboxLabel className="text-token-text-primary mb-2 block font-medium">
<Ariakit.ComboboxLabel className="mb-2 block font-medium text-text-primary">
{label}
</Ariakit.ComboboxLabel>
<div className="py-1.5">
<>
<div
className={cn(
'group relative mt-1 flex h-10 cursor-pointer items-center gap-3 rounded-lg border-border-medium px-3 py-2 text-text-primary transition-colors duration-200 focus-within:bg-surface-hover hover:bg-surface-hover',
'group relative flex h-10 cursor-pointer items-center gap-2 rounded-lg border-border-medium text-text-primary transition-colors duration-200 focus-within:bg-surface-hover hover:bg-surface-hover',
isSmallScreen === true ? 'mb-2 h-14 rounded-2xl' : '',
)}
>
{isLoading ? (
<Spinner className="absolute left-3 h-4 w-4 text-text-primary" />
<Spinner className="absolute left-3 h-4 w-4" />
) : (
<Search className="absolute left-3 h-4 w-4 text-text-secondary group-focus-within:text-text-primary group-hover:text-text-primary" />
)}
@ -118,28 +110,14 @@ export function SearchPicker<TOption extends { key: string; value: string }>({
value={localQuery}
// autoSelect
placeholder={placeholder || localize('com_ui_select_options')}
className="m-0 mr-0 w-full rounded-md border-none bg-transparent p-0 py-2 pl-9 pr-3 text-sm leading-tight text-text-primary placeholder-text-secondary placeholder-opacity-100 focus:outline-none focus-visible:outline-none group-focus-within:placeholder-text-primary group-hover:placeholder-text-primary"
className="h-10 w-full rounded-lg bg-transparent pl-10 text-sm leading-tight text-text-primary placeholder-text-secondary placeholder-opacity-100 focus:outline-none focus-visible:outline-none group-focus-within:placeholder-text-primary group-hover:placeholder-text-primary"
/>
<button
type="button"
aria-label={`${localize('com_ui_clear')} ${localize('com_ui_search')}`}
className={cn(
'absolute right-[7px] flex h-5 w-5 items-center justify-center rounded-full border-none bg-transparent p-0 transition-opacity duration-200',
showClearIcon ? 'opacity-100' : 'opacity-0',
isSmallScreen === true ? 'right-[16px]' : '',
)}
onClick={clearText}
tabIndex={showClearIcon ? 0 : -1}
disabled={!showClearIcon}
>
<X className="h-5 w-5 cursor-pointer" />
</button>
</div>
</div>
</>
<Ariakit.ComboboxPopover
portal={false} //todo fix focus when set to true
gutter={10}
// sameWidth
gutter={8}
sameWidth
open={
isLoading ||
options.length > 0 ||
@ -150,7 +128,7 @@ export function SearchPicker<TOption extends { key: string; value: string }>({
autoFocusOnShow={false}
modal={false}
className={cn(
'animate-popover z-[9999] min-w-64 overflow-hidden rounded-xl border border-border-light bg-surface-secondary shadow-lg',
'animate-popover z-[9999] min-w-64 overflow-hidden rounded-2xl border border-border-light bg-surface-secondary shadow-lg',
'[pointer-events:auto]', // Override body's pointer-events:none when in modal
)}
>