Commit b82b94a2 by Hugo Häggmark Committed by Leonard Gram

teams: disable buttons for team members

parent b60e71c2
...@@ -2,6 +2,7 @@ import React, { PureComponent, SyntheticEvent } from 'react'; ...@@ -2,6 +2,7 @@ import React, { PureComponent, SyntheticEvent } from 'react';
interface Props { interface Props {
onConfirm(): void; onConfirm(): void;
disabled?: boolean;
} }
interface State { interface State {
...@@ -33,25 +34,22 @@ export class DeleteButton extends PureComponent<Props, State> { ...@@ -33,25 +34,22 @@ export class DeleteButton extends PureComponent<Props, State> {
}; };
render() { render() {
const { onConfirm } = this.props; const { onConfirm, disabled } = this.props;
let showConfirm; const showConfirmClass = this.state.showConfirm ? 'show' : 'hide';
let showDeleteButton; const showDeleteButtonClass = this.state.showConfirm ? 'hide' : 'show';
const disabledClass = disabled ? 'disabled btn-inverse' : '';
if (this.state.showConfirm) { const onClick = disabled ? () => {} : this.onClickDelete;
showConfirm = 'show';
showDeleteButton = 'hide';
} else {
showConfirm = 'hide';
showDeleteButton = 'show';
}
return ( return (
<span className="delete-button-container"> <span className="delete-button-container">
<a className={'delete-button ' + showDeleteButton + ' btn btn-danger btn-small'} onClick={this.onClickDelete}> <a
className={`delete-button ${showDeleteButtonClass} btn btn-danger btn-small ${disabledClass}`}
onClick={onClick}
>
<i className="fa fa-remove" /> <i className="fa fa-remove" />
</a> </a>
<span className="confirm-delete-container"> <span className="confirm-delete-container">
<span className={'confirm-delete ' + showConfirm}> <span className={`confirm-delete ${showConfirmClass}`}>
<a className="btn btn-small" onClick={this.onClickCancel}> <a className="btn btn-small" onClick={this.onClickCancel}>
Cancel Cancel
</a> </a>
......
...@@ -6,16 +6,17 @@ import { getMockTeamMember, getMockTeamMembers } from './__mocks__/teamMocks'; ...@@ -6,16 +6,17 @@ import { getMockTeamMember, getMockTeamMembers } from './__mocks__/teamMocks';
import { SelectOptionItem } from '@grafana/ui'; import { SelectOptionItem } from '@grafana/ui';
import { contextSrv } from 'app/core/services/context_srv'; import { contextSrv } from 'app/core/services/context_srv';
const signedInUserId = 1;
const originalContextSrv = contextSrv;
jest.mock('app/core/services/context_srv', () => ({ jest.mock('app/core/services/context_srv', () => ({
contextSrv: { contextSrv: {
isGrafanaAdmin: false, isGrafanaAdmin: false,
hasRole: role => false, hasRole: role => false,
user: { id: 1 }, user: { id: signedInUserId },
}, },
})); }));
const originalContextSrv = contextSrv;
interface SetupProps { interface SetupProps {
propOverrides?: object; propOverrides?: object;
isGrafanaAdmin?: boolean; isGrafanaAdmin?: boolean;
...@@ -64,7 +65,7 @@ describe('Render', () => { ...@@ -64,7 +65,7 @@ describe('Render', () => {
it('should render team members', () => { it('should render team members', () => {
const { wrapper } = setup({ const { wrapper } = setup({
propOverrides: { propOverrides: {
members: getMockTeamMembers(5), members: getMockTeamMembers(5, 5),
}, },
}); });
...@@ -74,7 +75,7 @@ describe('Render', () => { ...@@ -74,7 +75,7 @@ describe('Render', () => {
it('should render team members when sync enabled', () => { it('should render team members when sync enabled', () => {
const { wrapper } = setup({ const { wrapper } = setup({
propOverrides: { propOverrides: {
members: getMockTeamMembers(5), members: getMockTeamMembers(5, 5),
syncEnabled: true, syncEnabled: true,
}, },
}); });
...@@ -84,8 +85,7 @@ describe('Render', () => { ...@@ -84,8 +85,7 @@ describe('Render', () => {
describe('when feature toggle editorsCanAdmin is turned on', () => { describe('when feature toggle editorsCanAdmin is turned on', () => {
it('should render permissions select if user is Grafana Admin', () => { it('should render permissions select if user is Grafana Admin', () => {
const members = getMockTeamMembers(5); const members = getMockTeamMembers(5, 5);
members[4].permission = TeamPermissionLevel.Admin;
const { wrapper } = setup({ const { wrapper } = setup({
propOverrides: { members, editorsCanAdmin: true }, propOverrides: { members, editorsCanAdmin: true },
isGrafanaAdmin: true, isGrafanaAdmin: true,
...@@ -96,8 +96,7 @@ describe('Render', () => { ...@@ -96,8 +96,7 @@ describe('Render', () => {
}); });
it('should render permissions select if user is Org Admin', () => { it('should render permissions select if user is Org Admin', () => {
const members = getMockTeamMembers(5); const members = getMockTeamMembers(5, 5);
members[4].permission = TeamPermissionLevel.Admin;
const { wrapper } = setup({ const { wrapper } = setup({
propOverrides: { members, editorsCanAdmin: true }, propOverrides: { members, editorsCanAdmin: true },
isGrafanaAdmin: false, isGrafanaAdmin: false,
...@@ -108,8 +107,7 @@ describe('Render', () => { ...@@ -108,8 +107,7 @@ describe('Render', () => {
}); });
it('should render permissions select if user is team admin', () => { it('should render permissions select if user is team admin', () => {
const members = getMockTeamMembers(5); const members = getMockTeamMembers(5, signedInUserId);
members[0].permission = TeamPermissionLevel.Admin;
const { wrapper } = setup({ const { wrapper } = setup({
propOverrides: { members, editorsCanAdmin: true }, propOverrides: { members, editorsCanAdmin: true },
isGrafanaAdmin: false, isGrafanaAdmin: false,
...@@ -118,6 +116,20 @@ describe('Render', () => { ...@@ -118,6 +116,20 @@ describe('Render', () => {
expect(wrapper).toMatchSnapshot(); 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();
});
}); });
}); });
......
...@@ -39,7 +39,7 @@ export class TeamMembers extends PureComponent<Props, State> { ...@@ -39,7 +39,7 @@ export class TeamMembers extends PureComponent<Props, State> {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { isAdding: false, newTeamMember: null }; this.state = { isAdding: false, newTeamMember: null };
this.renderPermissionsSelect = this.renderPermissionsSelect.bind(this); this.renderPermissions = this.renderPermissions.bind(this);
} }
componentDidMount() { componentDidMount() {
...@@ -88,13 +88,19 @@ export class TeamMembers extends PureComponent<Props, State> { ...@@ -88,13 +88,19 @@ export class TeamMembers extends PureComponent<Props, State> {
this.props.updateTeamMember(updatedTeamMember); this.props.updateTeamMember(updatedTeamMember);
}; };
renderPermissionsSelect(member: TeamMember) { private isSignedInUserTeamAdmin = () => {
const { members, editorsCanAdmin } = this.props; const { members, editorsCanAdmin } = this.props;
const userInMembers = members.find(m => m.userId === contextSrv.user.id); const userInMembers = members.find(m => m.userId === contextSrv.user.id);
const isUserTeamAdmin = const isAdmin = contextSrv.isGrafanaAdmin || contextSrv.hasRole(OrgRole.Admin);
contextSrv.isGrafanaAdmin || contextSrv.hasRole(OrgRole.Admin) const userIsTeamAdmin = userInMembers && userInMembers.permission === TeamPermissionLevel.Admin;
? true const isSignedInUserTeamAdmin = isAdmin || userIsTeamAdmin;
: userInMembers && userInMembers.permission === TeamPermissionLevel.Admin;
return isSignedInUserTeamAdmin || !editorsCanAdmin;
};
renderPermissions(member: TeamMember) {
const { editorsCanAdmin } = this.props;
const isUserTeamAdmin = this.isSignedInUserTeamAdmin();
const value = teamsPermissionLevels.find(dp => dp.value === member.permission); const value = teamsPermissionLevels.find(dp => dp.value === member.permission);
return ( return (
...@@ -125,10 +131,10 @@ export class TeamMembers extends PureComponent<Props, State> { ...@@ -125,10 +131,10 @@ export class TeamMembers extends PureComponent<Props, State> {
</td> </td>
<td>{member.login}</td> <td>{member.login}</td>
<td>{member.email}</td> <td>{member.email}</td>
{this.renderPermissionsSelect(member)} {this.renderPermissions(member)}
{syncEnabled && this.renderLabels(member.labels)} {syncEnabled && this.renderLabels(member.labels)}
<td className="text-right"> <td className="text-right">
<DeleteButton onConfirm={() => this.onRemoveMember(member)} /> <DeleteButton onConfirm={() => this.onRemoveMember(member)} disabled={!this.isSignedInUserTeamAdmin()} />
</td> </td>
</tr> </tr>
); );
...@@ -152,7 +158,11 @@ export class TeamMembers extends PureComponent<Props, State> { ...@@ -152,7 +158,11 @@ export class TeamMembers extends PureComponent<Props, State> {
<div className="page-action-bar__spacer" /> <div className="page-action-bar__spacer" />
<button className="btn btn-primary pull-right" onClick={this.onToggleAdding} disabled={isAdding}> <button
className="btn btn-primary pull-right"
onClick={this.onToggleAdding}
disabled={isAdding || !this.isSignedInUserTeamAdmin()}
>
Add member Add member
</button> </button>
</div> </div>
......
...@@ -25,7 +25,7 @@ export const getMockTeam = (): Team => { ...@@ -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[] = []; const teamMembers: TeamMember[] = [];
for (let i = 1; i <= amount; i++) { for (let i = 1; i <= amount; i++) {
...@@ -36,7 +36,7 @@ export const getMockTeamMembers = (amount: number): TeamMember[] => { ...@@ -36,7 +36,7 @@ export const getMockTeamMembers = (amount: number): TeamMember[] => {
email: 'test@test.com', email: 'test@test.com',
login: `testUser-${i}`, login: `testUser-${i}`,
labels: ['label 1', 'label 2'], labels: ['label 1', 'label 2'],
permission: TeamPermissionLevel.Member, permission: i === teamAdminId ? TeamPermissionLevel.Admin : TeamPermissionLevel.Member,
}); });
} }
......
...@@ -40,7 +40,7 @@ describe('Team selectors', () => { ...@@ -40,7 +40,7 @@ describe('Team selectors', () => {
}); });
describe('Get members', () => { describe('Get members', () => {
const mockTeamMembers = getMockTeamMembers(5); const mockTeamMembers = getMockTeamMembers(5, 5);
it('should return team members', () => { it('should return team members', () => {
const mockState: TeamState = { const mockState: TeamState = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment