feat: replace binary scope toggle with multi-select BU picker
- Add IVANTI_BU_FILTER to .env with all four BUs (STEAM, ACCESS-ENG, ACCESS-OPS, INTELDEV) - Rework AdminScopeToggle from binary (My Teams/All) to multi-select dropdown - Admin can now pick any combination of BUs to view - Presets: 'All BUs' and 'My Teams' for quick selection - Individual team checkboxes for custom combinations - Selection persisted in localStorage as JSON array - AuthContext updated: adminScope is now an array of selected teams - getActiveTeamsParam() returns comma-joined selected teams (empty = no filter) - getAvailableTeams() returns selected teams for compliance selector
This commit is contained in:
@@ -7,15 +7,33 @@ const KNOWN_TEAMS = ['STEAM', 'ACCESS-ENG', 'ACCESS-OPS', 'INTELDEV'];
|
||||
|
||||
const AuthContext = createContext(null);
|
||||
|
||||
// Load admin scope from localStorage — returns array of selected teams
|
||||
function loadAdminScope() {
|
||||
try {
|
||||
const saved = localStorage.getItem('admin_bu_scope');
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved);
|
||||
if (Array.isArray(parsed)) return parsed;
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
// Default: null means "not yet initialized" — will be set to user's teams on first load
|
||||
return null;
|
||||
}
|
||||
|
||||
function saveAdminScope(teams) {
|
||||
try {
|
||||
localStorage.setItem('admin_bu_scope', JSON.stringify(teams));
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
export function AuthProvider({ children }) {
|
||||
const [user, setUser] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
// Admin scope toggle — persisted in localStorage
|
||||
const [adminScope, setAdminScope] = useState(
|
||||
() => localStorage.getItem('admin_bu_scope') || 'my-teams'
|
||||
);
|
||||
// Admin scope — array of currently selected teams for filtering
|
||||
// null = not initialized yet (will default to user's teams after login)
|
||||
const [adminScope, setAdminScope] = useState(loadAdminScope);
|
||||
|
||||
// Check if user is authenticated on mount
|
||||
const checkAuth = useCallback(async () => {
|
||||
@@ -27,6 +45,12 @@ export function AuthProvider({ children }) {
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setUser(data.user);
|
||||
// Initialize admin scope to user's teams if not yet set
|
||||
if (adminScope === null && data.user?.teams?.length > 0) {
|
||||
const initial = data.user.teams;
|
||||
setAdminScope(initial);
|
||||
saveAdminScope(initial);
|
||||
}
|
||||
} else {
|
||||
setUser(null);
|
||||
}
|
||||
@@ -36,7 +60,7 @@ export function AuthProvider({ children }) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
useEffect(() => {
|
||||
checkAuth();
|
||||
@@ -60,6 +84,12 @@ export function AuthProvider({ children }) {
|
||||
}
|
||||
|
||||
setUser(data.user);
|
||||
// Initialize scope to user's teams on login
|
||||
if (data.user?.teams?.length > 0 && adminScope === null) {
|
||||
const initial = data.user.teams;
|
||||
setAdminScope(initial);
|
||||
saveAdminScope(initial);
|
||||
}
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
@@ -87,7 +117,6 @@ export function AuthProvider({ children }) {
|
||||
const canWrite = () => isInGroup('Admin', 'Standard_User');
|
||||
|
||||
// Check if user can delete a resource
|
||||
// Admin: always true; Standard_User: only if they own the resource; others: false
|
||||
const canDelete = (resource) => {
|
||||
if (!user) return false;
|
||||
if (isInGroup('Admin')) return true;
|
||||
@@ -108,36 +137,51 @@ export function AuthProvider({ children }) {
|
||||
// Whether the user has any BU teams assigned
|
||||
const hasTeams = () => (user?.teams?.length ?? 0) > 0;
|
||||
|
||||
// Whether the user is a member of a specific team (or is Admin in "All BUs" mode)
|
||||
// Whether the user is a member of a specific team
|
||||
const isTeamMember = (team) => {
|
||||
if (!user) return false;
|
||||
if (isInGroup('Admin') && adminScope === 'all') return true;
|
||||
if (isInGroup('Admin')) {
|
||||
// Admin: check against current scope selection
|
||||
const scope = adminScope || [];
|
||||
return scope.length === 0 || scope.includes(team);
|
||||
}
|
||||
return (user.teams || []).includes(team);
|
||||
};
|
||||
|
||||
// Toggle admin scope between 'my-teams' and 'all'
|
||||
const toggleAdminScope = () => {
|
||||
setAdminScope(prev => {
|
||||
const next = prev === 'my-teams' ? 'all' : 'my-teams';
|
||||
localStorage.setItem('admin_bu_scope', next);
|
||||
return next;
|
||||
});
|
||||
// Set the admin scope to a specific set of teams
|
||||
const setAdminScopeTeams = (teams) => {
|
||||
setAdminScope(teams);
|
||||
saveAdminScope(teams);
|
||||
};
|
||||
|
||||
// Returns the comma-joined teams string for API query params.
|
||||
// Empty string means "no filter" (show all).
|
||||
const getActiveTeamsParam = () => {
|
||||
if (!user) return '';
|
||||
if (isInGroup('Admin') && adminScope === 'all') return '';
|
||||
|
||||
if (isInGroup('Admin')) {
|
||||
const scope = adminScope || [];
|
||||
// If all teams selected or empty, no filter
|
||||
if (scope.length === 0 || scope.length === KNOWN_TEAMS.length) return '';
|
||||
return scope.join(',');
|
||||
}
|
||||
|
||||
// Non-admin: always use their assigned teams
|
||||
const teams = user.teams || [];
|
||||
return teams.join(',');
|
||||
};
|
||||
|
||||
// Returns the list of teams available for UI selectors (compliance team picker, etc.)
|
||||
// Admin in "All BUs" mode sees all known teams; otherwise scoped to user's teams.
|
||||
const getAvailableTeams = () => {
|
||||
if (!user) return [];
|
||||
if (isInGroup('Admin') && adminScope === 'all') return KNOWN_TEAMS;
|
||||
|
||||
if (isInGroup('Admin')) {
|
||||
const scope = adminScope || [];
|
||||
// If all selected or empty, show all known teams
|
||||
if (scope.length === 0 || scope.length === KNOWN_TEAMS.length) return KNOWN_TEAMS;
|
||||
return scope;
|
||||
}
|
||||
|
||||
return user.teams || [];
|
||||
};
|
||||
|
||||
@@ -158,7 +202,7 @@ export function AuthProvider({ children }) {
|
||||
hasTeams,
|
||||
isTeamMember,
|
||||
adminScope,
|
||||
toggleAdminScope,
|
||||
setAdminScopeTeams,
|
||||
getActiveTeamsParam,
|
||||
getAvailableTeams,
|
||||
KNOWN_TEAMS,
|
||||
|
||||
Reference in New Issue
Block a user