import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { KeyRound, ShieldCheck } from 'lucide-react'; import { useAccessKeys, useGrantBucketPermission } from '@/hooks/useApi'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Select, SelectOption } from '@/components/ui/select'; import { EmptyState } from '@/components/ui/empty-state'; import { Badge } from '@/components/ui/badge'; import { toast } from 'sonner'; export function BucketPermissions() { const { bucketName = '' } = useParams<{ bucketName: string }>(); const { data: availableKeys = [] } = useAccessKeys(); const grant = useGrantBucketPermission(); const [selectedKey, setSelectedKey] = useState(''); const [read, setRead] = useState(false); const [write, setWrite] = useState(false); const [owner, setOwner] = useState(false); useEffect(() => { if (!selectedKey) { setRead(false); setWrite(false); setOwner(false); return; } const key = availableKeys.find((k) => k.accessKeyId === selectedKey); const existing = key?.permissions.find( (p) => p.bucketName === bucketName || p.bucketId === bucketName, ); setRead(existing?.read ?? false); setWrite(existing?.write ?? false); setOwner(existing?.owner ?? false); }, [selectedKey, availableKeys, bucketName]); const canSubmit = !!selectedKey && (read || write || owner) && !grant.isPending; const onGrant = async () => { if (!selectedKey) { toast.error('Please select an access key'); return; } if (!read && !write && !owner) { toast.error('Please select at least one permission'); return; } try { await grant.mutateAsync({ bucketName, accessKeyId: selectedKey, permissions: { read, write, owner }, }); setSelectedKey(''); setRead(false); setWrite(false); setOwner(false); } catch { // error toast handled by axios interceptor } }; const granted = availableKeys .map((k) => ({ key: k, perm: k.permissions.find( (p) => p.bucketName === bucketName || p.bucketId === bucketName, ), })) .filter((x) => !!x.perm); return (

Grant access

Choose which access key should have permissions on this bucket. Current permissions pre-fill below.

Permissions

Granted

{granted.length === 0 ? (
} tone="neutral" title="No access granted" description="Grant at least one access key to make this bucket usable." />
) : ( )}
); } function PermRow({ id, checked, onChange, title, description, }: { id: string; checked: boolean; onChange: (v: boolean) => void; title: string; description: string; }) { return (
onChange(c as boolean)} />

{description}

); }