mirror of
https://github.com/grafana/grafana.git
synced 2024-11-24 09:50:29 -06:00
teams: disable new team button if user is viewer
This commit is contained in:
parent
e3fc61b326
commit
8c34f595f0
@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Props, TeamList } from './TeamList';
|
||||
import { NavModel, Team } from '../../types';
|
||||
import { NavModel, Team, OrgRole } from '../../types';
|
||||
import { getMockTeam, getMultipleMockTeams } from './__mocks__/teamMocks';
|
||||
import { User } from 'app/core/services/context_srv';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
@ -21,6 +22,11 @@ const setup = (propOverrides?: object) => {
|
||||
searchQuery: '',
|
||||
teamsCount: 0,
|
||||
hasFetched: false,
|
||||
editorsCanAdmin: false,
|
||||
signedInUser: {
|
||||
id: 1,
|
||||
orgRole: OrgRole.Viewer,
|
||||
} as User,
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
@ -49,6 +55,42 @@ describe('Render', () => {
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('when feature toggle editorsCanAdmin is turned on', () => {
|
||||
describe('and signedin user is not viewer', () => {
|
||||
it('should enable the new team button', () => {
|
||||
const { wrapper } = setup({
|
||||
teams: getMultipleMockTeams(1),
|
||||
teamsCount: 1,
|
||||
hasFetched: true,
|
||||
editorsCanAdmin: true,
|
||||
signedInUser: {
|
||||
id: 1,
|
||||
orgRole: OrgRole.Editor,
|
||||
} as User,
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('and signedin user is a viewer', () => {
|
||||
it('should disable the new team button', () => {
|
||||
const { wrapper } = setup({
|
||||
teams: getMultipleMockTeams(1),
|
||||
teamsCount: 1,
|
||||
hasFetched: true,
|
||||
editorsCanAdmin: true,
|
||||
signedInUser: {
|
||||
id: 1,
|
||||
orgRole: OrgRole.Viewer,
|
||||
} as User,
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Life cycle', () => {
|
||||
|
@ -4,11 +4,13 @@ import { hot } from 'react-hot-loader';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { DeleteButton } from '@grafana/ui';
|
||||
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
|
||||
import { NavModel, Team } from 'app/types';
|
||||
import { NavModel, Team, OrgRole } from 'app/types';
|
||||
import { loadTeams, deleteTeam, setSearchQuery } from './state/actions';
|
||||
import { getSearchQuery, getTeams, getTeamsCount } from './state/selectors';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { FilterInput } from 'app/core/components/FilterInput/FilterInput';
|
||||
import { config } from 'app/core/config';
|
||||
import { contextSrv, User } from 'app/core/services/context_srv';
|
||||
|
||||
export interface Props {
|
||||
navModel: NavModel;
|
||||
@ -19,6 +21,8 @@ export interface Props {
|
||||
loadTeams: typeof loadTeams;
|
||||
deleteTeam: typeof deleteTeam;
|
||||
setSearchQuery: typeof setSearchQuery;
|
||||
editorsCanAdmin?: boolean;
|
||||
signedInUser?: User;
|
||||
}
|
||||
|
||||
export class TeamList extends PureComponent<Props, any> {
|
||||
@ -84,7 +88,8 @@ export class TeamList extends PureComponent<Props, any> {
|
||||
}
|
||||
|
||||
renderTeamList() {
|
||||
const { teams, searchQuery } = this.props;
|
||||
const { teams, searchQuery, editorsCanAdmin, signedInUser } = this.props;
|
||||
const disabledClass = editorsCanAdmin && signedInUser.orgRole === OrgRole.Viewer ? ' disabled' : '';
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -101,7 +106,7 @@ export class TeamList extends PureComponent<Props, any> {
|
||||
|
||||
<div className="page-action-bar__spacer" />
|
||||
|
||||
<a className="btn btn-primary" href="org/teams/new">
|
||||
<a className={`btn btn-primary${disabledClass}`} href="org/teams/new">
|
||||
New team
|
||||
</a>
|
||||
</div>
|
||||
@ -152,6 +157,8 @@ function mapStateToProps(state) {
|
||||
searchQuery: getSearchQuery(state.teams),
|
||||
teamsCount: getTeamsCount(state.teams),
|
||||
hasFetched: state.teams.hasFetched,
|
||||
editorsCanAdmin: config.editorsCanAdmin, // this makes the feature toggle mockable/controllable from tests,
|
||||
signedInUser: contextSrv.user, // this makes the feature toggle mockable/controllable from tests,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -343,3 +343,253 @@ exports[`Render should render teams table 1`] = `
|
||||
</PageContents>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
exports[`Render when feature toggle editorsCanAdmin is turned on and signedin user is a viewer should disable the new team button 1`] = `
|
||||
<Page
|
||||
navModel={
|
||||
Object {
|
||||
"main": Object {
|
||||
"text": "Configuration",
|
||||
},
|
||||
"node": Object {
|
||||
"text": "Team List",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<PageContents
|
||||
isLoading={false}
|
||||
>
|
||||
<div
|
||||
className="page-action-bar"
|
||||
>
|
||||
<div
|
||||
className="gf-form gf-form--grow"
|
||||
>
|
||||
<ForwardRef
|
||||
inputClassName="gf-form-input"
|
||||
labelClassName="gf-form--has-input-icon gf-form--grow"
|
||||
onChange={[Function]}
|
||||
placeholder="Search teams"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
<a
|
||||
className="btn btn-primary disabled"
|
||||
href="org/teams/new"
|
||||
>
|
||||
New team
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="admin-list-table"
|
||||
>
|
||||
<table
|
||||
className="filter-table filter-table--hover form-inline"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th />
|
||||
<th>
|
||||
Name
|
||||
</th>
|
||||
<th>
|
||||
Email
|
||||
</th>
|
||||
<th>
|
||||
Members
|
||||
</th>
|
||||
<th
|
||||
style={
|
||||
Object {
|
||||
"width": "1%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
key="1"
|
||||
>
|
||||
<td
|
||||
className="width-4 text-center link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
<img
|
||||
className="filter-table__avatar"
|
||||
src="some/url/"
|
||||
/>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
test-1
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
test-1@test.com
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
1
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
onConfirm={[Function]}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</PageContents>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
exports[`Render when feature toggle editorsCanAdmin is turned on and signedin user is not viewer should enable the new team button 1`] = `
|
||||
<Page
|
||||
navModel={
|
||||
Object {
|
||||
"main": Object {
|
||||
"text": "Configuration",
|
||||
},
|
||||
"node": Object {
|
||||
"text": "Team List",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<PageContents
|
||||
isLoading={false}
|
||||
>
|
||||
<div
|
||||
className="page-action-bar"
|
||||
>
|
||||
<div
|
||||
className="gf-form gf-form--grow"
|
||||
>
|
||||
<ForwardRef
|
||||
inputClassName="gf-form-input"
|
||||
labelClassName="gf-form--has-input-icon gf-form--grow"
|
||||
onChange={[Function]}
|
||||
placeholder="Search teams"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="page-action-bar__spacer"
|
||||
/>
|
||||
<a
|
||||
className="btn btn-primary"
|
||||
href="org/teams/new"
|
||||
>
|
||||
New team
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="admin-list-table"
|
||||
>
|
||||
<table
|
||||
className="filter-table filter-table--hover form-inline"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th />
|
||||
<th>
|
||||
Name
|
||||
</th>
|
||||
<th>
|
||||
Email
|
||||
</th>
|
||||
<th>
|
||||
Members
|
||||
</th>
|
||||
<th
|
||||
style={
|
||||
Object {
|
||||
"width": "1%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
key="1"
|
||||
>
|
||||
<td
|
||||
className="width-4 text-center link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
<img
|
||||
className="filter-table__avatar"
|
||||
src="some/url/"
|
||||
/>
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
test-1
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
test-1@test.com
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="link-td"
|
||||
>
|
||||
<a
|
||||
href="org/teams/edit/1"
|
||||
>
|
||||
1
|
||||
</a>
|
||||
</td>
|
||||
<td
|
||||
className="text-right"
|
||||
>
|
||||
<DeleteButton
|
||||
onConfirm={[Function]}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</PageContents>
|
||||
</Page>
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user