Torkel Ödegaard 8 лет назад
Родитель
Сommit
945302ba52

+ 11 - 13
public/app/core/components/user_picker.ts

@@ -7,37 +7,35 @@ const template = `
   <gf-form-dropdown model="ctrl.user"
                     get-options="ctrl.debouncedSearchUsers($query)"
                     css-class="gf-size-auto"
-                    on-change="ctrl.onChange()"
+                    on-change="ctrl.onChange($option)"
   </gf-form-dropdown>
 </div>
 `;
 export class UserPickerCtrl {
   user: any;
-  userId: number;
   debouncedSearchUsers: any;
+  userPicked: any;
 
   /** @ngInject */
   constructor(private backendSrv, private $scope, $sce) {
-    this.user = {text: 'Choose', value: null};
+    this.reset();
     this.debouncedSearchUsers = _.debounce(this.searchUsers, 500, {'leading': true, 'trailing': false});
   }
 
   searchUsers(query: string) {
     return Promise.resolve(this.backendSrv.get('/api/users/search?perpage=10&page=1&query=' + query).then(result => {
       return _.map(result.users, user => {
-        return {text: user.login + ' -  ' + user.email, value: user.id};
+        return {text: user.login + ' -  ' + user.email, value: user};
       });
     }));
   }
 
-  onChange() {
-    this.userId = this.user.value;
+  onChange(option) {
+    this.userPicked({$user: option.value});
   }
 
-  userIdChanged() {
-    if (this.userId === null) {
-      this.user = {text: 'Choose', value: null};
-    }
+  reset() {
+    this.user = {text: 'Choose', value: null};
   }
 }
 
@@ -56,11 +54,11 @@ export function userPicker() {
     bindToController: true,
     controllerAs: 'ctrl',
     scope: {
-      userId: '=',
+      userPicked: '&',
     },
     link: function(scope, elem, attrs, ctrl) {
-      scope.$watch("ctrl.userId", (newVal, oldVal) => {
-        ctrl.userIdChanged(newVal);
+      scope.$on("user-picker-reset", () => {
+        ctrl.reset();
       });
     }
   };

+ 97 - 90
public/app/features/dashboard/acl/acl.html

@@ -1,4 +1,4 @@
-<div class="modal-body modal-body--with-overflow">
+<div class="modal-body">
   <div class="modal-header">
     <h2 class="modal-header-title">
       <i class="fa fa-lock"></i>
@@ -10,111 +10,118 @@
     </a>
   </div>
 
-  <form ng-submit="ctrl.save()" class="modal-content" novalidate>
-    <!-- <h5 class="section&#45;heading">Add New Permission</h5> -->
-    <!-- <form name="addPermission" class="gf&#45;form&#45;group"> -->
-    <!-- 	<div class="gf&#45;form&#45;inline"> -->
-    <!--     <div class="gf&#45;form"> -->
-    <!-- 			<span class="gf&#45;form&#45;label">Type</span> -->
-    <!-- 			<select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="ctrl.type" ng&#45;options="r for r in ['User Group', 'User']"></select> -->
-    <!-- 		</div> -->
-    <!--     <div class="gf&#45;form" ng&#45;show="ctrl.type === 'User'"> -->
-    <!--       <span class="gf&#45;form&#45;label">User</span> -->
-    <!--       <user&#45;picker user&#45;id="ctrl.userId"></user&#45;picker> -->
-    <!--     </div> -->
-    <!--     <div class="gf&#45;form" ng&#45;show="ctrl.type === 'User Group'"> -->
-    <!--       <span class="gf&#45;form&#45;label">User Group</span> -->
-    <!--       <user&#45;group&#45;picker user&#45;group&#45;id="ctrl.userGroupId"></user&#45;group&#45;picker> -->
-    <!--     </div> -->
-    <!-- 		<div class="gf&#45;form"> -->
-    <!-- 			<span class="gf&#45;form&#45;label">Permission</span> -->
-    <!-- 			<select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="ctrl.permission" ng&#45;options="p.value as p.text for p in ctrl.permissionTypeOptions"></select> -->
-    <!-- 		</div> -->
-    <!-- 		<div class="gf&#45;form"> -->
-    <!-- 			<button class="btn gf&#45;form&#45;btn btn&#45;success" ng&#45;click="ctrl.addPermission()">Add</button> -->
-    <!-- 		</div> -->
-    <!-- 	</div> -->
-    <!-- </form> -->
-
-    <table class="filter-table">
+  <div class="modal-content">
+    <table class="filter-table gf-form-group">
       <tr ng-repeat="acl in ctrl.aclItems">
         <td style="width: 100%;">
           <i class="{{acl.icon}}"></i>
           <span ng-bind-html="acl.nameHtml"></span>
         </td>
-        <td>can...</td>
-        <td class="dropdown">
-          <a class="pointer" style="white-space: nowrap">
-            {{acl.permissionName}}
-            <i class="fa fa-caret-down"></i>
-          </a>
+        <td class="query-keyword">Can</td>
+        <td>
+          <div class="gf-form-select-wrapper">
+            <select class="gf-form-input gf-size-auto" ng-model="acl.permission" ng-options="p.value as p.text for p in ctrl.permissionOptions" ng-change="ctrl.permissionChanged(acl)"></select>
+          </div>
         </td>
         <td>
-          <a class="btn btn-inverse btn-small" ng-show="revision.version !== ctrl.dashboard.version" ng-click="ctrl.restore(revision.version)">
+          <a class="btn btn-inverse btn-small" ng-click="ctrl.removeItem($index)">
             <i class="fa fa-remove"></i>
           </a>
         </td>
       </tr>
+      <tr ng-show="ctrl.aclItems.length === 0">
+        <td colspan="4">
+          <em>No permission, will only accessable by admins.</em>
+        </td>
+      </tr>
     </table>
 
+    <form name="addPermission" class="gf-form-group">
+      <h6 class="muted">Add Permission For</h6>
+      <div class="gf-form-inline">
+        <div class="gf-form">
+          <div class="gf-form-select-wrapper">
+            <select class="gf-form-input gf-size-auto" ng-model="ctrl.newType" ng-options="r for r in ['User Group', 'User']"></select>
+          </div>
+        </div>
+        <div class="gf-form" ng-show="ctrl.newType === 'User'">
+          <span class="gf-form-label">User</span>
+          <user-picker user-picked="ctrl.userPicked($user)"></user-picker>
+        </div>
+        <div class="gf-form" ng-show="ctrl.newType === 'User Group'">
+          <span class="gf-form-label">User Group</span>
+          <user-group-picker user-group-id="ctrl.newAcl.userGroupId"></user-group-picker>
+        </div>
+        <div class="gf-form">
+          <span class="gf-form-label query-keyword">Can</span>
+          <div class="gf-form-select-wrapper">
+            <select class="gf-form-input gf-size-auto" ng-model="ctrl.newAcl.permission" ng-options="p.value as p.text for p in ctrl.permissionOptions"></select>
+          </div>
+        </div>
+        <div class="gf-form">
+          <button class="btn gf-form-btn btn-secondary" ng-click="ctrl.addPermission()">Add</button>
+        </div>
+      </div>
+    </form>
 
     <div class="gf-form-button-row text-center">
-      <button type="submit" class="btn btn-danger" ng-disabled="!ctrl.canUpdate">Update Permissions</button>
+      <button type="button" class="btn btn-danger" ng-disabled="!ctrl.canUpdate" ng-click="ctrl.update()">
+        Update Permissions
+      </button>
       <a class="btn-text" ng-click="ctrl.dismiss();">Close</a>
     </div>
 
-  </form>
-</div>
+    </div>
+  </div>
 
-<!-- <br> -->
-<!-- <br> -->
-<!-- <br> -->
-<!--  -->
-<!-- <div class="permissionlist"> -->
-<!--   <div class="permissionlist__section"> -->
-<!--     <div class="permissionlist__section&#45;header"> -->
-<!--       <h6>Permissions</h6> -->
-<!--     </div> -->
-<!--     <table class="filter&#45;table form&#45;inline"> -->
-<!--       <thead> -->
-<!--         <tr> -->
-<!--           <th style="width: 50px;"></th> -->
-<!--           <th>Name</th> -->
-<!--           <th style="width: 220px;">Permission</th> -->
-<!--           <th style="width: 120px"></th> -->
-<!--         </tr> -->
-<!--       </thead> -->
-<!--       <tbody> -->
-<!--         <tr ng&#45;repeat="permission in ctrl.userPermissions" class="permissionlist__item"> -->
-<!--           <td><i class="fa fa&#45;fw fa&#45;user"></i></td> -->
-<!--           <td>{{permission.userLogin}}</td> -->
-<!--           <td><select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="permission.permissions" ng&#45;options="p.value as p.text for p in ctrl.permissionTypeOptions" ng&#45;change="ctrl.updatePermission(permission)"></select></td> -->
-<!--           <td class="text&#45;right"> -->
-<!--             <a ng&#45;click="ctrl.removePermission(permission)" class="btn btn&#45;danger btn&#45;small"> -->
-<!--               <i class="fa fa&#45;remove"></i> -->
-<!--             </a> -->
-<!--           </td> -->
-<!--         </tr> -->
-<!--         <tr ng&#45;repeat="permission in ctrl.userGroupPermissions" class="permissionlist__item"> -->
-<!--           <td><i class="fa fa&#45;fw fa&#45;users"></i></td> -->
-<!--           <td>{{permission.userGroup}}</td> -->
-<!--           <td><select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="permission.permissions" ng&#45;options="p.value as p.text for p in ctrl.permissionTypeOptions" ng&#45;change="ctrl.updatePermission(permission)"></select></td> -->
-<!--           <td class="text&#45;right"> -->
-<!--             <a ng&#45;click="ctrl.removePermission(permission)" class="btn btn&#45;danger btn&#45;small"> -->
-<!--               <i class="fa fa&#45;remove"></i> -->
-<!--             </a> -->
-<!--           </td> -->
-<!--         </tr> -->
-<!--         <tr ng&#45;repeat="role in ctrl.roles" class="permissionlist__item"> -->
-<!--           <td></td> -->
-<!--           <td>{{role.name}}</td> -->
-<!--           <td><select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="role.permissions" ng&#45;options="p.value as p.text for p in ctrl.roleOptions" ng&#45;change="ctrl.updatePermission(role)"></select></td> -->
-<!--           <td class="text&#45;right"> -->
-<!--  -->
-<!--           </td> -->
-<!--         </tr> -->
-<!--       </tbody> -->
-<!--     </table> -->
-<!--   </div> -->
-<!--   </div> -->
-<!-- </div> -->
+  <!-- <br> -->
+  <!-- <br> -->
+  <!-- <br> -->
+  <!--  -->
+  <!-- <div class="permissionlist"> -->
+  <!--   <div class="permissionlist__section"> -->
+  <!--     <div class="permissionlist__section&#45;header"> -->
+  <!--       <h6>Permissions</h6> -->
+  <!--     </div> -->
+  <!--     <table class="filter&#45;table form&#45;inline"> -->
+  <!--       <thead> -->
+  <!--         <tr> -->
+  <!--           <th style="width: 50px;"></th> -->
+  <!--           <th>Name</th> -->
+  <!--           <th style="width: 220px;">Permission</th> -->
+  <!--           <th style="width: 120px"></th> -->
+  <!--         </tr> -->
+  <!--       </thead> -->
+  <!--       <tbody> -->
+  <!--         <tr ng&#45;repeat="permission in ctrl.userPermissions" class="permissionlist__item"> -->
+  <!--           <td><i class="fa fa&#45;fw fa&#45;user"></i></td> -->
+  <!--           <td>{{permission.userLogin}}</td> -->
+  <!--           <td class="text&#45;right"> -->
+  <!--             <a ng&#45;click="ctrl.removePermission(permission)" class="btn btn&#45;danger btn&#45;small"> -->
+  <!--               <i class="fa fa&#45;remove"></i> -->
+  <!--             </a> -->
+  <!--           </td> -->
+  <!--         </tr> -->
+  <!--         <tr ng&#45;repeat="permission in ctrl.userGroupPermissions" class="permissionlist__item"> -->
+  <!--           <td><i class="fa fa&#45;fw fa&#45;users"></i></td> -->
+  <!--           <td>{{permission.userGroup}}</td> -->
+  <!--           <td><select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="permission.permissions" ng&#45;options="p.value as p.text for p in ctrl.permissionTypeOptions" ng&#45;change="ctrl.updatePermission(permission)"></select></td> -->
+  <!--           <td class="text&#45;right"> -->
+  <!--             <a ng&#45;click="ctrl.removePermission(permission)" class="btn btn&#45;danger btn&#45;small"> -->
+  <!--               <i class="fa fa&#45;remove"></i> -->
+  <!--             </a> -->
+  <!--           </td> -->
+  <!--         </tr> -->
+  <!--         <tr ng&#45;repeat="role in ctrl.roles" class="permissionlist__item"> -->
+  <!--           <td></td> -->
+  <!--           <td>{{role.name}}</td> -->
+  <!--           <td><select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="role.permissions" ng&#45;options="p.value as p.text for p in ctrl.roleOptions" ng&#45;change="ctrl.updatePermission(role)"></select></td> -->
+  <!--           <td class="text&#45;right"> -->
+  <!--  -->
+  <!--           </td> -->
+  <!--         </tr> -->
+  <!--       </tbody> -->
+  <!--     </table> -->
+  <!--   </div> -->
+  <!--   </div> -->
+  <!-- </div> -->

+ 54 - 67
public/app/features/dashboard/acl/acl.ts

@@ -13,14 +13,16 @@ export class AclCtrl {
     {value: 4, text: 'Admin'}
   ];
 
-  type = 'User Group';
-  permission = 1;
-  userId: number;
-  userGroupId: number;
+  newType: string;
+  newAcl: DashboardAcl;
+  canUpdate: boolean;
 
   /** @ngInject */
-  constructor(private backendSrv, private dashboardSrv, private $sce) {
+  constructor(private backendSrv, private dashboardSrv, private $sce, private $scope) {
     this.aclItems = [];
+    this.newType = 'User Group';
+    this.resetNew();
+
     this.dashboard = dashboardSrv.getCurrent();
     this.get(this.dashboard.id);
   }
@@ -28,72 +30,57 @@ export class AclCtrl {
   get(dashboardId: number) {
     return this.backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`)
       .then(result => {
-        this.aclItems = _.map(result, item => {
-          if (item.userId > 0) {
-            item.icon = "fa fa-fw fa-user";
-            item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
-          } else if (item.userGroupId > 0) {
-            item.icon = "fa fa-fw fa-users";
-            item.nameHtml = this.$sce.trustAsHtml(item.userGroup);
-          } 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`);
-          }
-          return item;
-        });
+        this.aclItems = _.map(result, this.prepareViewModel.bind(this));
       });
   }
 
