import { useState } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { useRoles, useGrantRevoke, useTablePrivileges, } from "@/hooks/use-management"; import { toast } from "sonner"; import { Loader2 } from "lucide-react"; import { Badge } from "@/components/ui/badge"; const PRIVILEGE_OPTIONS: Record = { TABLE: ["SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", "ALL"], SCHEMA: ["USAGE", "CREATE"], DATABASE: ["CONNECT", "CREATE", "TEMPORARY"], }; interface Props { open: boolean; onOpenChange: (open: boolean) => void; connectionId: string; objectType: string; objectName: string; schema?: string; table?: string; } export function GrantRevokeDialog({ open, onOpenChange, connectionId, objectType, objectName, schema, table, }: Props) { const [action, setAction] = useState("GRANT"); const [roleName, setRoleName] = useState(""); const [privileges, setPrivileges] = useState([]); const [withGrantOption, setWithGrantOption] = useState(false); const { data: roles } = useRoles(open ? connectionId : null); const { data: existingPrivileges } = useTablePrivileges( open && objectType === "TABLE" ? connectionId : null, schema ?? null, table ?? null ); const grantRevokeMutation = useGrantRevoke(); const [prevOpen, setPrevOpen] = useState(false); if (open !== prevOpen) { setPrevOpen(open); if (open) { setAction("GRANT"); setRoleName(""); setPrivileges([]); setWithGrantOption(false); } } const availablePrivileges = PRIVILEGE_OPTIONS[objectType.toUpperCase()] ?? PRIVILEGE_OPTIONS.TABLE; const togglePrivilege = (priv: string) => { setPrivileges((prev) => prev.includes(priv) ? prev.filter((p) => p !== priv) : [...prev, priv] ); }; const handleSubmit = () => { if (!roleName) { toast.error("Please select a role"); return; } if (privileges.length === 0) { toast.error("Please select at least one privilege"); return; } grantRevokeMutation.mutate( { connectionId, params: { action, privileges, object_type: objectType, object_name: objectName, role_name: roleName, with_grant_option: withGrantOption, }, }, { onSuccess: () => { toast.success( `${action === "GRANT" ? "Granted" : "Revoked"} privileges on ${objectName}` ); onOpenChange(false); }, onError: (err) => { toast.error("Operation failed", { description: String(err) }); }, } ); }; return ( Manage Privileges
{objectType}{" "} {objectName}
{availablePrivileges.map((priv) => ( ))}
{action === "GRANT" && (
)} {existingPrivileges && existingPrivileges.length > 0 && (
{existingPrivileges.map((p, i) => (
{p.grantee} {p.privilege_type} {p.is_grantable && ( GRANTABLE )}
))}
)}
); }