Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
44ea8e58
Commit
44ea8e58
authored
Jan 15, 2018
by
Johannes Schill
Committed by
Daniel Lee
Jan 25, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wip: More on the permissions. Left are team picker and user picker, tests and error messages #10275
parent
460cbe98
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
143 additions
and
156 deletions
+143
-156
public/app/core/components/Permissions/Permissions.tsx
+33
-129
public/app/core/components/Permissions/PermissionsList.tsx
+15
-3
public/app/core/components/Permissions/PermissionsListItem.tsx
+7
-3
public/app/stores/PermissionsStore/PermissionsStore.ts
+76
-13
public/app/stores/PermissionsStore/PermissionsStoreItem.ts
+12
-8
No files found.
public/app/core/components/Permissions/Permissions.tsx
View file @
44ea8e58
...
...
@@ -5,6 +5,7 @@ import DevTools from 'mobx-react-devtools';
import
{
inject
,
observer
}
from
'mobx-react'
;
import
{
Provider
}
from
'mobx-react'
;
import
{
store
}
from
'app/stores/store'
;
import
UserPicker
from
'app/core/components/UserPicker/UserPicker'
;
export
interface
DashboardAcl
{
id
?:
number
;
...
...
@@ -75,140 +76,42 @@ class PermissionsInner extends Component<IProps, any> {
this
.
permissionChanged
=
this
.
permissionChanged
.
bind
(
this
);
this
.
typeChanged
=
this
.
typeChanged
.
bind
(
this
);
this
.
removeItem
=
this
.
removeItem
.
bind
(
this
);
this
.
update
=
this
.
update
.
bind
(
this
);
permissions
.
load
(
this
.
dashboardId
);
this
.
state
=
{
newType
:
'Group'
,
canUpdate
:
false
,
error
:
''
,
};
}
componentWillReceiveProps
(
nextProps
)
{
console
.
log
(
'nextProps'
,
nextProps
);
}
sortItems
(
items
)
{
return
_
.
orderBy
(
items
,
[
'sortRank'
,
'sortName'
],
[
'desc'
,
'asc'
]);
}
permissionChanged
(
evt
)
{
// TODO
permissionChanged
(
index
:
number
,
permission
:
number
,
permissionName
:
string
)
{
const
{
permissions
}
=
this
.
props
;
// permissions.items[index].updatePermission(permission, permissionName);
permissions
.
updatePermissionOnIndex
(
index
,
permission
,
permissionName
);
}
removeItem
(
index
)
{
removeItem
(
index
:
number
)
{
const
{
permissions
}
=
this
.
props
;
permissions
.
removeStoreItem
(
index
);
}
update
()
{
var
updated
=
[];
for
(
let
item
of
this
.
state
.
items
)
{
if
(
item
.
inherited
)
{
continue
;
}
updated
.
push
({
id
:
item
.
id
,
userId
:
item
.
userId
,
teamId
:
item
.
teamId
,
role
:
item
.
role
,
permission
:
item
.
permission
,
});
}
return
this
.
backendSrv
.
post
(
`/api/dashboards/id/
${
this
.
dashboardId
}
/acl`
,
{
items
:
updated
,
})
.
then
(()
=>
{
this
.
setState
(
prevState
=>
{
return
{
...
prevState
,
canUpdate
:
false
,
};
});
});
}
prepareViewModel
(
item
:
DashboardAcl
):
DashboardAcl
{
// TODO: this.meta
// item.inherited = !this.meta.isFolder && this.dashboardId !== item.dashboardId;
item
.
inherited
=
this
.
dashboardId
!==
item
.
dashboardId
;
item
.
sortRank
=
0
;
if
(
item
.
userId
>
0
)
{
item
.
icon
=
'fa fa-fw fa-user'
;
// item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
item
.
nameHtml
=
item
.
userLogin
;
item
.
sortName
=
item
.
userLogin
;
item
.
sortRank
=
10
;
}
else
if
(
item
.
teamId
>
0
)
{
item
.
icon
=
'fa fa-fw fa-users'
;
// item.nameHtml = this.$sce.trustAsHtml(item.team);
item
.
nameHtml
=
item
.
team
;
item
.
sortName
=
item
.
team
;
item
.
sortRank
=
20
;
}
else
if
(
item
.
role
)
{
item
.
icon
=
'fa fa-fw fa-street-view'
;
// item.nameHtml = this.$sce.trustAsHtml(`Everyone with <span class="query-keyword">${item.role}</span> Role`);
item
.
nameHtml
=
`Everyone with <span class="query-keyword">
${
item
.
role
}
</span> Role`
;
item
.
sortName
=
item
.
role
;
item
.
sortRank
=
30
;
if
(
item
.
role
===
'Viewer'
)
{
item
.
sortRank
+=
1
;
}
}
if
(
item
.
inherited
)
{
item
.
sortRank
+=
100
;
}
return
item
;
}
isDuplicate
(
origItem
,
newItem
)
{
if
(
origItem
.
inherited
)
{
return
false
;
}
return
(
(
origItem
.
role
&&
newItem
.
role
&&
origItem
.
role
===
newItem
.
role
)
||
(
origItem
.
userId
&&
newItem
.
userId
&&
origItem
.
userId
===
newItem
.
userId
)
||
(
origItem
.
teamId
&&
newItem
.
teamId
&&
origItem
.
teamId
===
newItem
.
teamId
)
);
}
isValid
(
item
)
{
const
dupe
=
_
.
find
(
this
.
items
,
it
=>
{
return
this
.
isDuplicate
(
it
,
item
);
});
if
(
dupe
)
{
this
.
error
=
this
.
duplicateError
;
return
false
;
}
return
true
;
}
addNewItem
(
item
)
{
if
(
!
this
.
isValid
(
item
))
{
return
;
}
this
.
error
=
''
;
item
.
dashboardId
=
this
.
dashboardId
;
let
newItems
=
this
.
state
.
items
;
newItems
.
push
(
this
.
prepareViewModel
(
item
));
this
.
setState
(
prevState
=>
{
return
{
...
prevState
,
items
:
this
.
sortItems
(
newItems
),
canUpdate
:
true
,
};
});
const
{
permissions
,
dashboardId
}
=
this
.
props
;
permissions
.
update
(
dashboardId
);
}
resetNewType
()
{
this
.
setState
(
prevState
=>
{
return
{
...
prevState
,
newType
:
'Group'
,
};
});
...
...
@@ -216,48 +119,43 @@ class PermissionsInner extends Component<IProps, any> {
typeChanged
(
evt
)
{
const
{
value
}
=
evt
.
target
;
this
.
setState
(
prevState
=>
{
return
{
...
prevState
,
newType
:
value
,
};
});
}
const
{
permissions
}
=
this
.
props
;
typeChanged___
()
{
const
{
newType
}
=
this
.
state
;
if
(
newType
===
'Viewer'
||
newType
===
'Editor'
)
{
this
.
addNewItem
({
permission
:
1
,
role
:
newType
});
if
(
value
===
'Viewer'
||
value
===
'Editor'
)
{
permissions
.
addStoreItem
({
permission
:
1
,
role
:
value
,
dashboardId
:
this
.
dashboardId
},
this
.
dashboardId
);
this
.
resetNewType
();
return
;
}
this
.
setState
(
prevState
=>
{
return
{
...
prevState
,
canUpdate
:
tr
ue
,
newType
:
val
ue
,
};
});
}
}
render
()
{
const
{
error
,
aclTypes
,
permissions
}
=
this
.
props
;
console
.
log
(
'PermissionsInner render'
);
const
{
error
,
aclTypes
,
permissions
,
backendSrv
}
=
this
.
props
;
const
{
newType
}
=
this
.
state
;
return
(
<
div
className=
"gf-form-group"
>
<
PermissionsList
permissions=
{
permissions
.
items
.
toJS
()
}
permissions=
{
permissions
.
items
}
permissionsOptions=
{
this
.
permissionOptions
}
removeItem=
{
this
.
removeItem
}
permissionChanged=
{
this
.
permissionChanged
}
fetching=
{
permissions
.
fetching
}
/>
asd2
<
div
className=
"gf-form-inline"
>
<
form
name=
"addPermission"
className=
"gf-form-group"
>
<
h6
className=
"muted"
>
Add Permission For
</
h6
>
<
div
className=
"gf-form-inline"
>
<
div
className=
"gf-form"
>
<
div
className=
"gf-form-select-wrapper"
>
<
select
className=
"gf-form-input gf-size-auto"
onChange=
{
this
.
typeChanged
}
>
<
select
className=
"gf-form-input gf-size-auto"
value=
{
newType
}
onChange=
{
this
.
typeChanged
}
>
{
aclTypes
.
map
((
option
,
idx
)
=>
{
return
(
<
option
key=
{
idx
}
value=
{
option
.
value
}
>
...
...
@@ -280,6 +178,13 @@ class PermissionsInner extends Component<IProps, any> {
{
' '
}
User picker
<
user
-
picker
user
-
picked=
"ctrl.userPicked($user)"
/>
<
select
-
user
-
picker
backendSrv=
"ctrl.backendSrv"
teamId=
"ctrl.$routeParams.id"
refreshList=
"ctrl.get"
teamMembers=
"ctrl.teamMembers"
/>
<
UserPicker
backendSrv=
{
backendSrv
}
teamId=
{
0
}
/>
</
div
>
)
:
null
}
...
...
@@ -306,7 +211,6 @@ class PermissionsInner extends Component<IProps, any> {
Update Permissions
</
button
>
</
div
>
asd3
<
DevTools
/>
</
div
>
);
...
...
public/app/core/components/Permissions/PermissionsList.tsx
View file @
44ea8e58
import
React
,
{
Component
}
from
'react'
;
import
PermissionsListItem
from
'./PermissionsListItem'
;
import
{
observer
}
from
'mobx-react'
;
export
interface
IProps
{
permissions
:
any
[];
permissionsOptions
:
any
[];
removeItem
:
any
;
permissionChanged
:
any
;
fetching
:
boolean
;
}
@
observer
class
PermissionsList
extends
Component
<
IProps
,
any
>
{
render
()
{
const
{
permissions
,
permissionsOptions
,
removeItem
,
permissionChanged
}
=
this
.
props
;
const
{
permissions
,
permissionsOptions
,
removeItem
,
permissionChanged
,
fetching
}
=
this
.
props
;
return
(
<
table
className=
"filter-table gf-form-group"
>
<
tbody
>
{
permissions
.
map
((
item
,
idx
)
=>
{
return
(
<
PermissionsListItem
key=
{
i
tem
.
id
}
key=
{
i
dx
}
item=
{
item
}
itemIndex=
{
idx
}
permissionsOptions=
{
permissionsOptions
}
...
...
@@ -55,7 +59,15 @@ class PermissionsList extends Component<IProps, any> {
<em>No permissions are set. Will only be accessible by admins.</em>
</td>
</tr> */
}
{
permissions
.
length
<
1
?
(
{
fetching
===
true
&&
permissions
.
length
<
1
?
(
<
tr
>
<
td
colSpan=
{
4
}
>
<
em
>
Loading permissions...
</
em
>
</
td
>
</
tr
>
)
:
null
}
{
fetching
===
false
&&
permissions
.
length
<
1
?
(
<
tr
>
<
td
colSpan=
{
4
}
>
<
em
>
No permissions are set. Will only be accessible by admins.
</
em
>
...
...
public/app/core/components/Permissions/PermissionsListItem.tsx
View file @
44ea8e58
import
React
from
'react'
;
import
{
observer
}
from
'mobx-react'
;
const
setClassNameHelper
=
inherited
=>
{
return
inherited
?
'gf-form-disabled'
:
''
;
};
export
default
({
item
,
permissionsOptions
,
removeItem
,
permissionChanged
,
itemIndex
})
=>
{
export
default
observer
(
({
item
,
permissionsOptions
,
removeItem
,
permissionChanged
,
itemIndex
})
=>
{
const
handleRemoveItem
=
evt
=>
{
evt
.
preventDefault
();
removeItem
(
itemIndex
);
...
...
@@ -12,7 +13,10 @@ export default ({ item, permissionsOptions, removeItem, permissionChanged, itemI
const
handleChangePermission
=
evt
=>
{
evt
.
preventDefault
();
permissionChanged
(
itemIndex
,
evt
.
target
.
value
);
const
value
=
evt
.
target
.
value
;
const
valueAsInt
=
parseInt
(
value
,
10
);
const
newPermission
=
permissionsOptions
.
find
(
opt
=>
opt
.
value
===
valueAsInt
);
permissionChanged
(
itemIndex
,
newPermission
.
value
,
newPermission
.
text
);
};
return
(
...
...
@@ -57,4 +61,4 @@ export default ({ item, permissionsOptions, removeItem, permissionChanged, itemI
</
td
>
</
tr
>
);
};
}
)
;
public/app/stores/PermissionsStore/PermissionsStore.ts
View file @
44ea8e58
import
{
types
,
getEnv
,
flow
}
from
'mobx-state-tree'
;
import
{
PermissionsStoreItem
}
from
'./PermissionsStoreItem'
;
const
duplicateError
=
'This permission exists already.'
;
export
const
PermissionsStore
=
types
.
model
(
'PermissionsStore'
,
{
fetching
:
types
.
boolean
,
...
...
@@ -8,36 +10,87 @@ export const PermissionsStore = types
items
:
types
.
optional
(
types
.
array
(
PermissionsStoreItem
),
[]),
originalItems
:
types
.
optional
(
types
.
array
(
PermissionsStoreItem
),
[]),
})
// .views(self => ({
// canUpdate: () => {
// const itemsSnapshot = getSnapshot(self.items);
// const originalItemsSnapshot = getSnapshot(self.originalItems);
// console.log('itemsSnapshot', itemsSnapshot);
// console.log('editItemsSnapshot', originalItemsSnapshot);
// return true;
// }
// }))
.
views
(
self
=>
({
isValid
:
item
=>
{
const
dupe
=
self
.
items
.
find
(
it
=>
{
return
isDuplicate
(
it
,
item
);
});
if
(
dupe
)
{
this
.
error
=
duplicateError
;
return
false
;
}
return
true
;
},
}))
.
actions
(
self
=>
({
load
:
flow
(
function
*
load
(
dashboardId
:
number
)
{
self
.
fetching
=
true
;
const
backendSrv
=
getEnv
(
self
).
backendSrv
;
self
.
fetching
=
true
;
const
res
=
yield
backendSrv
.
get
(
`/api/dashboards/id/
${
dashboardId
}
/acl`
);
const
items
=
prepareServerResponse
(
res
,
dashboardId
);
self
.
items
=
items
;
self
.
originalItems
=
items
;
self
.
fetching
=
false
;
}),
addStoreItem
:
()
=>
{
addStoreItem
:
(
item
,
dashboardId
:
number
)
=>
{
if
(
!
self
.
isValid
(
item
))
{
return
;
}
self
.
items
.
push
(
prepareItem
(
item
,
dashboardId
));
self
.
canUpdate
=
true
;
},
removeStoreItem
:
idx
=>
{
self
.
items
.
splice
(
idx
,
1
);
self
.
canUpdate
=
true
;
},
updatePermissionOnIndex
(
idx
:
number
,
permission
:
number
,
permissionName
:
string
)
{
// self.items[idx].permission = permission;
// self.items[idx].permissionName = permissionName;
self
.
items
[
idx
].
updatePermission
(
permission
,
permissionName
);
self
.
canUpdate
=
true
;
},
// load: flow(function* load(dashboardId: number) {
update
:
flow
(
function
*
update
(
dashboardId
:
number
)
{
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
);
}
self
.
canUpdate
=
false
;
return
res
;
}),
}));
const
prepareServerResponse
=
(
response
,
dashboardId
:
number
)
=>
{
return
response
.
map
(
item
=>
{
return
prepareItem
(
item
,
dashboardId
);
});
};
const
prepareItem
=
(
item
,
dashboardId
:
number
)
=>
{
// TODO: this.meta
// item.inherited = !this.meta.isFolder && this.dashboardId !== item.dashboardId;
item
.
inherited
=
dashboardId
!==
item
.
dashboardId
;
...
...
@@ -68,7 +121,17 @@ const prepareServerResponse = (response, dashboardId: number) => {
if
(
item
.
inherited
)
{
item
.
sortRank
+=
100
;
}
return
item
;
});
};
const
isDuplicate
=
(
origItem
,
newItem
)
=>
{
if
(
origItem
.
inherited
)
{
return
false
;
}
return
(
(
origItem
.
role
&&
newItem
.
role
&&
origItem
.
role
===
newItem
.
role
)
||
(
origItem
.
userId
&&
newItem
.
userId
&&
origItem
.
userId
===
newItem
.
userId
)
||
(
origItem
.
teamId
&&
newItem
.
teamId
&&
origItem
.
teamId
===
newItem
.
teamId
)
);
};
public/app/stores/PermissionsStore/PermissionsStoreItem.ts
View file @
44ea8e58
...
...
@@ -2,16 +2,16 @@
export
const
PermissionsStoreItem
=
types
.
model
(
'PermissionsStoreItem'
,
{
dashboardId
:
types
.
number
,
id
:
types
.
number
,
dashboardId
:
types
.
optional
(
types
.
number
,
-
1
)
,
id
:
types
.
maybe
(
types
.
number
)
,
permission
:
types
.
number
,
permissionName
:
types
.
string
,
permissionName
:
types
.
maybe
(
types
.
string
)
,
role
:
types
.
maybe
(
types
.
string
),
team
:
types
.
string
,
teamId
:
types
.
number
,
userEmail
:
types
.
string
,
userId
:
types
.
number
,
userLogin
:
types
.
string
,
team
:
types
.
optional
(
types
.
string
,
''
)
,
teamId
:
types
.
optional
(
types
.
number
,
0
)
,
userEmail
:
types
.
optional
(
types
.
string
,
''
)
,
userId
:
types
.
optional
(
types
.
number
,
0
)
,
userLogin
:
types
.
optional
(
types
.
string
,
''
)
,
inherited
:
types
.
maybe
(
types
.
boolean
),
sortRank
:
types
.
maybe
(
types
.
number
),
icon
:
types
.
maybe
(
types
.
string
),
...
...
@@ -22,4 +22,8 @@ export const PermissionsStoreItem = types
updateRole
:
role
=>
{
self
.
role
=
role
;
},
updatePermission
(
permission
:
number
,
permissionName
:
string
)
{
self
.
permission
=
permission
;
self
.
permissionName
=
permissionName
;
},
}));
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment