Commit 7cd663bb by Torkel Ödegaard

feat(import): more import work

parent d9d46096
package dtos package dtos
import "github.com/grafana/grafana/pkg/plugins" import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/plugins"
)
type PluginSetting struct { type PluginSetting struct {
Name string `json:"name"` Name string `json:"name"`
...@@ -50,5 +53,6 @@ type ImportDashboardCommand struct { ...@@ -50,5 +53,6 @@ type ImportDashboardCommand struct {
PluginId string `json:"pluginId"` PluginId string `json:"pluginId"`
Path string `json:"path"` Path string `json:"path"`
Overwrite bool `json:"overwrite"` Overwrite bool `json:"overwrite"`
Dashboard *simplejson.Json `json:"dashboard"`
Inputs []plugins.ImportDashboardInput `json:"inputs"` Inputs []plugins.ImportDashboardInput `json:"inputs"`
} }
...@@ -168,10 +168,11 @@ func ImportDashboard(c *middleware.Context, apiCmd dtos.ImportDashboardCommand) ...@@ -168,10 +168,11 @@ func ImportDashboard(c *middleware.Context, apiCmd dtos.ImportDashboardCommand)
Path: apiCmd.Path, Path: apiCmd.Path,
Inputs: apiCmd.Inputs, Inputs: apiCmd.Inputs,
Overwrite: apiCmd.Overwrite, Overwrite: apiCmd.Overwrite,
Dashboard: apiCmd.Dashboard,
} }
if err := bus.Dispatch(&cmd); err != nil { if err := bus.Dispatch(&cmd); err != nil {
return ApiError(500, "Failed to install dashboard", err) return ApiError(500, "Failed to import dashboard", err)
} }
return Json(200, cmd.Result) return Json(200, cmd.Result)
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
) )
type ImportDashboardCommand struct { type ImportDashboardCommand struct {
Dashboard *simplejson.Json
Path string Path string
Inputs []ImportDashboardInput Inputs []ImportDashboardInput
Overwrite bool Overwrite bool
...@@ -41,17 +42,15 @@ func init() { ...@@ -41,17 +42,15 @@ func init() {
} }
func ImportDashboard(cmd *ImportDashboardCommand) error { func ImportDashboard(cmd *ImportDashboardCommand) error {
plugin, exists := Plugins[cmd.PluginId]
if !exists {
return PluginNotFoundError{cmd.PluginId}
}
var dashboard *m.Dashboard var dashboard *m.Dashboard
var err error var err error
if dashboard, err = loadPluginDashboard(plugin, cmd.Path); err != nil { if cmd.PluginId != "" {
return err if dashboard, err = loadPluginDashboard(cmd.PluginId, cmd.Path); err != nil {
return err
}
} else {
dashboard = m.NewDashboardFromJson(cmd.Dashboard)
} }
evaluator := &DashTemplateEvaluator{ evaluator := &DashTemplateEvaluator{
...@@ -76,13 +75,13 @@ func ImportDashboard(cmd *ImportDashboardCommand) error { ...@@ -76,13 +75,13 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
} }
cmd.Result = &PluginDashboardInfoDTO{ cmd.Result = &PluginDashboardInfoDTO{
PluginId: cmd.PluginId, PluginId: cmd.PluginId,
Title: dashboard.Title, Title: dashboard.Title,
Path: cmd.Path, Path: cmd.Path,
Revision: dashboard.GetString("revision", "1.0"), Revision: dashboard.Data.Get("revision").MustInt64(1),
InstalledUri: "db/" + saveCmd.Result.Slug, ImportedUri: "db/" + saveCmd.Result.Slug,
InstalledRevision: dashboard.GetString("revision", "1.0"), ImportedRevision: dashboard.Data.Get("revision").MustInt64(1),
Installed: true, Imported: true,
} }
return nil return nil
......
...@@ -10,14 +10,14 @@ import ( ...@@ -10,14 +10,14 @@ import (
) )
type PluginDashboardInfoDTO struct { type PluginDashboardInfoDTO struct {
PluginId string `json:"pluginId"` PluginId string `json:"pluginId"`
Title string `json:"title"` Title string `json:"title"`
Installed bool `json:"installed"` Imported bool `json:"imported"`
InstalledUri string `json:"installedUri"` ImportedUri string `json:"importedUri"`
InstalledRevision string `json:"installedRevision"` ImportedRevision int64 `json:"importedRevision"`
Revision string `json:"revision"` Revision int64 `json:"revision"`
Description string `json:"description"` Description string `json:"description"`
Path string `json:"path"` Path string `json:"path"`
} }
func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDTO, error) { func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDTO, error) {
...@@ -42,7 +42,12 @@ func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDT ...@@ -42,7 +42,12 @@ func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDT
return result, nil return result, nil
} }
func loadPluginDashboard(plugin *PluginBase, path string) (*m.Dashboard, error) { func loadPluginDashboard(pluginId, path string) (*m.Dashboard, error) {
plugin, exists := Plugins[pluginId]
if !exists {
return nil, PluginNotFoundError{pluginId}
}
dashboardFilePath := filepath.Join(plugin.PluginDir, path) dashboardFilePath := filepath.Join(plugin.PluginDir, path)
reader, err := os.Open(dashboardFilePath) reader, err := os.Open(dashboardFilePath)
...@@ -66,14 +71,14 @@ func getDashboardImportStatus(orgId int64, plugin *PluginBase, path string) (*Pl ...@@ -66,14 +71,14 @@ func getDashboardImportStatus(orgId int64, plugin *PluginBase, path string) (*Pl
var dashboard *m.Dashboard var dashboard *m.Dashboard
var err error var err error
if dashboard, err = loadPluginDashboard(plugin, path); err != nil { if dashboard, err = loadPluginDashboard(plugin.Id, path); err != nil {
return nil, err return nil, err
} }
res.Path = path res.Path = path
res.PluginId = plugin.Id res.PluginId = plugin.Id
res.Title = dashboard.Title res.Title = dashboard.Title
res.Revision = dashboard.GetString("revision", "1.0") res.Revision = dashboard.Data.Get("revision").MustInt64(1)
query := m.GetDashboardQuery{OrgId: orgId, Slug: dashboard.Slug} query := m.GetDashboardQuery{OrgId: orgId, Slug: dashboard.Slug}
...@@ -82,9 +87,9 @@ func getDashboardImportStatus(orgId int64, plugin *PluginBase, path string) (*Pl ...@@ -82,9 +87,9 @@ func getDashboardImportStatus(orgId int64, plugin *PluginBase, path string) (*Pl
return nil, err return nil, err
} }
} else { } else {
res.Installed = true res.Imported = true
res.InstalledUri = "db/" + query.Result.Slug res.ImportedUri = "db/" + query.Result.Slug
res.InstalledRevision = query.Result.GetString("revision", "1.0") res.ImportedRevision = query.Result.Data.Get("revision").MustInt64(1)
} }
return res, nil return res, nil
......
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
Create New Create New
</a> </a>
<a class="btn btn-inverse pull-left" ng-click="ctrl.import()" ng-show="ctrl.contextSrv.isEditor" ng-click="ctrl.isOpen = false;"> <a class="btn btn-inverse pull-left" href="dashboard/new/?editview=import" ng-show="ctrl.contextSrv.isEditor" ng-click="ctrl.isOpen = false;">
<i class="fa fa-upload"></i> <i class="fa fa-upload"></i>
Import Import
</a> </a>
......
...@@ -149,11 +149,6 @@ export class SearchCtrl { ...@@ -149,11 +149,6 @@ export class SearchCtrl {
this.searchDashboards(); this.searchDashboards();
}; };
import() {
appEvents.emit('show-modal', {
templateHtml: '<dash-import></dash-import>',
});
}
} }
export function searchDirective() { export function searchDirective() {
......
...@@ -12,7 +12,7 @@ function ($, coreModule) { ...@@ -12,7 +12,7 @@ function ($, coreModule) {
'import': { src: '<dash-import></dash-import>' } 'import': { src: '<dash-import></dash-import>' }
}; };
coreModule.default.directive('dashEditorView', function($compile, $location) { coreModule.default.directive('dashEditorView', function($compile, $location, $rootScope) {
return { return {
restrict: 'A', restrict: 'A',
link: function(scope, elem) { link: function(scope, elem) {
...@@ -57,6 +57,21 @@ function ($, coreModule) { ...@@ -57,6 +57,21 @@ function ($, coreModule) {
} }
}; };
if (editview === 'import') {
var modalScope = $rootScope.$new();
modalScope.$on("$destroy", function() {
editorScope.dismiss();
});
$rootScope.appEvent('show-modal', {
templateHtml: '<dash-import></dash-import>',
scope: modalScope,
backdrop: 'static'
});
return;
}
var view = payload.src; var view = payload.src;
if (view.indexOf('.html') > 0) { if (view.indexOf('.html') > 0) {
view = $('<div class="tabbed-view" ng-include="' + "'" + view + "'" + '"></div>'); view = $('<div class="tabbed-view" ng-include="' + "'" + view + "'" + '"></div>');
......
...@@ -81,11 +81,11 @@ function (angular, _, coreModule, config) { ...@@ -81,11 +81,11 @@ function (angular, _, coreModule, config) {
_.each(config.datasources, function(value, key) { _.each(config.datasources, function(value, key) {
if (value.meta && value.meta.metrics) { if (value.meta && value.meta.metrics) {
metricSources.push({ metricSources.push({value: key, name: key, meta: value.meta});
value: key === config.defaultDatasource ? null : key,
name: key, if (key === config.defaultDatasource) {
meta: value.meta, metricSources.push({value: null, name: 'default', meta: value.meta});
}); }
} }
}); });
......
...@@ -30,7 +30,8 @@ export class UtilSrv { ...@@ -30,7 +30,8 @@ export class UtilSrv {
persist: false, persist: false,
show: false, show: false,
scope: options.scope, scope: options.scope,
keyboard: false keyboard: false,
backdrop: options.backdrop
}); });
Promise.resolve(modal).then(function(modalEl) { Promise.resolve(modal).then(function(modalEl) {
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
</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-disable="!ctrl.inputsOk"> <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">
<i class="fa fa-save"></i> Save &amp; Open <i class="fa fa-save"></i> Save &amp; Open
</button> </button>
<a class="btn btn-link" ng-click="dismiss()">Cancel</a> <a class="btn btn-link" ng-click="dismiss()">Cancel</a>
......
...@@ -12,7 +12,6 @@ export class DashImportCtrl { ...@@ -12,7 +12,6 @@ export class DashImportCtrl {
parseError: string; parseError: string;
nameExists: boolean; nameExists: boolean;
dash: any; dash: any;
dismiss: any;
inputs: any[]; inputs: any[];
inputsValid: boolean; inputsValid: boolean;
...@@ -33,6 +32,7 @@ export class DashImportCtrl { ...@@ -33,6 +32,7 @@ export class DashImportCtrl {
var inputModel = { var inputModel = {
name: input.name, name: input.name,
type: input.type, type: input.type,
pluginId: input.pluginId,
options: [] options: []
}; };
...@@ -64,7 +64,7 @@ export class DashImportCtrl { ...@@ -64,7 +64,7 @@ export class DashImportCtrl {
}); });
} }
inputOptionChanged() { inputValueChanged() {
this.inputsValid = true; this.inputsValid = true;
for (let input of this.inputs) { for (let input of this.inputs) {
if (!input.value) { if (!input.value) {
...@@ -86,9 +86,22 @@ export class DashImportCtrl { ...@@ -86,9 +86,22 @@ export class DashImportCtrl {
} }
saveDashboard() { saveDashboard() {
return this.backendSrv.saveDashboard(this.dash, {overwrite: true}).then(res => { var inputs = this.inputs.map(input => {
this.$location.url('dashboard/db/' + res.slug); return {
this.dismiss(); name: input.name,
type: input.type,
pluginId: input.pluginId,
value: input.value
};
});
return this.backendSrv.post('api/dashboards/import', {
dashboard: this.dash,
overwrite: true,
inputs: inputs
}).then(res => {
this.$location.url('dashboard/' + res.importedUri);
this.$scope.dismiss();
}); });
} }
......
...@@ -6,27 +6,27 @@ ...@@ -6,27 +6,27 @@
<i class="icon-gf icon-gf-dashboard"></i> <i class="icon-gf icon-gf-dashboard"></i>
</td> </td>
<td> <td>
<a href="dashboard/{{dash.installedUri}}" ng-show="dash.installed"> <a href="dashboard/{{dash.importedUri}}" ng-show="dash.imported">
{{dash.title}} {{dash.title}}
</a> </a>
<span ng-show="!dash.installed"> <span ng-show="!dash.imported">
{{dash.title}} {{dash.title}}
</span> </span>
</td> </td>
<td> <td>
v{{dash.revision}} v{{dash.revision}}
<span ng-if="dash.installed"> <span ng-if="dash.installed">
&nbsp;(Imported v{{dash.installedRevision}}) &nbsp;(Imported v{{dash.importedRevision}})
<span> <span>
</td> </td>
<td style="text-align: right"> <td style="text-align: right">
<button class="btn btn-secondary" ng-click="ctrl.import(dash, false)" ng-show="!dash.installed"> <button class="btn btn-secondary" ng-click="ctrl.import(dash, false)" ng-show="!dash.imported">
Import Import
</button> </button>
<button class="btn btn-secondary" ng-click="ctrl.import(dash, true)" ng-show="dash.installed"> <button class="btn btn-secondary" ng-click="ctrl.import(dash, true)" ng-show="dash.imported">
Update Update
</button> </button>
<button class="btn btn-danger" ng-click="ctrl.remove(dash)" ng-show="dash.installed"> <button class="btn btn-danger" ng-click="ctrl.remove(dash)" ng-show="dash.imported">
Delete Delete
</button> </button>
</td> </td>
......
...@@ -61,15 +61,15 @@ export class DashImportListCtrl { ...@@ -61,15 +61,15 @@ export class DashImportListCtrl {
} }
return this.backendSrv.post(`/api/dashboards/import`, installCmd).then(res => { return this.backendSrv.post(`/api/dashboards/import`, installCmd).then(res => {
this.$rootScope.appEvent('alert-success', ['Dashboard Installed', dash.title]); this.$rootScope.appEvent('alert-success', ['Dashboard Imported', dash.title]);
_.extend(dash, res); _.extend(dash, res);
}); });
} }
remove(dash) { remove(dash) {
this.backendSrv.delete('/api/dashboards/' + dash.installedUri).then(() => { this.backendSrv.delete('/api/dashboards/' + dash.importedUri).then(() => {
this.$rootScope.appEvent('alert-success', ['Dashboard Deleted', dash.title]); this.$rootScope.appEvent('alert-success', ['Dashboard Deleted', dash.title]);
dash.installed = false; dash.imported = false;
}); });
} }
} }
......
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