-  addPermission() {
-    if (this.type === 'User') {
-      if (!this.userId) {
-        return;
-      }
-      return this.addOrUpdateUserPermission(this.userId, this.permission).then(() => {
-        this.userId = null;
-        return this.get(this.dashboard.id);
-      });
-    } else {
-      if (!this.userGroupId) {
-        return;
-      }
-
-      return this.addOrUpdateUserGroupPermission(this.userGroupId, this.permission).then(() => {
-        this.userGroupId = null;
-        return this.get(this.dashboard.id);
-      });
+  prepareViewModel(item: DashboardAcl): DashboardAcl {
+    if (item.userId > 0) {
+      item.icon = "fa fa-fw fa-user";
+      item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
+    } else if (item.userGroupId > 0) {
+      item.icon = "fa fa-fw fa-users";
+      item.nameHtml = this.$sce.trustAsHtml(item.userGroup);
+    } 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`);
     }
+
+    return item;
   }
 
-  addOrUpdateUserPermission(userId: number, permissions: number) {
-    return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, {
-      userId: userId,
-      permissions: permissions
-    });
+  addPermission() {
+    this.aclItems.push(this.prepareViewModel(this.newAcl));
+    this.$scope.$broadcast('user-picker-reset');
+    this.$scope.$broadcast('user-group-picker-reset');
+  }
+
+  resetNew() {
+    this.newAcl = {
+      userId: 0,
+      userGroupId: 0,
+      permission: 1
+    };
   }
 
-  addOrUpdateUserGroupPermission(userGroupId: number, permissions: number) {
+  update() {
     return this.backendSrv.post(`/api/dashboards/id/${this.dashboard.id}/acl`, {
-      userGroupId: userGroupId,
-      permissions: permissions
+      acl: this.aclItems
     });
   }
 
-  updatePermission(permission: DashboardAcl) {
-    if (permission.userId > 0) {
-      return this.addOrUpdateUserPermission(permission.userId, permission.permissions);
-    } else {
-      if (!permission.userGroupId) {
-        return;
-      }
-      return this.addOrUpdateUserGroupPermission(permission.userGroupId, permission.permissions);
-    }
+  permissionChanged() {
+    this.canUpdate = true;
   }
 
-  removePermission(permission: DashboardAcl) {
-    return this.backendSrv.delete(`/api/dashboards/id/${permission.dashboardId}/acl/${permission.id}`).then(() => {
-      return this.get(permission.dashboardId);
-    });
+  userPicked(user) {
+    this.newAcl.userLogin = user.login;
+    this.newAcl.userId = user.id;
+  }
+
+  removeItem(index) {
+    this.aclItems.splice(index, 1);
+    this.canUpdate = true;
   }
 }
 
@@ -118,18 +105,18 @@ export interface FormModel {
 }
 
 export interface DashboardAcl {
-  id: number;
-  orgId: number;
-  dashboardId: number;
-  created: Date;
-  updated: Date;
+  id?: number;
+  dashboardId?: number;
   userId: number;
-  userLogin: number;
-  userEmail: string;
+  userLogin?: number;
+  userEmail?: string;
   userGroupId: number;
-  userGroup: string;
-  permissions: number;
-  permissionName: string;
+  userGroup?: string;
+  permission?: number;
+  permissionName?: string;
+  role?: string;
+  icon?: string;
+  nameHtml?: string;
 }
 
 coreModule.directive('dashAclModal', dashAclModal);