mirror of
https://github.com/grafana/grafana.git
synced 2026-02-03 20:49:50 -05:00
What is this feature? This PR introduce refactoring for role picker for teams and users. It uses RTK Query. The related task: grafana/identity-access-team#1821 The previous PR with related logic: #113783 Why do we need this feature? This refactoring is a cleaner way for handing refetching.
164 lines
4.7 KiB
TypeScript
164 lines
4.7 KiB
TypeScript
import { skipToken } from '@reduxjs/toolkit/query';
|
|
import { useEffect, useMemo } from 'react';
|
|
|
|
import { useCreateFolder } from 'app/api/clients/folder/v1beta1/hooks';
|
|
import {
|
|
CreateTeamCommand,
|
|
UpdateTeamCommand,
|
|
useCreateTeamMutation,
|
|
useDeleteTeamByIdMutation,
|
|
useGetTeamByIdQuery,
|
|
useSearchTeamsQuery as useLegacySearchTeamsQuery,
|
|
useListTeamsRolesQuery,
|
|
useSetTeamRolesMutation,
|
|
useUpdateTeamMutation,
|
|
} from 'app/api/clients/legacy';
|
|
import { updateNavIndex } from 'app/core/reducers/navModel';
|
|
import { contextSrv } from 'app/core/services/context_srv';
|
|
import { addFilteredDisplayName } from 'app/core/utils/roles';
|
|
import { AccessControlAction, Role } from 'app/types/accessControl';
|
|
import { useDispatch } from 'app/types/store';
|
|
|
|
import { buildNavModel } from './state/navModel';
|
|
|
|
const rolesEnabled =
|
|
contextSrv.licensedAccessControlEnabled() && contextSrv.hasPermission(AccessControlAction.ActionTeamsRolesList);
|
|
|
|
const canUpdateRoles = () =>
|
|
contextSrv.hasPermission(AccessControlAction.ActionUserRolesAdd) &&
|
|
contextSrv.hasPermission(AccessControlAction.ActionUserRolesRemove);
|
|
|
|
/**
|
|
* Get list of teams and their associated roles (if roles are enabled)
|
|
*/
|
|
export const useGetTeams = ({
|
|
query,
|
|
pageSize,
|
|
page,
|
|
sort,
|
|
}: {
|
|
query?: string;
|
|
pageSize?: number;
|
|
page?: number;
|
|
sort?: string;
|
|
}) => {
|
|
const legacyResponse = useLegacySearchTeamsQuery({ perpage: pageSize, accesscontrol: true, page, sort, query });
|
|
|
|
const teamIds = useMemo(() => {
|
|
const teams = legacyResponse.data?.teams || [];
|
|
const ids = teams.map((team) => team.id);
|
|
return ids.filter((id): id is number => id !== undefined);
|
|
}, [legacyResponse.data?.teams]);
|
|
|
|
const teamsRolesResponse = useListTeamsRolesQuery(
|
|
rolesEnabled && teamIds.length ? { rolesSearchQuery: { teamIds } } : skipToken
|
|
);
|
|
|
|
const teamsWithRoles = useMemo(() => {
|
|
if (!rolesEnabled || (rolesEnabled && teamsRolesResponse.isLoading)) {
|
|
return legacyResponse.data?.teams || [];
|
|
}
|
|
return (legacyResponse.data?.teams || []).map((team) => {
|
|
const roles = team.id ? teamsRolesResponse.data?.[team.id] || [] : [];
|
|
const mappedRoles = roles.map((role) => addFilteredDisplayName(role));
|
|
return {
|
|
...team,
|
|
roles: mappedRoles,
|
|
};
|
|
});
|
|
}, [legacyResponse, teamsRolesResponse]);
|
|
|
|
return {
|
|
...legacyResponse,
|
|
isLoading: legacyResponse.isLoading || (rolesEnabled ? teamsRolesResponse.isLoading : false),
|
|
data: {
|
|
teams: teamsWithRoles,
|
|
totalCount: legacyResponse.data?.totalCount,
|
|
},
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Get a single team by UID
|
|
*/
|
|
export const useGetTeam = ({ uid }: { uid: string }) => {
|
|
const response = useGetTeamByIdQuery({ teamId: uid, accesscontrol: true });
|
|
const dispatch = useDispatch();
|
|
|
|
// TODO: Eventually remove and handle nav index logic elsewhere
|
|
useEffect(() => {
|
|
if (response.data) {
|
|
dispatch(updateNavIndex(buildNavModel(response.data)));
|
|
}
|
|
}, [response.data, dispatch]);
|
|
|
|
return response;
|
|
};
|
|
|
|
/**
|
|
* Update a team by UID
|
|
*/
|
|
export const useUpdateTeam = () => {
|
|
const [updateTeam, response] = useUpdateTeamMutation();
|
|
|
|
const trigger = async ({ uid, team }: { uid: string; team: UpdateTeamCommand }) => {
|
|
const mutationResult = await updateTeam({
|
|
teamId: uid,
|
|
updateTeamCommand: team,
|
|
});
|
|
|
|
return mutationResult;
|
|
};
|
|
|
|
return [trigger, response] as const;
|
|
};
|
|
|
|
/**
|
|
* Delete a team by UID
|
|
*/
|
|
export const useDeleteTeam = () => {
|
|
const [deleteTeam, response] = useDeleteTeamByIdMutation();
|
|
|
|
return [({ uid }: { uid: string }) => deleteTeam({ teamId: uid }), response] as const;
|
|
};
|
|
|
|
/**
|
|
* Create a new team, and link any pending roles
|
|
*/
|
|
export const useCreateTeam = () => {
|
|
const [createTeam, response] = useCreateTeamMutation();
|
|
const [setTeamRoles] = useSetTeamRolesMutation();
|
|
const [createFolder] = useCreateFolder();
|
|
|
|
const trigger = async (team: CreateTeamCommand, pendingRoles?: Role[], createTeamFolder?: boolean) => {
|
|
const mutationResult = await createTeam({
|
|
createTeamCommand: team,
|
|
});
|
|
|
|
const { data } = mutationResult;
|
|
|
|
// Add any pending roles to the team
|
|
if (data && data.teamId && pendingRoles && pendingRoles.length) {
|
|
await contextSrv.fetchUserPermissions();
|
|
if (contextSrv.licensedAccessControlEnabled() && canUpdateRoles()) {
|
|
await setTeamRoles({
|
|
teamId: data.teamId,
|
|
setTeamRolesCommand: {
|
|
roleUids: pendingRoles.map((role) => role.uid),
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
if (data && data.uid && createTeamFolder) {
|
|
await createFolder({
|
|
title: team.name,
|
|
teamOwnerReferences: [{ uid: data.uid, name: team.name }],
|
|
});
|
|
}
|
|
|
|
return mutationResult;
|
|
};
|
|
|
|
return [trigger, response] as const;
|
|
};
|