Commit 9ef64d30 by Daniel Lee

dashfolders: special case for folders in root

Allow users to change permissions inherited from root.
parent a7e57bc2
...@@ -36,17 +36,17 @@ export interface IProps { ...@@ -36,17 +36,17 @@ export interface IProps {
class Permissions extends Component<IProps, any> { class Permissions extends Component<IProps, any> {
constructor(props) { constructor(props) {
super(props); super(props);
const { dashboardId, isFolder } = this.props; const { dashboardId, isFolder, folderInfo } = this.props;
this.permissionChanged = this.permissionChanged.bind(this); this.permissionChanged = this.permissionChanged.bind(this);
this.typeChanged = this.typeChanged.bind(this); this.typeChanged = this.typeChanged.bind(this);
this.removeItem = this.removeItem.bind(this); this.removeItem = this.removeItem.bind(this);
this.userPicked = this.userPicked.bind(this); this.userPicked = this.userPicked.bind(this);
this.teamPicked = this.teamPicked.bind(this); this.teamPicked = this.teamPicked.bind(this);
this.loadStore(dashboardId, isFolder); this.loadStore(dashboardId, isFolder, folderInfo && folderInfo.id === 0);
} }
loadStore(dashboardId, isFolder) { loadStore(dashboardId, isFolder, isInRoot = false) {
return this.props.permissions.load(dashboardId, isFolder); return this.props.permissions.load(dashboardId, isFolder, isInRoot);
} }
permissionChanged(index: number, permission: number, permissionName: string) { permissionChanged(index: number, permission: number, permissionName: string) {
...@@ -78,13 +78,23 @@ class Permissions extends Component<IProps, any> { ...@@ -78,13 +78,23 @@ class Permissions extends Component<IProps, any> {
} }
userPicked(user: User) { userPicked(user: User) {
const { permissions } = this.props; const { permissions, dashboardId } = this.props;
return permissions.addStoreItem({ userId: user.id, userLogin: user.login, permission: 1 }); return permissions.addStoreItem({
userId: user.id,
userLogin: user.login,
permission: 1,
dashboardId: dashboardId,
});
} }
teamPicked(team: Team) { teamPicked(team: Team) {
const { permissions } = this.props; const { permissions, dashboardId } = this.props;
return permissions.addStoreItem({ teamId: team.id, team: team.name, permission: 1 }); return permissions.addStoreItem({
teamId: team.id,
team: team.name,
permission: 1,
dashboardId: dashboardId,
});
} }
render() { render() {
......
...@@ -17,6 +17,8 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde ...@@ -17,6 +17,8 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
permissionChanged(itemIndex, permissionOption.value, permissionOption.label); permissionChanged(itemIndex, permissionOption.value, permissionOption.label);
}; };
const inheritedFromRoot = item.dashboardId === -1 && folderInfo && folderInfo.id === 0;
return ( return (
<tr className={setClassNameHelper(item.inherited)}> <tr className={setClassNameHelper(item.inherited)}>
<td style={{ width: '100%' }}> <td style={{ width: '100%' }}>
...@@ -24,14 +26,16 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde ...@@ -24,14 +26,16 @@ export default observer(({ item, removeItem, permissionChanged, itemIndex, folde
<span dangerouslySetInnerHTML={{ __html: item.nameHtml }} /> <span dangerouslySetInnerHTML={{ __html: item.nameHtml }} />
</td> </td>
<td> <td>
{item.inherited && folderInfo ? ( {item.inherited &&
<em className="muted no-wrap"> folderInfo && (
Inherited from folder{' '} <em className="muted no-wrap">
<a className="text-link" href={`dashboards/folder/${folderInfo.id}/${folderInfo.slug}/permissions`}> Inherited from folder{' '}
{folderInfo.title} <a className="text-link" href={`dashboards/folder/${folderInfo.id}/${folderInfo.slug}/permissions`}>
</a>{' '} {folderInfo.title}
</em> </a>{' '}
) : null} </em>
)}
{inheritedFromRoot && <em className="muted no-wrap">Default Permission</em>}
</td> </td>
<td className="query-keyword">Can</td> <td className="query-keyword">Can</td>
<td> <td>
......
...@@ -32,7 +32,7 @@ describe('PermissionsStore', () => { ...@@ -32,7 +32,7 @@ describe('PermissionsStore', () => {
} }
); );
return store.load(1, false); return store.load(1, false, false);
}); });
it('should save update on permission change', () => { it('should save update on permission change', () => {
...@@ -78,6 +78,7 @@ describe('PermissionsStore', () => { ...@@ -78,6 +78,7 @@ describe('PermissionsStore', () => {
userId: 10, userId: 10,
userLogin: 'tester1', userLogin: 'tester1',
permission: 1, permission: 1,
dashboardId: 1,
}; };
store.addStoreItem(newItem); store.addStoreItem(newItem);
store.addStoreItem(newItem); store.addStoreItem(newItem);
...@@ -96,6 +97,7 @@ describe('PermissionsStore', () => { ...@@ -96,6 +97,7 @@ describe('PermissionsStore', () => {
teamId: 1, teamId: 1,
teamName: 'testerteam', teamName: 'testerteam',
permission: 1, permission: 1,
dashboardId: 1,
}; };
store.addStoreItem(newItem); store.addStoreItem(newItem);
store.addStoreItem(newItem); store.addStoreItem(newItem);
...@@ -114,6 +116,7 @@ describe('PermissionsStore', () => { ...@@ -114,6 +116,7 @@ describe('PermissionsStore', () => {
team: 'MyTestTeam', team: 'MyTestTeam',
teamId: 1, teamId: 1,
permission: 1, permission: 1,
dashboardId: 1,
}; };
store.addStoreItem(newItem); store.addStoreItem(newItem);
store.addStoreItem(newItem); store.addStoreItem(newItem);
......
...@@ -31,6 +31,7 @@ export const PermissionsStore = types ...@@ -31,6 +31,7 @@ export const PermissionsStore = types
error: types.maybe(types.string), error: types.maybe(types.string),
originalItems: types.optional(types.array(PermissionsStoreItem), []), originalItems: types.optional(types.array(PermissionsStoreItem), []),
newType: types.optional(types.string, defaultNewType), newType: types.optional(types.string, defaultNewType),
isInRoot: types.maybe(types.boolean),
}) })
.views(self => ({ .views(self => ({
isValid: item => { isValid: item => {
...@@ -47,16 +48,18 @@ export const PermissionsStore = types ...@@ -47,16 +48,18 @@ export const PermissionsStore = types
}, },
})) }))
.actions(self => ({ .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; const backendSrv = getEnv(self).backendSrv;
self.fetching = true; self.fetching = true;
self.isFolder = isFolder; self.isFolder = isFolder;
self.isInRoot = isInRoot;
self.dashboardId = dashboardId; self.dashboardId = dashboardId;
const res = yield backendSrv.get(`/api/dashboards/id/${dashboardId}/acl`); 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.items = items;
self.originalItems = items; self.originalItems = items;
self.fetching = false; self.fetching = false;
self.error = null;
}), }),
addStoreItem: flow(function* addStoreItem(item) { addStoreItem: flow(function* addStoreItem(item) {
self.error = null; self.error = null;
...@@ -64,7 +67,7 @@ export const PermissionsStore = types ...@@ -64,7 +67,7 @@ export const PermissionsStore = types
return undefined; 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); return updateItems(self);
}), }),
removeStoreItem: flow(function* removeStoreItem(idx: number) { removeStoreItem: flow(function* removeStoreItem(idx: number) {
...@@ -119,14 +122,15 @@ const updateItems = self => { ...@@ -119,14 +122,15 @@ const updateItems = self => {
return res; return res;
}; };
const prepareServerResponse = (response, dashboardId: number, isFolder: boolean) => { const prepareServerResponse = (response, dashboardId: number, isFolder: boolean, isInRoot: boolean) => {
return response.map(item => { return response.map(item => {
return prepareItem(item, dashboardId, isFolder); return prepareItem(item, dashboardId, isFolder, isInRoot);
}); });
}; };
const prepareItem = (item, dashboardId: number, isFolder: boolean) => { const prepareItem = (item, dashboardId: number, isFolder: boolean, isInRoot: boolean) => {
item.inherited = !isFolder && item.dashboardId > 0 && dashboardId !== item.dashboardId; item.inherited = !isFolder && !isInRoot && dashboardId !== item.dashboardId;
item.sortRank = 0; item.sortRank = 0;
if (item.userId > 0) { if (item.userId > 0) {
item.icon = 'fa fa-fw fa-user'; item.icon = 'fa fa-fw fa-user';
......
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