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
d6faa3d0
Commit
d6faa3d0
authored
Feb 27, 2018
by
bergquist
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
provisioning: improve UX when saving provisioned dashboards
parent
a20f3d19
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
152 additions
and
4 deletions
+152
-4
pkg/api/dashboard.go
+7
-0
pkg/api/dtos/dashboard.go
+1
-0
pkg/models/dashboards.go
+6
-0
pkg/services/provisioning/dashboards/types.go
+0
-3
pkg/services/sqlstore/dashboard_provisioning.go
+13
-0
pkg/services/sqlstore/dashboard_provisioning_test.go
+10
-0
public/app/features/dashboard/all.ts
+1
-0
public/app/features/dashboard/dashboard_srv.ts
+11
-0
public/app/features/dashboard/dashnav/dashnav.html
+1
-1
public/app/features/dashboard/save_provisioned_modal.ts
+74
-0
public/app/features/dashboard/specs/save_provisioned_modal.jest.ts
+28
-0
No files found.
pkg/api/dashboard.go
View file @
d6faa3d0
...
@@ -102,6 +102,13 @@ func GetDashboard(c *m.ReqContext) Response {
...
@@ -102,6 +102,13 @@ func GetDashboard(c *m.ReqContext) Response {
meta
.
FolderUrl
=
query
.
Result
.
GetUrl
()
meta
.
FolderUrl
=
query
.
Result
.
GetUrl
()
}
}
dpQuery
:=
&
m
.
GetProvisionedDashboardByDashboardId
{
DashboardId
:
dash
.
Id
}
err
=
bus
.
Dispatch
(
dpQuery
)
if
dpQuery
.
Result
!=
nil
{
meta
.
CanEdit
=
true
meta
.
Provisioned
=
true
}
// make sure db version is in sync with json model version
// make sure db version is in sync with json model version
dash
.
Data
.
Set
(
"version"
,
dash
.
Version
)
dash
.
Data
.
Set
(
"version"
,
dash
.
Version
)
...
...
pkg/api/dtos/dashboard.go
View file @
d6faa3d0
...
@@ -28,6 +28,7 @@ type DashboardMeta struct {
...
@@ -28,6 +28,7 @@ type DashboardMeta struct {
FolderId
int64
`json:"folderId"`
FolderId
int64
`json:"folderId"`
FolderTitle
string
`json:"folderTitle"`
FolderTitle
string
`json:"folderTitle"`
FolderUrl
string
`json:"folderUrl"`
FolderUrl
string
`json:"folderUrl"`
Provisioned
bool
`json:"provisioned"`
}
}
type
DashboardFullWithMeta
struct
{
type
DashboardFullWithMeta
struct
{
...
...
pkg/models/dashboards.go
View file @
d6faa3d0
...
@@ -317,6 +317,12 @@ type GetDashboardSlugByIdQuery struct {
...
@@ -317,6 +317,12 @@ type GetDashboardSlugByIdQuery struct {
Result
string
Result
string
}
}
type
GetProvisionedDashboardByDashboardId
struct
{
DashboardId
int64
Result
*
DashboardProvisioning
}
type
GetProvisionedDashboardDataQuery
struct
{
type
GetProvisionedDashboardDataQuery
struct
{
Name
string
Name
string
...
...
pkg/services/provisioning/dashboards/types.go
View file @
d6faa3d0
...
@@ -55,9 +55,6 @@ func createDashboardJson(data *simplejson.Json, lastModified time.Time, cfg *Das
...
@@ -55,9 +55,6 @@ func createDashboardJson(data *simplejson.Json, lastModified time.Time, cfg *Das
dash
.
OrgId
=
cfg
.
OrgId
dash
.
OrgId
=
cfg
.
OrgId
dash
.
Dashboard
.
OrgId
=
cfg
.
OrgId
dash
.
Dashboard
.
OrgId
=
cfg
.
OrgId
dash
.
Dashboard
.
FolderId
=
folderId
dash
.
Dashboard
.
FolderId
=
folderId
if
!
cfg
.
Editable
{
dash
.
Dashboard
.
Data
.
Set
(
"editable"
,
cfg
.
Editable
)
}
if
dash
.
Dashboard
.
Title
==
""
{
if
dash
.
Dashboard
.
Title
==
""
{
return
nil
,
models
.
ErrDashboardTitleEmpty
return
nil
,
models
.
ErrDashboardTitleEmpty
...
...
pkg/services/sqlstore/dashboard_provisioning.go
View file @
d6faa3d0
...
@@ -8,6 +8,7 @@ import (
...
@@ -8,6 +8,7 @@ import (
func
init
()
{
func
init
()
{
bus
.
AddHandler
(
"sql"
,
GetProvisionedDashboardDataQuery
)
bus
.
AddHandler
(
"sql"
,
GetProvisionedDashboardDataQuery
)
bus
.
AddHandler
(
"sql"
,
SaveProvisionedDashboard
)
bus
.
AddHandler
(
"sql"
,
SaveProvisionedDashboard
)
bus
.
AddHandler
(
"sql"
,
GetProvisionedDataByDashboardId
)
}
}
type
DashboardExtras
struct
{
type
DashboardExtras
struct
{
...
@@ -17,6 +18,18 @@ type DashboardExtras struct {
...
@@ -17,6 +18,18 @@ type DashboardExtras struct {
Value
string
Value
string
}
}
func
GetProvisionedDataByDashboardId
(
cmd
*
models
.
GetProvisionedDashboardByDashboardId
)
error
{
result
:=
&
models
.
DashboardProvisioning
{}
_
,
err
:=
x
.
Where
(
"dashboard_id = ?"
,
cmd
.
DashboardId
)
.
Get
(
result
)
if
err
!=
nil
{
return
err
}
cmd
.
Result
=
result
return
nil
}
func
SaveProvisionedDashboard
(
cmd
*
models
.
SaveProvisionedDashboardCommand
)
error
{
func
SaveProvisionedDashboard
(
cmd
*
models
.
SaveProvisionedDashboardCommand
)
error
{
return
inTransaction
(
func
(
sess
*
DBSession
)
error
{
return
inTransaction
(
func
(
sess
*
DBSession
)
error
{
err
:=
saveDashboard
(
sess
,
cmd
.
DashboardCmd
)
err
:=
saveDashboard
(
sess
,
cmd
.
DashboardCmd
)
...
...
pkg/services/sqlstore/dashboard_provisioning_test.go
View file @
d6faa3d0
...
@@ -50,6 +50,16 @@ func TestDashboardProvisioningTest(t *testing.T) {
...
@@ -50,6 +50,16 @@ func TestDashboardProvisioningTest(t *testing.T) {
So
(
query
.
Result
[
0
]
.
DashboardId
,
ShouldEqual
,
dashId
)
So
(
query
.
Result
[
0
]
.
DashboardId
,
ShouldEqual
,
dashId
)
So
(
query
.
Result
[
0
]
.
Updated
,
ShouldEqual
,
now
.
Unix
())
So
(
query
.
Result
[
0
]
.
Updated
,
ShouldEqual
,
now
.
Unix
())
})
})
Convey
(
"Can query for one provisioned dashboard"
,
func
()
{
query
:=
&
models
.
GetProvisionedDashboardByDashboardId
{
DashboardId
:
cmd
.
Result
.
Id
}
err
:=
GetProvisionedDataByDashboardId
(
query
)
So
(
err
,
ShouldBeNil
)
So
(
query
.
Result
.
DashboardId
,
ShouldEqual
,
cmd
.
Result
.
Id
)
So
(
query
.
Result
.
Updated
,
ShouldEqual
,
now
.
Unix
())
})
})
})
})
})
}
}
public/app/features/dashboard/all.ts
View file @
d6faa3d0
...
@@ -6,6 +6,7 @@ import './dashnav/dashnav';
...
@@ -6,6 +6,7 @@ import './dashnav/dashnav';
import
'./submenu/submenu'
;
import
'./submenu/submenu'
;
import
'./save_as_modal'
;
import
'./save_as_modal'
;
import
'./save_modal'
;
import
'./save_modal'
;
import
'./save_provisioned_modal'
;
import
'./shareModalCtrl'
;
import
'./shareModalCtrl'
;
import
'./share_snapshot_ctrl'
;
import
'./share_snapshot_ctrl'
;
import
'./dashboard_srv'
;
import
'./dashboard_srv'
;
...
...
public/app/features/dashboard/dashboard_srv.ts
View file @
d6faa3d0
...
@@ -105,6 +105,10 @@ export class DashboardSrv {
...
@@ -105,6 +105,10 @@ export class DashboardSrv {
this
.
setCurrent
(
this
.
create
(
clone
,
this
.
dash
.
meta
));
this
.
setCurrent
(
this
.
create
(
clone
,
this
.
dash
.
meta
));
}
}
if
(
this
.
dash
.
meta
.
provisioned
)
{
return
this
.
showDashboardProvisionedModal
();
}
if
(
!
this
.
dash
.
meta
.
canSave
&&
options
.
makeEditable
!==
true
)
{
if
(
!
this
.
dash
.
meta
.
canSave
&&
options
.
makeEditable
!==
true
)
{
return
Promise
.
resolve
();
return
Promise
.
resolve
();
}
}
...
@@ -120,6 +124,13 @@ export class DashboardSrv {
...
@@ -120,6 +124,13 @@ export class DashboardSrv {
return
this
.
save
(
this
.
dash
.
getSaveModelClone
(),
options
);
return
this
.
save
(
this
.
dash
.
getSaveModelClone
(),
options
);
}
}
showDashboardProvisionedModal
()
{
this
.
$rootScope
.
appEvent
(
'show-modal'
,
{
templateHtml
:
'<save-provisioned-dashboard-modal dismiss="dismiss()"></save-provisioned-dashboard-modal>'
,
modalClass
:
'modal--narrow'
,
});
}
showSaveAsModal
()
{
showSaveAsModal
()
{
this
.
$rootScope
.
appEvent
(
'show-modal'
,
{
this
.
$rootScope
.
appEvent
(
'show-modal'
,
{
templateHtml
:
'<save-dashboard-as-modal dismiss="dismiss()"></save-dashboard-as-modal>'
,
templateHtml
:
'<save-dashboard-as-modal dismiss="dismiss()"></save-dashboard-as-modal>'
,
...
...
public/app/features/dashboard/dashnav/dashnav.html
View file @
d6faa3d0
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
<div
class=
"navbar__spacer"
></div>
<div
class=
"navbar__spacer"
></div>
<div
class=
"navbar-buttons navbar-buttons--actions"
>
<div
class=
"navbar-buttons navbar-buttons--actions"
>
<button
class=
"btn navbar-button navbar-button--add-panel"
ng-show=
"::ctrl.dashboard.meta.can
Save
"
bs-tooltip=
"'Add panel'"
data-placement=
"bottom"
ng-click=
"ctrl.addPanel()"
>
<button
class=
"btn navbar-button navbar-button--add-panel"
ng-show=
"::ctrl.dashboard.meta.can
Edit
"
bs-tooltip=
"'Add panel'"
data-placement=
"bottom"
ng-click=
"ctrl.addPanel()"
>
<i
class=
"gicon gicon-add-panel"
></i>
<i
class=
"gicon gicon-add-panel"
></i>
</button>
</button>
...
...
public/app/features/dashboard/save_provisioned_modal.ts
0 → 100644
View file @
d6faa3d0
import
coreModule
from
'app/core/core_module'
;
const
template
=
`
<div class="modal-body">
<div class="modal-header">
<h2 class="modal-header-title">
<i class="fa fa-save"></i>
<span class="p-l-1">Cannot save provisioned dashboards</span>
</h2>
<a class="modal-header-close" ng-click="ctrl.dismiss();">
<i class="fa fa-remove"></i>
</a>
</div>
<form name="ctrl.saveForm" class="modal-content" novalidate>
<h6 class="text-center">
This dashboard cannot be saved from Grafana's UI since it have been
<a href="http://docs.grafana.org/administration/provisioning/#dashboards">provisioned</a> from
another source. Please ask your Administrator for more info.
</h6>
<div class="p-t-2">
<div class="gf-form">
<label class="gf-form-hint">
<textarea
type="text"
name="dashboardJson"
class="gf-form-input"
ng-model="ctrl.dashboardJson"
ng-model-options="{allowInvalid: true}"
autocomplete="off"
rows="3" /></textarea>
</label>
</div>
</div>
<div class="gf-form-button-row text-center">
<button type="submit" class="btn btn-success" clipboard-button="ctrl.getJsonForClipboard()" >
<i class="fa fa-clipboard"></i> Copy json
</button>
<button class="btn btn-inverse" ng-click="ctrl.dismiss();">Close</button>
</div>
</form>
</div>
`
;
export
class
SaveProvisionedDashboardModalCtrl
{
dashboardJson
:
string
;
dismiss
:
()
=>
void
;
/** @ngInject */
constructor
(
dashboardSrv
)
{
var
dashboard
=
dashboardSrv
.
getCurrent
().
getSaveModelClone
();
delete
dashboard
.
id
;
this
.
dashboardJson
=
JSON
.
stringify
(
dashboard
);
}
getJsonForClipboard
()
{
return
this
.
dashboardJson
;
}
}
export
function
saveProvisionedDashboardModalDirective
()
{
return
{
restrict
:
'E'
,
template
:
template
,
controller
:
SaveProvisionedDashboardModalCtrl
,
bindToController
:
true
,
controllerAs
:
'ctrl'
,
scope
:
{
dismiss
:
'&'
},
};
}
coreModule
.
directive
(
'saveProvisionedDashboardModal'
,
saveProvisionedDashboardModalDirective
);
public/app/features/dashboard/specs/save_provisioned_modal.jest.ts
0 → 100644
View file @
d6faa3d0
import
{
SaveProvisionedDashboardModalCtrl
}
from
'../save_provisioned_modal'
;
import
{
describe
,
it
,
expect
}
from
'test/lib/common'
;
describe
(
'SaveProvisionedDashboardModalCtrl'
,
()
=>
{
var
json
=
{
title
:
'name'
,
id
:
5
,
};
var
mockDashboardSrv
=
{
getCurrent
:
function
()
{
return
{
id
:
5
,
meta
:
{},
getSaveModelClone
:
function
()
{
return
json
;
},
};
},
};
var
ctrl
=
new
SaveProvisionedDashboardModalCtrl
(
mockDashboardSrv
);
it
(
'verify that the id have been removed'
,
()
=>
{
var
copy
=
ctrl
.
getJsonForClipboard
();
expect
(
copy
).
toBe
(
`{"title":"name"}`
);
});
});
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