Team: front end cleanup (#97945)

* Remove permissions levels that don't exists for team memberships

* Remove Permission from team structure

* Use WithAccessControlMetadata

* Remove roles from base Team interface
This commit is contained in:
Karl Persson 2024-12-16 10:39:29 +01:00 committed by GitHub
parent 1ac6143f4e
commit 97959b60bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 23 additions and 27 deletions

View File

@ -8,7 +8,6 @@ import * as useQueryParams from 'app/core/hooks/useQueryParams';
import { TestProvider } from '../../../test/helpers/TestProvider'; import { TestProvider } from '../../../test/helpers/TestProvider';
import { backendSrv } from '../../core/services/backend_srv'; import { backendSrv } from '../../core/services/backend_srv';
import { TeamPermissionLevel } from '../../types';
import { getMockTeam } from '../teams/__mocks__/teamMocks'; import { getMockTeam } from '../teams/__mocks__/teamMocks';
import { Props, UserProfileEditPage } from './UserProfileEditPage'; import { Props, UserProfileEditPage } from './UserProfileEditPage';
@ -45,7 +44,6 @@ const defaultProps: Props = {
email: 'team.one@test.com', email: 'team.one@test.com',
avatarUrl: '/avatar/07d881f402480a2a511a9a15b5fa82c0', avatarUrl: '/avatar/07d881f402480a2a511a9a15b5fa82c0',
memberCount: 2000, memberCount: 2000,
permission: TeamPermissionLevel.Admin,
}), }),
], ],
orgs: [ orgs: [

View File

@ -1,5 +1,5 @@
import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { reducerTester } from '../../../../test/core/redux/reducerTester';
import { OrgRole, TeamPermissionLevel } from '../../../types'; import { OrgRole } from '../../../types';
import { getMockTeam } from '../../teams/__mocks__/teamMocks'; import { getMockTeam } from '../../teams/__mocks__/teamMocks';
import { import {
@ -92,13 +92,13 @@ describe('userReducer', () => {
.givenReducer(userReducer, { ...initialUserState, teamsAreLoading: true }) .givenReducer(userReducer, { ...initialUserState, teamsAreLoading: true })
.whenActionIsDispatched( .whenActionIsDispatched(
teamsLoaded({ teamsLoaded({
teams: [getMockTeam(1, 'aaaaaa', { permission: TeamPermissionLevel.Admin })], teams: [getMockTeam(1, 'aaaaaa')],
}) })
) )
.thenStateShouldEqual({ .thenStateShouldEqual({
...initialUserState, ...initialUserState,
teamsAreLoading: false, teamsAreLoading: false,
teams: [getMockTeam(1, 'aaaaaa', { permission: TeamPermissionLevel.Admin })], teams: [getMockTeam(1, 'aaaaaa')],
}); });
}); });
}); });

View File

