Commit d74a98fe by Daniel Lee

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.
parent 7900fd4a
......@@ -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
......
......@@ -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 {
......
......@@ -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',
]);
}
......@@ -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>
......
export interface FolderInfo {
title: string;
id: number;
slug: string;
}
......@@ -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">
......
......@@ -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}
/>
);
})}
......
......@@ -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>
);
......
......@@ -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>
......
......@@ -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;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment