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
c3708b30
Commit
c3708b30
authored
May 27, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(import): import directly from grafana.net id/url now works
parent
22a7eaf2
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
123 additions
and
34 deletions
+123
-34
pkg/api/gnetproxy.go
+9
-4
public/app/features/dashboard/all.js
+1
-1
public/app/features/dashboard/export/export_modal.html
+0
-10
public/app/features/dashboard/import/dash_import.html
+31
-15
public/app/features/dashboard/import/dash_import.ts
+41
-1
public/app/features/dashboard/partials/settings.html
+1
-1
public/app/features/dashboard/specs/dash_import_ctrl_specs.ts
+36
-2
public/sass/components/_gf-form.scss
+4
-0
No files found.
pkg/api/gnetproxy.go
View file @
c3708b30
...
@@ -5,8 +5,10 @@ import (
...
@@ -5,8 +5,10 @@ import (
"net"
"net"
"net/http"
"net/http"
"net/http/httputil"
"net/http/httputil"
"net/url"
"time"
"time"
"github.com/Unknwon/log"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/util"
...
@@ -23,12 +25,15 @@ var gNetProxyTransport = &http.Transport{
...
@@ -23,12 +25,15 @@ var gNetProxyTransport = &http.Transport{
}
}
func
ReverseProxyGnetReq
(
proxyPath
string
)
*
httputil
.
ReverseProxy
{
func
ReverseProxyGnetReq
(
proxyPath
string
)
*
httputil
.
ReverseProxy
{
url
,
_
:=
url
.
Parse
(
setting
.
GrafanaNetUrl
)
director
:=
func
(
req
*
http
.
Request
)
{
director
:=
func
(
req
*
http
.
Request
)
{
req
.
URL
.
Scheme
=
"https"
req
.
URL
.
Scheme
=
url
.
Scheme
req
.
URL
.
Host
=
"grafana.net"
req
.
URL
.
Host
=
url
.
Host
req
.
Host
=
"grafana.net"
req
.
Host
=
url
.
Host
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
setting
.
GrafanaNetUrl
+
"/api"
,
proxyPath
)
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
url
.
Path
+
"/api"
,
proxyPath
)
log
.
Info
(
"Url: %v"
,
req
.
URL
.
Path
)
// clear cookie headers
// clear cookie headers
req
.
Header
.
Del
(
"Cookie"
)
req
.
Header
.
Del
(
"Cookie"
)
...
...
public/app/features/dashboard/all.js
View file @
c3708b30
...
@@ -17,7 +17,7 @@ define([
...
@@ -17,7 +17,7 @@ define([
'./importCtrl'
,
'./importCtrl'
,
'./impression_store'
,
'./impression_store'
,
'./upload'
,
'./upload'
,
'./import/import'
,
'./import/
dash_
import'
,
'./export/export_modal'
,
'./export/export_modal'
,
'./dash_list_ctrl'
,
'./dash_list_ctrl'
,
],
function
()
{});
],
function
()
{});
public/app/features/dashboard/export/export_modal.html
View file @
c3708b30
...
@@ -15,16 +15,6 @@
...
@@ -15,16 +15,6 @@
You can share dashboards on
<a
class=
"external-link"
href=
"https://grafana.net"
>
Grafana.net
</a>
You can share dashboards on
<a
class=
"external-link"
href=
"https://grafana.net"
>
Grafana.net
</a>
</p>
</p>
<div
class=
"gf-form-group"
>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-8"
>
Title
</label>
<input
type=
"text"
class=
"gf-form-input"
ng-model=
"ctrl.dash.title"
ng-change=
"ctrl.titleChanged()"
>
<label
class=
"gf-form-label text-success"
ng-show=
"ctrl.dash.title"
>
<i
class=
"fa fa-check"
></i>
</label>
</div>
</div>
<div
class=
"gf-form-button-row"
>
<div
class=
"gf-form-button-row"
>
<button
type=
"button"
class=
"btn gf-form-btn width-10 btn-success"
ng-click=
"ctrl.save()"
>
<button
type=
"button"
class=
"btn gf-form-btn width-10 btn-success"
ng-click=
"ctrl.save()"
>
<i
class=
"fa fa-save"
></i>
Save to file
<i
class=
"fa fa-save"
></i>
Save to file
...
...
public/app/features/dashboard/import/dash_import.html
View file @
c3708b30
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
<div
class=
"gf-form-group"
>
<div
class=
"gf-form-group"
>
<div
class=
"gf-form"
>
<div
class=
"gf-form"
>
<input
type=
"text"
class=
"gf-form-input"
ng-
ctrl=
"ctrl.grafanaNetUrl"
placeholder=
"Paste Grafana.net dashboard url or id"
ng-change
=
"ctrl.checkGnetDashboard()"
></textarea>
<input
type=
"text"
class=
"gf-form-input"
ng-
model=
"ctrl.gnetUrl"
placeholder=
"Paste Grafana.net dashboard url or id"
ng-blur
=
"ctrl.checkGnetDashboard()"
></textarea>
</div>
</div>
<div
class=
"gf-form"
ng-if=
"ctrl.gnetError"
>
<div
class=
"gf-form"
ng-if=
"ctrl.gnetError"
>
<label
class=
"gf-form-label text-warning"
>
<label
class=
"gf-form-label text-warning"
>
...
@@ -50,6 +50,21 @@
...
@@ -50,6 +50,21 @@
</div>
</div>
<div
ng-if=
"ctrl.step === 2"
>
<div
ng-if=
"ctrl.step === 2"
>
<h3
class=
"section-heading"
ng-if=
"ctrl.dash.gnetId"
>
Importing Dashboard from
<a
href=
"https://grafana.net/dashboards/{{ctrl.dash.gnetId}}"
class=
"external-link"
target=
"_blank"
>
Grafana.net
</a>
</h3>
<div
class=
"gf-form-group"
>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-15"
>
Published by
</label>
<label
class=
"gf-form-label width-15"
>
{{ctrl.gnetInfo.orgName}}
</label>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-15"
>
Updated on
</label>
<label
class=
"gf-form-label width-15"
>
{{ctrl.gnetInfo.updatedAt | date : 'yyyy-MM-dd HH:mm:ss'}}
</label>
</div>
</div>
<h3
class=
"section-heading"
>
<h3
class=
"section-heading"
>
Options
Options
</h3>
</h3>
...
@@ -57,7 +72,7 @@
...
@@ -57,7 +72,7 @@
<div
class=
"gf-form-group"
>
<div
class=
"gf-form-group"
>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form gf-form--grow"
>
<div
class=
"gf-form gf-form--grow"
>
<label
class=
"gf-form-label width-15"
>
Titl
e
</label>
<label
class=
"gf-form-label width-15"
>
Nam
e
</label>
<input
type=
"text"
class=
"gf-form-input"
ng-model=
"ctrl.dash.title"
give-focus=
"true"
ng-change=
"ctrl.titleChanged()"
ng-class=
"{'validation-error': ctrl.nameExists}"
>
<input
type=
"text"
class=
"gf-form-input"
ng-model=
"ctrl.dash.title"
give-focus=
"true"
ng-change=
"ctrl.titleChanged()"
ng-class=
"{'validation-error': ctrl.nameExists}"
>
<label
class=
"gf-form-label text-success"
ng-if=
"!ctrl.nameExists"
>
<label
class=
"gf-form-label text-success"
ng-if=
"!ctrl.nameExists"
>
<i
class=
"fa fa-check"
></i>
<i
class=
"fa fa-check"
></i>
...
@@ -76,32 +91,33 @@
...
@@ -76,32 +91,33 @@
<div
ng-repeat=
"input in ctrl.inputs"
>
<div
ng-repeat=
"input in ctrl.inputs"
>
<div
class=
"gf-form"
>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-15"
>
{{input.label}}
</label>
<label
class=
"gf-form-label width-15"
>
{{input.label}}
<info-popover
mode=
"right-normal"
>
{{input.info}}
</info-popover>
</label>
<div
class=
"gf-form-select-wrapper"
style=
"width: 100%"
>
<div
class=
"gf-form-select-wrapper"
style=
"width: 100%"
>
<select
class=
"gf-form-input"
ng-model=
"input.value"
ng-options=
"v.value as v.text for v in input.options"
ng-change=
"ctrl.inputValueChanged()"
></select>
<select
class=
"gf-form-input"
ng-model=
"input.value"
ng-options=
"v.value as v.text for v in input.options"
ng-change=
"ctrl.inputValueChanged()"
>
<option
value=
""
ng-hide=
"input.value"
>
{{input.info}}
</option>
</select>
</div>
</div>
<label
class=
"gf-form-label text-success"
ng-show=
"input.value"
>
<label
class=
"gf-form-label text-success"
ng-show=
"input.value"
>
<i
class=
"fa fa-check"
></i>
<i
class=
"fa fa-check"
></i>
</label>
</label>
</div>
</div>
<div
class=
"gf-form offset-width-15 gf-form--grow"
>
<label
class=
"gf-form-label gf-form-label--grow"
ng-show=
"input.info"
>
<i
class=
"fa fa-info-circle"
></i>
{{input.info}}
</label>
<label
class=
"gf-form-label gf-form-label--grow"
ng-show=
"input.error"
>
<i
class=
"fa fa-info-circle"
></i>
{{input.info}}
</label>
</div>
</div>
</div>
</div>
</div>
<div
class=
"gf-form-button-row"
>
<div
class=
"gf-form-button-row"
>
<button
type=
"button"
class=
"btn gf-form-btn
width-10"
ng-click=
"ctrl.saveDashboard()"
ng-class=
"{'btn-danger': ctrl.nameExists, 'btn-success': !ctrl.nameExists}
"
ng-disabled=
"!ctrl.inputsValid"
>
<button
type=
"button"
class=
"btn gf-form-btn
btn-success width-10"
ng-click=
"ctrl.saveDashboard()"
ng-hide=
"ctrl.nameExists
"
ng-disabled=
"!ctrl.inputsValid"
>
<i
class=
"fa fa-save"
></i>
Save
&
Open
<i
class=
"fa fa-save"
></i>
Save
&
Open
</button>
</button>
<button
type=
"button"
class=
"btn gf-form-btn btn-danger width-10"
ng-click=
"ctrl.saveDashboard()"
ng-show=
"ctrl.nameExists"
ng-disabled=
"!ctrl.inputsValid"
>
<i
class=
"fa fa-save"
></i>
Overwrite
&
Open
</button>
<a
class=
"btn btn-link"
ng-click=
"dismiss()"
>
Cancel
</a>
<a
class=
"btn btn-link"
ng-click=
"dismiss()"
>
Cancel
</a>
<a
class=
"btn btn-link"
ng-click=
"ctrl.back()"
>
Back
</a>
</div>
</div>
</div>
</div>
...
...
public/app/features/dashboard/import/dash_import.ts
View file @
c3708b30
...
@@ -14,11 +14,20 @@ export class DashImportCtrl {
...
@@ -14,11 +14,20 @@ export class DashImportCtrl {
dash
:
any
;
dash
:
any
;
inputs
:
any
[];
inputs
:
any
[];
inputsValid
:
boolean
;
inputsValid
:
boolean
;
gnetUrl
:
string
;
gnetError
:
string
;
gnetInfo
:
any
;
/** @ngInject */
/** @ngInject */
constructor
(
private
backendSrv
,
private
$location
,
private
$scope
)
{
constructor
(
private
backendSrv
,
private
$location
,
private
$scope
,
private
$routeParams
)
{
this
.
step
=
1
;
this
.
step
=
1
;
this
.
nameExists
=
false
;
this
.
nameExists
=
false
;
// check gnetId in url
if
(
$routeParams
.
gnetId
)
{
this
.
gnetUrl
=
$routeParams
.
gnetId
;
this
.
checkGnetDashboard
();
}
}
}
onUpload
(
dash
)
{
onUpload
(
dash
)
{
...
@@ -121,6 +130,37 @@ export class DashImportCtrl {
...
@@ -121,6 +130,37 @@ export class DashImportCtrl {
}
}
}
}
checkGnetDashboard
()
{
this
.
gnetError
=
''
;
var
match
=
/
(
^
\d
+$
)
|dashboards
\/(\d
+
)
/
.
exec
(
this
.
gnetUrl
);
var
dashboardId
;
if
(
match
&&
match
[
1
])
{
dashboardId
=
match
[
1
];
}
else
if
(
match
&&
match
[
2
])
{
dashboardId
=
match
[
2
];
}
else
{
this
.
gnetError
=
'Could not find dashboard'
;
}
return
this
.
backendSrv
.
get
(
'api/gnet/dashboards/'
+
dashboardId
).
then
(
res
=>
{
this
.
gnetInfo
=
res
;
// store reference to grafana.net
res
.
json
.
gnetId
=
dashboardId
;
this
.
onUpload
(
res
.
json
);
}).
catch
(
err
=>
{
this
.
gnetError
=
err
.
message
||
err
;
});
}
back
()
{
this
.
gnetUrl
=
''
;
this
.
step
=
1
;
this
.
gnetError
=
''
;
this
.
gnetInfo
=
''
;
}
}
}
export
function
dashImportDirective
()
{
export
function
dashImportDirective
()
{
...
...
public/app/features/dashboard/partials/settings.html
View file @
c3708b30
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
<div
class=
"gf-form-group section"
>
<div
class=
"gf-form-group section"
>
<h5
class=
"section-heading"
>
Details
</h5>
<h5
class=
"section-heading"
>
Details
</h5>
<div
class=
"gf-form"
>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-7"
>
Titl
e
</label>
<label
class=
"gf-form-label width-7"
>
Nam
e
</label>
<input
type=
"text"
class=
"gf-form-input width-30"
ng-model=
'dashboard.title'
></input>
<input
type=
"text"
class=
"gf-form-input width-30"
ng-model=
'dashboard.title'
></input>
</div>
</div>
<div
class=
"gf-form"
>
<div
class=
"gf-form"
>
...
...
public/app/features/dashboard/specs/dash_import_ctrl_specs.ts
View file @
c3708b30
...
@@ -7,6 +7,7 @@ describe('DashImportCtrl', function() {
...
@@ -7,6 +7,7 @@ describe('DashImportCtrl', function() {
var
ctx
:
any
=
{};
var
ctx
:
any
=
{};
var
backendSrv
=
{
var
backendSrv
=
{
search
:
sinon
.
stub
().
returns
(
Promise
.
resolve
([])),
search
:
sinon
.
stub
().
returns
(
Promise
.
resolve
([])),
get
:
sinon
.
stub
()
};
};
beforeEach
(
angularMocks
.
module
(
'grafana.core'
));
beforeEach
(
angularMocks
.
module
(
'grafana.core'
));
...
@@ -20,7 +21,7 @@ describe('DashImportCtrl', function() {
...
@@ -20,7 +21,7 @@ describe('DashImportCtrl', function() {
});
});
}));
}));
describe
(
'when upload json'
,
function
()
{
describe
(
'when upload
ing
json'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
config
.
datasources
=
{
config
.
datasources
=
{
ds
:
{
ds
:
{
...
@@ -37,14 +38,47 @@ describe('DashImportCtrl', function() {
...
@@ -37,14 +38,47 @@ describe('DashImportCtrl', function() {
it
(
'should build input model'
,
function
()
{
it
(
'should build input model'
,
function
()
{
expect
(
ctx
.
ctrl
.
inputs
.
length
).
to
.
eql
(
1
);
expect
(
ctx
.
ctrl
.
inputs
.
length
).
to
.
eql
(
1
);
expect
(
ctx
.
ctrl
.
inputs
[
0
].
label
).
to
.
eql
(
1
);
expect
(
ctx
.
ctrl
.
inputs
[
0
].
name
).
to
.
eql
(
'ds'
);
expect
(
ctx
.
ctrl
.
inputs
[
0
].
info
).
to
.
eql
(
'Select a Test DB data source'
);
});
});
it
(
'should set inputValid to false'
,
function
()
{
it
(
'should set inputValid to false'
,
function
()
{
expect
(
ctx
.
ctrl
.
inputsValid
).
to
.
eql
(
false
);
expect
(
ctx
.
ctrl
.
inputsValid
).
to
.
eql
(
false
);
});
});
});
describe
(
'when specifing grafana.net url'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
ctrl
.
gnetUrl
=
'http://grafana.net/dashboards/123'
;
// setup api mock
backendSrv
.
get
=
sinon
.
spy
(()
=>
{
return
Promise
.
resolve
({
});
});
ctx
.
ctrl
.
checkGnetDashboard
();
});
it
(
'should call gnet api with correct dashboard id'
,
function
()
{
expect
(
backendSrv
.
get
.
getCall
(
0
).
args
[
0
]).
to
.
eql
(
'api/gnet/dashboards/123'
);
});
});
describe
(
'when specifing dashbord id'
,
function
()
{
beforeEach
(
function
()
{
ctx
.
ctrl
.
gnetUrl
=
'2342'
;
// setup api mock
backendSrv
.
get
=
sinon
.
spy
(()
=>
{
return
Promise
.
resolve
({
});
});
ctx
.
ctrl
.
checkGnetDashboard
();
});
it
(
'should call gnet api with correct dashboard id'
,
function
()
{
expect
(
backendSrv
.
get
.
getCall
(
0
).
args
[
0
]).
to
.
eql
(
'api/gnet/dashboards/2342'
);
});
});
});
});
});
public/sass/components/_gf-form.scss
View file @
c3708b30
...
@@ -158,6 +158,10 @@ $gf-form-margin: 0.25rem;
...
@@ -158,6 +158,10 @@ $gf-form-margin: 0.25rem;
color
:
transparent
;
color
:
transparent
;
text-shadow
:
0
0
0
$text-color
;
text-shadow
:
0
0
0
$text-color
;
}
}
&
.ng-empty
{
color
:
$text-color-weak
;
}
}
}
&
:after
{
&
:after
{
...
...
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