mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-22 06:00:56 +02: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
97 lines
3.4 KiB
TypeScript
97 lines
3.4 KiB
TypeScript
import React from 'react';
|
|
import * as Ariakit from '@ariakit/react';
|
|
import { ChevronDown } from 'lucide-react';
|
|
import { DropdownPopup } from '@librechat/client';
|
|
import { AccessRoleIds, ResourceType } from 'librechat-data-provider';
|
|
import { useGetAccessRolesQuery } from 'librechat-data-provider/react-query';
|
|
import type { AccessRole } from 'librechat-data-provider';
|
|
import type * as t from '~/common';
|
|
import { cn, getRoleLocalizationKeys } from '~/utils';
|
|
import { useLocalize } from '~/hooks';
|
|
|
|
interface AccessRolesPickerProps {
|
|
resourceType?: ResourceType;
|
|
selectedRoleId?: AccessRoleIds;
|
|
onRoleChange: (roleId: AccessRoleIds) => void;
|
|
className?: string;
|
|
}
|
|
|
|
export default function AccessRolesPicker({
|
|
resourceType = ResourceType.AGENT,
|
|
selectedRoleId = AccessRoleIds.AGENT_VIEWER,
|
|
onRoleChange,
|
|
className = '',
|
|
}: AccessRolesPickerProps) {
|
|
const localize = useLocalize();
|
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
const { data: accessRoles, isLoading: rolesLoading } = useGetAccessRolesQuery(resourceType);
|
|
|
|
/** Helper function to get localized role name and description */
|
|
const getLocalizedRoleInfo = (roleId: AccessRoleIds) => {
|
|
const keys = getRoleLocalizationKeys(roleId);
|
|
return {
|
|
name: localize(keys.name),
|
|
description: localize(keys.description),
|
|
};
|
|
};
|
|
|
|
const selectedRole = accessRoles?.find((role) => role.accessRoleId === selectedRoleId);
|
|
const selectedRoleInfo = selectedRole ? getLocalizedRoleInfo(selectedRole.accessRoleId) : null;
|
|
|
|
if (rolesLoading || !accessRoles) {
|
|
return (
|
|
<div className={className}>
|
|
<div className="flex items-center justify-center py-2">
|
|
<div className="h-4 w-4 animate-spin rounded-full border-2 border-border-light border-t-blue-600"></div>
|
|
<span className="ml-2 text-sm text-text-secondary">{localize('com_ui_loading')}</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const dropdownItems: t.MenuItemProps[] = accessRoles.map((role: AccessRole) => {
|
|
const localizedInfo = getLocalizedRoleInfo(role.accessRoleId);
|
|
return {
|
|
id: role.accessRoleId,
|
|
label: localizedInfo.name,
|
|
onClick: () => {
|
|
onRoleChange(role.accessRoleId);
|
|
setIsOpen(false);
|
|
},
|
|
render: (props) => (
|
|
<button {...props}>
|
|
<div className="flex flex-col items-start gap-0.5 text-left">
|
|
<span className="font-medium text-text-primary">{localizedInfo.name}</span>
|
|
<span className="text-xs text-text-secondary">{localizedInfo.description}</span>
|
|
</div>
|
|
</button>
|
|
),
|
|
};
|
|
});
|
|
|
|
return (
|
|
<div className={className}>
|
|
<DropdownPopup
|
|
menuId="access-roles-menu"
|
|
isOpen={isOpen}
|
|
setIsOpen={setIsOpen}
|
|
trigger={
|
|
<Ariakit.MenuButton
|
|
aria-label={selectedRoleInfo?.description || 'Select role'}
|
|
className={cn(
|
|
'flex items-center justify-between gap-2 rounded-lg border border-border-light bg-surface-primary px-3 py-2 text-sm transition-colors hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-ring-primary',
|
|
'min-w-[200px]',
|
|
)}
|
|
>
|
|
<span className="font-medium">
|
|
{selectedRoleInfo?.name || localize('com_ui_select')}
|
|
</span>
|
|
<ChevronDown className="h-4 w-4 text-text-secondary" />
|
|
</Ariakit.MenuButton>
|
|
}
|
|
items={dropdownItems}
|
|
className="w-[280px]"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|