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]);
|
}, [tenantUsersList]);
|
||||||
|
|
||||||
const modalExecutiveUsers = React.useMemo(() => {
|
const modalExecutiveUsers = React.useMemo(() => {
|
||||||
let list: User[] = [];
|
const list: User[] = [];
|
||||||
|
const seenIds = new Set<string>();
|
||||||
|
|
||||||
if (isAdmin) {
|
const addCandidate = (u?: User | null) => {
|
||||||
list = usersDirectory.filter((u) => String(u.role || '').toLowerCase() === 'executive');
|
if (!u || !u.id) return;
|
||||||
} else {
|
const key = String(u.id).toLowerCase();
|
||||||
list = tenantUsersList
|
if (seenIds.has(key)) return;
|
||||||
.map((tu) => tu.user || ({ id: tu.userId, email: getUserEmail(tu.userId), role: 'Executive' } as User))
|
seenIds.add(key);
|
||||||
.filter((u) => String(u.role || '').toLowerCase() === 'executive');
|
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?.UserId ||
|
editingOrg?.UserId ||
|
||||||
editingOrg?.organisationUser ||
|
editingOrg?.organisationUser ||
|
||||||
editingOrg?.OrganisationUser ||
|
editingOrg?.OrganisationUser ||
|
||||||
'';
|
'';
|
||||||
|
|
||||||
if (currentLinkedUserId) {
|
if (linkedUserId) {
|
||||||
const alreadyIncluded = list.some(
|
const resolvedEmail = getUserEmail(linkedUserId);
|
||||||
(u) => u.id && String(u.id).toLowerCase() === String(currentLinkedUserId).toLowerCase()
|
const matched = usersDirectory.find(
|
||||||
|
(u) => u.id && String(u.id).toLowerCase() === String(linkedUserId).toLowerCase()
|
||||||
);
|
);
|
||||||
if (!alreadyIncluded) {
|
addCandidate({
|
||||||
const resolvedEmail = getUserEmail(currentLinkedUserId);
|
id: linkedUserId,
|
||||||
const matchedInDir = usersDirectory.find(
|
email: matched?.email || (resolvedEmail !== '—' && resolvedEmail ? resolvedEmail : linkedUserId),
|
||||||
(u) => u.id && String(u.id).toLowerCase() === String(currentLinkedUserId).toLowerCase()
|
role: matched?.role || 'Executive',
|
||||||
);
|
status: ActivityStatus.Active,
|
||||||
list = [
|
lastLoginAt: null,
|
||||||
{
|
});
|
||||||
id: currentLinkedUserId,
|
}
|
||||||
email: matchedInDir?.email || (resolvedEmail !== '—' && resolvedEmail ? resolvedEmail : currentLinkedUserId),
|
|
||||||
|
// 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',
|
role: 'Executive',
|
||||||
status: ActivityStatus.Active,
|
status: ActivityStatus.Active,
|
||||||
lastLoginAt: null,
|
lastLoginAt: null,
|
||||||
},
|
});
|
||||||
...list,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}, [isAdmin, usersDirectory, tenantUsersList, editingOrg]);
|
}, [isAdmin, usersDirectory, tenantUsersList, editingOrg?.id, editingOrg?.userId]);
|
||||||
|
|
||||||
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]);
|
|
||||||
|
|
||||||
// Quick Add Executive User Subform state
|
// Quick Add Executive User Subform state
|
||||||
const [isQuickAddUserOpen, setIsQuickAddUserOpen] = useState(false);
|
const [isQuickAddUserOpen, setIsQuickAddUserOpen] = useState(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user