mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge remote-tracking branch 'upstream/master' into add_permissions_10676
This commit is contained in:
@@ -6,41 +6,33 @@ import { shallow } from 'enzyme';
|
||||
|
||||
describe('AddPermissions', () => {
|
||||
let wrapper;
|
||||
let store;
|
||||
let instance;
|
||||
|
||||
beforeAll(() => {
|
||||
backendSrv.get.mockReturnValue(
|
||||
Promise.resolve([
|
||||
{ id: 2, dashboardId: 1, role: 'Viewer', permission: 1, permissionName: 'View' },
|
||||
{ id: 3, dashboardId: 1, role: 'Editor', permission: 1, permissionName: 'Edit' },
|
||||
{
|
||||
id: 4,
|
||||
dashboardId: 1,
|
||||
userId: 2,
|
||||
userLogin: 'danlimerick',
|
||||
userEmail: 'dan.limerick@gmail.com',
|
||||
permission: 4,
|
||||
permissionName: 'Admin',
|
||||
},
|
||||
])
|
||||
);
|
||||
|
||||
backendSrv.post = jest.fn();
|
||||
|
||||
const store = RootStore.create(
|
||||
store = RootStore.create(
|
||||
{},
|
||||
{
|
||||
backendSrv: backendSrv,
|
||||
}
|
||||
);
|
||||
|
||||
// wrapper = shallow(<Permissions backendSrv={backendSrv} isFolder={true} dashboardId={1} {...store} />);
|
||||
wrapper = shallow(<AddPermissions permissions={store.permissions} backendSrv={backendSrv} dashboardId={1} />);
|
||||
//<AddPermissions permissions={permissions} backendSrv={backendSrv} dashboardId={dashboardId} />
|
||||
// return wrapper.instance().loadStore(1, true);
|
||||
instance = wrapper.instance();
|
||||
return store.permissions.load(1, true, false);
|
||||
});
|
||||
|
||||
describe('when permission for a user is added', () => {
|
||||
it('should save permission to db', async () => {
|
||||
it('should save permission to db', () => {
|
||||
const evt = {
|
||||
target: {
|
||||
value: 'User',
|
||||
@@ -51,29 +43,48 @@ describe('AddPermissions', () => {
|
||||
login: 'user2',
|
||||
};
|
||||
|
||||
const instance = wrapper.instance();
|
||||
instance.typeChanged(evt);
|
||||
instance.userPicked(userItem);
|
||||
wrapper.find('[data-save-permission]').simulate('click');
|
||||
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('[data-save-permission]').prop('disabled')).toBe(false);
|
||||
|
||||
wrapper.find('form').simulate('submit', { preventDefault() {} });
|
||||
|
||||
expect(backendSrv.post.mock.calls.length).toBe(1);
|
||||
expect(backendSrv.post.mock.calls[0][0]).toBe('/api/dashboards/id/1/acl');
|
||||
});
|
||||
});
|
||||
|
||||
// describe('when permission for team is added', () => {
|
||||
// it('should save permission to db', () => {
|
||||
// const teamItem = {
|
||||
// id: 2,
|
||||
// name: 'ug1',
|
||||
// };
|
||||
describe('when permission for team is added', () => {
|
||||
it('should save permission to db', () => {
|
||||
const evt = {
|
||||
target: {
|
||||
value: 'Group',
|
||||
},
|
||||
};
|
||||
|
||||
// wrapper
|
||||
// .instance()
|
||||
// .teamPicked(teamItem)
|
||||
// .then(() => {
|
||||
// expect(backendSrv.post.mock.calls.length).toBe(1);
|
||||
// expect(backendSrv.post.mock.calls[0][0]).toBe('/api/dashboards/id/1/acl');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
const teamItem = {
|
||||
id: 2,
|
||||
name: 'ug1',
|
||||
};
|
||||
|
||||
instance.typeChanged(evt);
|
||||
instance.teamPicked(teamItem);
|
||||
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('[data-save-permission]').prop('disabled')).toBe(false);
|
||||
|
||||
wrapper.find('form').simulate('submit', { preventDefault() {} });
|
||||
|
||||
expect(backendSrv.post.mock.calls.length).toBe(1);
|
||||
expect(backendSrv.post.mock.calls[0][0]).toBe('/api/dashboards/id/1/acl');
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
backendSrv.post.mockClear();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,8 +46,7 @@ class AddPermissions extends Component<IProps, any> {
|
||||
permissions.newItem.setUser(null, null);
|
||||
return;
|
||||
}
|
||||
permissions.newItem.setUser(user.id, user.login);
|
||||
// return permissions.addStoreItem({ userId: user.id, userLogin: user.login, permission: 1 });
|
||||
return permissions.newItem.setUser(user.id, user.login);
|
||||
}
|
||||
|
||||
teamPicked(team: Team) {
|
||||
@@ -56,17 +55,17 @@ class AddPermissions extends Component<IProps, any> {
|
||||
permissions.newItem.setTeam(null, null);
|
||||
return;
|
||||
}
|
||||
permissions.newItem.setTeam(team.id, team.name);
|
||||
return permissions.newItem.setTeam(team.id, team.name);
|
||||
}
|
||||
|
||||
permissionPicked(permission: OptionWithDescription) {
|
||||
const { permissions } = this.props;
|
||||
permissions.newItem.setPermission(permission.value);
|
||||
return permissions.newItem.setPermission(permission.value);
|
||||
}
|
||||
|
||||
resetNewType() {
|
||||
const { permissions } = this.props;
|
||||
permissions.resetNewType();
|
||||
return permissions.resetNewType();
|
||||
}
|
||||
|
||||
handleSubmit(evt) {
|
||||
@@ -80,6 +79,8 @@ class AddPermissions extends Component<IProps, any> {
|
||||
const newItem = permissions.newItem;
|
||||
const pickerClassName = 'width-20';
|
||||
|
||||
const isValid = newItem.isValid();
|
||||
|
||||
return (
|
||||
<div className="gf-form-inline cta-form">
|
||||
<button className="cta-form__close btn btn-transparent" onClick={permissions.hideAddPermissions}>
|
||||
@@ -135,7 +136,7 @@ class AddPermissions extends Component<IProps, any> {
|
||||
</div>
|
||||
|
||||
<div className="gf-form">
|
||||
<button data-save-permission className="btn btn-success" type="submit" disabled={!newItem.isValid()}>
|
||||
<button data-save-permission className="btn btn-success" type="submit" disabled={!isValid}>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@ class DashboardPermissions extends Component<IProps, any> {
|
||||
permissions={this.permissions}
|
||||
isFolder={false}
|
||||
dashboardId={dashboardId}
|
||||
folderInfo={{ title: folderTitle, slug: folderSlug, id: folderId }}
|
||||
folderInfo={{ title: folderTitle, slug: folderSlug, id: folderId }}
|
||||
backendSrv={backendSrv}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import PermissionsList from './PermissionsList';
|
||||
import { observer } from 'mobx-react';
|
||||
import { FolderInfo } from './FolderInfo';
|
||||
@@ -33,15 +33,15 @@ export interface IProps {
|
||||
class Permissions extends Component<IProps, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { dashboardId, isFolder } = this.props;
|
||||
const { dashboardId, isFolder, folderInfo } = this.props;
|
||||
this.permissionChanged = this.permissionChanged.bind(this);
|
||||
this.typeChanged = this.typeChanged.bind(this);
|
||||
this.removeItem = this.removeItem.bind(this);
|
||||
this.loadStore(dashboardId, isFolder);
|
||||
this.loadStore(dashboardId, isFolder, folderInfo && folderInfo.id === 0);
|
||||
}
|
||||
|
||||
loadStore(dashboardId, isFolder) {
|
||||
return this.props.permissions.load(dashboardId, isFolder);
|
||||
loadStore(dashboardId, isFolder, isInRoot = false) {
|
||||
return this.props.permissions.load(dashboardId, isFolder, isInRoot);
|
||||
}
|
||||
|
||||
permissionChanged(index: number, permission: number, permissionName: string) {
|
||||
|
||||
@@ -17,6 +17,8 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
|
||||
permissionChanged(itemIndex, permissionOption.value, permissionOption.label);
|
||||
};
|
||||
|
||||
const inheritedFromRoot = item.dashboardId === -1 && folderInfo && folderInfo.id === 0;
|
||||
|
||||
return (
|
||||
<tr className={setClassNameHelper(item.inherited)}>
|
||||
<td style={{ width: '100%' }}>
|
||||
@@ -24,14 +26,16 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
|
||||
<span dangerouslySetInnerHTML={{ __html: item.nameHtml }} />
|
||||
</td>
|
||||
<td>
|
||||
{item.inherited && folderInfo ? (
|
||||
<em className="muted no-wrap">
|
||||
Inherited from folder{' '}
|
||||
<a className="text-link" href={`dashboards/folder/${folderInfo.id}/${folderInfo.slug}/permissions`}>
|
||||
{folderInfo.title}
|
||||
</a>{' '}
|
||||
</em>
|
||||
) : null}
|
||||
{item.inherited &&
|
||||
folderInfo && (
|
||||
<em className="muted no-wrap">
|
||||
Inherited from folder{' '}
|
||||
<a className="text-link" href={`dashboards/folder/${folderInfo.id}/${folderInfo.slug}/permissions`}>
|
||||
{folderInfo.title}
|
||||
</a>{' '}
|
||||
</em>
|
||||
)}
|
||||
{inheritedFromRoot && <em className="muted no-wrap">Default Permission</em>}
|
||||
</td>
|
||||
<td className="query-keyword">Can</td>
|
||||
<td>
|
||||
|
||||
@@ -41,18 +41,12 @@ class DescriptionOption extends Component<IProps, any> {
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseMove={this.handleMouseMove}
|
||||
title={option.title}
|
||||
className={`user-picker-option__button btn btn-link ${className} width-19`}
|
||||
style={{
|
||||
whiteSpace: 'normal',
|
||||
// height: '55px',
|
||||
}}
|
||||
className={`description-picker-option__button btn btn-link ${className} width-19`}
|
||||
>
|
||||
<div className="gf-form">{children}</div>
|
||||
<div className="gf-form">
|
||||
<div className="muted width-17">{option.description}</div>
|
||||
{className.indexOf('is-selected') > -1 && (
|
||||
<i style={{ paddingLeft: '2px' }} className="fa fa-check" aria-hidden="true" />
|
||||
)}
|
||||
{className.indexOf('is-selected') > -1 && <i className="fa fa-check" aria-hidden="true" />}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -71,6 +71,7 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
|
||||
body.toggleClass('sidemenu-open', sidemenuOpen);
|
||||
|
||||
appEvents.on('toggle-sidemenu', () => {
|
||||
sidemenuOpen = scope.contextSrv.sidemenu;
|
||||
body.toggleClass('sidemenu-open');
|
||||
});
|
||||
|
||||
@@ -167,6 +168,8 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
|
||||
// mouse and keyboard is user activity
|
||||
body.mousemove(userActivityDetected);
|
||||
body.keydown(userActivityDetected);
|
||||
// set useCapture = true to catch event here
|
||||
document.addEventListener('wheel', userActivityDetected, true);
|
||||
// treat tab change as activity
|
||||
document.addEventListener('visibilitychange', userActivityDetected);
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
buttonIcon: 'gicon gicon-dashboard-new',
|
||||
buttonLink: 'dashboard/new?folderId={{ctrl.folderId}}',
|
||||
buttonTitle: 'Create Dashboard',
|
||||
proTip: 'Add dashboards into your folder at ->',
|
||||
proTip: 'Add/move dashboards to your folder at ->',
|
||||
proTipLink: 'dashboards',
|
||||
proTipLinkTitle: 'Manage dashboards',
|
||||
proTipTarget: ''
|
||||
|
||||
Reference in New Issue
Block a user