Fix UI freeze by removing cyclical useEffect and stabilizing executive candidate memo
This commit is contained in:
@@ -292,69 +292,64 @@ export const GovernancePage: React.FC = () => {
|
||||
}, [tenantUsersList]);
|
||||
|
||||
const modalExecutiveUsers = React.useMemo(() => {
|
||||
let list: User[] = [];
|
||||
const list: User[] = [];
|
||||
const seenIds = new Set<string>();
|
||||
|
||||
if (isAdmin) {
|
||||
list = usersDirectory.filter((u) => String(u.role || '').toLowerCase() === 'executive');
|
||||
} else {
|
||||
list = tenantUsersList
|
||||
.map((tu) => tu.user || ({ id: tu.userId, email: getUserEmail(tu.userId), role: 'Executive' } as User))
|
||||
.filter((u) => String(u.role || '').toLowerCase() === 'executive');
|
||||
}
|
||||
const addCandidate = (u?: User | null) => {
|
||||
if (!u || !u.id) return;
|
||||
const key = String(u.id).toLowerCase();
|
||||
if (seenIds.has(key)) return;
|
||||
seenIds.add(key);
|
||||
list.push(u);
|
||||
};
|
||||
|
||||
const currentLinkedUserId =
|
||||
// 1. Always include the organisation's linked user so the select option exists and selects immediately
|
||||
const linkedUserId =
|
||||
editingOrg?.userId ||
|
||||
editingOrg?.UserId ||
|
||||
editingOrg?.organisationUser ||
|
||||
editingOrg?.OrganisationUser ||
|
||||
'';
|
||||
|
||||
if (currentLinkedUserId) {
|
||||
const alreadyIncluded = list.some(
|
||||
(u) => u.id && String(u.id).toLowerCase() === String(currentLinkedUserId).toLowerCase()
|
||||
if (linkedUserId) {
|
||||
const resolvedEmail = getUserEmail(linkedUserId);
|
||||
const matched = usersDirectory.find(
|
||||
(u) => u.id && String(u.id).toLowerCase() === String(linkedUserId).toLowerCase()
|
||||
);
|
||||
if (!alreadyIncluded) {
|
||||
const resolvedEmail = getUserEmail(currentLinkedUserId);
|
||||
const matchedInDir = usersDirectory.find(
|
||||
(u) => u.id && String(u.id).toLowerCase() === String(currentLinkedUserId).toLowerCase()
|
||||
);
|
||||
list = [
|
||||
{
|
||||
id: currentLinkedUserId,
|
||||
email: matchedInDir?.email || (resolvedEmail !== '—' && resolvedEmail ? resolvedEmail : currentLinkedUserId),
|
||||
role: 'Executive',
|
||||
status: ActivityStatus.Active,
|
||||
lastLoginAt: null,
|
||||
},
|
||||
...list,
|
||||
];
|
||||
}
|
||||
addCandidate({
|
||||
id: linkedUserId,
|
||||
email: matched?.email || (resolvedEmail !== '—' && resolvedEmail ? resolvedEmail : linkedUserId),
|
||||
role: matched?.role || 'Executive',
|
||||
status: ActivityStatus.Active,
|
||||
lastLoginAt: null,
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Load Executive role users: Admin sees all executives across tenants; normal tenant user focuses on tenantusers
|
||||
if (isAdmin) {
|
||||
usersDirectory
|
||||
.filter((u) => String(u.role || '').toLowerCase() === 'executive')
|
||||
.forEach(addCandidate);
|
||||
} else {
|
||||
tenantUsersList
|
||||
.filter((tu) => String(tu.user?.role || '').toLowerCase() === 'executive')
|
||||
.forEach((tu) => {
|
||||
if (tu.user) {
|
||||
addCandidate(tu.user);
|
||||
} else if (tu.userId) {
|
||||
addCandidate({
|
||||
id: tu.userId,
|
||||
email: getUserEmail(tu.userId),
|
||||
role: 'Executive',
|
||||
status: ActivityStatus.Active,
|
||||
lastLoginAt: null,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}, [isAdmin, usersDirectory, tenantUsersList, editingOrg]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOrgModalOpen && editingOrg) {
|
||||
const targetUserId =
|
||||
editingOrg.userId ||
|
||||
editingOrg.UserId ||
|
||||
editingOrg.organisationUser ||
|
||||
editingOrg.OrganisationUser ||
|
||||
'';
|
||||
|
||||
if (targetUserId) {
|
||||
const targetEmail = getUserEmail(targetUserId);
|
||||
const matched = modalExecutiveUsers.find(
|
||||
(u) =>
|
||||
(u.id && String(u.id).toLowerCase() === String(targetUserId).toLowerCase()) ||
|
||||
(u.email && targetEmail && targetEmail !== '—' && u.email.toLowerCase() === targetEmail.toLowerCase())
|
||||
);
|
||||
const resolvedId = matched?.id || targetUserId;
|
||||
orgForm.setValue('organisationUser', resolvedId, { shouldValidate: true, shouldDirty: false });
|
||||
}
|
||||
}
|
||||
}, [isOrgModalOpen, editingOrg, modalExecutiveUsers]);
|
||||
}, [isAdmin, usersDirectory, tenantUsersList, editingOrg?.id, editingOrg?.userId]);
|
||||
|
||||
// Quick Add Executive User Subform state
|
||||
const [isQuickAddUserOpen, setIsQuickAddUserOpen] = useState(false);
|
||||
|
||||
Reference in New Issue
Block a user