Browse Source

dashfolders: link to folder for inherited permissions

In the permissions view in dashboard settings, this adds a
link to the parent folder for inherited permissions. Which
allows the user to easily navigate to the folder and change
inherited permissions.
Daniel Lee 8 years ago
parent
commit
d74a98feff

+ 1 - 0
pkg/api/dashboard.go

@@ -99,6 +99,7 @@ func GetDashboard(c *middleware.Context) Response {
 			return ApiError(500, "Dashboard folder could not be read", err)
 		}
 		meta.FolderTitle = query.Result.Title
+		meta.FolderSlug = query.Result.Slug
 	}
 
 	// make sure db version is in sync with json model version

+ 1 - 0
pkg/api/dtos/dashboard.go

@@ -26,6 +26,7 @@ type DashboardMeta struct {
 	IsFolder    bool      `json:"isFolder"`
 	FolderId    int64     `json:"folderId"`
 	FolderTitle string    `json:"folderTitle"`
+	FolderSlug  string    `json:"folderSlug"`
 }
 
 type DashboardFullWithMeta struct {

+ 7 - 1
public/app/core/angular_wrappers.ts

@@ -20,5 +20,11 @@ export function registerAngularDirectives() {
     ['tagOptions', { watchDepth: 'reference' }],
   ]);
   react2AngularDirective('selectUserPicker', UserPicker, ['backendSrv', 'handlePicked']);
-  react2AngularDirective('dashboardPermissions', DashboardPermissions, ['backendSrv', 'dashboardId', 'folderTitle']);
+  react2AngularDirective('dashboardPermissions', DashboardPermissions, [
+    'backendSrv',
+    'dashboardId',
+    'folderTitle',
+    'folderSlug',
+    'folderId',
+  ]);
 }

+ 4 - 2
public/app/core/components/Permissions/DashboardPermissions.tsx

@@ -6,7 +6,9 @@ import PermissionsInfo from 'app/core/components/Permissions/PermissionsInfo';
 
 export interface IProps {
   dashboardId: number;
+  folderId: number;
   folderTitle: string;
+  folderSlug: string;
   backendSrv: any;
 }
 
@@ -19,7 +21,7 @@ class DashboardPermissions extends Component<IProps, any> {
   }
 
   render() {
-    const { dashboardId, folderTitle, backendSrv } = this.props;
+    const { dashboardId, folderTitle, folderSlug, folderId, backendSrv } = this.props;
 
     return (
       <div>
@@ -33,7 +35,7 @@ class DashboardPermissions extends Component<IProps, any> {
           permissions={this.permissions}
           isFolder={false}
           dashboardId={dashboardId}
-          folderTitle={folderTitle}
+           folderInfo={{ title: folderTitle, slug: folderSlug, id: folderId }}
           backendSrv={backendSrv}
         />
       </div>

+ 5 - 0
public/app/core/components/Permissions/FolderInfo.ts

@@ -0,0 +1,5 @@
+export interface FolderInfo {
+  title: string;
+  id: number;
+  slug: string;
+}

+ 4 - 3
public/app/core/components/Permissions/Permissions.tsx

@@ -4,6 +4,7 @@ import { observer } from 'mobx-react';
 import UserPicker, { User } from 'app/core/components/Picker/UserPicker';
 import TeamPicker, { Team } from 'app/core/components/Picker/TeamPicker';
 import { aclTypes } from 'app/stores/PermissionsStore/PermissionsStore';
+import { FolderInfo } from './FolderInfo';
 
 export interface DashboardAcl {
   id?: number;
@@ -25,7 +26,7 @@ export interface DashboardAcl {
 
 export interface IProps {
   dashboardId: number;
-  folderTitle?: string;
+  folderInfo?: FolderInfo;
   permissions?: any;
   isFolder: boolean;
   backendSrv: any;
@@ -87,7 +88,7 @@ class Permissions extends Component<IProps, any> {
   }
 
   render() {
-    const { permissions, folderTitle, backendSrv } = this.props;
+    const { permissions, folderInfo, backendSrv } = this.props;
 
     return (
       <div className="gf-form-group">
@@ -96,7 +97,7 @@ class Permissions extends Component<IProps, any> {
           removeItem={this.removeItem}
           permissionChanged={this.permissionChanged}
           fetching={permissions.fetching}
-          folderTitle={folderTitle}
+          folderInfo={folderInfo}
         />
         <div className="gf-form-inline">
           <form name="addPermission" className="gf-form-group">

+ 4 - 3
public/app/core/components/Permissions/PermissionsList.tsx

@@ -2,19 +2,20 @@
 import PermissionsListItem from './PermissionsListItem';
 import DisabledPermissionsListItem from './DisabledPermissionsListItem';
 import { observer } from 'mobx-react';
+import { FolderInfo } from './FolderInfo';
 
 export interface IProps {
   permissions: any[];
   removeItem: any;
   permissionChanged: any;
   fetching: boolean;
-  folderTitle: string;
+  folderInfo?: FolderInfo;
 }
 
 @observer
 class PermissionsList extends Component<IProps, any> {
   render() {
-    const { permissions, removeItem, permissionChanged, fetching, folderTitle } = this.props;
+    const { permissions, removeItem, permissionChanged, fetching, folderInfo } = this.props;
 
     return (
       <table className="filter-table gf-form-group">
@@ -35,7 +36,7 @@ class PermissionsList extends Component<IProps, any> {
                 itemIndex={idx}
                 removeItem={removeItem}
                 permissionChanged={permissionChanged}
-                folderTitle={folderTitle}
+                folderInfo={folderInfo}
               />
             );
           })}

+ 16 - 3
public/app/core/components/Permissions/PermissionsListItem.tsx

@@ -7,7 +7,7 @@ const setClassNameHelper = inherited => {
   return inherited ? 'gf-form-disabled' : '';
 };
 
-export default observer(({ item, removeItem, permissionChanged, itemIndex, folderTitle }) => {
+export default observer(({ item, removeItem, permissionChanged, itemIndex, folderInfo }) => {
   const handleRemoveItem = evt => {
     evt.preventDefault();
     removeItem(itemIndex);
@@ -23,7 +23,16 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
         <i className={item.icon} />
         <span dangerouslySetInnerHTML={{ __html: item.nameHtml }} />
       </td>
-      <td>{item.inherited ? <em className="muted no-wrap">Inherited from folder {folderTitle} </em> : null}</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}
+      </td>
       <td className="query-keyword">Can</td>
       <td>
         <div className="gf-form">
@@ -41,7 +50,11 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
           <a className="btn btn-danger btn-small" onClick={handleRemoveItem}>
             <i className="fa fa-remove" />
           </a>
-        ) : null}
+        ) : (
+          <button className="btn btn-inverse btn-small">
+            <i className="fa fa-lock" />
+          </button>
+        )}
       </td>
     </tr>
   );

+ 2 - 0
public/app/features/dashboard/settings/settings.html

@@ -100,6 +100,8 @@
     dashboardId="ctrl.dashboard.id"
     backendSrv="ctrl.backendSrv"
     folderTitle="ctrl.dashboard.meta.folderTitle"
+    folderSlug="ctrl.dashboard.meta.folderSlug"
+    folderId="ctrl.dashboard.meta.folderId"
   />
 </div>
 

+ 1 - 0
public/app/features/dashboard/settings/settings.ts

@@ -191,6 +191,7 @@ export class SettingsCtrl {
   onFolderChange(folder) {
     this.dashboard.meta.folderId = folder.id;
     this.dashboard.meta.folderTitle = folder.title;
+    this.dashboard.meta.folderSlug = folder.slug;
   }
 }