Files
grafana/public/app/core/components/Permissions/Permissions.tsx

317 lines
8.2 KiB
TypeScript
Raw Normal View History

import React, { Component } from 'react';
import PermissionsList from './PermissionsList';
import _ from 'lodash';
import DevTools from 'mobx-react-devtools';
import { inject, observer } from 'mobx-react';
import { Provider } from 'mobx-react';
import { store } from 'app/stores/store';
export interface DashboardAcl {
id?: number;
dashboardId?: number;
userId?: number;
userLogin?: string;
userEmail?: string;
teamId?: number;
team?: string;
permission?: number;
permissionName?: string;
role?: string;
icon?: string;
nameHtml?: string;
inherited?: boolean;
sortName?: string;
sortRank?: number;
}
export interface IProps {
error: any;
newType: any;
aclTypes: any;
backendSrv: any;
dashboardId: number;
permissions: any;
}
class Permissions extends Component<IProps, any> {
render() {
return (
<Provider {...store}>
<PermissionsInner {...this.props} />
</Provider>
);
}
}
@inject('permissions')
@observer
class PermissionsInner extends Component<IProps, any> {
// TODO Remove Inner from Name when we get access via ReactContainer
dashboardId: any;
meta: any;
items: DashboardAcl[];
dummyItems: DashboardAcl[];
permissionOptions = [{ value: 1, text: 'View' }, { value: 2, text: 'Edit' }, { value: 4, text: 'Admin' }];
backendSrv: any;
aclTypes = [
{ value: 'Group', text: 'Team' },
{ value: 'User', text: 'User' },
{ value: 'Viewer', text: 'Everyone With Viewer Role' },
{ value: 'Editor', text: 'Everyone With Editor Role' },
];
newType: string;
canUpdate: boolean;
error: string;
readonly duplicateError = 'This permission exists already.';
constructor(props) {
super(props);
const { dashboardId, backendSrv, permissions } = this.props;
this.dashboardId = dashboardId;
this.backendSrv = backendSrv;
this.permissionChanged = this.permissionChanged.bind(this);
this.typeChanged = this.typeChanged.bind(this);
this.removeItem = this.removeItem.bind(this);
permissions.load(this.dashboardId);
this.state = {
newType: 'Group',
canUpdate: false,
error: '',
};
}
sortItems(items) {
return _.orderBy(items, ['sortRank', 'sortName'], ['desc', 'asc']);
}
permissionChanged(evt) {
// TODO
}
removeItem(index) {
const { permissions } = this.props;
permissions.removeStoreItem(index);
}
update() {
var updated = [];
for (let item of this.state.items) {
if (item.inherited) {
continue;
}
updated.push({
id: item.id,
userId: item.userId,
teamId: item.teamId,
role: item.role,
permission: item.permission,
});
}
return this.backendSrv
.post(`/api/dashboards/id/${this.dashboardId}/acl`, {
items: updated,
})
.then(() => {
this.setState(prevState => {
return {
...prevState,
canUpdate: false,
};
});
});
}
prepareViewModel(item: DashboardAcl): DashboardAcl {
// TODO: this.meta
// item.inherited = !this.meta.isFolder && this.dashboardId !== item.dashboardId;
item.inherited = this.dashboardId !== item.dashboardId;
item.sortRank = 0;
if (item.userId > 0) {
item.icon = 'fa fa-fw fa-user';
// item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
item.nameHtml = item.userLogin;
item.sortName = item.userLogin;
item.sortRank = 10;
} else if (item.teamId > 0) {
item.icon = 'fa fa-fw fa-users';
// item.nameHtml = this.$sce.trustAsHtml(item.team);
item.nameHtml = item.team;
item.sortName = item.team;
item.sortRank = 20;
} else if (item.role) {
item.icon = 'fa fa-fw fa-street-view';
// item.nameHtml = this.$sce.trustAsHtml(`Everyone with <span class="query-keyword">${item.role}</span> Role`);
item.nameHtml = `Everyone with <span class="query-keyword">${item.role}</span> Role`;
item.sortName = item.role;
item.sortRank = 30;
if (item.role === 'Viewer') {
item.sortRank += 1;
}
}
if (item.inherited) {
item.sortRank += 100;
}
return item;
}
isDuplicate(origItem, newItem) {
if (origItem.inherited) {
return false;
}
return (
(origItem.role && newItem.role && origItem.role === newItem.role) ||
(origItem.userId && newItem.userId && origItem.userId === newItem.userId) ||
(origItem.teamId && newItem.teamId && origItem.teamId === newItem.teamId)
);
}
isValid(item) {
const dupe = _.find(this.items, it => {
return this.isDuplicate(it, item);
});
if (dupe) {
this.error = this.duplicateError;
return false;
}
return true;
}
addNewItem(item) {
if (!this.isValid(item)) {
return;
}
this.error = '';
item.dashboardId = this.dashboardId;
let newItems = this.state.items;
newItems.push(this.prepareViewModel(item));
this.setState(prevState => {
return {
...prevState,
items: this.sortItems(newItems),
canUpdate: true,
};
});
}
resetNewType() {
this.setState(prevState => {
return {
newType: 'Group',
};
});
}
typeChanged(evt) {
const { value } = evt.target;
this.setState(prevState => {
return {
...prevState,
newType: value,
};
});
}
typeChanged___() {
const { newType } = this.state;
if (newType === 'Viewer' || newType === 'Editor') {
this.addNewItem({ permission: 1, role: newType });
this.resetNewType();
this.setState(prevState => {
return {
...prevState,
canUpdate: true,
};
});
}
}
render() {
const { error, aclTypes, permissions } = this.props;
const { newType } = this.state;
return (
<div className="gf-form-group">
<PermissionsList
permissions={permissions.items.toJS()}
permissionsOptions={this.permissionOptions}
removeItem={this.removeItem}
permissionChanged={this.permissionChanged}
/>
asd2
<div className="gf-form-inline">
<form name="addPermission" className="gf-form-group">
<h6 className="muted">Add Permission For</h6>
<div className="gf-form-inline">
<div className="gf-form">
<div className="gf-form-select-wrapper">
<select className="gf-form-input gf-size-auto" onChange={this.typeChanged}>
{aclTypes.map((option, idx) => {
return (
<option key={idx} value={option.value}>
{option.text}
</option>
);
})}
</select>
{/* <select
className="gf-form-input gf-size-auto"
ng-model="ctrl.newType"
ng-options="p.value as p.text for p in ctrl.aclTypes"
ng-change="ctrl.typeChanged()"
/> */}
</div>
</div>
{newType === 'User' ? (
<div className="gf-form">
{' '}
User picker
<user-picker user-picked="ctrl.userPicked($user)" />
</div>
) : null}
{newType === 'Group' ? (
<div className="gf-form">
{' '}
Team picker
<team-picker team-picked="ctrl.groupPicked($group)" />
</div>
) : null}
</div>
</form>
{error ? (
<div className="gf-form width-17">
<span ng-if="ctrl.error" className="text-error p-l-1">
<i className="fa fa-warning" />
{error}
</span>
</div>
) : null}
</div>
<div className="gf-form-button-row">
<button type="button" className="btn btn-danger" onClick={this.update} disabled={!permissions.canUpdate}>
Update Permissions
</button>
</div>
asd3
<DevTools />
</div>
);
}
}
export default Permissions;