diff options
Diffstat (limited to 'lib/users/table/assign-roles-dialog.tsx')
| -rw-r--r-- | lib/users/table/assign-roles-dialog.tsx | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/lib/users/table/assign-roles-dialog.tsx b/lib/users/table/assign-roles-dialog.tsx new file mode 100644 index 00000000..003f6500 --- /dev/null +++ b/lib/users/table/assign-roles-dialog.tsx @@ -0,0 +1,194 @@ +import * as React from "react" +import { useForm } from "react-hook-form" +import { zodResolver } from "@hookform/resolvers/zod" +import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { Check, ChevronsUpDown, Loader, UserRoundPlus } from "lucide-react" +import { cn } from "@/lib/utils" +import { toast } from "sonner" + +import { Textarea } from "@/components/ui/textarea" +import { Company } from "@/db/schema/companies" +import { getAllCompanies } from "@/lib/admin-users/service" +import { + Popover, + PopoverTrigger, + PopoverContent, +} from "@/components/ui/popover" +import { + Command, + CommandInput, + CommandList, + CommandGroup, + CommandItem, + CommandEmpty, +} from "@/components/ui/command" +import { assignRolesToUsers, getAllRoleView } from "@/lib/roles/services" +import { RoleView } from "@/db/schema/users" +import { type UserView } from "@/db/schema/users" +import { type Row } from "@tanstack/react-table" +import { createRoleAssignmentSchema, CreateRoleAssignmentSchema, createRoleSchema, CreateRoleSchema } from "@/lib/roles/validations" +import { MultiSelect } from "@/components/ui/multi-select" + +interface AssignRoleDialogProps + extends React.ComponentPropsWithoutRef<typeof Dialog> { + users: Row<UserView>["original"][] + +} + + +export function AssignRoleDialog({ users }: AssignRoleDialogProps) { + const [open, setOpen] = React.useState(false) + const [isAddPending, startAddTransition] = React.useTransition() + const [roles, setRoles] = React.useState<RoleView[]>([]) // 회사 목록 + const [loading, setLoading] = React.useState(false) + + const partnersRoles = roles.filter(v => v.domain === "partners") + const evcpRoles = roles.filter(v => v.domain === "evcp") + + + React.useEffect(() => { + getAllRoleView("evcp").then((res) => { + setRoles(res) + }) + }, []) + + + const form = useForm<CreateRoleAssignmentSchema>({ + resolver: zodResolver(createRoleAssignmentSchema), + defaultValues: { + evcpRoles: [], + }, + }) + + + function handleDialogOpenChange(nextOpen: boolean) { + if (!nextOpen) { + form.reset() + } + setOpen(nextOpen) + } + + const evcpUsers = users.filter(v => v.user_domain === "evcp"); + + + async function onSubmit(data: CreateRoleAssignmentSchema) { + console.log(data.evcpRoles.map((v)=>Number(v))) + startAddTransition(async () => { + + + // if(partnerUsers.length>0){ + // const result = await assignRolesToUsers( partnerUsers.map(v=>v.user_id) ,data.partnersRoles) + + // if (result.error) { + // toast.error(`에러: ${result.error}`) + // return + // } + // } + + if (evcpUsers.length > 0) { + const result = await assignRolesToUsers( data.evcpRoles.map((v)=>Number(v)), evcpUsers.map(v => v.user_id)) + + if (result.error) { + toast.error(`에러: ${result.error}`) + return + } + } + + form.reset() + setOpen(false) + toast.success("Role assgined") + }) + } + + return ( + <Dialog open={open} onOpenChange={handleDialogOpenChange}> + <DialogTrigger asChild> + <Button variant="default" size="sm"> + <UserRoundPlus className="mr-2 size-4" aria-hidden="true" /> + Assign Role ({users.length}) + </Button> + </DialogTrigger> + + <DialogContent> + <DialogHeader> + <DialogTitle>Assign Roles to {evcpUsers.length} Users</DialogTitle> + <DialogDescription> + Role을 Multi-select 하시기 바랍니다. + </DialogDescription> + </DialogHeader> + + + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)}> + <div className="space-y-4 py-4"> + {/* evcp 롤 선택 */} + {evcpUsers.length > 0 && + <FormField + control={form.control} + name="evcpRoles" + render={({ field }) => ( + <FormItem> + <FormLabel>eVCP Role</FormLabel> + <FormControl> + <MultiSelect + options={evcpRoles.map((role) => ({ value: String(role.id), label: role.name }))} + onValueChange={(values) => { + field.onChange(values); + }} + + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + } + </div> + + <DialogFooter> + <Button + type="button" + variant="outline" + onClick={() => setOpen(false)} + disabled={isAddPending} + > + Cancel + </Button> + <Button + type="submit" + disabled={form.formState.isSubmitting || isAddPending} + > + {isAddPending && ( + <Loader + className="mr-2 size-4 animate-spin" + aria-hidden="true" + /> + )} + Assgin + </Button> + </DialogFooter> + </form> + </Form> + </DialogContent> + </Dialog> + ) +}
\ No newline at end of file |
