mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-21 02:40:14 +01:00
refactor: organize Sharing/Agent components, improve type safety for resource types and access role ids, rename enums to PascalCase refactor: organize Sharing/Agent components, improve type safety for resource types and access role ids chore: move sharing related components to dedicated "Sharing" directory chore: remove PublicSharingToggle component and update index exports chore: move non-sidepanel agent components to `~/components/Agents` chore: move AgentCategoryDisplay component with tests chore: remove commented out code refactor: change PERMISSION_BITS from const to enum for better type safety refactor: reorganize imports in GenericGrantAccessDialog and update index exports for hooks refactor: update type definitions to use ACCESS_ROLE_IDS for improved type safety refactor: remove unused canAccessPromptResource middleware and related code refactor: remove unused prompt access roles from createAccessRoleMethods refactor: update resourceType in AclEntry type definition to remove unused 'prompt' value refactor: introduce ResourceType enum and update resourceType usage across data provider files for improved type safety refactor: update resourceType usage to ResourceType enum across sharing and permissions components for improved type safety refactor: standardize resourceType usage to ResourceType enum across agent and prompt models, permissions controller, and middleware for enhanced type safety refactor: update resourceType references from PROMPT_GROUP to PROMPTGROUP for consistency across models, middleware, and components refactor: standardize access role IDs and resource type usage across agent, file, and prompt models for improved type safety and consistency chore: add typedefs for TUpdateResourcePermissionsRequest and TUpdateResourcePermissionsResponse to enhance type definitions chore: move SearchPicker to PeoplePicker dir refactor: implement debouncing for query changes in SearchPicker for improved performance chore: fix typing, import order for agent admin settings fix: agent admin settings, prevent agent form submission refactor: rename `ACCESS_ROLE_IDS` to `AccessRoleIds` refactor: replace PermissionBits with PERMISSION_BITS refactor: replace PERMISSION_BITS with PermissionBits
101 lines
2.8 KiB
TypeScript
101 lines
2.8 KiB
TypeScript
import React from 'react';
|
|
import { Users, User } from 'lucide-react';
|
|
import type { TPrincipal } from 'librechat-data-provider';
|
|
import { cn } from '~/utils';
|
|
|
|
interface PrincipalAvatarProps {
|
|
principal: TPrincipal;
|
|
size?: 'sm' | 'md' | 'lg';
|
|
className?: string;
|
|
}
|
|
|
|
export default function PrincipalAvatar({
|
|
principal,
|
|
size = 'md',
|
|
className,
|
|
}: PrincipalAvatarProps) {
|
|
const { avatar, type, name } = principal;
|
|
const displayName = name || 'Unknown';
|
|
|
|
// Size variants
|
|
const sizeClasses = {
|
|
sm: 'h-6 w-6',
|
|
md: 'h-8 w-8',
|
|
lg: 'h-10 w-10',
|
|
};
|
|
|
|
const iconSizeClasses = {
|
|
sm: 'h-3 w-3',
|
|
md: 'h-4 w-4',
|
|
lg: 'h-5 w-5',
|
|
};
|
|
|
|
const avatarSizeClass = sizeClasses[size];
|
|
const iconSizeClass = iconSizeClasses[size];
|
|
|
|
// Avatar or icon logic
|
|
if (avatar) {
|
|
return (
|
|
<div className={cn('flex-shrink-0', className)}>
|
|
<img
|
|
src={avatar}
|
|
alt={`${displayName} avatar`}
|
|
className={cn(avatarSizeClass, 'rounded-full object-cover')}
|
|
onError={(e) => {
|
|
// Fallback to icon if image fails to load
|
|
const target = e.target as HTMLImageElement;
|
|
target.style.display = 'none';
|
|
target.nextElementSibling?.classList.remove('hidden');
|
|
}}
|
|
/>
|
|
{/* Hidden fallback icon that shows if image fails */}
|
|
<div className={cn('hidden', avatarSizeClass)}>
|
|
{type === 'user' ? (
|
|
<div
|
|
className={cn(
|
|
avatarSizeClass,
|
|
'flex items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900',
|
|
)}
|
|
>
|
|
<User className={cn(iconSizeClass, 'text-blue-600 dark:text-blue-400')} />
|
|
</div>
|
|
) : (
|
|
<div
|
|
className={cn(
|
|
avatarSizeClass,
|
|
'flex items-center justify-center rounded-full bg-green-100 dark:bg-green-900',
|
|
)}
|
|
>
|
|
<Users className={cn(iconSizeClass, 'text-green-600 dark:text-green-400')} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Fallback icon based on type
|
|
return (
|
|
<div className={cn('flex-shrink-0', className)}>
|
|
{type === 'user' ? (
|
|
<div
|
|
className={cn(
|
|
avatarSizeClass,
|
|
'flex items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900',
|
|
)}
|
|
>
|
|
<User className={cn(iconSizeClass, 'text-blue-600 dark:text-blue-400')} />
|
|
</div>
|
|
) : (
|
|
<div
|
|
className={cn(
|
|
avatarSizeClass,
|
|
'flex items-center justify-center rounded-full bg-green-100 dark:bg-green-900',
|
|
)}
|
|
>
|
|
<Users className={cn(iconSizeClass, 'text-green-600 dark:text-green-400')} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|