teams: disable buttons for team members

This commit is contained in:
Hugo Häggmark 2019-03-13 15:34:38 +01:00 committed by Leonard Gram
parent b60e71c28b
commit b82b94a247
6 changed files with 734 additions and 242 deletions

View File

@ -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<Props, State> {
};
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 (
<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" />
</a>
<span className="confirm-delete-container">
<span className={'confirm-delete ' + showConfirm}>
<span className={`confirm-delete ${showConfirmClass}`}>
<a className="btn btn-small" onClick={this.onClickCancel}>
Cancel
</a>

View File

@ -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();
});
});
});

View File

@ -39,7 +39,7 @@ export class TeamMembers extends PureComponent<Props, State> {
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<Props, State> {
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<Props, State> {
</td>
<td>{member.login}</td>
<td>{member.email}</td>
{this.renderPermissionsSelect(member)}
{this.renderPermissions(member)}
{syncEnabled && this.renderLabels(member.labels)}
<td className="text-right">
<DeleteButton onConfirm={() => this.onRemoveMember(member)} />
<DeleteButton onConfirm={() => this.onRemoveMember(member)} disabled={!this.isSignedInUserTeamAdmin()} />
</td>
</tr>
);
@ -152,7 +158,11 @@ export class TeamMembers extends PureComponent<Props, State> {
<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
</button>
</div>

View File

@ -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,
});
}

View File

@ -40,7 +40,7 @@ describe('Team selectors', () => {
});
describe('Get members', () => {
const mockTeamMembers = getMockTeamMembers(5);
const mockTeamMembers = getMockTeamMembers(5, 5);
it('should return team members', () => {
const mockState: TeamState = {