Applied UI rendering fixes

This commit is contained in:
2026-10-22 06:23:22 +02:00
parent 87f597c091
commit c24e809b88
11 changed files with 261 additions and 154 deletions
@@ -210,24 +210,6 @@ export const UserSecurityModal: React.FC<UserSecurityModalProps> = ({
onError: (err: any) => toastError('Status Update Failed', err),
});
if (!user) return null;
const effectiveUser = freshUser || user;
const decodedId = effectiveUser?.idNumber ? decodeIdNumberHex(effectiveUser.idNumber) : null;
const assignedRoleIds = new Set(
(Array.isArray(userRoles) ? userRoles : []).map((r) => r?.id || (r as any)?.Id).filter(Boolean)
);
const availableRoles = (Array.isArray(systemRoles) ? systemRoles : []).filter((r) => {
if (!r) return false;
const rId = r.id || (r as any).Id;
const rName = r.name || (r as any).Name || '';
if (rId && assignedRoleIds.has(rId)) return false;
if (hasTenantSelfHelpAccess && (rName.toLowerCase() === 'admin' || String(rId) === '1')) {
return false;
}
return true;
});
const assignableClaims = React.useMemo(() => {
const claimMap = new Map<string, { claim: string; label: string }>();
if (Array.isArray(systemClaims)) {
@@ -255,6 +237,30 @@ export const UserSecurityModal: React.FC<UserSecurityModalProps> = ({
return Array.from(claimMap.values());
}, [systemClaims, hasTenantSelfHelpAccess]);
const assignedRoleIds = React.useMemo(() => {
return new Set(
(Array.isArray(userRoles) ? userRoles : []).map((r) => r?.id || (r as any)?.Id).filter(Boolean)
);
}, [userRoles]);
const availableRoles = React.useMemo(() => {
return (Array.isArray(systemRoles) ? systemRoles : []).filter((r) => {
if (!r) return false;
const rId = r.id || (r as any).Id;
const rName = r.name || (r as any).Name || '';
if (rId && assignedRoleIds.has(rId)) return false;
if (hasTenantSelfHelpAccess && (rName.toLowerCase() === 'admin' || String(rId) === '1')) {
return false;
}
return true;
});
}, [systemRoles, assignedRoleIds, hasTenantSelfHelpAccess]);
if (!isOpen || !user) return null;
const effectiveUser = freshUser || user;
const decodedId = effectiveUser?.idNumber ? decodeIdNumberHex(effectiveUser.idNumber) : null;
return (
<Modal
isOpen={isOpen}
@@ -286,7 +292,7 @@ export const UserSecurityModal: React.FC<UserSecurityModalProps> = ({
}`}
>
<Shield className="w-3.5 h-3.5" />
<span>Roles ({userRoles.length})</span>
<span>Roles ({(Array.isArray(userRoles) ? userRoles : []).length})</span>
</button>
<button
type="button"
@@ -298,7 +304,7 @@ export const UserSecurityModal: React.FC<UserSecurityModalProps> = ({
}`}
>
<Key className="w-3.5 h-3.5" />
<span>Claims ({userClaims.length})</span>
<span>Claims ({(Array.isArray(userClaims) ? userClaims : []).length})</span>
</button>
<button
type="button"
@@ -358,14 +364,14 @@ export const UserSecurityModal: React.FC<UserSecurityModalProps> = ({
</span>
<span
className={`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-semibold border ${
(getActivityStatusBadge(effectiveUser.status) || {}).className || 'bg-slate-800 text-slate-300'
(getActivityStatusBadge(effectiveUser?.status) || {}).className || 'bg-slate-800 text-slate-300'
}`}
>
{(getActivityStatusBadge(effectiveUser.status) || {}).label || 'Active'}
{(getActivityStatusBadge(effectiveUser?.status) || {}).label || 'Active'}
</span>
</div>
<div className="flex items-center gap-2">
{effectiveUser.status === ActivityStatus.Active ? (
{effectiveUser?.status === ActivityStatus.Active ? (
<button
type="button"
onClick={() => statusMutation.mutate(ActivityStatus.Inactive)}
@@ -404,11 +410,15 @@ export const UserSecurityModal: React.FC<UserSecurityModalProps> = ({
<option value="">
{availableRoles.length === 0 ? 'All system roles assigned' : 'Select role to assign...'}
</option>
{availableRoles.map((r) => (
<option key={r.id} value={r.id}>
{r.name}
</option>
))}
{availableRoles.map((r: any) => {
const roleOptId = r?.id || r?.Id || String(r);
const roleOptName = r?.name || r?.Name || String(r);
return (
<option key={roleOptId} value={roleOptId}>
{roleOptName}
</option>
);
})}
</select>
<button
type="button"