mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactor: splitted TeamMembers to TeamMemberRow
This commit is contained in:
parent
6a63725df0
commit
178d637b4e
82
public/app/features/teams/TeamMemberRow.test.tsx
Normal file
82
public/app/features/teams/TeamMemberRow.test.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { TeamMember, TeamPermissionLevel } from '../../types';
|
||||
import { getMockTeamMember } from './__mocks__/teamMocks';
|
||||
import { TeamMemberRow, Props } from './TeamMemberRow';
|
||||
import { SelectOptionItem } from '@grafana/ui';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
member: getMockTeamMember(),
|
||||
syncEnabled: false,
|
||||
editorsCanAdmin: false,
|
||||
signedInUserIsTeamAdmin: false,
|
||||
updateTeamMember: jest.fn(),
|
||||
removeTeamMember: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = shallow(<TeamMemberRow {...props} />);
|
||||
const instance = wrapper.instance() as TeamMemberRow;
|
||||
|
||||
return {
|
||||
wrapper,
|
||||
instance,
|
||||
};
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
describe('when feature toggle editorsCanAdmin is turned on', () => {
|
||||
it('should render permissions select if user is team admin', () => {
|
||||
const { wrapper } = setup({ editorsCanAdmin: true, signedInUserIsTeamAdmin: true });
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render span and disable buttons if user is team member', () => {
|
||||
const { wrapper } = setup({ editorsCanAdmin: true, signedInUserIsTeamAdmin: false });
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when feature toggle editorsCanAdmin is turned off', () => {
|
||||
it('should not render permissions', () => {
|
||||
const { wrapper } = setup({ editorsCanAdmin: false, signedInUserIsTeamAdmin: true });
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Functions', () => {
|
||||
describe('on remove member', () => {
|
||||
const member = getMockTeamMember();
|
||||
const { instance } = setup({ member });
|
||||
|
||||
instance.onRemoveMember(member);
|
||||
|
||||
expect(instance.props.removeTeamMember).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
describe('on update permision for user in team', () => {
|
||||
const member: TeamMember = {
|
||||
userId: 3,
|
||||
teamId: 2,
|
||||
avatarUrl: '',
|
||||
email: 'user@user.org',
|
||||
labels: [],
|
||||
login: 'member',
|
||||
permission: TeamPermissionLevel.Member,
|
||||
};
|
||||
const { instance } = setup({ member });
|
||||
const permission = TeamPermissionLevel.Admin;
|
||||
const item: SelectOptionItem = { value: permission };
|
||||
const expectedTeamMemeber = { ...member, permission };
|
||||
|
||||
instance.onPermissionChange(item, member);
|
||||
|
||||
expect(instance.props.updateTeamMember).toHaveBeenCalledWith(expectedTeamMemeber);
|
||||
});
|
||||
});
|
106
public/app/features/teams/TeamMemberRow.tsx
Normal file
106
public/app/features/teams/TeamMemberRow.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { DeleteButton, Select, SelectOptionItem } from '@grafana/ui';
|
||||
|
||||
import { TeamMember, teamsPermissionLevels } from 'app/types';
|
||||
import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle';
|
||||
import { updateTeamMember, removeTeamMember } from './state/actions';
|
||||
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
|
||||
|
||||
export interface Props {
|
||||
member: TeamMember;
|
||||
syncEnabled: boolean;
|
||||
editorsCanAdmin: boolean;
|
||||
signedInUserIsTeamAdmin: boolean;
|
||||
removeTeamMember?: typeof removeTeamMember;
|
||||
updateTeamMember?: typeof updateTeamMember;
|
||||
}
|
||||
|
||||
export class TeamMemberRow extends PureComponent<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.renderLabels = this.renderLabels.bind(this);
|
||||
this.renderPermissions = this.renderPermissions.bind(this);
|
||||
}
|
||||
|
||||
onRemoveMember(member: TeamMember) {
|
||||
this.props.removeTeamMember(member.userId);
|
||||
}
|
||||
|
||||
onPermissionChange = (item: SelectOptionItem, member: TeamMember) => {
|
||||
const permission = item.value;
|
||||
const updatedTeamMember = { ...member, permission };
|
||||
|
||||
this.props.updateTeamMember(updatedTeamMember);
|
||||
};
|
||||
|
||||
renderPermissions(member: TeamMember) {
|
||||
const { editorsCanAdmin, signedInUserIsTeamAdmin } = this.props;
|
||||
const value = teamsPermissionLevels.find(dp => dp.value === member.permission);
|
||||
|
||||
return (
|
||||
<WithFeatureToggle featureToggle={editorsCanAdmin}>
|
||||
<td>
|
||||
<div className="gf-form">
|
||||
{signedInUserIsTeamAdmin && (
|
||||
<Select
|
||||
isSearchable={false}
|
||||
options={teamsPermissionLevels}
|
||||
onChange={item => this.onPermissionChange(item, member)}
|
||||
className="gf-form-select-box__control--menu-right"
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
{!signedInUserIsTeamAdmin && <span>{value.label}</span>}
|
||||
</div>
|
||||
</td>
|
||||
</WithFeatureToggle>
|
||||
);
|
||||
}
|
||||
|
||||
renderLabels(labels: string[]) {
|
||||
if (!labels) {
|
||||
return <td />;
|
||||
}
|
||||
|
||||
return (
|
||||
<td>
|
||||
{labels.map(label => (
|
||||
<TagBadge key={label} label={label} removeIcon={false} count={0} onClick={() => {}} />
|
||||
))}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { member, syncEnabled, signedInUserIsTeamAdmin } = this.props;
|
||||
return (
|
||||
<tr key={member.userId}>
|
||||
<td className="width-4 text-center">
|
||||
<img className="filter-table__avatar" src={member.avatarUrl} />
|
||||
</td>
|
||||
<td>{member.login}</td>
|
||||
<td>{member.email}</td>
|
||||
{this.renderPermissions(member)}
|
||||
{syncEnabled && this.renderLabels(member.labels)}
|
||||
<td className="text-right">
|
||||
<DeleteButton onConfirm={() => this.onRemoveMember(member)} disabled={!signedInUserIsTeamAdmin} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
removeTeamMember,
|
||||
updateTeamMember,
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(TeamMemberRow);
|
@ -1,45 +1,29 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { TeamMembers, Props, State } from './TeamMembers';
|
||||
import { TeamMember, TeamPermissionLevel } from '../../types';
|
||||
import { getMockTeamMember, getMockTeamMembers } from './__mocks__/teamMocks';
|
||||
import { SelectOptionItem } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { TeamMember, OrgRole } from '../../types';
|
||||
import { getMockTeamMembers } from './__mocks__/teamMocks';
|
||||
import { User } 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: signedInUserId },
|
||||
},
|
||||
}));
|
||||
|
||||
interface SetupProps {
|
||||
propOverrides?: object;
|
||||
isGrafanaAdmin?: boolean;
|
||||
isOrgAdmin?: boolean;
|
||||
}
|
||||
|
||||
const setup = (setupProps: SetupProps) => {
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
members: [] as TeamMember[],
|
||||
searchMemberQuery: '',
|
||||
setSearchMemberQuery: jest.fn(),
|
||||
loadTeamMembers: jest.fn(),
|
||||
addTeamMember: jest.fn(),
|
||||
removeTeamMember: jest.fn(),
|
||||
updateTeamMember: jest.fn(),
|
||||
syncEnabled: false,
|
||||
editorsCanAdmin: false,
|
||||
signedInUser: {
|
||||
id: signedInUserId,
|
||||
isGrafanaAdmin: false,
|
||||
orgRole: OrgRole.Viewer,
|
||||
} as User,
|
||||
};
|
||||
|
||||
contextSrv.isGrafanaAdmin = setupProps.isGrafanaAdmin || false;
|
||||
contextSrv.hasRole = role => setupProps.isOrgAdmin || false;
|
||||
|
||||
Object.assign(props, setupProps.propOverrides);
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = shallow(<TeamMembers {...props} />);
|
||||
const instance = wrapper.instance() as TeamMembers;
|
||||
@ -51,11 +35,6 @@ const setup = (setupProps: SetupProps) => {
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
beforeEach(() => {
|
||||
contextSrv.isGrafanaAdmin = originalContextSrv.isGrafanaAdmin;
|
||||
contextSrv.hasRole = originalContextSrv.hasRole;
|
||||
});
|
||||
|
||||
it('should render component', () => {
|
||||
const { wrapper } = setup({});
|
||||
|
||||
@ -63,74 +42,16 @@ describe('Render', () => {
|
||||
});
|
||||
|
||||
it('should render team members', () => {
|
||||
const { wrapper } = setup({
|
||||
propOverrides: {
|
||||
members: getMockTeamMembers(5, 5),
|
||||
},
|
||||
});
|
||||
const { wrapper } = setup({ members: getMockTeamMembers(5, 5) });
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render team members when sync enabled', () => {
|
||||
const { wrapper } = setup({
|
||||
propOverrides: {
|
||||
members: getMockTeamMembers(5, 5),
|
||||
syncEnabled: true,
|
||||
},
|
||||
});
|
||||
const { wrapper } = setup({ members: getMockTeamMembers(5, 5), syncEnabled: true });
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('when feature toggle editorsCanAdmin is turned on', () => {
|
||||
it('should render permissions select if user is Grafana Admin', () => {
|
||||
const members = getMockTeamMembers(5, 5);
|
||||
const { wrapper } = setup({
|
||||
propOverrides: { members, editorsCanAdmin: true },
|
||||
isGrafanaAdmin: true,
|
||||
isOrgAdmin: false,
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render permissions select if user is Org Admin', () => {
|
||||
const members = getMockTeamMembers(5, 5);
|
||||
const { wrapper } = setup({
|
||||
propOverrides: { members, editorsCanAdmin: true },
|
||||
isGrafanaAdmin: false,
|
||||
isOrgAdmin: true,
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render permissions select if user is team admin', () => {
|
||||
const members = getMockTeamMembers(5, signedInUserId);
|
||||
const { wrapper } = setup({
|
||||
propOverrides: { members, editorsCanAdmin: true },
|
||||
isGrafanaAdmin: false,
|
||||
isOrgAdmin: false,
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Functions', () => {
|
||||
@ -144,15 +65,6 @@ describe('Functions', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('on remove member', () => {
|
||||
const { instance } = setup({});
|
||||
const mockTeamMember = getMockTeamMember();
|
||||
|
||||
instance.onRemoveMember(mockTeamMember);
|
||||
|
||||
expect(instance.props.removeTeamMember).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
describe('on add user to team', () => {
|
||||
const { wrapper, instance } = setup({});
|
||||
const state = wrapper.state() as State;
|
||||
@ -169,23 +81,85 @@ describe('Functions', () => {
|
||||
expect(instance.props.addTeamMember).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
describe('on update permision for user in team', () => {
|
||||
const { instance } = setup({});
|
||||
const permission = TeamPermissionLevel.Admin;
|
||||
const item: SelectOptionItem = { value: permission };
|
||||
const member: TeamMember = {
|
||||
userId: 3,
|
||||
teamId: 2,
|
||||
avatarUrl: '',
|
||||
email: 'user@user.org',
|
||||
labels: [],
|
||||
login: 'member',
|
||||
permission: TeamPermissionLevel.Member,
|
||||
};
|
||||
const expectedTeamMemeber = { ...member, permission };
|
||||
describe('isSignedInUserTeamAdmin', () => {
|
||||
describe('when feature toggle editorsCanAdmin is turned off', () => {
|
||||
it('should return true', () => {
|
||||
const { instance } = setup({ editorsCanAdmin: false });
|
||||
|
||||
instance.onPermissionChange(item, member);
|
||||
const result = instance.isSignedInUserTeamAdmin();
|
||||
|
||||
expect(instance.props.updateTeamMember).toHaveBeenCalledWith(expectedTeamMemeber);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when feature toggle editorsCanAdmin is turned on', () => {
|
||||
it('should return true if signed in user is grafanaAdmin', () => {
|
||||
const members = getMockTeamMembers(5, 5);
|
||||
const { instance } = setup({
|
||||
members,
|
||||
editorsCanAdmin: true,
|
||||
signedInUser: {
|
||||
id: signedInUserId,
|
||||
isGrafanaAdmin: true,
|
||||
orgRole: OrgRole.Viewer,
|
||||
},
|
||||
});
|
||||
|
||||
const result = instance.isSignedInUserTeamAdmin();
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true if signed in user is org admin', () => {
|
||||
const members = getMockTeamMembers(5, 5);
|
||||
const { instance } = setup({
|
||||
members,
|
||||
editorsCanAdmin: true,
|
||||
signedInUser: {
|
||||
id: signedInUserId,
|
||||
isGrafanaAdmin: false,
|
||||
orgRole: OrgRole.Admin,
|
||||
},
|
||||
});
|
||||
|
||||
const result = instance.isSignedInUserTeamAdmin();
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true if signed in user is team admin', () => {
|
||||
const members = getMockTeamMembers(5, signedInUserId);
|
||||
const { instance } = setup({
|
||||
members,
|
||||
editorsCanAdmin: true,
|
||||
signedInUser: {
|
||||
id: signedInUserId,
|
||||
isGrafanaAdmin: false,
|
||||
orgRole: OrgRole.Viewer,
|
||||
},
|
||||
});
|
||||
|
||||
const result = instance.isSignedInUserTeamAdmin();
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if signed in user is not grafanaAdmin, org admin or team admin', () => {
|
||||
const members = getMockTeamMembers(5, 5);
|
||||
const { instance } = setup({
|
||||
members,
|
||||
editorsCanAdmin: true,
|
||||
signedInUser: {
|
||||
id: signedInUserId,
|
||||
isGrafanaAdmin: false,
|
||||
orgRole: OrgRole.Viewer,
|
||||
},
|
||||
});
|
||||
|
||||
const result = instance.isSignedInUserTeamAdmin();
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,32 +2,25 @@ import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import SlideDown from 'app/core/components/Animations/SlideDown';
|
||||
import { UserPicker } from 'app/core/components/Select/UserPicker';
|
||||
import { DeleteButton, Select, SelectOptionItem } from '@grafana/ui';
|
||||
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
|
||||
import { TeamMember, User, teamsPermissionLevels, TeamPermissionLevel, OrgRole } from 'app/types';
|
||||
import {
|
||||
loadTeamMembers,
|
||||
addTeamMember,
|
||||
removeTeamMember,
|
||||
setSearchMemberQuery,
|
||||
updateTeamMember,
|
||||
} from './state/actions';
|
||||
import { TeamMember, User, TeamPermissionLevel, OrgRole } from 'app/types';
|
||||
import { loadTeamMembers, addTeamMember, setSearchMemberQuery } from './state/actions';
|
||||
import { getSearchMemberQuery, getTeamMembers } from './state/selectors';
|
||||
import { FilterInput } from 'app/core/components/FilterInput/FilterInput';
|
||||
import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle';
|
||||
import { config } from 'app/core/config';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { contextSrv, User as SignedInUser } from 'app/core/services/context_srv';
|
||||
import TeamMemberRow from './TeamMemberRow';
|
||||
|
||||
export interface Props {
|
||||
members: TeamMember[];
|
||||
searchMemberQuery: string;
|
||||
loadTeamMembers: typeof loadTeamMembers;
|
||||
addTeamMember: typeof addTeamMember;
|
||||
removeTeamMember: typeof removeTeamMember;
|
||||
setSearchMemberQuery: typeof setSearchMemberQuery;
|
||||
updateTeamMember: typeof updateTeamMember;
|
||||
syncEnabled: boolean;
|
||||
editorsCanAdmin?: boolean;
|
||||
signedInUser?: SignedInUser;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
@ -39,7 +32,6 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { isAdding: false, newTeamMember: null };
|
||||
this.renderPermissions = this.renderPermissions.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -50,10 +42,6 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
this.props.setSearchMemberQuery(value);
|
||||
};
|
||||
|
||||
onRemoveMember(member: TeamMember) {
|
||||
this.props.removeTeamMember(member.userId);
|
||||
}
|
||||
|
||||
onToggleAdding = () => {
|
||||
this.setState({ isAdding: !this.state.isAdding });
|
||||
};
|
||||
@ -81,65 +69,16 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
onPermissionChange = (item: SelectOptionItem, member: TeamMember) => {
|
||||
const permission = item.value;
|
||||
const updatedTeamMember = { ...member, permission };
|
||||
|
||||
this.props.updateTeamMember(updatedTeamMember);
|
||||
};
|
||||
|
||||
private isSignedInUserTeamAdmin = () => {
|
||||
const { members, editorsCanAdmin } = this.props;
|
||||
const userInMembers = members.find(m => m.userId === contextSrv.user.id);
|
||||
const isAdmin = contextSrv.isGrafanaAdmin || contextSrv.hasRole(OrgRole.Admin);
|
||||
isSignedInUserTeamAdmin = (): boolean => {
|
||||
const { members, editorsCanAdmin, signedInUser } = this.props;
|
||||
const userInMembers = members.find(m => m.userId === signedInUser.id);
|
||||
const isAdmin = signedInUser.isGrafanaAdmin || signedInUser.orgRole === 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 (
|
||||
<WithFeatureToggle featureToggle={editorsCanAdmin}>
|
||||
<td>
|
||||
<div className="gf-form">
|
||||
{isUserTeamAdmin && (
|
||||
<Select
|
||||
isSearchable={false}
|
||||
options={teamsPermissionLevels}
|
||||
onChange={item => this.onPermissionChange(item, member)}
|
||||
className="gf-form-select-box__control--menu-right"
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
{!isUserTeamAdmin && <span>{value.label}</span>}
|
||||
</div>
|
||||
</td>
|
||||
</WithFeatureToggle>
|
||||
);
|
||||
}
|
||||
|
||||
renderMember(member: TeamMember, syncEnabled: boolean) {
|
||||
return (
|
||||
<tr key={member.userId}>
|
||||
<td className="width-4 text-center">
|
||||
<img className="filter-table__avatar" src={member.avatarUrl} />
|
||||
</td>
|
||||
<td>{member.login}</td>
|
||||
<td>{member.email}</td>
|
||||
{this.renderPermissions(member)}
|
||||
{syncEnabled && this.renderLabels(member.labels)}
|
||||
<td className="text-right">
|
||||
<DeleteButton onConfirm={() => this.onRemoveMember(member)} disabled={!this.isSignedInUserTeamAdmin()} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isAdding } = this.state;
|
||||
const { searchMemberQuery, members, syncEnabled, editorsCanAdmin } = this.props;
|
||||
@ -198,7 +137,18 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
<th style={{ width: '1%' }} />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{members && members.map(member => this.renderMember(member, syncEnabled))}</tbody>
|
||||
<tbody>
|
||||
{members &&
|
||||
members.map(member => (
|
||||
<TeamMemberRow
|
||||
key={member.userId}
|
||||
member={member}
|
||||
syncEnabled={syncEnabled}
|
||||
editorsCanAdmin={editorsCanAdmin}
|
||||
signedInUserIsTeamAdmin={this.isSignedInUserTeamAdmin()}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -211,15 +161,14 @@ function mapStateToProps(state) {
|
||||
members: getTeamMembers(state.team),
|
||||
searchMemberQuery: getSearchMemberQuery(state.team),
|
||||
editorsCanAdmin: config.editorsCanAdmin, // this makes the feature toggle mockable/controllable from tests,
|
||||
signedInUser: contextSrv.user, // this makes the feature toggle mockable/controllable from tests,
|
||||
};
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
loadTeamMembers,
|
||||
addTeamMember,
|
||||
removeTeamMember,
|
||||
setSearchMemberQuery,
|
||||
updateTeamMember,
|
||||
};
|
||||
|
||||
export default connect(
|
||||
|
@ -0,0 +1,191 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render when feature toggle editorsCanAdmin is turned off should not render permissions 1`] = `
|
||||
<tr
|
||||
key="1"
|
||||
>
|
||||
<td
|
||||
className="width-4 text-center"
|
||||
>
|
||||
<img
|
||||
className="filter-table__avatar"
|
||||
src="some/url/"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
testUser
|
||||
</td>
|
||||
<td>
|
||||
test@test.com
|
||||
</td>
|
||||
<Component
|
||||
featureToggle={false}
|
||||
>
|
||||
<td>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<Select
|
||||
autoFocus={false}
|
||||
backspaceRemovesValue={true}
|
||||
className="gf-form-select-box__control--menu-right"
|
||||
isClearable={false}
|
||||
isDisabled={false}
|
||||
isLoading={false}
|
||||
isMulti={false}
|
||||
isSearchable={false}
|
||||
maxMenuHeight={300}
|
||||
onChange={[Function]}
|
||||
openMenuOnFocus={false}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Is team member",
|
||||
"label": "Member",
|
||||
"value": 0,
|
||||
},
|
||||
Object {
|
||||
"description": "Can add/remove permissions, members and delete team.",
|
||||
"label": "Admin",
|
||||
"value": 4,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={
|
||||
Object {
|
||||
"description": "Is team member",
|
||||
"label": "Member",
|
||||
"value": 0,
|
||||
}
|
||||
}
|
||||
width={null}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</Component>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
exports[`Render when feature toggle editorsCanAdmin is turned on should render permissions select if user is team admin 1`] = `
|
||||
<tr
|
||||
key="1"
|
||||
>
|
||||
<td
|
||||
className="width-4 text-center"
|
||||
>
|
||||
<img
|
||||
className="filter-table__avatar"
|
||||
src="some/url/"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
testUser
|
||||
</td>
|
||||
<td>
|
||||
test@test.com
|
||||
</td>
|
||||
<Component
|
||||
featureToggle={true}
|
||||
>
|
||||
<td>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<Select
|
||||
autoFocus={false}
|
||||
backspaceRemovesValue={true}
|
||||
className="gf-form-select-box__control--menu-right"
|
||||
isClearable={false}
|
||||
isDisabled={false}
|
||||
isLoading={false}
|
||||
isMulti={false}
|
||||
isSearchable={false}
|
||||
maxMenuHeight={300}
|
||||
onChange={[Function]}
|
||||
openMenuOnFocus={false}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Is team member",
|
||||
"label": "Member",
|
||||
"value": 0,
|
||||
},
|
||||
Object {
|
||||
"description": "Can add/remove permissions, members and delete team.",
|
||||
"label": "Admin",
|
||||
"value": 4,
|
||||
},
|
||||
]
|
||||
}
|
||||
value={
|
||||
Object {
|
||||
"description": "Is team member",
|
||||
"label": "Member",
|
||||
"value": 0,
|
||||
}
|
||||
}
|
||||
width={null}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</Component>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
disabled={false}
|
||||
onConfirm={[Function]}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
exports[`Render when feature toggle editorsCanAdmin is turned on should render span and disable buttons if user is team member 1`] = `
|
||||
<tr
|
||||
key="1"
|
||||
>
|
||||
<td
|
||||
className="width-4 text-center"
|
||||
>
|
||||
<img
|
||||
className="filter-table__avatar"
|
||||
src="some/url/"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
testUser
|
||||
</td>
|
||||
<td>
|
||||
test@test.com
|
||||
</td>
|
||||
<Component
|
||||
featureToggle={true}
|
||||
>
|
||||
<td>
|
||||
<div
|
||||
className="gf-form"
|
||||
>
|
||||
<span>
|
||||
Member
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</Component>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
disabled={true}
|
||||
onConfirm={[Function]}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user