Browse Source

dashfolders: special case for folders in root

Allow users to change permissions inherited from root.
Daniel Lee 8 năm trước cách đây
mục cha
commit
9ef64d3056

+ 18 - 8
public/app/core/components/Permissions/Permissions.tsx

@@ -36,17 +36,17 @@ export interface IProps {
 class Permissions extends Component<IProps, any> {
   constructor(props) {
     super(props);
-    const { dashboardId, isFolder } = this.props;
+    const { dashboardId, isFolder, folderInfo } = this.props;
     this.permissionChanged = this.permissionChanged.bind(this);
     this.typeChanged = this.typeChanged.bind(this);
     this.removeItem = this.removeItem.bind(this);
     this.userPicked = this.userPicked.bind(this);
     this.teamPicked = this.teamPicked.bind(this);
-    this.loadStore(dashboardId, isFolder);
+    this.loadStore(dashboardId, isFolder, folderInfo && folderInfo.id === 0);
   }
 
-  loadStore(dashboardId, isFolder) {
-    return this.props.permissions.load(dashboardId, isFolder);
+  loadStore(dashboardId, isFolder, isInRoot = false) {
+    return this.props.permissions.load(dashboardId, isFolder, isInRoot);
   }
 
   permissionChanged(index: number, permission: number, permissionName: string) {
@@ -78,13 +78,23 @@ class Permissions extends Component<IProps, any> {
   }
 
   userPicked(user: User) {
-    const { permissions } = this.props;
-    return permissions.addStoreItem({ userId: user.id, userLogin: user.login, permission: 1 });
+    const { permissions, dashboardId } = this.props;
+    return permissions.addStoreItem({
+      userId: user.id,
+      userLogin: user.login,
+      permission: 1,
+      dashboardId: dashboardId,
+    });
   }
 
   teamPicked(team: Team) {
-    const { permissions } = this.props;
-    return permissions.addStoreItem({ teamId: team.id, team: team.name, permission: 1 });
+    const { permissions, dashboardId } = this.props;
+    return permissions.addStoreItem({
+      teamId: team.id,
+      team: team.name,
+      permission: 1,
+      dashboardId: dashboardId,
+    });
   }
 
   render() {

+ 12 - 8
public/app/core/components/Permissions/PermissionsListItem.tsx

@@ -17,6 +17,8 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
     permissionChanged(itemIndex, permissionOption.value, permissionOption.label);
   };
 
+  const inheritedFromRoot = item.dashboardId === -1 && folderInfo && folderInfo.id === 0;
+
   return (
     <tr className={setClassNameHelper(item.inherited)}>
       <td style={{ width: '100%' }}>
@@ -24,14 +26,16 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
         <span dangerouslySetInnerHTML={{ __html: item.nameHtml }} />
       </td>
       <td>
-        {item.inherited && folderInfo ? (
-          <em className="muted no-wrap">
-            Inherited from folder{' '}
-            <a className="text-link" href={`dashboards/folder/${folderInfo.id}/${folderInfo.slug}/permissions`}>
-              {folderInfo.title}
-            </a>{' '}
-          </em>
-        ) : null}
+        {item.inherited &&
+          folderInfo && (
+            <em className="muted no-wrap">
+              Inherited from folder{' '}
+              <a className="text-link" href={`dashboards/folder/${folderInfo.id}/${folderInfo.slug}/permissions`}>
+                {folderInfo.title}
+              </a>{' '}
+            </em>
+          )}
+        {inheritedFromRoot && <em className="muted no-wrap">Default Permission</em>}
       </td>
       <td className="query-keyword">Can</td>
       <td>

+ 4 - 1
public/app/stores/PermissionsStore/PermissionsStore.jest.ts

@@ -32,7 +32,7 @@ describe('PermissionsStore', () => {
       }
     );
 
-    return store.load(1, false);
+    return store.load(1, false, false);
   });
 
   it('should save update on permission change', () => {
@@ -78,6 +78,7 @@ describe('PermissionsStore', () => {
         userId: 10,
         userLogin: 'tester1',
         permission: 1,
+        dashboardId: 1,
       };
       store.addStoreItem(newItem);
       store.addStoreItem(newItem);
@@ -96,6 +97,7 @@ describe('PermissionsStore', () => {
         teamId: 1,
         teamName: 'testerteam',
         permission: 1,
+        dashboardId: 1,
       };
       store.addStoreItem(newItem);
       store.addStoreItem(newItem);
@@ -114,6 +116,7 @@ describe('PermissionsStore', () => {
         team: 'MyTestTeam',
         teamId: 1,
         permission: 1,
+        dashboardId: 1,
       };
       store.addStoreItem(newItem);
       store.addStoreItem(newItem);

+ 11 - 7
public/app/stores/PermissionsStore/PermissionsStore.ts

@@ -31,6 +31,7 @@ export const PermissionsStore = types
     error: types.maybe(types.string),
     originalItems: types.optional(types.array(PermissionsStoreItem), []),
     newType: types.optional(types.string, defaultNewType),
+    isInRoot: types.maybe(types.boolean),
   })
   .views(self => ({
     isValid: item => {
@@ -47,16 +48,18 @@ export const PermissionsStore = types
     },
   }))
   .actions(self => ({
-    load: flow(function* load(dashboardId: number, isFolder: boolean) {
+    load: flow(function* load(dashboardId: number, isFolder: boolean, isInRoot: boolean) {
       const backendSrv = getEnv(self).backendSrv;
       self.fetching = true;
       self.isFolder = isFolder;
+      self.isInRoot = isInRoot;
       self.dashboardId = dashboardId;
       const res = yield backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`);
-      const items = prepareServerResponse(res, dashboardId, isFolder);
+      const items = prepareServerResponse(res, dashboardId, isFolder, isInRoot);
       self.items = items;
       self.originalItems = items;
       self.fetching = false;
+      self.error = null;
     }),
     addStoreItem: flow(function* addStoreItem(item) {
       self.error = null;
@@ -64,7 +67,7 @@ export const PermissionsStore = types
         return undefined;
       }
 
-      self.items.push(prepareItem(item, self.dashboardId, self.isFolder));
+      self.items.push(prepareItem(item, self.dashboardId, self.isFolder, self.isInRoot));
       return updateItems(self);
     }),
     removeStoreItem: flow(function* removeStoreItem(idx: number) {
@@ -119,14 +122,15 @@ const updateItems = self => {
   return res;
 };
 
-const prepareServerResponse = (response, dashboardId: number, isFolder: boolean) => {
+const prepareServerResponse = (response, dashboardId: number, isFolder: boolean, isInRoot: boolean) => {
   return response.map(item => {
-    return prepareItem(item, dashboardId, isFolder);
+    return prepareItem(item, dashboardId, isFolder, isInRoot);
   });
 };
 
-const prepareItem = (item, dashboardId: number, isFolder: boolean) => {
-  item.inherited = !isFolder && item.dashboardId > 0 && dashboardId !== item.dashboardId;
+const prepareItem = (item, dashboardId: number, isFolder: boolean, isInRoot: boolean) => {
+  item.inherited = !isFolder && !isInRoot && dashboardId !== item.dashboardId;
+
   item.sortRank = 0;
   if (item.userId > 0) {
     item.icon = 'fa fa-fw fa-user';