Commit c8193e10 by Johannes Schill Committed by Daniel Lee

dashfolder: wip: More wip on acl.html2permissions.tsx #10275

parent 7616cfb5
......@@ -91,7 +91,7 @@
"typescript": "^2.6.2",
"webpack": "^3.10.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-cleanup-plugin": "^0.5.1",
"webpack-cleanup-plugin": "^0.5.1",
"webpack-merge": "^4.1.0",
"zone.js": "^0.7.2"
},
......@@ -140,6 +140,7 @@
"lodash": "^4.17.4",
"mobx": "^3.4.1",
"mobx-react": "^4.3.5",
"mobx-react-devtools": "^4.2.15",
"mobx-state-tree": "^1.3.1",
"moment": "^2.18.1",
"mousetrap": "^1.6.0",
......@@ -148,8 +149,8 @@
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-grid-layout": "^0.16.2",
"react-popper": "^0.7.5",
"react-highlight-words": "^0.10.0",
"react-popper": "^0.7.5",
"react-select": "^1.1.0",
"react-sizeme": "^2.3.6",
"remarkable": "^1.7.1",
......
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;
......@@ -24,12 +28,25 @@ export interface IProps {
error: any;
newType: any;
aclTypes: any;
typeChanged: 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[];
......@@ -50,58 +67,34 @@ class Permissions extends Component<IProps, any> {
constructor(props) {
super(props);
this.dashboardId = this.props.dashboardId;
this.backendSrv = this.props.backendSrv;
const { dashboardId, backendSrv, permissions } = this.props;
this.dashboardId = dashboardId;
this.backendSrv = backendSrv;
this.permissionChanged = this.permissionChanged.bind(this);
console.log('this.setState', this.setState);
this.typeChanged = this.typeChanged.bind(this);
this.removeItem = this.removeItem.bind(this);
permissions.load(this.dashboardId);
this.state = {
items: [],
newType: '',
newType: 'Group',
canUpdate: false,
error: '',
};
}
componentWillMount() {
this.getAcl(this.props.dashboardId);
}
getAcl(dashboardId: number) {
return this.backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`).then(result => {
console.log('this', this.setState);
const items = result.map(this.prepareViewModel.bind(this));
// this.items = _.map(result, this.prepareViewModel.bind(this));
this.setState(prevState => {
return {
...prevState,
items: this.sortItems(items),
};
});
});
}
sortItems(items) {
return _.orderBy(items, ['sortRank', 'sortName'], ['desc', 'asc']);
}
permissionChanged() {
this.setState(prevState => {
return {
...prevState,
canUpdate: true,
};
});
permissionChanged(evt) {
// TODO
}
removeItem(index) {
this.setState(prevState => {
return {
...prevState,
items: this.state.items.splice(index, 1),
canUpdate: true,
};
});
const { permissions } = this.props;
permissions.removeStoreItem(index);
}
update() {
......@@ -168,29 +161,91 @@ class Permissions extends Component<IProps, any> {
return item;
}
// componentWillUpdate(nextProps, nextState) {
// console.log('nextProps', nextProps);
// console.log('nextState', nextState);
// }
isDuplicate(origItem, newItem) {
if (origItem.inherited) {
return false;
}
// componentWillReceiveProps(nextProps) {
// console.log('nextPropzzzz', nextProps);
// }
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)
);
}
render() {
const { error, newType, aclTypes, typeChanged } = this.props;
isValid(item) {
const dupe = _.find(this.items, it => {
return this.isDuplicate(it, item);
});
if (dupe) {
this.error = this.duplicateError;
return false;
}
const { items, canUpdate } = this.state;
return true;
}
const handleTypeChange = () => {
typeChanged();
};
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">
asd
<PermissionsList
permissions={items}
permissions={permissions.items.toJS()}
permissionsOptions={this.permissionOptions}
removeItem={this.removeItem}
permissionChanged={this.permissionChanged}
......@@ -202,7 +257,7 @@ class Permissions extends Component<IProps, any> {
<div className="gf-form-inline">
<div className="gf-form">
<div className="gf-form-select-wrapper">
<select className="gf-form-input gf-size-auto" onChange={handleTypeChange}>
<select className="gf-form-input gf-size-auto" onChange={this.typeChanged}>
{aclTypes.map((option, idx) => {
return (
<option key={idx} value={option.value}>
......@@ -222,12 +277,16 @@ class Permissions extends Component<IProps, any> {
</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}
......@@ -243,11 +302,12 @@ class Permissions extends Component<IProps, any> {
) : null}
</div>
<div className="gf-form-button-row">
<button type="button" className="btn btn-danger" onClick={this.update} disabled={!canUpdate}>
<button type="button" className="btn btn-danger" onClick={this.update} disabled={!permissions.canUpdate}>
Update Permissions
</button>
</div>
asd3
<DevTools />
</div>
);
}
......
......@@ -9,18 +9,8 @@ export interface IProps {
}
class PermissionsList extends Component<IProps, any> {
// componentWillUpdate(nextProps, nextState) {
// console.log('nextProps', nextProps);
// console.log('nextState', nextState);
// }
// componentWillReceiveProps(nextProps) {
// console.log('nextPropzzzz', nextProps);
// }
render() {
const { permissions, permissionsOptions, removeItem, permissionChanged } = this.props;
return (
<table className="filter-table gf-form-group">
<tbody>
......
......@@ -12,7 +12,7 @@ export default ({ item, permissionsOptions, removeItem, permissionChanged, itemI
const handleChangePermission = evt => {
evt.preventDefault();
permissionChanged();
permissionChanged(itemIndex, evt.target.value);
};
return (
......
......@@ -6,21 +6,6 @@
dashboardId="ctrl.dashboard.id"
backendSrv="ctrl.backendSrv" />
<per m i s sions
permissions="{{ctrl.dummyItems}}"
permissionsOptions="{{ctrl.permissionOptions}}"
removeItem="ctrl.removeItem"
permissionChanged="ctrl.permissionChanged"
error="{{ctrl.error}}"
newType="ctrl.newType"
aclTypes="{{ctrl.aclTypes}}"
typeChanged="ctrl.typeChanged"
dashboardId="ctrl.dashboard.id"
backendSrv="ctrl.backendSrv"/>
<div class="gf-form-group">
<table class="filter-table gf-form-group">
<tr ng-repeat="acl in ctrl.items" ng-class="{'gf-form-disabled': acl.inherited}">
......
import { types, getEnv, flow } from 'mobx-state-tree';
import { PermissionsStoreItem } from './PermissionsStoreItem';
export const PermissionsStore = types
.model('PermissionsStore', {
fetching: types.boolean,
canUpdate: types.boolean,
items: types.optional(types.array(PermissionsStoreItem), []),
originalItems: types.optional(types.array(PermissionsStoreItem), []),
})
// .views(self => ({
// canUpdate: () => {
// const itemsSnapshot = getSnapshot(self.items);
// const originalItemsSnapshot = getSnapshot(self.originalItems);
// console.log('itemsSnapshot', itemsSnapshot);
// console.log('editItemsSnapshot', originalItemsSnapshot);
// return true;
// }
// }))
.actions(self => ({
load: flow(function* load(dashboardId: number) {
self.fetching = true;
const backendSrv = getEnv(self).backendSrv;
const res = yield backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`);
const items = prepareServerResponse(res, dashboardId);
self.items = items;
self.originalItems = items;
self.fetching = false;
}),
addStoreItem: () => {
self.canUpdate = true;
},
removeStoreItem: idx => {
self.items.splice(idx, 1);
self.canUpdate = true;
},
}));
const prepareServerResponse = (response, dashboardId: number) => {
return response.map(item => {
// TODO: this.meta
// item.inherited = !this.meta.isFolder && this.dashboardId !== item.dashboardId;
item.inherited = 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;
});
};
import { types } from 'mobx-state-tree';
export const PermissionsStoreItem = types
.model('PermissionsStoreItem', {
dashboardId: types.number,
id: types.number,
permission: types.number,
permissionName: types.string,
role: types.maybe(types.string),
team: types.string,
teamId: types.number,
userEmail: types.string,
userId: types.number,
userLogin: types.string,
inherited: types.maybe(types.boolean),
sortRank: types.maybe(types.number),
icon: types.maybe(types.string),
nameHtml: types.maybe(types.string),
sortName: types.maybe(types.string),
})
.actions(self => ({
updateRole: role => {
self.role = role;
},
}));
......@@ -5,6 +5,7 @@ import { NavStore } from './../NavStore/NavStore';
import { AlertListStore } from './../AlertListStore/AlertListStore';
import { ViewStore } from './../ViewStore/ViewStore';
import { FolderStore } from './../FolderStore/FolderStore';
import { PermissionsStore } from './../PermissionsStore/PermissionsStore';
export const RootStore = types.model({
search: types.optional(SearchStore, {
......@@ -17,6 +18,11 @@ export const RootStore = types.model({
alertList: types.optional(AlertListStore, {
rules: [],
}),
permissions: types.optional(PermissionsStore, {
fetching: false,
canUpdate: false,
items: [],
}),
view: types.optional(ViewStore, {
path: '',
query: {},
......
......@@ -6467,6 +6467,10 @@ mkdirp@0.5.1, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdi
dependencies:
minimist "0.0.8"
mobx-react-devtools@^4.2.15:
version "4.2.15"
resolved "https://registry.yarnpkg.com/mobx-react-devtools/-/mobx-react-devtools-4.2.15.tgz#881c038fb83db4dffd1e72bbaf5374d26b2fdebb"
mobx-react@^4.3.5:
version "4.3.5"
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-4.3.5.tgz#76853f2f2ef4a6f960c374bcd9f01e875929c04c"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment