From 97959b60bb63e9f39975b79d89a7732bc1fd3d8c Mon Sep 17 00:00:00 2001 From: Karl Persson Date: Mon, 16 Dec 2024 10:39:29 +0100 Subject: [PATCH] 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 --- .../profile/UserProfileEditPage.test.tsx | 2 -- .../features/profile/state/reducers.test.ts | 6 ++--- public/app/features/teams/TeamList.tsx | 9 ++++--- .../app/features/teams/__mocks__/teamMocks.ts | 1 - public/app/features/teams/state/actions.ts | 6 ++--- public/app/types/acl.ts | 2 -- public/app/types/teams.ts | 24 ++++++++++--------- 7 files changed, 23 insertions(+), 27 deletions(-) diff --git a/public/app/features/profile/UserProfileEditPage.test.tsx b/public/app/features/profile/UserProfileEditPage.test.tsx index 87d3f2bd7dc..9f0adc7cee1 100644 --- a/public/app/features/profile/UserProfileEditPage.test.tsx +++ b/public/app/features/profile/UserProfileEditPage.test.tsx @@ -8,7 +8,6 @@ import * as useQueryParams from 'app/core/hooks/useQueryParams'; import { TestProvider } from '../../../test/helpers/TestProvider'; import { backendSrv } from '../../core/services/backend_srv'; -import { TeamPermissionLevel } from '../../types'; import { getMockTeam } from '../teams/__mocks__/teamMocks'; import { Props, UserProfileEditPage } from './UserProfileEditPage'; @@ -45,7 +44,6 @@ const defaultProps: Props = { email: 'team.one@test.com', avatarUrl: '/avatar/07d881f402480a2a511a9a15b5fa82c0', memberCount: 2000, - permission: TeamPermissionLevel.Admin, }), ], orgs: [ diff --git a/public/app/features/profile/state/reducers.test.ts b/public/app/features/profile/state/reducers.test.ts index c0f62ef1591..352f824cc55 100644 --- a/public/app/features/profile/state/reducers.test.ts +++ b/public/app/features/profile/state/reducers.test.ts @@ -1,5 +1,5 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { OrgRole, TeamPermissionLevel } from '../../../types'; +import { OrgRole } from '../../../types'; import { getMockTeam } from '../../teams/__mocks__/teamMocks'; import { @@ -92,13 +92,13 @@ describe('userReducer', () => { .givenReducer(userReducer, { ...initialUserState, teamsAreLoading: true }) .whenActionIsDispatched( teamsLoaded({ - teams: [getMockTeam(1, 'aaaaaa', { permission: TeamPermissionLevel.Admin })], + teams: [getMockTeam(1, 'aaaaaa')], }) ) .thenStateShouldEqual({ ...initialUserState, teamsAreLoading: false, - teams: [getMockTeam(1, 'aaaaaa', { permission: TeamPermissionLevel.Admin })], + teams: [getMockTeam(1, 'aaaaaa')], }); }); }); diff --git a/public/app/features/teams/TeamList.tsx b/public/app/features/teams/TeamList.tsx index 35dd58c3355..a3c1155ade9 100644 --- a/public/app/features/teams/TeamList.tsx +++ b/public/app/features/teams/TeamList.tsx @@ -23,13 +23,13 @@ import { Page } from 'app/core/components/Page/Page'; import { fetchRoleOptions } from 'app/core/components/RolePicker/api'; import { Trans, t } from 'app/core/internationalization'; 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 { deleteTeam, loadTeams, changePage, changeQuery, changeSort } from './state/actions'; -type Cell = CellProps; +type Cell = CellProps; export interface OwnProps {} 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 -const skeletonData: Team[] = new Array(3).fill(null).map((_, index) => ({ +const skeletonData: TeamWithRoles[] = new Array(3).fill(null).map((_, index) => ({ id: index, uid: '', memberCount: 0, name: '', orgId: 0, - permission: 0, })); export const TeamList = ({ @@ -76,7 +75,7 @@ export const TeamList = ({ const canCreate = contextSrv.hasPermission(AccessControlAction.ActionTeamsCreate); const displayRolePicker = shouldDisplayRolePicker(); - const columns: Array> = useMemo( + const columns: Array> = useMemo( () => [ { id: 'avatarUrl', diff --git a/public/app/features/teams/__mocks__/teamMocks.ts b/public/app/features/teams/__mocks__/teamMocks.ts index 5cfbe77a143..1e75b8a6283 100644 --- a/public/app/features/teams/__mocks__/teamMocks.ts +++ b/public/app/features/teams/__mocks__/teamMocks.ts @@ -24,7 +24,6 @@ export const getMockTeam = (i = 1, uid = 'aaaaaa', overrides = {}): Team => { avatarUrl: 'some/url/', email: `test-${uid}@test.com`, memberCount: i, - permission: TeamPermissionLevel.Member, accessControl: { isEditor: false }, orgId: 0, ...overrides, diff --git a/public/app/features/teams/state/actions.ts b/public/app/features/teams/state/actions.ts index 38f3a110a97..32c0e1fdd22 100644 --- a/public/app/features/teams/state/actions.ts +++ b/public/app/features/teams/state/actions.ts @@ -5,7 +5,7 @@ import { FetchDataArgs } from '@grafana/ui'; import { updateNavIndex } from 'app/core/actions'; import { contextSrv } from 'app/core/core'; 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 { @@ -46,9 +46,9 @@ export function loadTeams(initial = false): ThunkResult { contextSrv.hasPermission(AccessControlAction.ActionTeamsRolesList) ) { 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 }); - response.teams.forEach((t: Team) => { + response.teams.forEach((t: TeamWithRoles) => { t.roles = roles ? roles[t.id] || [] : []; }); dispatch(rolesFetchEnd()); diff --git a/public/app/types/acl.ts b/public/app/types/acl.ts index 3cbb2c110e1..b939d67c726 100644 --- a/public/app/types/acl.ts +++ b/public/app/types/acl.ts @@ -2,9 +2,7 @@ import { OrgRole } from '@grafana/data'; export enum TeamPermissionLevel { Admin = 4, - Editor = 2, Member = 0, - Viewer = 1, } export { OrgRole as OrgRole }; diff --git a/public/app/types/teams.ts b/public/app/types/teams.ts index 52407a544f9..26f4e6f3aa7 100644 --- a/public/app/types/teams.ts +++ b/public/app/types/teams.ts @@ -1,5 +1,6 @@ +import { WithAccessControlMetadata } from '@grafana/data'; + import { Role } from './accessControl'; -import { TeamPermissionLevel } from './acl'; export interface TeamDTO { /** @@ -13,14 +14,16 @@ export interface TeamDTO { } // This is the team resource with permissions and metadata expanded -export interface Team { - id: number; // TODO switch to UUID - uid: string; // Prefer UUID - +export interface Team extends WithAccessControlMetadata { /** - * AccessControl metadata associated with a given resource. + * Internal id of team + * @deprecated use uid instead */ - accessControl?: Record; + id: number; + /** + * A unique identifier for the team. + */ + uid: string; // Prefer UUID /** * 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: number; - /** - * TODO - it seems it's a team_member.permission, unlikely it should belong to the team kind - */ - permission: TeamPermissionLevel; +} + +export interface TeamWithRoles extends Team { /** * RBAC roles assigned to the team. */