mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-20 18:30:15 +01:00
🖼️ 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:
parent
9585db14ba
commit
d82a63642d
51 changed files with 2074 additions and 1311 deletions
|
|
@ -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
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue