summaryrefslogtreecommitdiff
path: root/lib/users
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-07-15 10:07:09 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-07-15 10:07:09 +0000
commit4eb7532f822c821fb6b69bf103bd075fefba769b (patch)
treeb4bcf6c0bf791d71569f3f35498ed256bf7cfaf3 /lib/users
parent660c7888d885badab7af3e96f9c16bd0172ad0f1 (diff)
(대표님) 20250715 협력사 정기평가, spreadJS, roles 서비스에 함수 추가
Diffstat (limited to 'lib/users')
-rw-r--r--lib/users/service.ts147
-rw-r--r--lib/users/table/assign-roles-dialog.tsx353
-rw-r--r--lib/users/table/users-table-toolbar-actions.tsx6
-rw-r--r--lib/users/table/users-table.tsx5
4 files changed, 448 insertions, 63 deletions
diff --git a/lib/users/service.ts b/lib/users/service.ts
index e32d450e..7a635113 100644
--- a/lib/users/service.ts
+++ b/lib/users/service.ts
@@ -560,12 +560,112 @@ export async function getUsersAllbyVendor(input: GetUsersSchema, domain: string)
}
export async function assignUsersToRole(roleId: number, userIds: number[]) {
- unstable_noStore(); // 캐싱 방지(Next.js 서버 액션용)
- try{
+ unstable_noStore() // 캐싱 방지(Next.js 서버 액션용)
+
+ try {
+ if (userIds.length === 0) {
+ return { data: null, error: "선택된 사용자가 없습니다." }
+ }
+
+ await db.transaction(async (tx) => {
+ // 1) 이미 할당된 사용자들 확인
+ const existingAssignments = await tx
+ .select({ userId: userRoles.userId })
+ .from(userRoles)
+ .where(
+ and(
+ eq(userRoles.roleId, roleId),
+ inArray(userRoles.userId, userIds)
+ )
+ )
+
+ const existingUserIds = existingAssignments.map(item => item.userId)
+
+ // 2) 새로 할당할 사용자들만 필터링
+ const newUserIds = userIds.filter(uid => !existingUserIds.includes(uid))
+
+ // 3) 새로운 할당만 추가
+ if (newUserIds.length > 0) {
+ await tx.insert(userRoles).values(
+ newUserIds.map((uid) => ({
+ userId: uid,
+ roleId: roleId
+ }))
+ )
+ }
+ })
+
+ revalidateTag("users")
+ revalidateTag("roles")
+
+ return {
+ data: {
+ assignedCount: userIds.length,
+ message: `${userIds.length}명의 사용자가 성공적으로 할당되었습니다.`
+ },
+ error: null
+ }
+ } catch (err) {
+ return {
+ data: null,
+ error: getErrorMessage(err)
+ }
+ }
+}
+
+/**
+ * 특정 롤에서 사용자들을 제거합니다
+ */
+export async function removeUsersFromRole(roleId: number, userIds: number[]) {
+ unstable_noStore() // 캐싱 방지(Next.js 서버 액션용)
+
+ try {
+ if (userIds.length === 0) {
+ return { data: null, error: "선택된 사용자가 없습니다." }
+ }
+
+ await db.transaction(async (tx) => {
+ // 해당 롤에서 특정 사용자들만 삭제
+ await tx
+ .delete(userRoles)
+ .where(
+ and(
+ eq(userRoles.roleId, roleId),
+ inArray(userRoles.userId, userIds)
+ )
+ )
+ })
+
+ revalidateTag("users")
+ revalidateTag("roles")
+
+ return {
+ data: {
+ removedCount: userIds.length,
+ message: `${userIds.length}명의 사용자가 성공적으로 제거되었습니다.`
+ },
+ error: null
+ }
+ } catch (err) {
+ return {
+ data: null,
+ error: getErrorMessage(err)
+ }
+ }
+}
+
+/**
+ * 롤의 모든 사용자 할당을 재설정합니다 (기존 함수와 동일)
+ * 기존 할당을 모두 삭제하고 새로운 할당으로 교체합니다
+ */
+export async function replaceRoleAssignments(roleId: number, userIds: number[]) {
+ unstable_noStore() // 캐싱 방지(Next.js 서버 액션용)
+
+ try {
await db.transaction(async (tx) => {
// 1) 기존 userRoles 레코드 삭제
await tx.delete(userRoles).where(eq(userRoles.roleId, roleId))
-
+
// 2) 새로 넣기
if (userIds.length > 0) {
await tx.insert(userRoles).values(
@@ -573,15 +673,41 @@ export async function assignUsersToRole(roleId: number, userIds: number[]) {
)
}
})
- revalidateTag("users");
- revalidateTag("roles");
-
- return { data: null, error: null };
- } catch (err){
- return { data: null, error: getErrorMessage(err) };
-
+
+ revalidateTag("users")
+ revalidateTag("roles")
+
+ return { data: null, error: null }
+ } catch (err) {
+ return { data: null, error: getErrorMessage(err) }
}
+}
+/**
+ * 특정 롤에 할당된 사용자 목록을 가져옵니다
+ */
+export async function getUsersAssignedToRole(roleId: number) {
+ unstable_noStore()
+
+ try {
+ const assignedUsers = await db
+ .select({
+ userId: userRoles.userId,
+ // 필요한 다른 사용자 정보들도 join해서 가져올 수 있습니다
+ })
+ .from(userRoles)
+ .where(eq(userRoles.roleId, roleId))
+
+ return {
+ data: assignedUsers.map(u => u.userId),
+ error: null
+ }
+ } catch (err) {
+ return {
+ data: [],
+ error: getErrorMessage(err)
+ }
+ }
}
@@ -767,3 +893,4 @@ export async function getUserRoles(userId: number): Promise<string[]> {
return []
}
}
+
diff --git a/lib/users/table/assign-roles-dialog.tsx b/lib/users/table/assign-roles-dialog.tsx
index 003f6500..7bc7e138 100644
--- a/lib/users/table/assign-roles-dialog.tsx
+++ b/lib/users/table/assign-roles-dialog.tsx
@@ -21,9 +21,11 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
-import { Check, ChevronsUpDown, Loader, UserRoundPlus } from "lucide-react"
+import { Check, ChevronsUpDown, Loader, UserRoundPlus, AlertTriangle, Users, UserMinus } from "lucide-react"
import { cn } from "@/lib/utils"
import { toast } from "sonner"
+import { Alert, AlertDescription } from "@/components/ui/alert"
+import { Badge } from "@/components/ui/badge"
import { Textarea } from "@/components/ui/textarea"
import { Company } from "@/db/schema/companies"
@@ -41,8 +43,8 @@ import {
CommandItem,
CommandEmpty,
} from "@/components/ui/command"
-import { assignRolesToUsers, getAllRoleView } from "@/lib/roles/services"
-import { RoleView } from "@/db/schema/users"
+import { assignRolesToUsers, getAllRoleView, checkMultipleRegularEvaluationRolesAssigned } from "@/lib/roles/services"
+import { Role, 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"
@@ -51,26 +53,81 @@ import { MultiSelect } from "@/components/ui/multi-select"
interface AssignRoleDialogProps
extends React.ComponentPropsWithoutRef<typeof Dialog> {
users: Row<UserView>["original"][]
-
+ roles: RoleView[]
}
+// 역할 상태 타입 정의
+type RoleAssignmentStatus = 'all' | 'some' | 'none'
+
+interface RoleAnalysis {
+ roleId: string
+ roleName: string
+ status: RoleAssignmentStatus
+ assignedUserCount: number
+ totalUserCount: number
+}
-export function AssignRoleDialog({ users }: AssignRoleDialogProps) {
+export function AssignRoleDialog({ users, roles }: 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 [regularEvaluationAssigned, setRegularEvaluationAssigned] = React.useState<{[roleId: string]: boolean}>({})
+ const [isCheckingRegularEvaluation, setIsCheckingRegularEvaluation] = React.useState(false)
- const partnersRoles = roles.filter(v => v.domain === "partners")
- const evcpRoles = roles.filter(v => v.domain === "evcp")
+ // 메모이제이션된 필터링된 역할들
+ const partnersRoles = React.useMemo(() =>
+ roles.filter(v => v.domain === "partners"), [roles])
+
+ const evcpRoles = React.useMemo(() =>
+ roles.filter(v => v.domain === "evcp"), [roles])
+ // 메모이제이션된 evcp 사용자들
+ const evcpUsers = React.useMemo(() =>
+ users.filter(v => v.user_domain === "evcp"), [users])
- React.useEffect(() => {
- getAllRoleView("evcp").then((res) => {
- setRoles(res)
+ // 선택된 사용자들의 역할 분석
+ const roleAnalysis = React.useMemo((): RoleAnalysis[] => {
+ if (evcpUsers.length === 0) return []
+
+ const analysis = evcpRoles.map(role => {
+ const assignedUsers = evcpUsers.filter(user =>
+ user.roles && user.roles.includes(role.name)
+ )
+
+ const assignedUserCount = assignedUsers.length
+ const totalUserCount = evcpUsers.length
+
+ let status: RoleAssignmentStatus
+ if (assignedUserCount === totalUserCount) {
+ status = 'all'
+ } else if (assignedUserCount > 0) {
+ status = 'some'
+ } else {
+ status = 'none'
+ }
+
+ return {
+ roleId: String(role.id),
+ roleName: role.name,
+ status,
+ assignedUserCount,
+ totalUserCount
+ }
})
- }, [])
+ console.log('Role analysis:', analysis)
+ return analysis
+ }, [evcpUsers, evcpRoles])
+
+ // 초기 선택된 역할들 (모든 사용자에게 할당된 역할들 + 일부에게 할당된 역할들)
+ const initialSelectedRoles = React.useMemo(() => {
+ const selected = roleAnalysis
+ .filter(analysis => analysis.status === 'all' || analysis.status === 'some')
+ .map(analysis => analysis.roleId)
+
+ console.log('Initial selected roles:', selected)
+ return selected
+ }, [roleAnalysis])
const form = useForm<CreateRoleAssignmentSchema>({
resolver: zodResolver(createRoleAssignmentSchema),
@@ -79,89 +136,280 @@ export function AssignRoleDialog({ users }: AssignRoleDialogProps) {
},
})
-
- function handleDialogOpenChange(nextOpen: boolean) {
+ const handleDialogOpenChange = React.useCallback((nextOpen: boolean) => {
if (!nextOpen) {
- form.reset()
+ // 다이얼로그가 닫힐 때 리셋
+ form.reset({
+ evcpRoles: [],
+ })
+ setRegularEvaluationAssigned({})
}
setOpen(nextOpen)
- }
+ }, [form])
- const evcpUsers = users.filter(v => v.user_domain === "evcp");
+ // 선택된 evcpRoles 감시 - 메모이제이션
+ const selectedEvcpRoles = form.watch("evcpRoles")
+ const memoizedSelectedEvcpRoles = React.useMemo(() =>
+ selectedEvcpRoles || [], [selectedEvcpRoles])
+ // 정기평가 role들 찾기 - 의존성 수정
+ const selectedRegularEvaluationRoles = React.useMemo(() => {
+ return memoizedSelectedEvcpRoles.filter(roleId => {
+ const role = evcpRoles.find(r => String(r.id) === roleId)
+ return role && role.name.includes("정기평가")
+ })
+ }, [memoizedSelectedEvcpRoles, evcpRoles])
- async function onSubmit(data: CreateRoleAssignmentSchema) {
- console.log(data.evcpRoles.map((v)=>Number(v)))
- startAddTransition(async () => {
+ // 정기평가 role 할당 상태 체크 (debounced)
+ React.useEffect(() => {
+ if (selectedRegularEvaluationRoles.length === 0) {
+ setRegularEvaluationAssigned({})
+ return
+ }
+
+ const timeoutId = setTimeout(async () => {
+ setIsCheckingRegularEvaluation(true)
+ try {
+ const roleIds = selectedRegularEvaluationRoles.map(roleId => Number(roleId))
+ const assignmentStatus = await checkMultipleRegularEvaluationRolesAssigned(roleIds)
+
+ const stringKeyStatus: {[roleId: string]: boolean} = {}
+ Object.entries(assignmentStatus).forEach(([roleId, isAssigned]) => {
+ stringKeyStatus[roleId] = isAssigned
+ })
+
+ setRegularEvaluationAssigned(stringKeyStatus)
+ } catch (error) {
+ console.error("정기평가 role 할당 상태 체크 실패:", error)
+ toast.error("정기평가 role 상태 확인에 실패했습니다")
+ } finally {
+ setIsCheckingRegularEvaluation(false)
+ }
+ }, 500)
+ return () => clearTimeout(timeoutId)
+ }, [selectedRegularEvaluationRoles])
- // if(partnerUsers.length>0){
- // const result = await assignRolesToUsers( partnerUsers.map(v=>v.user_id) ,data.partnersRoles)
+ // 할당 불가능한 정기평가 role 확인
+ const blockedRegularEvaluationRoles = React.useMemo(() => {
+ return selectedRegularEvaluationRoles.filter(roleId =>
+ regularEvaluationAssigned[roleId] === true
+ )
+ }, [selectedRegularEvaluationRoles, regularEvaluationAssigned])
- // if (result.error) {
- // toast.error(`에러: ${result.error}`)
- // return
- // }
- // }
+ // 제출 가능 여부
+ const canSubmit = React.useMemo(() =>
+ blockedRegularEvaluationRoles.length === 0, [blockedRegularEvaluationRoles])
- if (evcpUsers.length > 0) {
- const result = await assignRolesToUsers( data.evcpRoles.map((v)=>Number(v)), evcpUsers.map(v => v.user_id))
+ // MultiSelect options 메모이제이션 - 상태 정보와 함께 표시
+ const multiSelectOptions = React.useMemo(() => {
+ return evcpRoles.map((role) => {
+ const analysis = roleAnalysis.find(a => a.roleId === String(role.id))
+
+ let statusSuffix = ''
+ if (analysis) {
+ if (analysis.status === 'all') {
+ statusSuffix = ` (모든 사용자 ${analysis.assignedUserCount}/${analysis.totalUserCount})`
+ } else if (analysis.status === 'some') {
+ statusSuffix = ` (일부 사용자 ${analysis.assignedUserCount}/${analysis.totalUserCount})`
+ }
+ }
+
+ return {
+ value: String(role.id),
+ label: role.name + statusSuffix,
+ disabled: role.name.includes("정기평가") && regularEvaluationAssigned[String(role.id)] === true
+ }
+ })
+ }, [evcpRoles, roleAnalysis, regularEvaluationAssigned])
+ const onSubmit = React.useCallback(async (data: CreateRoleAssignmentSchema) => {
+ startAddTransition(async () => {
+ if (evcpUsers.length === 0) return
+
+ try {
+ const selectedRoleIds = data.evcpRoles.map(v => Number(v))
+ const userIds = evcpUsers.map(v => v.user_id)
+
+ // assignRolesToUsers는 이미 기존 관계를 삭제하고 새로 삽입하므로
+ // 최종 선택된 역할들만 전달하면 됩니다
+ const result = await assignRolesToUsers(selectedRoleIds, userIds)
+
if (result.error) {
- toast.error(`에러: ${result.error}`)
+ toast.error(`역할 업데이트 실패: ${result.error}`)
return
}
- }
- form.reset()
- setOpen(false)
- toast.success("Role assgined")
+ form.reset()
+ setOpen(false)
+ setRegularEvaluationAssigned({})
+
+ // 변경사항 계산해서 피드백
+ const initialRoleIds = initialSelectedRoles.map(v => Number(v))
+ const addedRoles = selectedRoleIds.filter(roleId => !initialRoleIds.includes(roleId))
+ const removedRoles = initialRoleIds.filter(roleId => !selectedRoleIds.includes(roleId))
+
+ if (addedRoles.length > 0 && removedRoles.length > 0) {
+ toast.success(`역할이 성공적으로 업데이트되었습니다 (추가: ${addedRoles.length}, 제거: ${removedRoles.length})`)
+ } else if (addedRoles.length > 0) {
+ toast.success(`${addedRoles.length}개 역할이 성공적으로 추가되었습니다`)
+ } else if (removedRoles.length > 0) {
+ toast.success(`${removedRoles.length}개 역할이 성공적으로 제거되었습니다`)
+ } else {
+ toast.info("변경사항이 없습니다")
+ }
+ } catch (error) {
+ console.error("역할 업데이트 실패:", error)
+ toast.error("역할 업데이트에 실패했습니다")
+ }
})
- }
+ }, [evcpUsers, form, initialSelectedRoles])
+
+ // 정기평가 role 관련 경고 메시지 생성
+ const regularEvaluationWarning = React.useMemo(() => {
+ if (selectedRegularEvaluationRoles.length === 0) return null
+
+ if (isCheckingRegularEvaluation) {
+ return (
+ <Alert key="checking">
+ <Loader className="h-4 w-4 animate-spin" />
+ <AlertDescription>
+ 정기평가 role 할당 상태를 확인하고 있습니다...
+ </AlertDescription>
+ </Alert>
+ )
+ }
+
+ if (blockedRegularEvaluationRoles.length > 0) {
+ const blockedRoleNames = blockedRegularEvaluationRoles.map(roleId => {
+ const role = evcpRoles.find(r => String(r.id) === roleId)
+ return role?.name || roleId
+ })
+
+ return (
+ <Alert key="blocked" variant="destructive">
+ <AlertTriangle className="h-4 w-4" />
+ <AlertDescription>
+ <strong>할당 불가:</strong> 다음 정기평가 role이 이미 다른 유저에게 할당되어 있습니다:
+ <br />
+ <strong>{blockedRoleNames.join(", ")}</strong>
+ <br />
+ 정기평가 role은 한 명의 유저에게만 할당할 수 있습니다.
+ </AlertDescription>
+ </Alert>
+ )
+ }
+
+ if (selectedRegularEvaluationRoles.length > 0) {
+ const availableRoleNames = selectedRegularEvaluationRoles.map(roleId => {
+ const role = evcpRoles.find(r => String(r.id) === roleId)
+ return role?.name || roleId
+ })
+
+ return (
+ <Alert key="available">
+ <Check className="h-4 w-4" />
+ <AlertDescription>
+ 정기평가 role을 할당할 수 있습니다: <strong>{availableRoleNames.join(", ")}</strong>
+ </AlertDescription>
+ </Alert>
+ )
+ }
+
+ return null
+ }, [
+ selectedRegularEvaluationRoles,
+ isCheckingRegularEvaluation,
+ blockedRegularEvaluationRoles,
+ evcpRoles
+ ])
+
+ // 현재 역할 상태 요약
+ const roleStatusSummary = React.useMemo(() => {
+ const allRoles = roleAnalysis.filter(r => r.status === 'all').length
+ const someRoles = roleAnalysis.filter(r => r.status === 'some').length
+ const totalRoles = roleAnalysis.length
+
+ return { allRoles, someRoles, totalRoles }
+ }, [roleAnalysis])
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})
+ 역할 편집 ({users.length}명)
</Button>
</DialogTrigger>
- <DialogContent>
+ <DialogContent className="max-w-2xl">
<DialogHeader>
- <DialogTitle>Assign Roles to {evcpUsers.length} Users</DialogTitle>
- <DialogDescription>
- Role을 Multi-select 하시기 바랍니다.
+ <DialogTitle className="flex items-center gap-2">
+ <Users className="size-5" />
+ {evcpUsers.length}명 사용자의 역할 편집
+ </DialogTitle>
+ <DialogDescription className="space-y-2">
+ <div>선택된 사용자들의 역할을 편집할 수 있습니다. 기존 역할 상태가 표시됩니다.</div>
+ <div className="flex gap-2 text-sm">
+ <Badge variant="secondary">
+ 공통 역할: {roleStatusSummary.allRoles}개
+ </Badge>
+ <Badge variant="outline">
+ 일부 역할: {roleStatusSummary.someRoles}개
+ </Badge>
+ <Badge variant="secondary">
+ 전체 역할: {roleStatusSummary.totalRoles}개
+ </Badge>
+ </div>
</DialogDescription>
</DialogHeader>
-
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div className="space-y-4 py-4">
{/* evcp 롤 선택 */}
- {evcpUsers.length > 0 &&
+ {evcpUsers.length > 0 && (
<FormField
control={form.control}
name="evcpRoles"
render={({ field }) => (
<FormItem>
- <FormLabel>eVCP Role</FormLabel>
+ <FormLabel className="flex items-center gap-2">
+ eVCP 역할 선택
+ <span className="text-sm text-muted-foreground">
+ (체크: 할당됨, 해제: 제거됨)
+ </span>
+ </FormLabel>
<FormControl>
<MultiSelect
- options={evcpRoles.map((role) => ({ value: String(role.id), label: role.name }))}
+ key={`multiselect-${open}-${initialSelectedRoles.join(',')}`}
+ options={multiSelectOptions}
onValueChange={(values) => {
- field.onChange(values);
+ console.log('MultiSelect value changed:', values)
+ field.onChange(values)
}}
-
+ defaultValue={initialSelectedRoles}
/>
</FormControl>
<FormMessage />
+
+ {/* 역할 상태 설명 */}
+ <div className="text-sm text-muted-foreground space-y-1">
+ <div>• <strong>모든 사용자</strong>: 선택된 모든 사용자에게 할당된 역할</div>
+ <div>• <strong>일부 사용자</strong>: 일부 사용자에게만 할당된 역할</div>
+ <div>• 역할을 체크하면 모든 사용자에게 할당되고, 해제하면 모든 사용자에서 제거됩니다</div>
+ </div>
+
+ {/* 정기평가 관련 경고 메시지 */}
+ {regularEvaluationWarning && (
+ <div className="mt-2">
+ {regularEvaluationWarning}
+ </div>
+ )}
</FormItem>
)}
/>
- }
+ )}
</div>
<DialogFooter>
@@ -171,11 +419,16 @@ export function AssignRoleDialog({ users }: AssignRoleDialogProps) {
onClick={() => setOpen(false)}
disabled={isAddPending}
>
- Cancel
+ 취소
</Button>
<Button
type="submit"
- disabled={form.formState.isSubmitting || isAddPending}
+ disabled={
+ form.formState.isSubmitting ||
+ isAddPending ||
+ !canSubmit ||
+ isCheckingRegularEvaluation
+ }
>
{isAddPending && (
<Loader
@@ -183,7 +436,7 @@ export function AssignRoleDialog({ users }: AssignRoleDialogProps) {
aria-hidden="true"
/>
)}
- Assgin
+ 역할 업데이트
</Button>
</DialogFooter>
</form>
diff --git a/lib/users/table/users-table-toolbar-actions.tsx b/lib/users/table/users-table-toolbar-actions.tsx
index 106953a6..eef93546 100644
--- a/lib/users/table/users-table-toolbar-actions.tsx
+++ b/lib/users/table/users-table-toolbar-actions.tsx
@@ -10,15 +10,16 @@ import { Button } from "@/components/ui/button"
-import { UserView } from "@/db/schema/users"
+import { Role, RoleView, UserView } from "@/db/schema/users"
import { DeleteUsersDialog } from "@/lib/admin-users/table/delete-ausers-dialog"
import { AssignRoleDialog } from "./assign-roles-dialog"
interface UsersTableToolbarActionsProps {
table: Table<UserView>
+ roles: RoleView[]
}
-export function UsersTableToolbarActions({ table }: UsersTableToolbarActionsProps) {
+export function UsersTableToolbarActions({ table, roles }: UsersTableToolbarActionsProps) {
// 파일 input을 숨기고, 버튼 클릭 시 참조해 클릭하는 방식
const fileInputRef = React.useRef<HTMLInputElement>(null)
@@ -36,6 +37,7 @@ export function UsersTableToolbarActions({ table }: UsersTableToolbarActionsProp
users={table
.getFilteredSelectedRowModel()
.rows.map((row) => row.original)}
+ roles={roles}
/>
) : null}
diff --git a/lib/users/table/users-table.tsx b/lib/users/table/users-table.tsx
index 53cb961e..784c1e5d 100644
--- a/lib/users/table/users-table.tsx
+++ b/lib/users/table/users-table.tsx
@@ -39,6 +39,9 @@ export function UserTable({ promises }: UsersTableProps) {
React.use(promises)
+ console.log(roles,"user")
+
+
const [rowAction, setRowAction] =
React.useState<DataTableRowAction<UserView> | null>(null)
@@ -139,7 +142,7 @@ export function UserTable({ promises }: UsersTableProps) {
filterFields={advancedFilterFields}
shallow={false}
>
- <UsersTableToolbarActions table={table}/>
+ <UsersTableToolbarActions table={table} roles={roles}/>
</DataTableAdvancedToolbar>
</DataTable>