Commit 7cd663bb by Torkel Ödegaard

feat(import): more import work

parent d9d46096
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 {
Name string `json:"name"`
......@@ -50,5 +53,6 @@ type ImportDashboardCommand struct {
PluginId string `json:"pluginId"`
Path string `json:"path"`
Overwrite bool `json:"overwrite"`
Dashboard *simplejson.Json `json:"dashboard"`
Inputs []plugins.ImportDashboardInput `json:"inputs"`
}
......@@ -168,10 +168,11 @@ func ImportDashboard(c *middleware.Context, apiCmd dtos.ImportDashboardCommand)
Path: apiCmd.Path,
Inputs: apiCmd.Inputs,
Overwrite: apiCmd.Overwrite,
Dashboard: apiCmd.Dashboard,
}
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)
......
......@@ -11,6 +11,7 @@ import (
)
type ImportDashboardCommand struct {
Dashboard *simplejson.Json
Path string
Inputs []ImportDashboardInput
Overwrite bool
......@@ -41,17 +42,15 @@ func init() {
}
func ImportDashboard(cmd *ImportDashboardCommand) error {
plugin, exists := Plugins[cmd.PluginId]
if !exists {
return PluginNotFoundError{cmd.PluginId}
}
var dashboard *m.Dashboard
var err error
if dashboard, err = loadPluginDashboard(plugin, cmd.Path); err != nil {
return err
if cmd.PluginId != "" {
if dashboard, err = loadPluginDashboard(cmd.PluginId, cmd.Path); err != nil {
return err
}
} else {
dashboard = m.NewDashboardFromJson(cmd.Dashboard)
}
evaluator := &DashTemplateEvaluator{
......@@ -76,13 +75,13 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
}
cmd.Result = &PluginDashboardInfoDTO{
PluginId: cmd.PluginId,
Title: dashboard.Title,
Path: cmd.Path,
Revision: dashboard.GetString("revision", "1.0"),
InstalledUri: "db/" + saveCmd.Result.Slug,
InstalledRevision: dashboard.GetString("revision", "1.0"),
Installed: true,
PluginId: cmd.PluginId,
Title: dashboard.Title,
Path: cmd.Path,
Revision: dashboard.Data.Get("revision").MustInt64(1),
ImportedUri: "db/" + saveCmd.Result.Slug,
ImportedRevision: dashboard.Data.Get("revision").MustInt64(1),
Imported: true,
}
return nil
......
......@@ -10,14 +10,14 @@ import (
)
type PluginDashboardInfoDTO struct {
PluginId string `json:"pluginId"`
Title string `json:"title"`
Installed bool `json:"installed"`
InstalledUri string `json:"installedUri"`
InstalledRevision string `json:"installedRevision"`
Revision string `json:"revision"`
Description string `json:"description"`
Path string `json:"path"`
PluginId string `json:"pluginId"`
Title string `json:"title"`
Imported bool `json:"imported"`
ImportedUri string `json:"importedUri"`
ImportedRevision int64 `json:"importedRevision"`
Revision int64 `json:"revision"`
Description string `json:"description"`
Path string `json:"path"`
}
func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDTO, error) {
......@@ -42,7 +42,12 @@ func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDT
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)
reader, err := os.Open(dashboardFilePath)
......@@ -66,14 +71,14 @@ func getDashboardImportStatus(orgId int64, plugin *PluginBase, path string) (*Pl
var dashboard *m.Dashboard
var err error
if dashboard, err = loadPluginDashboard(plugin, path); err != nil {
if dashboard, err = loadPluginDashboard(plugin.Id, path); err != nil {
return nil, err
}
res.Path = path
res.PluginId = plugin.Id
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}
......@@ -82,9 +87,9 @@ func getDashboardImportStatus(orgId int64, plugin *PluginBase, path string) (*Pl
return nil, err
}
} else {
res.Installed = true
res.InstalledUri = "db/" + query.Result.Slug
res.InstalledRevision = query.Result.GetString("revision", "1.0")
res.Imported = true
res.ImportedUri = "db/" + query.Result.Slug
res.ImportedRevision = query.Result.Data.Get("revision").MustInt64(1)
}
return res, nil
......
......@@ -67,7 +67,7 @@
Create New
</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>
Import
</a>
......
......@@ -149,11 +149,6 @@ export class SearchCtrl {
this.searchDashboards();
};
import() {
appEvents.emit('show-modal', {
templateHtml: '<dash-import></dash-import>',
});
}
}
export function searchDirective() {
......
......@@ -12,7 +12,7 @@ function ($, coreModule) {
'import': { src: '<dash-import></dash-import>' }
};
coreModule.default.directive('dashEditorView', function($compile, $location) {
coreModule.default.directive('dashEditorView', function($compile, $location, $rootScope) {
return {
restrict: 'A',
link: function(scope, elem) {
......@@ -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;
if (view.indexOf('.html') > 0) {
view = $('<div class="tabbed-view" ng-include="' + "'" + view + "'" + '"></div>');
......
......@@ -81,11 +81,11 @@ function (angular, _, coreModule, config) {
_.each(config.datasources, function(value, key) {
if (value.meta && value.meta.metrics) {
metricSources.push({
value: key === config.defaultDatasource ? null : key,
name: key,
meta: value.meta,
});
metricSources.push({value: key, name: key, meta: value.meta});
if (key === config.defaultDatasource) {
metricSources.push({value: null, name: 'default', meta: value.meta});
}
}
});
......
......@@ -30,7 +30,8 @@ export class UtilSrv {
persist: false,
show: false,
scope: options.scope,
keyboard: false
keyboard: false,
backdrop: options.backdrop
});
Promise.resolve(modal).then(function(modalEl) {
......
......@@ -84,7 +84,7 @@
</div>
<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
</button>
<a class="btn btn-link" ng-click="dismiss()">Cancel</a>
......
......@@ -12,7 +12,6 @@ export class DashImportCtrl {
parseError: string;
nameExists: boolean;
dash: any;
dismiss: any;
inputs: any[];
inputsValid: boolean;
......@@ -33,6 +32,7 @@ export class DashImportCtrl {
var inputModel = {
name: input.name,
type: input.type,
pluginId: input.pluginId,
options: []
};
......@@ -64,7 +64,7 @@ export class DashImportCtrl {
});
}
inputOptionChanged() {
inputValueChanged() {
this.inputsValid = true;
for (let input of this.inputs) {
if (!input.value) {
......@@ -86,9 +86,22 @@ export class DashImportCtrl {
}
saveDashboard() {
return this.backendSrv.saveDashboard(this.dash, {overwrite: true}).then(res => {
this.$location.url('dashboard/db/' + res.slug);
this.dismiss();
var inputs = this.inputs.map(input => {
return {
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 @@
<i class="icon-gf icon-gf-dashboard"></i>
</td>
<td>
<a href="dashboard/{{dash.installedUri}}" ng-show="dash.installed">
<a href="dashboard/{{dash.importedUri}}" ng-show="dash.imported">
{{dash.title}}
</a>
<span ng-show="!dash.installed">
<span ng-show="!dash.imported">
{{dash.title}}
</span>
</td>
<td>
v{{dash.revision}}
<span ng-if="dash.installed">
&nbsp;(Imported v{{dash.installedRevision}})
&nbsp;(Imported v{{dash.importedRevision}})
<span>
</td>
<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
</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
</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
</button>
</td>
......
......@@ -61,15 +61,15 @@ export class DashImportListCtrl {
}
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);
});
}
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]);
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