From b82b94a2470e6d6f5889076b20dd4155ec4d473e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Wed, 13 Mar 2019 15:34:38 +0100 Subject: [PATCH] teams: disable buttons for team members --- .../components/DeleteButton/DeleteButton.tsx | 24 +- .../app/features/teams/TeamMembers.test.tsx | 34 +- public/app/features/teams/TeamMembers.tsx | 28 +- .../app/features/teams/__mocks__/teamMocks.ts | 4 +- .../__snapshots__/TeamMembers.test.tsx.snap | 884 ++++++++++++++---- .../features/teams/state/selectors.test.ts | 2 +- 6 files changed, 734 insertions(+), 242 deletions(-) diff --git a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx index df65d156ab3..d262c821968 100644 --- a/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx +++ b/packages/grafana-ui/src/components/DeleteButton/DeleteButton.tsx @@ -2,6 +2,7 @@ import React, { PureComponent, SyntheticEvent } from 'react'; interface Props { onConfirm(): void; + disabled?: boolean; } interface State { @@ -33,25 +34,22 @@ export class DeleteButton extends PureComponent { }; render() { - const { onConfirm } = this.props; - let showConfirm; - let showDeleteButton; - - if (this.state.showConfirm) { - showConfirm = 'show'; - showDeleteButton = 'hide'; - } else { - showConfirm = 'hide'; - showDeleteButton = 'show'; - } + const { onConfirm, disabled } = this.props; + const showConfirmClass = this.state.showConfirm ? 'show' : 'hide'; + const showDeleteButtonClass = this.state.showConfirm ? 'hide' : 'show'; + const disabledClass = disabled ? 'disabled btn-inverse' : ''; + const onClick = disabled ? () => {} : this.onClickDelete; return ( - + - + Cancel diff --git a/public/app/features/teams/TeamMembers.test.tsx b/public/app/features/teams/TeamMembers.test.tsx index 64609f1fd79..f6f0b4a5e49 100644 --- a/public/app/features/teams/TeamMembers.test.tsx +++ b/public/app/features/teams/TeamMembers.test.tsx @@ -6,16 +6,17 @@ import { getMockTeamMember, getMockTeamMembers } from './__mocks__/teamMocks'; import { SelectOptionItem } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; +const signedInUserId = 1; +const originalContextSrv = contextSrv; + jest.mock('app/core/services/context_srv', () => ({ contextSrv: { isGrafanaAdmin: false, hasRole: role => false, - user: { id: 1 }, + user: { id: signedInUserId }, }, })); -const originalContextSrv = contextSrv; - interface SetupProps { propOverrides?: object; isGrafanaAdmin?: boolean; @@ -64,7 +65,7 @@ describe('Render', () => { it('should render team members', () => { const { wrapper } = setup({ propOverrides: { - members: getMockTeamMembers(5), + members: getMockTeamMembers(5, 5), }, }); @@ -74,7 +75,7 @@ describe('Render', () => { it('should render team members when sync enabled', () => { const { wrapper } = setup({ propOverrides: { - members: getMockTeamMembers(5), + members: getMockTeamMembers(5, 5), syncEnabled: true, }, }); @@ -84,8 +85,7 @@ describe('Render', () => { describe('when feature toggle editorsCanAdmin is turned on', () => { it('should render permissions select if user is Grafana Admin', () => { - const members = getMockTeamMembers(5); - members[4].permission = TeamPermissionLevel.Admin; + const members = getMockTeamMembers(5, 5); const { wrapper } = setup({ propOverrides: { members, editorsCanAdmin: true }, isGrafanaAdmin: true, @@ -96,8 +96,7 @@ describe('Render', () => { }); it('should render permissions select if user is Org Admin', () => { - const members = getMockTeamMembers(5); - members[4].permission = TeamPermissionLevel.Admin; + const members = getMockTeamMembers(5, 5); const { wrapper } = setup({ propOverrides: { members, editorsCanAdmin: true }, isGrafanaAdmin: false, @@ -108,8 +107,7 @@ describe('Render', () => { }); it('should render permissions select if user is team admin', () => { - const members = getMockTeamMembers(5); - members[0].permission = TeamPermissionLevel.Admin; + const members = getMockTeamMembers(5, signedInUserId); const { wrapper } = setup({ propOverrides: { members, editorsCanAdmin: true }, isGrafanaAdmin: false, @@ -118,6 +116,20 @@ describe('Render', () => { expect(wrapper).toMatchSnapshot(); }); + + it('should render span and disable buttons if user is team member', () => { + const members = getMockTeamMembers(5, 5); + const { wrapper } = setup({ + propOverrides: { + members, + editorsCanAdmin: true, + }, + isGrafanaAdmin: false, + isOrgAdmin: false, + }); + + expect(wrapper).toMatchSnapshot(); + }); }); }); diff --git a/public/app/features/teams/TeamMembers.tsx b/public/app/features/teams/TeamMembers.tsx index 89ad24f9c58..fc5706ec68f 100644 --- a/public/app/features/teams/TeamMembers.tsx +++ b/public/app/features/teams/TeamMembers.tsx @@ -39,7 +39,7 @@ export class TeamMembers extends PureComponent { constructor(props) { super(props); this.state = { isAdding: false, newTeamMember: null }; - this.renderPermissionsSelect = this.renderPermissionsSelect.bind(this); + this.renderPermissions = this.renderPermissions.bind(this); } componentDidMount() { @@ -88,13 +88,19 @@ export class TeamMembers extends PureComponent { this.props.updateTeamMember(updatedTeamMember); }; - renderPermissionsSelect(member: TeamMember) { + private isSignedInUserTeamAdmin = () => { const { members, editorsCanAdmin } = this.props; const userInMembers = members.find(m => m.userId === contextSrv.user.id); - const isUserTeamAdmin = - contextSrv.isGrafanaAdmin || contextSrv.hasRole(OrgRole.Admin) - ? true - : userInMembers && userInMembers.permission === TeamPermissionLevel.Admin; + const isAdmin = contextSrv.isGrafanaAdmin || contextSrv.hasRole(OrgRole.Admin); + const userIsTeamAdmin = userInMembers && userInMembers.permission === TeamPermissionLevel.Admin; + const isSignedInUserTeamAdmin = isAdmin || userIsTeamAdmin; + + return isSignedInUserTeamAdmin || !editorsCanAdmin; + }; + + renderPermissions(member: TeamMember) { + const { editorsCanAdmin } = this.props; + const isUserTeamAdmin = this.isSignedInUserTeamAdmin(); const value = teamsPermissionLevels.find(dp => dp.value === member.permission); return ( @@ -125,10 +131,10 @@ export class TeamMembers extends PureComponent { {member.login} {member.email} - {this.renderPermissionsSelect(member)} + {this.renderPermissions(member)} {syncEnabled && this.renderLabels(member.labels)} - this.onRemoveMember(member)} /> + this.onRemoveMember(member)} disabled={!this.isSignedInUserTeamAdmin()} /> ); @@ -152,7 +158,11 @@ export class TeamMembers extends PureComponent {
-
diff --git a/public/app/features/teams/__mocks__/teamMocks.ts b/public/app/features/teams/__mocks__/teamMocks.ts index 3f0830eda16..f38f8f2b144 100644 --- a/public/app/features/teams/__mocks__/teamMocks.ts +++ b/public/app/features/teams/__mocks__/teamMocks.ts @@ -25,7 +25,7 @@ export const getMockTeam = (): Team => { }; }; -export const getMockTeamMembers = (amount: number): TeamMember[] => { +export const getMockTeamMembers = (amount: number, teamAdminId: number): TeamMember[] => { const teamMembers: TeamMember[] = []; for (let i = 1; i <= amount; i++) { @@ -36,7 +36,7 @@ export const getMockTeamMembers = (amount: number): TeamMember[] => { email: 'test@test.com', login: `testUser-${i}`, labels: ['label 1', 'label 2'], - permission: TeamPermissionLevel.Member, + permission: i === teamAdminId ? TeamPermissionLevel.Admin : TeamPermissionLevel.Member, }); } diff --git a/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap b/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap index 77b50436590..da89d26d191 100644 --- a/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap +++ b/public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap @@ -201,9 +201,41 @@ exports[`Render should render team members 1`] = `
- - Member - +
@@ -249,6 +314,7 @@ exports[`Render should render team members 1`] = ` className="text-right" > @@ -277,9 +343,41 @@ exports[`Render should render team members 1`] = `
- - Member - +
@@ -325,6 +456,7 @@ exports[`Render should render team members 1`] = ` className="text-right" > @@ -353,9 +485,41 @@ exports[`Render should render team members 1`] = `
- - Member - +
@@ -510,6 +707,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > @@ -538,9 +736,41 @@ exports[`Render should render team members when sync enabled 1`] = `
- - Member - +
@@ -618,6 +881,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > @@ -646,9 +910,41 @@ exports[`Render should render team members when sync enabled 1`] = `
- - Member - +
@@ -726,6 +1055,7 @@ exports[`Render should render team members when sync enabled 1`] = ` className="text-right" > @@ -888,6 +1218,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -958,6 +1289,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1028,6 +1360,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1098,6 +1431,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1168,6 +1502,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1330,6 +1665,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1400,6 +1736,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1470,6 +1807,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1540,6 +1878,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1610,6 +1949,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p className="text-right" > @@ -1641,7 +1981,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p />