Fixed frozen org editor modal
This commit is contained in:
@@ -62,7 +62,6 @@ import {
|
|||||||
assignUserRole,
|
assignUserRole,
|
||||||
getSystemRoles,
|
getSystemRoles,
|
||||||
getCurrentUserTenantId,
|
getCurrentUserTenantId,
|
||||||
getTenantUsers,
|
|
||||||
notifyNewUserCreated,
|
notifyNewUserCreated,
|
||||||
} from '../services/api';
|
} from '../services/api';
|
||||||
import { Modal } from '../components/ui/Modal';
|
import { Modal } from '../components/ui/Modal';
|
||||||
@@ -78,8 +77,6 @@ import { FundingInstrumentsSection, InstructionsSection } from '../components/go
|
|||||||
import { RulesSection } from '../components/governance/RulesSection';
|
import { RulesSection } from '../components/governance/RulesSection';
|
||||||
import {
|
import {
|
||||||
Organisation,
|
Organisation,
|
||||||
TenantOrganisation,
|
|
||||||
TenantUser,
|
|
||||||
Portfolio,
|
Portfolio,
|
||||||
Programme,
|
Programme,
|
||||||
Instrument,
|
Instrument,
|
||||||
@@ -268,42 +265,8 @@ export const GovernancePage: React.FC = () => {
|
|||||||
});
|
});
|
||||||
}, [usersDirectory]);
|
}, [usersDirectory]);
|
||||||
|
|
||||||
const isAdmin =
|
|
||||||
Boolean(isUnrestricted) ||
|
|
||||||
(Array.isArray(roles) && roles.some((r) => r.toLowerCase().trim() === 'admin')) ||
|
|
||||||
(claims?.role && String(claims.role).toLowerCase().includes('admin'));
|
|
||||||
|
|
||||||
const orgTenantId = editingOrg?.tenantId || tenantId || getCurrentUserTenantId() || 1;
|
|
||||||
|
|
||||||
const { data: tenantUsersList = [] } = useQuery<TenantUser[]>({
|
|
||||||
queryKey: ['tenant-users', orgTenantId],
|
|
||||||
queryFn: () => getTenantUsers(orgTenantId),
|
|
||||||
enabled: isOrgModalOpen && !!editingOrg && !isAdmin,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (tenantUsersList.length > 0) {
|
|
||||||
tenantUsersList.forEach((tu) => {
|
|
||||||
if (tu.userId && tu.user?.email) {
|
|
||||||
registerUserEmail(tu.userId, tu.user.email);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [tenantUsersList]);
|
|
||||||
|
|
||||||
const modalExecutiveUsers = React.useMemo(() => {
|
const modalExecutiveUsers = React.useMemo(() => {
|
||||||
const list: User[] = [];
|
const list: User[] = [...executiveAndManagerUsers];
|
||||||
const seenIds = new Set<string>();
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 1. Always include the organisation's linked user so the select option exists and selects immediately
|
|
||||||
const linkedUserId =
|
const linkedUserId =
|
||||||
editingOrg?.userId ||
|
editingOrg?.userId ||
|
||||||
editingOrg?.UserId ||
|
editingOrg?.UserId ||
|
||||||
@@ -312,44 +275,28 @@ export const GovernancePage: React.FC = () => {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
if (linkedUserId) {
|
if (linkedUserId) {
|
||||||
const resolvedEmail = getUserEmail(linkedUserId);
|
const linkedStr = String(linkedUserId).toLowerCase();
|
||||||
const matched = usersDirectory.find(
|
const alreadyIncluded = list.some((u) => u.id && String(u.id).toLowerCase() === linkedStr);
|
||||||
(u) => u.id && String(u.id).toLowerCase() === String(linkedUserId).toLowerCase()
|
if (!alreadyIncluded) {
|
||||||
);
|
const inDirectory = usersDirectory.find((u) => u.id && String(u.id).toLowerCase() === linkedStr);
|
||||||
addCandidate({
|
if (inDirectory) {
|
||||||
id: linkedUserId,
|
list.unshift(inDirectory);
|
||||||
email: matched?.email || (resolvedEmail !== '—' && resolvedEmail ? resolvedEmail : linkedUserId),
|
} else {
|
||||||
role: matched?.role || 'Executive',
|
const email = getUserEmail(linkedUserId);
|
||||||
status: ActivityStatus.Active,
|
const hasRealEmail = email && email !== '—' && email.includes('@') && email !== String(linkedUserId);
|
||||||
lastLoginAt: null,
|
list.unshift({
|
||||||
});
|
id: String(linkedUserId),
|
||||||
}
|
email: hasRealEmail ? email : String(linkedUserId),
|
||||||
|
role: 'Executive',
|
||||||
// 2. Load Executive role users: Admin sees all executives across tenants; normal tenant user focuses on tenantusers
|
status: ActivityStatus.Active,
|
||||||
if (isAdmin) {
|
lastLoginAt: null,
|
||||||
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;
|
return list;
|
||||||
}, [isAdmin, usersDirectory, tenantUsersList, editingOrg?.id, editingOrg?.userId]);
|
}, [executiveAndManagerUsers, usersDirectory, editingOrg?.id, editingOrg?.userId, editingOrg?.organisationUser]);
|
||||||
|
|
||||||
// Quick Add Executive User Subform state
|
// Quick Add Executive User Subform state
|
||||||
const [isQuickAddUserOpen, setIsQuickAddUserOpen] = useState(false);
|
const [isQuickAddUserOpen, setIsQuickAddUserOpen] = useState(false);
|
||||||
@@ -828,23 +775,29 @@ export const GovernancePage: React.FC = () => {
|
|||||||
org.createdBy ||
|
org.createdBy ||
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
let selectedUserId = '';
|
||||||
if (targetUserId) {
|
if (targetUserId) {
|
||||||
const email = getUserEmail(targetUserId);
|
const targetStr = String(targetUserId).toLowerCase();
|
||||||
if (email && email !== '—') {
|
const matchedUser = usersDirectory.find(
|
||||||
registerUserEmail(targetUserId, email);
|
(u) =>
|
||||||
|
(u.id && String(u.id).toLowerCase() === targetStr) ||
|
||||||
|
(u.email && u.email.toLowerCase() === targetStr)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (matchedUser) {
|
||||||
|
selectedUserId = matchedUser.id;
|
||||||
|
if (matchedUser.email) {
|
||||||
|
registerUserEmail(matchedUser.id, matchedUser.email);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedUserId = String(targetUserId);
|
||||||
|
const email = getUserEmail(targetUserId);
|
||||||
|
if (email && email !== '—' && email.includes('@')) {
|
||||||
|
registerUserEmail(selectedUserId, email);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const matchedUser = targetUserId
|
|
||||||
? usersDirectory.find(
|
|
||||||
(u) =>
|
|
||||||
(u.id && String(u.id).toLowerCase() === String(targetUserId).toLowerCase()) ||
|
|
||||||
(u.email && getUserEmail(targetUserId) && u.email.toLowerCase() === getUserEmail(targetUserId).toLowerCase())
|
|
||||||
)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const selectedUserId = matchedUser?.id || targetUserId || '';
|
|
||||||
|
|
||||||
orgForm.reset({
|
orgForm.reset({
|
||||||
name: org.name || '',
|
name: org.name || '',
|
||||||
registrationNo: org.registrationNo || '',
|
registrationNo: org.registrationNo || '',
|
||||||
@@ -1812,7 +1765,7 @@ export const GovernancePage: React.FC = () => {
|
|||||||
className="w-full px-3 py-2 text-xs border border-slate-700/80 rounded-xl focus:outline-none focus:ring-1 focus:ring-blue-500 bg-[#090d16] text-white font-medium"
|
className="w-full px-3 py-2 text-xs border border-slate-700/80 rounded-xl focus:outline-none focus:ring-1 focus:ring-blue-500 bg-[#090d16] text-white font-medium"
|
||||||
>
|
>
|
||||||
<option value="">-- Select linked executive or manager account --</option>
|
<option value="">-- Select linked executive or manager account --</option>
|
||||||
{(editingOrg ? modalExecutiveUsers : executiveAndManagerUsers).map((u) => (
|
{modalExecutiveUsers.map((u) => (
|
||||||
<option key={u.id} value={u.id}>
|
<option key={u.id} value={u.id}>
|
||||||
{u.email || u.id} ({u.role || 'Executive'})
|
{u.email || u.id} ({u.role || 'Executive'})
|
||||||
</option>
|
</option>
|
||||||
|
|||||||
Reference in New Issue
Block a user