@ -23,13 +23,13 @@ import { Page } from 'app/core/components/Page/Page';
import { fetchRoleOptions } from 'app/core/components/RolePicker/api'; import { fetchRoleOptions } from 'app/core/components/RolePicker/api';
import { Trans, t } from 'app/core/internationalization'; import { Trans, t } from 'app/core/internationalization';
import { contextSrv } from 'app/core/services/context_srv'; import { contextSrv } from 'app/core/services/context_srv';
import { AccessControlAction, Role, StoreState, Team } from 'app/types'; import { AccessControlAction, Role, StoreState, TeamWithRoles } from 'app/types';
import { TeamRolePicker } from '../../core/components/RolePicker/TeamRolePicker'; import { TeamRolePicker } from '../../core/components/RolePicker/TeamRolePicker';
import { deleteTeam, loadTeams, changePage, changeQuery, changeSort } from './state/actions'; import { deleteTeam, loadTeams, changePage, changeQuery, changeSort } from './state/actions';
type Cell<T extends keyof Team = keyof Team> = CellProps<Team, Team[T]>; type Cell<T extends keyof TeamWithRoles = keyof TeamWithRoles> = CellProps<TeamWithRoles, TeamWithRoles[T]>;
export interface OwnProps {} export interface OwnProps {}
export interface State { export interface State {
@ -37,13 +37,12 @@ export interface State {
} }
// this is dummy data to pass to the table while the real data is loading // this is dummy data to pass to the table while the real data is loading
const skeletonData: Team[] = new Array(3).fill(null).map((_, index) => ({ const skeletonData: TeamWithRoles[] = new Array(3).fill(null).map((_, index) => ({
id: index, id: index,
uid: '', uid: '',
memberCount: 0, memberCount: 0,
name: '', name: '',
orgId: 0, orgId: 0,
permission: 0,
})); }));
export const TeamList = ({ export const TeamList = ({
@ -76,7 +75,7 @@ export const TeamList = ({
const canCreate = contextSrv.hasPermission(AccessControlAction.ActionTeamsCreate); const canCreate = contextSrv.hasPermission(AccessControlAction.ActionTeamsCreate);
const displayRolePicker = shouldDisplayRolePicker(); const displayRolePicker = shouldDisplayRolePicker();
const columns: Array<Column<Team>> = useMemo( const columns: Array<Column<TeamWithRoles>> = useMemo(
() => [ () => [
{ {
id: 'avatarUrl', id: 'avatarUrl',

View File

@ -24,7 +24,6 @@ export const getMockTeam = (i = 1, uid = 'aaaaaa', overrides = {}): Team => {
avatarUrl: 'some/url/', avatarUrl: 'some/url/',
email: `test-${uid}@test.com`, email: `test-${uid}@test.com`,
memberCount: i, memberCount: i,
permission: TeamPermissionLevel.Member,
accessControl: { isEditor: false }, accessControl: { isEditor: false },
orgId: 0, orgId: 0,
...overrides, ...overrides,

View File

@ -5,7 +5,7 @@ import { FetchDataArgs } from '@grafana/ui';
import { updateNavIndex } from 'app/core/actions'; import { updateNavIndex } from 'app/core/actions';
import { contextSrv } from 'app/core/core'; import { contextSrv } from 'app/core/core';
import { accessControlQueryParam } from 'app/core/utils/accessControl'; import { accessControlQueryParam } from 'app/core/utils/accessControl';
import { AccessControlAction, Team, TeamMember, ThunkResult } from 'app/types'; import { AccessControlAction, TeamWithRoles, TeamMember, ThunkResult, Team } from 'app/types';
import { buildNavModel } from './navModel'; import { buildNavModel } from './navModel';
import { import {
@ -46,9 +46,9 @@ export function loadTeams(initial = false): ThunkResult<void> {
contextSrv.hasPermission(AccessControlAction.ActionTeamsRolesList) contextSrv.hasPermission(AccessControlAction.ActionTeamsRolesList)
) { ) {
dispatch(rolesFetchBegin()); dispatch(rolesFetchBegin());
const teamIds = response?.teams.map((t: Team) => t.id); const teamIds = response?.teams.map((t: TeamWithRoles) => t.id);
const roles = await getBackendSrv().post(`/api/access-control/teams/roles/search`, { teamIds }); const roles = await getBackendSrv().post(`/api/access-control/teams/roles/search`, { teamIds });
response.teams.forEach((t: Team) => { response.teams.forEach((t: TeamWithRoles) => {
t.roles = roles ? roles[t.id] || [] : []; t.roles = roles ? roles[t.id] || [] : [];
}); });
dispatch(rolesFetchEnd()); dispatch(rolesFetchEnd());

View File

@ -2,9 +2,7 @@ import { OrgRole } from '@grafana/data';
export enum TeamPermissionLevel { export enum TeamPermissionLevel {
Admin = 4, Admin = 4,
Editor = 2,
Member = 0, Member = 0,
Viewer = 1,
} }
export { OrgRole as OrgRole }; export { OrgRole as OrgRole };

View File

@ -1,5 +1,6 @@
import { WithAccessControlMetadata } from '@grafana/data';
import { Role } from './accessControl'; import { Role } from './accessControl';
import { TeamPermissionLevel } from './acl';
export interface TeamDTO { export interface TeamDTO {
/** /**
@ -13,14 +14,16 @@ export interface TeamDTO {
} }
// This is the team resource with permissions and metadata expanded // This is the team resource with permissions and metadata expanded
export interface Team { export interface Team extends WithAccessControlMetadata {
id: number; // TODO switch to UUID
uid: string; // Prefer UUID
/** /**
* AccessControl metadata associated with a given resource. * Internal id of team
* @deprecated use uid instead
*/ */
accessControl?: Record<string, boolean>; id: number;
/**
* A unique identifier for the team.
*/
uid: string; // Prefer UUID
/** /**
* AvatarUrl is the team's avatar URL. * AvatarUrl is the team's avatar URL.
*/ */
@ -41,10 +44,9 @@ export interface Team {
* OrgId is the ID of an organisation the team belongs to. * OrgId is the ID of an organisation the team belongs to.
*/ */
orgId: number; orgId: number;
/** }
* TODO - it seems it's a team_member.permission, unlikely it should belong to the team kind
*/ export interface TeamWithRoles extends Team {
permission: TeamPermissionLevel;
/** /**
* RBAC roles assigned to the team. * RBAC roles assigned to the team.
*/ */