hermes-web/components/elements/group-permission.tsx

211 lines
7.8 KiB
TypeScript

import axios from "axios";
import { useEffect, useState } from "react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Label } from "../ui/label";
import { HelpCircleIcon, Trash2Icon } from "lucide-react";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "../ui/tooltip"
import { Checkbox } from "../ui/checkbox";
interface Permission {
id: string|undefined
path: string
allow: boolean|null
groupId: string
edit: boolean
showEdit: boolean
isNew: boolean
permissionPaths: { path: string, description: string }[]
adder: (id: string, path: string, allow: boolean|null) => void
remover: (redemption: { id: string, path: string, allow: boolean|null }) => void
}
const GroupPermission = ({
id,
path,
allow,
groupId,
edit,
showEdit,
isNew,
permissionPaths,
adder,
remover
}: Permission) => {
const [pathOpen, setPathOpen] = useState(false)
const [isEditable, setIsEditable] = useState(edit)
const [oldData, setOldData] = useState<{ path: string, allow: boolean|null } | undefined>(undefined)
const [permission, setPermission] = useState<{ id: string|undefined, path: string, allow: boolean|null }>({ id, path, allow });
function Save() {
if (!permission || !permission.path)
return
if (isNew) {
axios.post("/api/settings/groups/permissions", {
path: permission.path,
allow: permission.allow,
groupId: groupId
}).then(d => {
if (!d || !d.data)
return
adder(d.data.id, permission.path, permission.allow)
setPermission({ id: undefined, path: "", allow: true })
})
} else {
axios.put("/api/settings/groups/permissions", {
id: permission.id,
path: permission.path,
allow: permission.allow
}).then(d => {
setIsEditable(false)
})
}
}
function Cancel() {
if (!oldData)
return
setPermission({ ...oldData, id: permission.id })
setIsEditable(false)
setOldData(undefined)
}
function Delete() {
axios.delete("/api/settings/groups/permissions?id=" + permission.id)
.then(d => {
remover(d.data)
})
}
return (
<div
className="bg-green-400 p-2 border-2 border-green-500 rounded-lg grid grid-flow-row">
<div
className="pb-3 flex grow">
{!isEditable &&
<Input
className="flex grow ml-1"
id="path"
value={permission.path}
readOnly />
|| isEditable &&
<Popover
open={pathOpen}
onOpenChange={setPathOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
id="path"
role="combobox"
className="flex grow justify-between"
>{!permission.path ? "Select a permission" : permission.path}</Button>
</PopoverTrigger>
<PopoverContent>
<Command>
<CommandInput
placeholder="Search..."
inputMode="search"
autoFocus={true} />
<CommandList>
<CommandEmpty>No permission found.</CommandEmpty>
<CommandGroup>
{permissionPaths.map((p) => (
<CommandItem
value={p.path}
key={p.path}
onSelect={(value) => {
setPermission({ ...permission, path: permissionPaths.find(v => v.path.toLowerCase() == value.toLowerCase())?.path ?? value.toLowerCase()})
setPathOpen(false)
}}>
<div>
<div className="text-lg">
{p.path}
</div>
<div className="text-xs text-green-200">
{p.description}
</div>
</div>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
}
</div>
<div
className="grid grid-cols-2 gap-1">
<Label>
Inherit from parent
</Label>
<Checkbox
checked={permission.allow === null}
onCheckedChange={(e) => {
if (permission.allow === null)
setPermission({ ...permission, allow: false })
else
setPermission({ ...permission, allow: null })
}}
disabled={!isEditable} />
<Label
htmlFor="inherit">
Allow
</Label>
<Checkbox
id="inherit"
checked={permission.allow === true}
onCheckedChange={(e) => {
setPermission({ ...permission, allow: !permission.allow })
}}
disabled={!isEditable || permission === undefined} />
</div>
<div>
{isEditable &&
<Button
className="m-3"
onClick={() => Save()}>
{isNew ? "Add" : "Save"}
</Button>
}
{isEditable && !isNew &&
<Button
className="m-3"
onClick={() => Cancel()}>
Cancel
</Button>
}
{showEdit && !isEditable &&
<Button
className="m-3"
onClick={() => {
setOldData({ ...permission })
setIsEditable(true)
}}>
Edit
</Button>
}
{!isEditable &&
<Button
className="m-3 bg-red-500 hover:bg-red-600 align-bottom"
onClick={() => Delete()}>
<Trash2Icon />
</Button>
}
</div>
</div>
);
}
export default GroupPermission;