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
f360b618
Commit
f360b618
authored
Sep 13, 2018
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wip: first couple of things starting to work
parent
8096cd8f
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
465 additions
and
38 deletions
+465
-38
public/app/core/actions/permissions.ts
+24
-0
public/app/core/components/PermissionList/DisabledPermissionListItem.tsx
+43
-0
public/app/core/components/PermissionList/PermissionList.tsx
+61
-0
public/app/core/components/PermissionList/PermissionListItem.tsx
+100
-0
public/app/features/folders/FolderPermissions.tsx
+41
-29
public/app/features/folders/state/actions.ts
+80
-5
public/app/features/folders/state/reducers.ts
+39
-2
public/app/types/acl.ts
+60
-0
public/app/types/folder.ts
+10
-1
public/app/types/index.ts
+7
-1
No files found.
public/app/core/actions/permissions.ts
0 → 100644
View file @
f360b618
import
{
DashboardAcl
}
from
'../../types'
;
export
enum
ActionTypes
{
LoadFolderPermissions
=
'LoadFolderPermissions'
,
}
export
interface
LoadFolderPermissionsAction
{
type
:
ActionTypes
.
LoadFolderPermissions
;
payload
:
DashboardAcl
[];
}
export
type
Action
=
LoadFolderPermissions
;
export
const
loadFolderPermissions
=
(
items
:
DashboardAcl
[]):
LoadFolderPermissionsAction
=>
({
type
:
ActionTypes
.
LoadFolderPermissions
,
payload
:
items
,
});
export
function
getFolderPermissions
(
uid
:
string
):
ThunkResult
<
void
>
{
return
async
dispatch
=>
{
const
permissions
=
await
backendSrv
.
get
(
`/api/folders/
${
uid
}
/permissions`
);
dispatch
(
loadFolderPermissions
(
permissions
));
};
}
public/app/core/components/PermissionList/DisabledPermissionListItem.tsx
0 → 100644
View file @
f360b618
import
React
,
{
Component
}
from
'react'
;
import
DescriptionPicker
from
'app/core/components/Picker/DescriptionPicker'
;
import
{
permissionOptions
}
from
'app/stores/PermissionsStore/PermissionsStore'
;
export
interface
Props
{
item
:
any
;
}
export
default
class
DisabledPermissionListItem
extends
Component
<
Props
,
any
>
{
render
()
{
const
{
item
}
=
this
.
props
;
return
(
<
tr
className=
"gf-form-disabled"
>
<
td
style=
{
{
width
:
'1%'
}
}
>
<
i
style=
{
{
width
:
'25px'
,
height
:
'25px'
}
}
className=
"gicon gicon-shield"
/>
</
td
>
<
td
style=
{
{
width
:
'90%'
}
}
>
{
item
.
name
}
<
span
className=
"filter-table__weak-italic"
>
(Role)
</
span
>
</
td
>
<
td
/>
<
td
className=
"query-keyword"
>
Can
</
td
>
<
td
>
<
div
className=
"gf-form"
>
<
DescriptionPicker
optionsWithDesc=
{
permissionOptions
}
onSelected=
{
()
=>
{}
}
value=
{
item
.
permission
}
disabled=
{
true
}
className=
{
'gf-form-input--form-dropdown-right'
}
/>
</
div
>
</
td
>
<
td
>
<
button
className=
"btn btn-inverse btn-small"
>
<
i
className=
"fa fa-lock"
/>
</
button
>
</
td
>
</
tr
>
);
}
}
public/app/core/components/PermissionList/PermissionList.tsx
0 → 100644
View file @
f360b618
import
React
,
{
PureComponent
}
from
'react'
;
import
PermissionsListItem
from
'./PermissionListItem'
;
import
DisabledPermissionsListItem
from
'./DisabledPermissionListItem'
;
import
{
DashboardAcl
,
FolderInfo
}
from
'app/types'
;
export
interface
Props
{
items
:
DashboardAcl
[];
onRemoveItem
:
(
item
:
DashboardAcl
)
=>
void
;
onPermissionChanged
:
any
;
isFetching
:
boolean
;
folderInfo
?:
FolderInfo
;
}
class
PermissionList
extends
PureComponent
<
Props
>
{
render
()
{
const
{
items
,
onRemoveItem
,
onPermissionChanged
,
isFetching
,
folderInfo
}
=
this
.
props
;
return
(
<
table
className=
"filter-table gf-form-group"
>
<
tbody
>
<
DisabledPermissionsListItem
key=
{
0
}
item=
{
{
name
:
'Admin'
,
permission
:
4
,
icon
:
'fa fa-fw fa-street-view'
,
}
}
/>
{
items
.
map
((
item
,
idx
)
=>
{
return
(
<
PermissionsListItem
key=
{
idx
+
1
}
item=
{
item
}
onRemoveItem=
{
onRemoveItem
}
onPermissionChanged=
{
onPermissionChanged
}
folderInfo=
{
folderInfo
}
/>
);
})
}
{
isFetching
===
true
&&
items
.
length
<
1
?
(
<
tr
>
<
td
colSpan=
{
4
}
>
<
em
>
Loading permissions...
</
em
>
</
td
>
</
tr
>
)
:
null
}
{
isFetching
===
false
&&
items
.
length
<
1
?
(
<
tr
>
<
td
colSpan=
{
4
}
>
<
em
>
No permissions are set. Will only be accessible by admins.
</
em
>
</
td
>
</
tr
>
)
:
null
}
</
tbody
>
</
table
>
);
}
}
export
default
PermissionList
;
public/app/core/components/PermissionList/PermissionListItem.tsx
0 → 100644
View file @
f360b618
import
React
,
{
PureComponent
}
from
'react'
;
import
DescriptionPicker
from
'app/core/components/Picker/DescriptionPicker'
;
import
{
dashboardPermissionLevels
}
from
'app/types/acl'
;
import
{
DashboardAcl
,
FolderInfo
,
PermissionLevel
}
from
'app/types'
;
const
setClassNameHelper
=
inherited
=>
{
return
inherited
?
'gf-form-disabled'
:
''
;
};
function
ItemAvatar
({
item
})
{
if
(
item
.
userAvatarUrl
)
{
return
<
img
className=
"filter-table__avatar"
src=
{
item
.
userAvatarUrl
}
/>;
}
if
(
item
.
teamAvatarUrl
)
{
return
<
img
className=
"filter-table__avatar"
src=
{
item
.
teamAvatarUrl
}
/>;
}
if
(
item
.
role
===
'Editor'
)
{
return
<
i
style=
{
{
width
:
'25px'
,
height
:
'25px'
}
}
className=
"gicon gicon-editor"
/>;
}
return
<
i
style=
{
{
width
:
'25px'
,
height
:
'25px'
}
}
className=
"gicon gicon-viewer"
/>;
}
function
ItemDescription
({
item
})
{
if
(
item
.
userId
)
{
return
<
span
className=
"filter-table__weak-italic"
>
(User)
</
span
>;
}
if
(
item
.
teamId
)
{
return
<
span
className=
"filter-table__weak-italic"
>
(Team)
</
span
>;
}
return
<
span
className=
"filter-table__weak-italic"
>
(Role)
</
span
>;
}
interface
Props
{
item
:
DashboardAcl
;
onRemoveItem
:
(
item
:
DashboardAcl
)
=>
void
;
onPermissionChanged
:
(
item
:
DashboardAcl
,
level
:
PermissionLevel
)
=>
void
;
folderInfo
?:
FolderInfo
;
}
export
default
class
PermissionsListItem
extends
PureComponent
<
Props
>
{
onPermissionChanged
=
option
=>
{
this
.
props
.
onPermissionChanged
(
this
.
props
.
item
,
option
.
value
as
PermissionLevel
);
};
onRemoveItem
=
()
=>
{
this
.
props
.
onRemoveItem
(
this
.
props
.
item
);
};
render
()
{
const
{
item
,
folderInfo
}
=
this
.
props
;
const
inheritedFromRoot
=
item
.
dashboardId
===
-
1
&&
!
item
.
inherited
;
return
(
<
tr
className=
{
setClassNameHelper
(
item
.
inherited
)
}
>
<
td
style=
{
{
width
:
'1%'
}
}
>
<
ItemAvatar
item=
{
item
}
/>
</
td
>
<
td
style=
{
{
width
:
'90%'
}
}
>
{
item
.
name
}
<
ItemDescription
item=
{
item
}
/>
</
td
>
<
td
>
{
item
.
inherited
&&
folderInfo
&&
(
<
em
className=
"muted no-wrap"
>
Inherited from folder
{
' '
}
<
a
className=
"text-link"
href=
{
`${folderInfo.url}/permissions`
}
>
{
folderInfo
.
title
}
</
a
>
{
' '
}
</
em
>
)
}
{
inheritedFromRoot
&&
<
em
className=
"muted no-wrap"
>
Default Permission
</
em
>
}
</
td
>
<
td
className=
"query-keyword"
>
Can
</
td
>
<
td
>
<
div
className=
"gf-form"
>
<
DescriptionPicker
optionsWithDesc=
{
dashboardPermissionLevels
}
onSelected=
{
this
.
onPermissionChanged
}
value=
{
item
.
permission
}
disabled=
{
item
.
inherited
}
className=
{
'gf-form-input--form-dropdown-right'
}
/>
</
div
>
</
td
>
<
td
>
{
!
item
.
inherited
?
(
<
a
className=
"btn btn-danger btn-small"
onClick=
{
this
.
onRemoveItem
}
>
<
i
className=
"fa fa-remove"
/>
</
a
>
)
:
(
<
button
className=
"btn btn-inverse btn-small"
>
<
i
className=
"fa fa-lock"
/>
</
button
>
)
}
</
td
>
</
tr
>
);
}
}
public/app/features/folders/FolderPermissions.tsx
View file @
f360b618
import
React
,
{
Component
}
from
'react'
;
import
{
hot
}
from
'react-hot-loader'
;
import
{
inject
,
observer
}
from
'mobx-react'
;
import
{
connect
}
from
'react-redux'
;
import
PageHeader
from
'app/core/components/PageHeader/PageHeader'
;
import
Permissions
from
'app/core/components/Permissions/Permissions'
;
...
...
@@ -9,50 +8,61 @@ import PermissionsInfo from 'app/core/components/Permissions/PermissionsInfo';
import
AddPermissions
from
'app/core/components/Permissions/AddPermissions'
;
import
SlideDown
from
'app/core/components/Animations/SlideDown'
;
import
{
getNavModel
}
from
'app/core/selectors/navModel'
;
import
{
NavModel
,
StoreState
,
FolderState
}
from
'app/types'
;
import
{
getFolderByUid
}
from
'./state/actions'
;
import
{
PermissionsStore
}
from
'app/stores/PermissionsStore/PermissionsStore'
;
import
{
NavModel
,
StoreState
,
FolderState
,
DashboardAcl
,
PermissionLevel
}
from
'app/types'
;
import
{
getFolderByUid
,
getFolderPermissions
,
updateFolderPermission
,
removeFolderPermission
}
from
'./state/actions'
;
import
{
getLoadingNav
}
from
'./state/navModel'
;
import
PermissionList
from
'app/core/components/PermissionList/PermissionList'
;
export
interface
Props
{
navModel
:
NavModel
;
getFolderByUid
:
typeof
getFolderByUid
;
folderUid
:
string
;
folder
:
FolderState
;
permissions
:
typeof
PermissionsStore
.
Type
;
backendSrv
:
any
;
getFolderByUid
:
typeof
getFolderByUid
;
getFolderPermissions
:
typeof
getFolderPermissions
;
updateFolderPermission
:
typeof
updateFolderPermission
;
removeFolderPermission
:
typeof
removeFolderPermission
;
}
export
interface
State
{
isAdding
:
boolean
;
}
@
inject
(
'permissions'
)
@
observer
export
class
FolderPermissions
extends
Component
<
Props
>
{
export
class
FolderPermissions
extends
Component
<
Props
,
State
>
{
constructor
(
props
)
{
super
(
props
);
this
.
handleAddPermission
=
this
.
handleAddPermission
.
bind
(
this
);
this
.
state
=
{
isAdding
:
false
,
};
}
componentDidMount
()
{
this
.
props
.
getFolderByUid
(
this
.
props
.
folderUid
);
this
.
props
.
getFolderPermissions
(
this
.
props
.
folderUid
);
}
componentWillUnmount
()
{
const
{
permissions
}
=
this
.
props
;
permissions
.
hideAddPermissions
();
}
onOpenAddPermissions
=
()
=>
{
this
.
setState
({
isAdding
:
true
});
};
handleAddPermission
()
{
const
{
permissions
}
=
this
.
props
;
permissions
.
toggleAddPermissions
();
}
onRemoveItem
=
(
item
:
DashboardAcl
)
=>
{
this
.
props
.
removeFolderPermission
(
item
);
};
onPermissionChanged
=
(
item
:
DashboardAcl
,
level
:
PermissionLevel
)
=>
{
this
.
props
.
updateFolderPermission
(
item
,
level
);
};
render
()
{
const
{
navModel
,
permissions
,
backendSrv
,
folder
}
=
this
.
props
;
const
{
navModel
,
folder
}
=
this
.
props
;
const
{
isAdding
}
=
this
.
state
;
if
(
folder
.
id
===
0
)
{
return
<
PageHeader
model=
{
navModel
}
/>;
}
const
dashboardId
=
folder
.
id
;
const
folderInfo
=
{
title
:
folder
.
tile
,
url
:
folder
.
url
,
id
:
folder
.
id
};
return
(
<
div
>
...
...
@@ -64,18 +74,17 @@ export class FolderPermissions extends Component<Props> {
<
i
className=
"gicon gicon-question gicon--has-hover"
/>
</
Tooltip
>
<
div
className=
"page-action-bar__spacer"
/>
<
button
className=
"btn btn-success pull-right"
onClick=
{
this
.
handleAddPermission
}
disabled=
{
permissions
.
isAddPermissionsVisible
}
>
<
button
className=
"btn btn-success pull-right"
onClick=
{
this
.
onOpenAddPermissions
}
disabled=
{
isAdding
}
>
<
i
className=
"fa fa-plus"
/>
Add Permission
</
button
>
</
div
>
<
SlideDown
in=
{
permissions
.
isAddPermissionsVisible
}
>
<
AddPermissions
permissions=
{
permissions
}
/>
</
SlideDown
>
<
Permissions
permissions=
{
permissions
}
isFolder=
{
true
}
dashboardId=
{
dashboardId
}
backendSrv=
{
backendSrv
}
/>
<
PermissionList
items=
{
folder
.
permissions
}
onRemoveItem=
{
this
.
onRemoveItem
}
onPermissionChanged=
{
this
.
onPermissionChanged
}
isFetching=
{
false
}
folderInfo=
{
folderInfo
}
/>
</
div
>
</
div
>
);
...
...
@@ -93,6 +102,9 @@ const mapStateToProps = (state: StoreState) => {
const
mapDispatchToProps
=
{
getFolderByUid
,
getFolderPermissions
,
updateFolderPermission
,
removeFolderPermission
,
};
export
default
hot
(
module
)(
connect
(
mapStateToProps
,
mapDispatchToProps
)(
FolderPermissions
));
public/app/features/folders/state/actions.ts
View file @
f360b618
import
{
getBackendSrv
}
from
'app/core/services/backend_srv'
;
import
{
StoreState
}
from
'app/types'
;
import
{
ThunkAction
}
from
'redux-thunk'
;
import
{
FolderDTO
,
FolderState
}
from
'app/types'
;
import
{
FolderDTO
,
FolderState
,
DashboardAcl
,
DashboardAclDTO
,
PermissionLevel
,
DashboardAclUpdateDTO
,
}
from
'app/types'
;
import
{
updateNavIndex
,
updateLocation
}
from
'app/core/actions'
;
import
{
buildNavModel
}
from
'./navModel'
;
import
appEvents
from
'app/core/app_events'
;
...
...
@@ -10,6 +17,7 @@ export enum ActionTypes {
LoadFolder
=
'LOAD_FOLDER'
,
SetFolderTitle
=
'SET_FOLDER_TITLE'
,
SaveFolder
=
'SAVE_FOLDER'
,
LoadFolderPermissions
=
'LOAD_FOLDER_PERMISSONS'
,
}
export
interface
LoadFolderAction
{
...
...
@@ -22,6 +30,15 @@ export interface SetFolderTitleAction {
payload
:
string
;
}
export
interface
LoadFolderPermissionsAction
{
type
:
ActionTypes
.
LoadFolderPermissions
;
payload
:
DashboardAcl
[];
}
export
type
Action
=
LoadFolderAction
|
SetFolderTitleAction
|
LoadFolderPermissionsAction
;
type
ThunkResult
<
R
>
=
ThunkAction
<
R
,
StoreState
,
undefined
,
any
>
;
export
const
loadFolder
=
(
folder
:
FolderDTO
):
LoadFolderAction
=>
({
type
:
ActionTypes
.
LoadFolder
,
payload
:
folder
,
...
...
@@ -32,10 +49,10 @@ export const setFolderTitle = (newTitle: string): SetFolderTitleAction => ({
payload
:
newTitle
,
});
export
type
Action
=
LoadFolderAction
|
SetFolderTitleAction
;
type
ThunkResult
<
R
>
=
ThunkAction
<
R
,
StoreState
,
undefined
,
any
>
;
export
const
loadFolderPermissions
=
(
items
:
DashboardAclDTO
[]):
LoadFolderPermissionsAction
=>
({
type
:
ActionTypes
.
LoadFolderPermissions
,
payload
:
items
,
});
export
function
getFolderByUid
(
uid
:
string
):
ThunkResult
<
void
>
{
return
async
dispatch
=>
{
...
...
@@ -65,3 +82,61 @@ export function deleteFolder(uid: string): ThunkResult<void> {
dispatch
(
updateLocation
({
path
:
`dashboards`
}));
};
}
export
function
getFolderPermissions
(
uid
:
string
):
ThunkResult
<
void
>
{
return
async
dispatch
=>
{
const
permissions
=
await
getBackendSrv
().
get
(
`/api/folders/
${
uid
}
/permissions`
);
dispatch
(
loadFolderPermissions
(
permissions
));
};
}
function
toUpdateItem
(
item
:
DashboardAcl
):
DashboardAclUpdateDTO
{
return
{
userId
:
item
.
userId
,
teamId
:
item
.
teamId
,
role
:
item
.
role
,
permission
:
item
.
permission
,
};
}
export
function
updateFolderPermission
(
itemToUpdate
:
DashboardAcl
,
level
:
PermissionLevel
):
ThunkResult
<
void
>
{
return
async
(
dispatch
,
getStore
)
=>
{
const
folder
=
getStore
().
folder
;
const
itemsToUpdate
=
[];
for
(
const
item
of
folder
.
permissions
)
{
if
(
item
.
inherited
)
{
continue
;
}
const
updated
=
toUpdateItem
(
itemToUpdate
);
// if this is the item we want to update, update it's permisssion
if
(
itemToUpdate
===
item
)
{
updated
.
permission
=
level
;
}
itemsToUpdate
.
push
(
updated
);
}
await
getBackendSrv
().
post
(
`/api/folders/
${
folder
.
uid
}
/permissions`
,
{
items
:
itemsToUpdate
});
await
dispatch
(
getFolderPermissions
(
folder
.
uid
));
};
}
export
function
removeFolderPermission
(
itemToDelete
:
DashboardAcl
):
ThunkResult
<
void
>
{
return
async
(
dispatch
,
getStore
)
=>
{
const
folder
=
getStore
().
folder
;
const
itemsToUpdate
=
[];
for
(
const
item
of
folder
.
permissions
)
{
if
(
item
.
inherited
||
item
===
itemToDelete
)
{
continue
;
}
itemsToUpdate
.
push
(
toUpdateItem
(
item
));
}
await
getBackendSrv
().
post
(
`/api/folders/
${
folder
.
uid
}
/permissions`
,
{
items
:
itemsToUpdate
});
await
dispatch
(
getFolderPermissions
(
folder
.
uid
));
};
}
public/app/features/folders/state/reducers.ts
View file @
f360b618
import
{
FolderState
}
from
'app/types'
;
import
{
FolderState
,
DashboardAcl
,
DashboardAclDTO
}
from
'app/types'
;
import
{
Action
,
ActionTypes
}
from
'./actions'
;
export
const
inititalState
:
FolderState
=
{
...
...
@@ -8,13 +8,15 @@ export const inititalState: FolderState = {
url
:
''
,
canSave
:
false
,
hasChanged
:
false
,
version
:
0
,
version
:
1
,
permissions
:
[],
};
export
const
folderReducer
=
(
state
=
inititalState
,
action
:
Action
):
FolderState
=>
{
switch
(
action
.
type
)
{
case
ActionTypes
.
LoadFolder
:
return
{
...
state
,
...
action
.
payload
,
hasChanged
:
false
,
};
...
...
@@ -24,10 +26,45 @@ export const folderReducer = (state = inititalState, action: Action): FolderStat
title
:
action
.
payload
,
hasChanged
:
action
.
payload
.
trim
().
length
>
0
,
};
case
ActionTypes
.
LoadFolderPermissions
:
return
{
...
state
,
permissions
:
processAclItems
(
action
.
payload
),
};
}
return
state
;
};
function
processAclItems
(
items
:
DashboardAclDTO
[]):
DashboardAcl
[]
{
return
items
.
map
(
processAclItem
).
sort
((
a
,
b
)
=>
b
.
sortRank
-
a
.
sortRank
||
a
.
name
.
localeCompare
(
b
.
name
));
}
function
processAclItem
(
dto
:
DashboardAclDTO
):
DashboardAcl
{
const
item
=
dto
as
DashboardAcl
;
item
.
sortRank
=
0
;
if
(
item
.
userId
>
0
)
{
item
.
name
=
item
.
userLogin
;
item
.
sortRank
=
10
;
}
else
if
(
item
.
teamId
>
0
)
{
item
.
name
=
item
.
team
;
item
.
sortRank
=
20
;
}
else
if
(
item
.
role
)
{
item
.
icon
=
'fa fa-fw fa-street-view'
;
item
.
name
=
item
.
role
;
item
.
sortRank
=
30
;
if
(
item
.
role
===
'Editor'
)
{
item
.
sortRank
+=
1
;
}
}
if
(
item
.
inherited
)
{
item
.
sortRank
+=
100
;
}
return
item
;
}
export
default
{
folder
:
folderReducer
,
};
public/app/types/acl.ts
0 → 100644
View file @
f360b618
export
interface
DashboardAclDTO
{
id
?:
number
;
dashboardId
?:
number
;
userId
?:
number
;
userLogin
?:
string
;
userEmail
?:
string
;
teamId
?:
number
;
team
?:
string
;
permission
?:
PermissionLevel
;
permissionName
?:
string
;
role
?:
string
;
icon
?:
string
;
inherited
?:
boolean
;
}
export
interface
DashboardAclUpdateDTO
{
userId
:
number
;
teamId
:
number
;
role
:
string
;
permission
:
PermissionLevel
;
}
export
interface
DashboardAcl
{
id
?:
number
;
dashboardId
?:
number
;
userId
?:
number
;
userLogin
?:
string
;
userEmail
?:
string
;
teamId
?:
number
;
team
?:
string
;
permission
?:
PermissionLevel
;
permissionName
?:
string
;
role
?:
string
;
icon
?:
string
;
name
?:
string
;
inherited
?:
boolean
;
sortRank
?:
number
;
}
export
interface
DashboardPermissionInfo
{
value
:
PermissionLevel
;
label
:
string
;
description
:
string
;
}
export
enum
PermissionLevel
{
View
=
1
,
Edit
=
2
,
Admin
=
4
,
}
export
const
dashboardPermissionLevels
:
DashboardPermissionInfo
[]
=
[
{
value
:
PermissionLevel
.
View
,
label
:
'View'
,
description
:
'Can view dashboards.'
},
{
value
:
PermissionLevel
.
Edit
,
label
:
'Edit'
,
description
:
'Can add, edit and delete dashboards.'
},
{
value
:
PermissionLevel
.
Admin
,
label
:
'Admin'
,
description
:
'Can add/remove permissions and can add, edit and delete dashboards.'
,
},
];
public/app/types/folder.ts
View file @
f360b618
import
{
DashboardAcl
}
from
'./acl'
;
export
interface
FolderDTO
{
id
:
number
;
uid
:
string
;
...
...
@@ -12,7 +14,14 @@ export interface FolderState {
uid
:
string
;
title
:
string
;
url
:
string
;
version
:
number
;
canSave
:
boolean
;
hasChanged
:
boolean
;
version
:
number
;
permissions
:
DashboardAcl
[];
}
export
interface
FolderInfo
{
id
:
number
;
title
:
string
;
url
:
string
;
}
public/app/types/index.ts
View file @
f360b618
...
...
@@ -2,7 +2,8 @@ import { Team, TeamsState, TeamState, TeamGroup, TeamMember } from './teams';
import
{
AlertRuleDTO
,
AlertRule
,
AlertRulesState
}
from
'./alerting'
;
import
{
LocationState
,
LocationUpdate
,
UrlQueryMap
,
UrlQueryValue
}
from
'./location'
;
import
{
NavModel
,
NavModelItem
,
NavIndex
}
from
'./navModel'
;
import
{
FolderDTO
,
FolderState
}
from
'./folder'
;
import
{
FolderDTO
,
FolderState
,
FolderInfo
}
from
'./folder'
;
import
{
DashboardAcl
,
DashboardAclDTO
,
PermissionLevel
,
DashboardAclUpdateDTO
}
from
'./acl'
;
export
{
Team
,
...
...
@@ -22,6 +23,11 @@ export {
UrlQueryValue
,
FolderDTO
,
FolderState
,
FolderInfo
,
DashboardAcl
,
DashboardAclDTO
,
DashboardAclUpdateDTO
,
PermissionLevel
,
};
export
interface
StoreState
{
...
...
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