import React, { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { useTranslation } from "react-i18next"; import { Shield } from "lucide-react"; interface FileItem { name: string; type: "file" | "directory" | "link"; path: string; permissions?: string; owner?: string; group?: string; } interface PermissionsDialogProps { file: FileItem | null; open: boolean; onOpenChange: (open: boolean) => void; onSave: (file: FileItem, permissions: string) => Promise; } // Parse permissions like "rwxr-xr-x" or "755" to individual bits const parsePermissions = ( perms: string, ): { owner: number; group: number; other: number } => { if (!perms) { return { owner: 0, group: 0, other: 0 }; } // If numeric format like "755" if (/^\d{3,4}$/.test(perms)) { const numStr = perms.slice(-3); return { owner: parseInt(numStr[0] || "0", 10), group: parseInt(numStr[1] || "0", 10), other: parseInt(numStr[2] || "0", 10), }; } // If symbolic format like "rwxr-xr-x" or "-rwxr-xr-x" const cleanPerms = perms.replace(/^-/, "").substring(0, 9); const calcBits = (str: string): number => { let value = 0; if (str[0] === "r") value += 4; if (str[1] === "w") value += 2; if (str[2] === "x") value += 1; return value; }; return { owner: calcBits(cleanPerms.substring(0, 3)), group: calcBits(cleanPerms.substring(3, 6)), other: calcBits(cleanPerms.substring(6, 9)), }; }; // Convert individual bits to numeric format const toNumeric = (owner: number, group: number, other: number): string => { return `${owner}${group}${other}`; }; export function PermissionsDialog({ file, open, onOpenChange, onSave, }: PermissionsDialogProps) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); const initialPerms = parsePermissions(file?.permissions || "644"); const [ownerRead, setOwnerRead] = useState((initialPerms.owner & 4) !== 0); const [ownerWrite, setOwnerWrite] = useState((initialPerms.owner & 2) !== 0); const [ownerExecute, setOwnerExecute] = useState( (initialPerms.owner & 1) !== 0, ); const [groupRead, setGroupRead] = useState((initialPerms.group & 4) !== 0); const [groupWrite, setGroupWrite] = useState((initialPerms.group & 2) !== 0); const [groupExecute, setGroupExecute] = useState( (initialPerms.group & 1) !== 0, ); const [otherRead, setOtherRead] = useState((initialPerms.other & 4) !== 0); const [otherWrite, setOtherWrite] = useState((initialPerms.other & 2) !== 0); const [otherExecute, setOtherExecute] = useState( (initialPerms.other & 1) !== 0, ); // Reset when file changes useEffect(() => { if (file) { const perms = parsePermissions(file.permissions || "644"); setOwnerRead((perms.owner & 4) !== 0); setOwnerWrite((perms.owner & 2) !== 0); setOwnerExecute((perms.owner & 1) !== 0); setGroupRead((perms.group & 4) !== 0); setGroupWrite((perms.group & 2) !== 0); setGroupExecute((perms.group & 1) !== 0); setOtherRead((perms.other & 4) !== 0); setOtherWrite((perms.other & 2) !== 0); setOtherExecute((perms.other & 1) !== 0); } }, [file]); const calculateOctal = (): string => { const owner = (ownerRead ? 4 : 0) + (ownerWrite ? 2 : 0) + (ownerExecute ? 1 : 0); const group = (groupRead ? 4 : 0) + (groupWrite ? 2 : 0) + (groupExecute ? 1 : 0); const other = (otherRead ? 4 : 0) + (otherWrite ? 2 : 0) + (otherExecute ? 1 : 0); return toNumeric(owner, group, other); }; const handleSave = async () => { if (!file) return; setLoading(true); try { const permissions = calculateOctal(); await onSave(file, permissions); onOpenChange(false); } catch (error) { console.error("Failed to update permissions:", error); } finally { setLoading(false); } }; if (!file) return null; const octal = calculateOctal(); return ( {t("fileManager.changePermissions")} {t("fileManager.changePermissionsDesc")}:{" "} {file.name}
{/* Current info */}

{file.permissions || "644"}

{octal}

{/* Owner permissions */}
setOwnerRead(checked === true)} />
setOwnerWrite(checked === true)} />
setOwnerExecute(checked === true) } />
{/* Group permissions */}
setGroupRead(checked === true)} />
setGroupWrite(checked === true)} />
setGroupExecute(checked === true) } />
{/* Others permissions */}
setOtherRead(checked === true)} />
setOtherWrite(checked === true)} />
setOtherExecute(checked === true) } />
); }