Jelajahi Sumber

dashfolders: autosave permissions on change (remove update button)

Daniel Lee 8 tahun lalu
induk
melakukan
ccd86873e7

+ 6 - 13
public/app/core/components/Permissions/Permissions.tsx

@@ -34,14 +34,17 @@ export interface IProps {
 class Permissions extends Component<IProps, any> {
   constructor(props) {
     super(props);
-    const { dashboardId, permissions, isFolder } = this.props;
+    const { dashboardId, isFolder } = this.props;
     this.permissionChanged = this.permissionChanged.bind(this);
     this.typeChanged = this.typeChanged.bind(this);
     this.removeItem = this.removeItem.bind(this);
-    this.update = this.update.bind(this);
     this.userPicked = this.userPicked.bind(this);
     this.teamPicked = this.teamPicked.bind(this);
-    permissions.load(dashboardId, isFolder);
+    this.loadStore(dashboardId, isFolder);
+  }
+
+  loadStore(dashboardId, isFolder) {
+    return this.props.permissions.load(dashboardId, isFolder);
   }
 
   permissionChanged(index: number, permission: number, permissionName: string) {
@@ -54,11 +57,6 @@ class Permissions extends Component<IProps, any> {
     permissions.removeStoreItem(index);
   }
 
-  update() {
-    const { permissions, dashboardId } = this.props;
-    permissions.update(dashboardId);
-  }
-
   resetNewType() {
     const { permissions } = this.props;
     permissions.resetNewType();
@@ -142,11 +140,6 @@ class Permissions extends Component<IProps, any> {
             </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>
         <div className="empty-list-cta m-t-3">
           <div className="grafana-info-box">
             <h5>What are Permissions?</h5>

+ 0 - 5
public/app/routes/routes.ts

@@ -69,11 +69,6 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
       controller: 'CreateFolderCtrl',
       controllerAs: 'ctrl',
     })
-    // .when('/dashboards/folder/:folderId/:slug/permissions', {
-    //   templateUrl: 'public/app/features/dashboard/partials/folder_permissions.html',
-    //   controller: 'FolderPermissionsCtrl',
-    //   controllerAs: 'ctrl',
-    // })
     .when('/dashboards/folder/:folderId/:slug/permissions', {
       template: '<react-container />',
       resolve: {

+ 76 - 0
public/app/stores/PermissionsStore/PermissionsStore.jest.ts

@@ -0,0 +1,76 @@
+import { PermissionsStore } from './PermissionsStore';
+import { backendSrv } from 'test/mocks/common';
+
+describe('PermissionsStore', () => {
+  let store;
+
+  beforeEach(() => {
+    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();
+
+    store = PermissionsStore.create(
+      {
+        fetching: false,
+        canUpdate: false,
+        items: [],
+      },
+      {
+        backendSrv: backendSrv,
+      }
+    );
+
+    return store.load(1, true);
+  });
+
+  it('should save update on permission change', () => {
+    expect(store.items[0].permission).toBe(1);
+    expect(store.items[0].permissionName).toBe('View');
+
+    store.updatePermissionOnIndex(0, 2, 'Edit');
+
+    expect(store.items[0].permission).toBe(2);
+    expect(store.items[0].permissionName).toBe('Edit');
+    expect(backendSrv.post.mock.calls.length).toBe(1);
+    expect(backendSrv.post.mock.calls[0][0]).toBe('/api/dashboards/id/1/acl');
+  });
+
+  it('should save newly added permissions automatically', () => {
+    expect(store.items.length).toBe(3);
+
+    const newItem = {
+      userId: 10,
+      userLogin: 'tester1',
+      permission: 1,
+    };
+    store.addStoreItem(newItem);
+
+    expect(store.items.length).toBe(4);
+    expect(backendSrv.post.mock.calls.length).toBe(1);
+    expect(backendSrv.post.mock.calls[0][0]).toBe('/api/dashboards/id/1/acl');
+  });
+
+  it('should save removed permissions automatically', () => {
+    expect(store.items.length).toBe(3);
+
+    store.removeStoreItem(2);
+
+    expect(store.items.length).toBe(2);
+    expect(backendSrv.post.mock.calls.length).toBe(1);
+    expect(backendSrv.post.mock.calls[0][0]).toBe('/api/dashboards/id/1/acl');
+  });
+});

+ 43 - 39
public/app/stores/PermissionsStore/PermissionsStore.ts

@@ -19,7 +19,6 @@ export const PermissionsStore = types
     fetching: types.boolean,
     isFolder: types.maybe(types.boolean),
     dashboardId: types.maybe(types.number),
-    canUpdate: types.boolean,
     items: types.optional(types.array(PermissionsStoreItem), []),
     error: types.maybe(types.string),
     originalItems: types.optional(types.array(PermissionsStoreItem), []),
@@ -51,61 +50,66 @@ export const PermissionsStore = types
       self.originalItems = items;
       self.fetching = false;
     }),
-    addStoreItem: item => {
+    addStoreItem: flow(function* addStoreItem(item) {
       self.error = null;
       if (!self.isValid(item)) {
-        return;
+        return undefined;
       }
 
       self.items.push(prepareItem(item, self.dashboardId, self.isFolder));
-      self.canUpdate = true;
-    },
-    removeStoreItem: idx => {
+      updateItems(self);
+    }),
+    removeStoreItem: flow(function* removeStoreItem(idx: number) {
       self.error = null;
       self.items.splice(idx, 1);
-      self.canUpdate = true;
-    },
-    updatePermissionOnIndex(idx: number, permission: number, permissionName: string) {
+      updateItems(self);
+    }),
+    updatePermissionOnIndex: flow(function* updatePermissionOnIndex(
+      idx: number,
+      permission: number,
+      permissionName: string
+    ) {
       self.error = null;
       self.items[idx].updatePermission(permission, permissionName);
-      self.canUpdate = true;
-    },
+      updateItems(self);
+    }),
     setNewType(newType: string) {
       self.newType = newType;
     },
     resetNewType() {
       self.newType = defaultNewType;
     },
-    update: flow(function* update(dashboardId: number) {
-      self.error = null;
-      const backendSrv = getEnv(self).backendSrv;
-      const updated = [];
-      for (let item of self.items) {
-        if (item.inherited) {
-          continue;
-        }
-        updated.push({
-          id: item.id,
-          userId: item.userId,
-          teamId: item.teamId,
-          role: item.role,
-          permission: item.permission,
-        });
-      }
+  }));
 
-      let res;
-      try {
-        res = backendSrv.post(`/api/dashboards/id/${dashboardId}/acl`, {
-          items: updated,
-        });
-      } catch (error) {
-        console.error(error);
-      }
+const updateItems = self => {
+  self.error = null;
 
-      self.canUpdate = false;
-      return res;
-    }),
-  }));
+  const backendSrv = getEnv(self).backendSrv;
+  const updated = [];
+  for (let item of self.items) {
+    if (item.inherited) {
+      continue;
+    }
+    updated.push({
+      id: item.id,
+      userId: item.userId,
+      teamId: item.teamId,
+      role: item.role,
+      permission: item.permission,
+    });
+  }
+
+  let res;
+  try {
+    res = backendSrv.post(`/api/dashboards/id/${self.dashboardId}/acl`, {
+      items: updated,
+    });
+  } catch (error) {
+    console.error(error);
+  }
+
+  return res;
+};
 
 const prepareServerResponse = (response, dashboardId: number, isFolder: boolean) => {
   return response.map(item => {

+ 0 - 1
public/app/stores/RootStore/RootStore.ts

@@ -20,7 +20,6 @@ export const RootStore = types.model({
   }),
   permissions: types.optional(PermissionsStore, {
     fetching: false,
-    canUpdate: false,
     items: [],
   }),
   view: types.optional(ViewStore, {