diff --git a/client/src/components/Prompts/AdminSettings.tsx b/client/src/components/Prompts/AdminSettings.tsx index 86c851bb47..bccd4d5a21 100644 --- a/client/src/components/Prompts/AdminSettings.tsx +++ b/client/src/components/Prompts/AdminSettings.tsx @@ -109,7 +109,7 @@ const AdminSettings = () => { const labelControllerData = [ { promptPerm: Permissions.SHARED_GLOBAL, - label: localize('com_ui_prompts_allow_share_global'), + label: localize('com_ui_prompts_allow_share'), }, { promptPerm: Permissions.CREATE, diff --git a/client/src/components/Sharing/ManagePermissionsDialog.tsx b/client/src/components/Sharing/ManagePermissionsDialog.tsx deleted file mode 100644 index 7d5f88750a..0000000000 --- a/client/src/components/Sharing/ManagePermissionsDialog.tsx +++ /dev/null @@ -1,350 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { AccessRoleIds, ResourceType } from 'librechat-data-provider'; -import { Settings, Users, UserCheck, Trash2, Shield } from 'lucide-react'; -import { - useGetResourcePermissionsQuery, - useUpdateResourcePermissionsMutation, -} from 'librechat-data-provider/react-query'; -import type { TPrincipal } from 'librechat-data-provider'; -import { - Button, - Spinner, - OGDialog, - OGDialogTitle, - OGDialogClose, - OGDialogContent, - OGDialogTrigger, - useToastContext, -} from '@librechat/client'; -import { SelectedPrincipalsList } from './PeoplePicker'; -import PublicSharingToggle from './PublicSharingToggle'; -import { cn, removeFocusOutlines } from '~/utils'; -import { useLocalize } from '~/hooks'; - -export default function ManagePermissionsDialog({ - agentName, - resourceType = ResourceType.AGENT, - agentDbId, - onUpdatePermissions, -}: { - agentDbId: string; - agentName?: string; - resourceType?: ResourceType; - onUpdatePermissions?: ( - shares: TPrincipal[], - isPublic: boolean, - publicRole: AccessRoleIds, - ) => void; -}) { - const localize = useLocalize(); - const { showToast } = useToastContext(); - - const { - data: permissionsData, - isLoading: isLoadingPermissions, - error: permissionsError, - } = useGetResourcePermissionsQuery(resourceType, agentDbId, { - enabled: !!agentDbId, - }); - - const updatePermissionsMutation = useUpdateResourcePermissionsMutation(); - - const [managedShares, setManagedShares] = useState([]); - const [managedIsPublic, setManagedIsPublic] = useState(false); - const [managedPublicRole, setManagedPublicRole] = useState( - AccessRoleIds.AGENT_VIEWER, - ); - const [isModalOpen, setIsModalOpen] = useState(false); - const [hasChanges, setHasChanges] = useState(false); - - const currentShares: TPrincipal[] = permissionsData?.principals || []; - - const isPublic = permissionsData?.public || false; - const publicRole = permissionsData?.publicAccessRoleId || AccessRoleIds.AGENT_VIEWER; - - useEffect(() => { - if (permissionsData) { - const shares = permissionsData.principals || []; - const isPublicValue = permissionsData.public || false; - const publicRoleValue = permissionsData.publicAccessRoleId || AccessRoleIds.AGENT_VIEWER; - - setManagedShares(shares); - setManagedIsPublic(isPublicValue); - setManagedPublicRole(publicRoleValue); - setHasChanges(false); - } - }, [permissionsData, isModalOpen]); - - if (!agentDbId) { - return null; - } - - if (permissionsError) { - return
{localize('com_ui_permissions_failed_load')}
; - } - - const handleRemoveShare = (idOnTheSource: string) => { - setManagedShares(managedShares.filter((s) => s.idOnTheSource !== idOnTheSource)); - setHasChanges(true); - }; - - const handleRoleChange = (idOnTheSource: string, newRole: AccessRoleIds) => { - setManagedShares( - managedShares.map((s) => - s.idOnTheSource === idOnTheSource ? { ...s, accessRoleId: newRole } : s, - ), - ); - setHasChanges(true); - }; - - const handleSaveChanges = async () => { - try { - const originalSharesMap = new Map( - currentShares.map((share) => [`${share.type}-${share.idOnTheSource}`, share]), - ); - const managedSharesMap = new Map( - managedShares.map((share) => [`${share.type}-${share.idOnTheSource}`, share]), - ); - - const updated = managedShares.filter((share) => { - const key = `${share.type}-${share.idOnTheSource}`; - const original = originalSharesMap.get(key); - return !original || original.accessRoleId !== share.accessRoleId; - }); - - const removed = currentShares.filter((share) => { - const key = `${share.type}-${share.idOnTheSource}`; - return !managedSharesMap.has(key); - }); - - await updatePermissionsMutation.mutateAsync({ - resourceType, - resourceId: agentDbId, - data: { - updated, - removed, - public: managedIsPublic, - publicAccessRoleId: managedIsPublic ? managedPublicRole : undefined, - }, - }); - - if (onUpdatePermissions) { - onUpdatePermissions(managedShares, managedIsPublic, managedPublicRole); - } - - showToast({ - message: localize('com_ui_permissions_updated_success'), - status: 'success', - }); - - setIsModalOpen(false); - } catch (error) { - console.error('Error updating permissions:', error); - showToast({ - message: localize('com_ui_permissions_failed_update'), - status: 'error', - }); - } - }; - - const handleCancel = () => { - setManagedShares(currentShares); - setManagedIsPublic(isPublic); - setManagedPublicRole(publicRole); - setIsModalOpen(false); - }; - - const handleRevokeAll = () => { - setManagedShares([]); - setManagedIsPublic(false); - setHasChanges(true); - }; - const handlePublicToggle = (isPublic: boolean) => { - setManagedIsPublic(isPublic); - setHasChanges(true); - if (!isPublic) { - setManagedPublicRole(AccessRoleIds.AGENT_VIEWER); - } - }; - const handlePublicRoleChange = (role: AccessRoleIds) => { - setManagedPublicRole(role); - setHasChanges(true); - }; - const totalShares = managedShares.length + (managedIsPublic ? 1 : 0); - const originalTotalShares = currentShares.length + (isPublic ? 1 : 0); - - /** Check if there's at least one owner (user, group, or public with owner role) */ - const hasAtLeastOneOwner = - managedShares.some((share) => share.accessRoleId === AccessRoleIds.AGENT_OWNER) || - (managedIsPublic && managedPublicRole === AccessRoleIds.AGENT_OWNER); - - let peopleLabel = localize('com_ui_people'); - if (managedShares.length === 1) { - peopleLabel = localize('com_ui_person'); - } - - let buttonAriaLabel = localize('com_ui_manage_permissions_for') + ' agent'; - if (agentName != null && agentName !== '') { - buttonAriaLabel = localize('com_ui_manage_permissions_for') + ` "${agentName}"`; - } - - let dialogTitle = localize('com_ui_manage_permissions_for') + ' Agent'; - if (agentName != null && agentName !== '') { - dialogTitle = localize('com_ui_manage_permissions_for') + ` "${agentName}"`; - } - - let publicSuffix = ''; - if (managedIsPublic) { - publicSuffix = localize('com_ui_and_public'); - } - - return ( - - - - - - - -
- - {dialogTitle} -
-
- -
-
-
-
-

- {localize('com_ui_current_access')} -

-

- {(() => { - if (totalShares === 0) { - return localize('com_ui_no_users_groups_access'); - } - return localize('com_ui_shared_with_count', { - 0: managedShares.length, - 1: peopleLabel, - 2: publicSuffix, - }); - })()} -

-
- {(managedShares.length > 0 || managedIsPublic) && ( - - )} -
-
- - {(() => { - if (isLoadingPermissions) { - return ( -
- - - {localize('com_ui_loading_permissions')} - -
- ); - } - - if (managedShares.length > 0) { - return ( -
-

- - {localize('com_ui_user_group_permissions')} ({managedShares.length}) -

- handleRoleChange(id, newRole)} - /> -
- ); - } - - return ( -
- -

- {localize('com_ui_no_individual_access')} -

-
- ); - })()} - - - -
- - - - -
- - {hasChanges && ( -
- * {localize('com_ui_unsaved_changes')} -
- )} - - {!hasAtLeastOneOwner && hasChanges && ( -
- * {localize('com_ui_at_least_one_owner_required')} -
- )} -
-
-
- ); -} diff --git a/client/src/components/Sharing/PublicSharingToggle.tsx b/client/src/components/Sharing/PublicSharingToggle.tsx index 48a2656c40..393c7e6f85 100644 --- a/client/src/components/Sharing/PublicSharingToggle.tsx +++ b/client/src/components/Sharing/PublicSharingToggle.tsx @@ -16,6 +16,11 @@ interface PublicSharingToggleProps { className?: string; } +const accessDescriptions: Record = { + [ResourceType.AGENT]: 'com_ui_agent', + [ResourceType.PROMPTGROUP]: 'com_ui_prompt', +}; + export default function PublicSharingToggle({ isPublic, publicRole, @@ -49,19 +54,25 @@ export default function PublicSharingToggle({
- +
@@ -94,7 +105,7 @@ export default function PublicSharingToggle({
diff --git a/client/src/components/Sharing/index.ts b/client/src/components/Sharing/index.ts index e04d7c7efe..8d847623a2 100644 --- a/client/src/components/Sharing/index.ts +++ b/client/src/components/Sharing/index.ts @@ -1,5 +1,4 @@ -export { default as AccessRolesPicker } from './AccessRolesPicker'; -export { default as GenericGrantAccessDialog } from './GenericGrantAccessDialog'; -export { default as ManagePermissionsDialog } from './ManagePermissionsDialog'; export { default as PrincipalAvatar } from './PrincipalAvatar'; +export { default as AccessRolesPicker } from './AccessRolesPicker'; export { default as PublicSharingToggle } from './PublicSharingToggle'; +export { default as GenericGrantAccessDialog } from './GenericGrantAccessDialog'; diff --git a/client/src/components/SidePanel/Agents/AdminSettings.tsx b/client/src/components/SidePanel/Agents/AdminSettings.tsx index 39990f773a..71fce3bede 100644 --- a/client/src/components/SidePanel/Agents/AdminSettings.tsx +++ b/client/src/components/SidePanel/Agents/AdminSettings.tsx @@ -114,7 +114,7 @@ const AdminSettings = () => { const labelControllerData = [ { agentPerm: Permissions.SHARED_GLOBAL, - label: localize('com_ui_agents_allow_share_global'), + label: localize('com_ui_agents_allow_share'), }, { agentPerm: Permissions.CREATE, diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json index e96436879d..54fbd3e756 100644 --- a/client/src/locales/en/translation.json +++ b/client/src/locales/en/translation.json @@ -586,7 +586,7 @@ "com_ui_agent_version_unknown_date": "Unknown date", "com_ui_agents": "Agents", "com_ui_agents_allow_create": "Allow creating Agents", - "com_ui_agents_allow_share_global": "Allow sharing Agents to all users", + "com_ui_agents_allow_share": "Allow sharing Agents", "com_ui_agents_allow_use": "Allow using Agents", "com_ui_people_picker": "People Picker", "com_ui_people_picker_allow_view_users": "Allow viewing users", @@ -981,7 +981,7 @@ "com_ui_prompt_update_error": "There was an error updating the prompt", "com_ui_prompts": "Prompts", "com_ui_prompts_allow_create": "Allow creating Prompts", - "com_ui_prompts_allow_share_global": "Allow sharing Prompts to all users", + "com_ui_prompts_allow_share": "Allow sharing Prompts", "com_ui_prompts_allow_use": "Allow using Prompts", "com_ui_provider": "Provider", "com_ui_quality": "Quality", @@ -1167,6 +1167,7 @@ "com_ui_select_options": "Select options...", "com_ui_no_results_found": "No results found", "com_ui_try_adjusting_search": "Try adjusting your search terms", + "com_ui_resource": "resource", "com_ui_role_viewer": "Viewer", "com_ui_role_editor": "Editor", "com_ui_role_manager": "Manager", @@ -1189,11 +1190,11 @@ "com_ui_loading_permissions": "Loading permissions...", "com_ui_user_group_permissions": "User & Group Permissions", "com_ui_no_individual_access": "No individual users or groups have access to this agent", - "com_ui_public_access": "Public Access", - "com_ui_public_access_description": "Anyone can access this resource publicly", + "com_ui_share_everyone": "Share with everyone", + "com_ui_share_everyone_description_var": "This {{resource}} will be available to everyone. Please make sure the {{resource}} is really meant to be shared with everyone. Be careful with your data.", "com_ui_save_changes": "Save Changes", "com_ui_unsaved_changes": "You have unsaved changes", - "com_ui_public_permission_level": "Public permission level", + "com_ui_everyone_permission_level": "Everyone's permission level", "com_ui_at_least_one_owner_required": "At least one owner is required", "com_agents_marketplace": "Agent Marketplace", "com_agents_all": "All Agents",