From 7616cfb5f0b22dd98ec1ef54ff41519be36c721e Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Thu, 11 Jan 2018 10:47:39 +0100 Subject: [PATCH] dashfolders: wip - Move Permissions into React #10275 --- public/app/core/angular_wrappers.ts | 9 + .../components/Permissions/Permissions.tsx | 256 ++++++++++++++++++ .../Permissions/PermissionsList.tsx | 81 ++++++ .../Permissions/PermissionsListItem.tsx | 60 ++++ public/app/features/dashboard/acl/acl.html | 23 ++ 5 files changed, 429 insertions(+) create mode 100644 public/app/core/components/Permissions/Permissions.tsx create mode 100644 public/app/core/components/Permissions/PermissionsList.tsx create mode 100644 public/app/core/components/Permissions/PermissionsListItem.tsx diff --git a/public/app/core/angular_wrappers.ts b/public/app/core/angular_wrappers.ts index c3311e39659..e359a7c76f9 100644 --- a/public/app/core/angular_wrappers.ts +++ b/public/app/core/angular_wrappers.ts @@ -6,6 +6,7 @@ import LoginBackground from './components/Login/LoginBackground'; import { SearchResult } from './components/search/SearchResult'; import UserPicker from './components/UserPicker/UserPicker'; import { TagFilter } from './components/TagFilter/TagFilter'; +import Permissions from './components/Permissions/Permissions'; export function registerAngularDirectives() { react2AngularDirective('passwordStrength', PasswordStrength, ['password']); @@ -19,4 +20,12 @@ export function registerAngularDirectives() { ['onSelect', { watchDepth: 'reference' }], ['tagOptions', { watchDepth: 'reference' }], ]); + react2AngularDirective('permissions', Permissions, [ + 'error', + 'newType', + 'aclTypes', + 'typeChanged', + 'backendSrv', + 'dashboardId', + ]); } diff --git a/public/app/core/components/Permissions/Permissions.tsx b/public/app/core/components/Permissions/Permissions.tsx new file mode 100644 index 00000000000..01b0ffc7be9 --- /dev/null +++ b/public/app/core/components/Permissions/Permissions.tsx @@ -0,0 +1,256 @@ +import React, { Component } from 'react'; +import PermissionsList from './PermissionsList'; +import _ from 'lodash'; + +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; + typeChanged: any; + backendSrv: any; + dashboardId: number; +} + +class Permissions extends Component { + 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); + this.dashboardId = this.props.dashboardId; + this.backendSrv = this.props.backendSrv; + this.permissionChanged = this.permissionChanged.bind(this); + console.log('this.setState', this.setState); + + this.state = { + items: [], + newType: '', + 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, + }; + }); + } + + removeItem(index) { + this.setState(prevState => { + return { + ...prevState, + items: this.state.items.splice(index, 1), + canUpdate: true, + }; + }); + } + + 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 ${item.role} Role`); + item.nameHtml = `Everyone with ${item.role} Role`; + item.sortName = item.role; + item.sortRank = 30; + if (item.role === 'Viewer') { + item.sortRank += 1; + } + } + + if (item.inherited) { + item.sortRank += 100; + } + + return item; + } + + // componentWillUpdate(nextProps, nextState) { + // console.log('nextProps', nextProps); + // console.log('nextState', nextState); + // } + + // componentWillReceiveProps(nextProps) { + // console.log('nextPropzzzz', nextProps); + // } + + render() { + const { error, newType, aclTypes, typeChanged } = this.props; + + const { items, canUpdate } = this.state; + + const handleTypeChange = () => { + typeChanged(); + }; + + return ( +
+ asd + + asd2 +
+
+
Add Permission For
+
+
+
+ + + {/* +
+ + + + + + + + + + No permissions are set. Will only be accessible by admins. + + */} + {permissions.length < 1 ? ( + + + No permissions are set. Will only be accessible by admins. + + + ) : null} + + + ); + } +} + +export default PermissionsList; diff --git a/public/app/core/components/Permissions/PermissionsListItem.tsx b/public/app/core/components/Permissions/PermissionsListItem.tsx new file mode 100644 index 00000000000..7b77f47e488 --- /dev/null +++ b/public/app/core/components/Permissions/PermissionsListItem.tsx @@ -0,0 +1,60 @@ +import React from 'react'; + +const setClassNameHelper = inherited => { + return inherited ? 'gf-form-disabled' : ''; +}; + +export default ({ item, permissionsOptions, removeItem, permissionChanged, itemIndex }) => { + const handleRemoveItem = evt => { + evt.preventDefault(); + removeItem(itemIndex); + }; + + const handleChangePermission = evt => { + evt.preventDefault(); + permissionChanged(); + }; + + return ( + + + {/* style="width: 100%;" */} + + + + {item.inherited ? Inherited from folder : null} + Can + +
+ + + {/*