hazo_auth 4.5.2 → 4.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/user_management/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/user_management/index.tsx"],"names":[],"mappings":"AA2DA,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,kBAAkB,CAAC,EAAE,cAAc,EAAE,CAAC;CACvC,CAAC;AA+BF;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,YAAoB,EAAE,mBAA2B,EAAE,gBAAwB,EAAE,kBAAuB,EAAE,EAAE,yBAAyB,2CA+nDlL"}
|
|
@@ -20,7 +20,8 @@ import { ScopeHierarchyTab } from "./components/scope_hierarchy_tab";
|
|
|
20
20
|
import { ScopeLabelsTab } from "./components/scope_labels_tab";
|
|
21
21
|
import { UserScopesTab } from "./components/user_scopes_tab";
|
|
22
22
|
import { OrgHierarchyTab } from "./components/org_hierarchy_tab";
|
|
23
|
-
import { UserX, KeyRound, Edit, Trash2, Loader2, CircleCheck, CircleX, Plus, UserPlus } from "lucide-react";
|
|
23
|
+
import { UserX, KeyRound, Edit, Trash2, Loader2, CircleCheck, CircleX, Plus, UserPlus, Building2 } from "lucide-react";
|
|
24
|
+
import { TreeView } from "../../ui/tree-view";
|
|
24
25
|
import { toast } from "sonner";
|
|
25
26
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../../ui/tooltip";
|
|
26
27
|
import { useHazoAuthConfig } from "../../../contexts/hazo_auth_provider";
|
|
@@ -75,6 +76,11 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
75
76
|
const [userTypeUpdateLoading, setUserTypeUpdateLoading] = useState(false);
|
|
76
77
|
const [orgUpdateLoading, setOrgUpdateLoading] = useState(false);
|
|
77
78
|
const [availableOrgs, setAvailableOrgs] = useState([]);
|
|
79
|
+
// Org assignment dialog state
|
|
80
|
+
const [orgAssignDialogOpen, setOrgAssignDialogOpen] = useState(false);
|
|
81
|
+
const [orgAssignUser, setOrgAssignUser] = useState(null);
|
|
82
|
+
const [selectedOrgForAssign, setSelectedOrgForAssign] = useState(null);
|
|
83
|
+
const [orgAssignLoading, setOrgAssignLoading] = useState(false);
|
|
78
84
|
// Tab 3: Permissions state
|
|
79
85
|
const [permissions, setPermissions] = useState([]);
|
|
80
86
|
const [permissionsLoading, setPermissionsLoading] = useState(true);
|
|
@@ -127,6 +133,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
127
133
|
setAvailableOrgs(data.orgs.map((org) => ({
|
|
128
134
|
id: org.id,
|
|
129
135
|
name: org.name,
|
|
136
|
+
parent_org_id: org.parent_org_id,
|
|
130
137
|
})));
|
|
131
138
|
}
|
|
132
139
|
}
|
|
@@ -259,6 +266,8 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
259
266
|
return;
|
|
260
267
|
setUserTypeUpdateLoading(true);
|
|
261
268
|
try {
|
|
269
|
+
// Convert sentinel value "__none__" to null for API
|
|
270
|
+
const typeValue = newType === "__none__" ? null : newType;
|
|
262
271
|
const response = await fetch(`${apiBasePath}/user_management/users`, {
|
|
263
272
|
method: "PATCH",
|
|
264
273
|
headers: {
|
|
@@ -266,7 +275,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
266
275
|
},
|
|
267
276
|
body: JSON.stringify({
|
|
268
277
|
user_id: selectedUser.id,
|
|
269
|
-
user_type:
|
|
278
|
+
user_type: typeValue,
|
|
270
279
|
}),
|
|
271
280
|
});
|
|
272
281
|
const data = await response.json();
|
|
@@ -294,6 +303,8 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
294
303
|
return;
|
|
295
304
|
setOrgUpdateLoading(true);
|
|
296
305
|
try {
|
|
306
|
+
// Convert sentinel value "__none__" to null for API
|
|
307
|
+
const orgIdValue = newOrgId === "__none__" ? null : newOrgId;
|
|
297
308
|
const response = await fetch(`${apiBasePath}/user_management/users`, {
|
|
298
309
|
method: "PATCH",
|
|
299
310
|
headers: {
|
|
@@ -301,7 +312,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
301
312
|
},
|
|
302
313
|
body: JSON.stringify({
|
|
303
314
|
user_id: selectedUser.id,
|
|
304
|
-
org_id:
|
|
315
|
+
org_id: orgIdValue,
|
|
305
316
|
}),
|
|
306
317
|
});
|
|
307
318
|
const data = await response.json();
|
|
@@ -323,6 +334,83 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
323
334
|
setOrgUpdateLoading(false);
|
|
324
335
|
}
|
|
325
336
|
};
|
|
337
|
+
// Build org tree from flat list for TreeView component
|
|
338
|
+
const buildOrgTree = (orgs) => {
|
|
339
|
+
// Create a map for quick lookup
|
|
340
|
+
const orgMap = new Map();
|
|
341
|
+
orgs.forEach((org) => {
|
|
342
|
+
orgMap.set(org.id, Object.assign(Object.assign({}, org), { children: [] }));
|
|
343
|
+
});
|
|
344
|
+
const rootNodes = [];
|
|
345
|
+
// Build tree structure
|
|
346
|
+
orgs.forEach((org) => {
|
|
347
|
+
const node = orgMap.get(org.id);
|
|
348
|
+
const treeItem = {
|
|
349
|
+
id: org.id,
|
|
350
|
+
name: org.name,
|
|
351
|
+
children: node.children.length > 0 ? node.children : undefined,
|
|
352
|
+
};
|
|
353
|
+
if (org.parent_org_id && orgMap.has(org.parent_org_id)) {
|
|
354
|
+
const parent = orgMap.get(org.parent_org_id);
|
|
355
|
+
parent.children.push(treeItem);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
rootNodes.push(treeItem);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
// Update children in the tree
|
|
362
|
+
const updateChildren = (nodes) => {
|
|
363
|
+
return nodes.map((node) => {
|
|
364
|
+
const orgNode = orgMap.get(node.id);
|
|
365
|
+
if (orgNode && orgNode.children.length > 0) {
|
|
366
|
+
return Object.assign(Object.assign({}, node), { children: updateChildren(orgNode.children) });
|
|
367
|
+
}
|
|
368
|
+
return node;
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
return updateChildren(rootNodes);
|
|
372
|
+
};
|
|
373
|
+
// Handle org assignment from dialog
|
|
374
|
+
const handleOrgAssignFromDialog = async () => {
|
|
375
|
+
if (!orgAssignUser)
|
|
376
|
+
return;
|
|
377
|
+
setOrgAssignLoading(true);
|
|
378
|
+
try {
|
|
379
|
+
const orgIdValue = selectedOrgForAssign;
|
|
380
|
+
const response = await fetch(`${apiBasePath}/user_management/users`, {
|
|
381
|
+
method: "PATCH",
|
|
382
|
+
headers: {
|
|
383
|
+
"Content-Type": "application/json",
|
|
384
|
+
},
|
|
385
|
+
body: JSON.stringify({
|
|
386
|
+
user_id: orgAssignUser.id,
|
|
387
|
+
org_id: orgIdValue,
|
|
388
|
+
}),
|
|
389
|
+
});
|
|
390
|
+
const data = await response.json();
|
|
391
|
+
if (data.success) {
|
|
392
|
+
toast.success("Organization updated successfully");
|
|
393
|
+
setOrgAssignDialogOpen(false);
|
|
394
|
+
// Reload users list to get updated org info
|
|
395
|
+
await loadUsers();
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
toast.error(data.error || "Failed to update organization");
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
toast.error("Failed to update organization");
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
setOrgAssignLoading(false);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
// Open org assignment dialog for a user
|
|
409
|
+
const openOrgAssignDialog = (user) => {
|
|
410
|
+
setOrgAssignUser(user);
|
|
411
|
+
setSelectedOrgForAssign(user.org_id);
|
|
412
|
+
setOrgAssignDialogOpen(true);
|
|
413
|
+
};
|
|
326
414
|
// Handle migrate permissions
|
|
327
415
|
const handleMigratePermissions = async () => {
|
|
328
416
|
var _a, _b;
|
|
@@ -559,7 +647,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
559
647
|
})() })), _jsx(TableCell, { className: "cls_user_management_users_table_cell_actions text-right", children: _jsx(TooltipProvider, { children: _jsxs("div", { className: "cls_user_management_users_table_actions flex items-center justify-end gap-2", onClick: (e) => e.stopPropagation(), children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
|
|
560
648
|
setSelectedUser(user);
|
|
561
649
|
setAssignRolesDialogOpen(true);
|
|
562
|
-
}, variant: "outline", size: "sm", className: "cls_user_management_users_table_action_assign_roles", children: _jsx(UserPlus, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Assign Roles" }) })] }), user.is_active && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
|
|
650
|
+
}, variant: "outline", size: "sm", className: "cls_user_management_users_table_action_assign_roles", children: _jsx(UserPlus, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Assign Roles" }) })] }), multiTenancyEnabled && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => openOrgAssignDialog(user), variant: "outline", size: "sm", className: "cls_user_management_users_table_action_assign_org", children: _jsx(Building2, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Assign Organization" }) })] })), user.is_active && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
|
|
563
651
|
setSelectedUser(user);
|
|
564
652
|
setDeactivateDialogOpen(true);
|
|
565
653
|
}, variant: "outline", size: "sm", className: "cls_user_management_users_table_action_deactivate", children: _jsx(UserX, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Deactivate" }) })] })), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
|
|
@@ -596,7 +684,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
596
684
|
setAddPermissionDialogOpen(false);
|
|
597
685
|
setNewPermissionName("");
|
|
598
686
|
setNewPermissionDescription("");
|
|
599
|
-
}, variant: "outline", className: "cls_user_management_add_permission_dialog_cancel", children: [_jsx(CircleX, { className: "h-4 w-4 mr-2" }), "Cancel"] })] })] }) }), _jsx(Dialog, { open: userDetailDialogOpen, onOpenChange: setUserDetailDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_user_detail_dialog max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "User Details" }), _jsxs(DialogDescription, { children: ["Complete information for ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address)] })] }), _jsx("div", { className: "cls_user_management_user_detail_dialog_content flex flex-col gap-4 py-4", children: selectedUser && (_jsxs("div", { className: "cls_user_management_user_detail_fields grid grid-cols-1 gap-4", children: [_jsxs("div", { className: "cls_user_management_user_detail_field_profile_pic flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Profile Picture" }), _jsxs("div", { className: "cls_user_management_user_detail_profile_pic_container flex items-center gap-4", children: [_jsxs(Avatar, { className: "cls_user_management_user_detail_avatar h-16 w-16", children: [_jsx(AvatarImage, { src: selectedUser.profile_picture_url || undefined, alt: selectedUser.name ? `Profile picture of ${selectedUser.name}` : "Profile picture", className: "cls_user_management_user_detail_avatar_image" }), _jsx(AvatarFallback, { className: "cls_user_management_user_detail_avatar_fallback bg-slate-200 text-slate-600 text-lg", children: getUserInitials(selectedUser) })] }), _jsxs("div", { className: "cls_user_management_user_detail_profile_pic_info flex flex-col gap-1", children: [_jsx("span", { className: "cls_user_management_user_detail_profile_pic_url text-sm text-muted-foreground", children: selectedUser.profile_picture_url || "No profile picture" }), _jsxs("span", { className: "cls_user_management_user_detail_profile_pic_source text-xs text-muted-foreground", children: ["Source: ", selectedUser.profile_source || "N/A"] })] })] })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_id flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "User ID" }), _jsx("div", { className: "cls_user_management_user_detail_id_value font-mono text-sm bg-muted p-2 rounded", children: selectedUser.id })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_name flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Name" }), _jsx("div", { className: "cls_user_management_user_detail_name_value text-sm", children: selectedUser.name || "-" })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_email flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Email Address" }), _jsx("div", { className: "cls_user_management_user_detail_email_value text-sm", children: selectedUser.email_address })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_email_verified flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Email Verified" }), _jsx("div", { className: "cls_user_management_user_detail_email_verified_value", children: selectedUser.email_verified ? (_jsx("span", { className: "text-green-600 font-medium", children: "Yes" })) : (_jsx("span", { className: "text-red-600 font-medium", children: "No" })) })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_is_active flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Active Status" }), _jsx("div", { className: "cls_user_management_user_detail_is_active_value", children: selectedUser.is_active ? (_jsx("span", { className: "text-green-600 font-medium", children: "Active" })) : (_jsx("span", { className: "text-red-600 font-medium", children: "Inactive" })) })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_last_logon flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Last Logon" }), _jsx("div", { className: "cls_user_management_user_detail_last_logon_value text-sm", children: selectedUser.last_logon ? (_jsx("span", { className: "font-medium", children: new Date(selectedUser.last_logon).toLocaleString(undefined, {
|
|
687
|
+
}, variant: "outline", className: "cls_user_management_add_permission_dialog_cancel", children: [_jsx(CircleX, { className: "h-4 w-4 mr-2" }), "Cancel"] })] })] }) }), _jsx(Dialog, { open: userDetailDialogOpen, onOpenChange: setUserDetailDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_user_detail_dialog max-w-2xl max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "User Details" }), _jsxs(DialogDescription, { children: ["Complete information for ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address)] })] }), _jsx("div", { className: "cls_user_management_user_detail_dialog_content flex flex-col gap-4 py-4", children: selectedUser && (_jsxs("div", { className: "cls_user_management_user_detail_fields grid grid-cols-1 gap-4", children: [_jsxs("div", { className: "cls_user_management_user_detail_field_profile_pic flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Profile Picture" }), _jsxs("div", { className: "cls_user_management_user_detail_profile_pic_container flex items-center gap-4", children: [_jsxs(Avatar, { className: "cls_user_management_user_detail_avatar h-16 w-16", children: [_jsx(AvatarImage, { src: selectedUser.profile_picture_url || undefined, alt: selectedUser.name ? `Profile picture of ${selectedUser.name}` : "Profile picture", className: "cls_user_management_user_detail_avatar_image" }), _jsx(AvatarFallback, { className: "cls_user_management_user_detail_avatar_fallback bg-slate-200 text-slate-600 text-lg", children: getUserInitials(selectedUser) })] }), _jsxs("div", { className: "cls_user_management_user_detail_profile_pic_info flex flex-col gap-1", children: [_jsx("span", { className: "cls_user_management_user_detail_profile_pic_url text-sm text-muted-foreground", children: selectedUser.profile_picture_url || "No profile picture" }), _jsxs("span", { className: "cls_user_management_user_detail_profile_pic_source text-xs text-muted-foreground", children: ["Source: ", selectedUser.profile_source || "N/A"] })] })] })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_id flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "User ID" }), _jsx("div", { className: "cls_user_management_user_detail_id_value font-mono text-sm bg-muted p-2 rounded", children: selectedUser.id })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_name flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Name" }), _jsx("div", { className: "cls_user_management_user_detail_name_value text-sm", children: selectedUser.name || "-" })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_email flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Email Address" }), _jsx("div", { className: "cls_user_management_user_detail_email_value text-sm", children: selectedUser.email_address })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_email_verified flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Email Verified" }), _jsx("div", { className: "cls_user_management_user_detail_email_verified_value", children: selectedUser.email_verified ? (_jsx("span", { className: "text-green-600 font-medium", children: "Yes" })) : (_jsx("span", { className: "text-red-600 font-medium", children: "No" })) })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_is_active flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Active Status" }), _jsx("div", { className: "cls_user_management_user_detail_is_active_value", children: selectedUser.is_active ? (_jsx("span", { className: "text-green-600 font-medium", children: "Active" })) : (_jsx("span", { className: "text-red-600 font-medium", children: "Inactive" })) })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_last_logon flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Last Logon" }), _jsx("div", { className: "cls_user_management_user_detail_last_logon_value text-sm", children: selectedUser.last_logon ? (_jsx("span", { className: "font-medium", children: new Date(selectedUser.last_logon).toLocaleString(undefined, {
|
|
600
688
|
year: "numeric",
|
|
601
689
|
month: "long",
|
|
602
690
|
day: "numeric",
|
|
@@ -612,7 +700,7 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
612
700
|
minute: "2-digit",
|
|
613
701
|
second: "2-digit",
|
|
614
702
|
timeZoneName: "short",
|
|
615
|
-
}) })) : (_jsx("span", { className: "text-muted-foreground", children: "-" })) })] }), userTypesEnabled && (_jsxs("div", { className: "cls_user_management_user_detail_field_user_type flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "User Type" }), _jsxs("div", { className: "cls_user_management_user_detail_user_type_value flex items-center gap-2", children: [_jsxs(Select, { value: selectedUser.user_type || "", onValueChange: (value) => handleUserTypeChange(value), disabled: userTypeUpdateLoading, children: [_jsx(SelectTrigger, { className: "w-48", children: _jsx(SelectValue, { placeholder: "Select user type" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "", children: "None" }), availableUserTypes.map((type) => (_jsx(SelectItem, { value: type.key, children: type.label }, type.key)))] })] }), userTypeUpdateLoading && (_jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }))] })] })), multiTenancyEnabled && (_jsxs("div", { className: "cls_user_management_user_detail_field_org flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Organization" }), _jsxs("div", { className: "cls_user_management_user_detail_org_value flex items-center gap-2", children: [_jsxs(Select, { value: selectedUser.org_id || "", onValueChange: (value) => handleOrgChange(value), disabled: orgUpdateLoading, children: [_jsx(SelectTrigger, { className: "w-64", children: _jsx(SelectValue, { placeholder: "Select organization" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "", children: "None" }), availableOrgs.map((org) => (_jsx(SelectItem, { value: org.id, children: org.name }, org.id)))] })] }), orgUpdateLoading && (_jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }))] })] }))] })) }), _jsx(DialogFooter, { className: "cls_user_management_user_detail_dialog_footer", children: _jsx(Button, { onClick: () => setUserDetailDialogOpen(false), variant: "outline", className: "cls_user_management_user_detail_dialog_close", children: "Close" }) })] }) }), _jsx(Dialog, { open: assignRolesDialogOpen, onOpenChange: setAssignRolesDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_assign_roles_dialog max-w-4xl max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Assign Roles to User" }), _jsxs(DialogDescription, { children: ["Select roles to assign to ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), ". Check the roles you want to assign, then click Save."] })] }), _jsx("div", { className: "cls_user_management_assign_roles_dialog_content py-4", children: _jsx(RolesMatrix, { add_button_enabled: false, role_name_selection_enabled: true, permissions_read_only: true, show_save_cancel: true, user_id: selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id, onSave: (data) => {
|
|
703
|
+
}) })) : (_jsx("span", { className: "text-muted-foreground", children: "-" })) })] }), userTypesEnabled && (_jsxs("div", { className: "cls_user_management_user_detail_field_user_type flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "User Type" }), _jsxs("div", { className: "cls_user_management_user_detail_user_type_value flex items-center gap-2", children: [_jsxs(Select, { value: selectedUser.user_type || "__none__", onValueChange: (value) => handleUserTypeChange(value), disabled: userTypeUpdateLoading, children: [_jsx(SelectTrigger, { className: "w-48", children: _jsx(SelectValue, { placeholder: "Select user type" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "__none__", children: "None" }), availableUserTypes.map((type) => (_jsx(SelectItem, { value: type.key, children: type.label }, type.key)))] })] }), userTypeUpdateLoading && (_jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }))] })] })), multiTenancyEnabled && (_jsxs("div", { className: "cls_user_management_user_detail_field_org flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Organization" }), _jsxs("div", { className: "cls_user_management_user_detail_org_value flex items-center gap-2", children: [_jsxs(Select, { value: selectedUser.org_id || "__none__", onValueChange: (value) => handleOrgChange(value), disabled: orgUpdateLoading, children: [_jsx(SelectTrigger, { className: "w-64", children: _jsx(SelectValue, { placeholder: "Select organization" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "__none__", children: "None" }), availableOrgs.map((org) => (_jsx(SelectItem, { value: org.id, children: org.name }, org.id)))] })] }), orgUpdateLoading && (_jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }))] })] }))] })) }), _jsx(DialogFooter, { className: "cls_user_management_user_detail_dialog_footer", children: _jsx(Button, { onClick: () => setUserDetailDialogOpen(false), variant: "outline", className: "cls_user_management_user_detail_dialog_close", children: "Close" }) })] }) }), _jsx(Dialog, { open: assignRolesDialogOpen, onOpenChange: setAssignRolesDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_assign_roles_dialog max-w-4xl max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Assign Roles to User" }), _jsxs(DialogDescription, { children: ["Select roles to assign to ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), ". Check the roles you want to assign, then click Save."] })] }), _jsx("div", { className: "cls_user_management_assign_roles_dialog_content py-4", children: _jsx(RolesMatrix, { add_button_enabled: false, role_name_selection_enabled: true, permissions_read_only: true, show_save_cancel: true, user_id: selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id, onSave: (data) => {
|
|
616
704
|
// Data is already saved by RolesMatrix component
|
|
617
705
|
console.log("User roles saved:", data);
|
|
618
706
|
// Refresh users list to show updated roles
|
|
@@ -622,5 +710,11 @@ export function UserManagementLayout({ className, hrbacEnabled = false, multiTen
|
|
|
622
710
|
}, onCancel: () => {
|
|
623
711
|
setAssignRolesDialogOpen(false);
|
|
624
712
|
setSelectedUser(null);
|
|
625
|
-
}, className: "cls_user_management_assign_roles_matrix" }) })] }) })] }))
|
|
713
|
+
}, className: "cls_user_management_assign_roles_matrix" }) })] }) }), _jsx(Dialog, { open: orgAssignDialogOpen, onOpenChange: setOrgAssignDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_org_assign_dialog max-w-lg max-h-[80vh] flex flex-col", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Assign Organization" }), _jsxs(DialogDescription, { children: ["Select an organization for ", (orgAssignUser === null || orgAssignUser === void 0 ? void 0 : orgAssignUser.name) || (orgAssignUser === null || orgAssignUser === void 0 ? void 0 : orgAssignUser.email_address)] })] }), _jsxs("div", { className: "cls_user_management_org_assign_dialog_content flex-1 overflow-y-auto py-4 min-h-0", children: [_jsxs("div", { className: `cls_user_management_org_assign_none p-3 mb-2 rounded-lg border cursor-pointer transition-colors ${selectedOrgForAssign === null
|
|
714
|
+
? "border-primary bg-primary/10"
|
|
715
|
+
: "border-border hover:bg-muted"}`, onClick: () => setSelectedOrgForAssign(null), children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CircleX, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { className: "font-medium", children: "None" })] }), _jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Remove organization assignment" })] }), availableOrgs.length > 0 ? (_jsx("div", { className: "cls_user_management_org_assign_tree border rounded-lg overflow-auto min-h-[200px]", children: _jsx(TreeView, { data: buildOrgTree(availableOrgs), expandAll: true, defaultNodeIcon: Building2, defaultLeafIcon: Building2, onSelectChange: (item) => {
|
|
716
|
+
if (item) {
|
|
717
|
+
setSelectedOrgForAssign(item.id);
|
|
718
|
+
}
|
|
719
|
+
}, initialSelectedItemId: selectedOrgForAssign || undefined, className: "w-full p-2" }) })) : (_jsx("div", { className: "cls_user_management_org_assign_empty text-center py-8 text-muted-foreground", children: "No organizations available" }))] }), _jsxs(DialogFooter, { className: "cls_user_management_org_assign_dialog_footer", children: [_jsx(Button, { variant: "outline", onClick: () => setOrgAssignDialogOpen(false), disabled: orgAssignLoading, children: "Cancel" }), _jsx(Button, { onClick: handleOrgAssignFromDialog, disabled: orgAssignLoading, children: orgAssignLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Saving..."] })) : ("Save") })] })] }) })] }));
|
|
626
720
|
}
|