mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(import): more import work
This commit is contained in:
parent
d9d46096dd
commit
7cd663bbe8
@ -1,6 +1,9 @@
|
||||
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 & 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">
|
||||
(Imported v{{dash.installedRevision}})
|
||||
(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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user