mirror of https://github.com/grafana/grafana
feat(plugins): began refactoring AppSettings -> PluginSettings, and have the plugins list view and plugin edit view be common for all plugins
parent
30f3b55baf
commit
8db7cf49a6
@ -1,59 +0,0 @@ |
||||
package api |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/api/dtos" |
||||
"github.com/grafana/grafana/pkg/bus" |
||||
"github.com/grafana/grafana/pkg/middleware" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
"github.com/grafana/grafana/pkg/plugins" |
||||
) |
||||
|
||||
func GetOrgAppsList(c *middleware.Context) Response { |
||||
orgApps, err := plugins.GetOrgAppSettings(c.OrgId) |
||||
|
||||
if err != nil { |
||||
return ApiError(500, "Failed to list of apps", err) |
||||
} |
||||
|
||||
result := make([]*dtos.AppSettings, 0) |
||||
for _, app := range plugins.Apps { |
||||
orgApp := orgApps[app.Id] |
||||
result = append(result, dtos.NewAppSettingsDto(app, orgApp)) |
||||
} |
||||
|
||||
return Json(200, result) |
||||
} |
||||
|
||||
func GetAppSettingsById(c *middleware.Context) Response { |
||||
appId := c.Params(":appId") |
||||
|
||||
if pluginDef, exists := plugins.Apps[appId]; !exists { |
||||
return ApiError(404, "PluginId not found, no installed plugin with that id", nil) |
||||
} else { |
||||
orgApps, err := plugins.GetOrgAppSettings(c.OrgId) |
||||
if err != nil { |
||||
return ApiError(500, "Failed to get org app settings ", nil) |
||||
} |
||||
orgApp := orgApps[appId] |
||||
|
||||
return Json(200, dtos.NewAppSettingsDto(pluginDef, orgApp)) |
||||
} |
||||
} |
||||
|
||||
func UpdateAppSettings(c *middleware.Context, cmd m.UpdateAppSettingsCmd) Response { |
||||
appId := c.Params(":appId") |
||||
|
||||
cmd.OrgId = c.OrgId |
||||
cmd.AppId = appId |
||||
|
||||
if _, ok := plugins.Apps[cmd.AppId]; !ok { |
||||
return ApiError(404, "App type not installed.", nil) |
||||
} |
||||
|
||||
err := bus.Dispatch(&cmd) |
||||
if err != nil { |
||||
return ApiError(500, "Failed to update App Plugin", err) |
||||
} |
||||
|
||||
return ApiSuccess("App updated") |
||||
} |
@ -0,0 +1,68 @@ |
||||
package api |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/api/dtos" |
||||
"github.com/grafana/grafana/pkg/bus" |
||||
"github.com/grafana/grafana/pkg/middleware" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
"github.com/grafana/grafana/pkg/plugins" |
||||
) |
||||
|
||||
func GetPluginList(c *middleware.Context) Response { |
||||
pluginSettingsMap, err := plugins.GetPluginSettings(c.OrgId) |
||||
|
||||
if err != nil { |
||||
return ApiError(500, "Failed to get list of plugins", err) |
||||
} |
||||
|
||||
result := make([]*dtos.PluginListItem, 0) |
||||
for _, pluginDef := range plugins.Plugins { |
||||
listItem := &dtos.PluginListItem{ |
||||
PluginId: pluginDef.Id, |
||||
Name: pluginDef.Name, |
||||
Type: pluginDef.Type, |
||||
Info: &pluginDef.Info, |
||||
} |
||||
|
||||
if pluginSetting, exists := pluginSettingsMap[pluginDef.Id]; exists { |
||||
listItem.Enabled = pluginSetting.Enabled |
||||
listItem.Pinned = pluginSetting.Pinned |
||||
} |
||||
|
||||
result = append(result, listItem) |
||||
} |
||||
|
||||
return Json(200, result) |
||||
} |
||||
|
||||
func GetPluginSettingById(c *middleware.Context) Response { |
||||
pluginId := c.Params(":pluginId") |
||||
|
||||
if pluginDef, exists := plugins.Apps[pluginId]; !exists { |
||||
return ApiError(404, "PluginId not found, no installed plugin with that id", nil) |
||||
} else { |
||||
query := m.GetPluginSettingByIdQuery{PluginId: pluginId, OrgId: c.OrgId} |
||||
if err := bus.Dispatch(&query); err != nil { |
||||
return ApiError(500, "Failed to get login settings", nil) |
||||
} |
||||
|
||||
return Json(200, dtos.NewPluginSettingDto(pluginDef, query.Result)) |
||||
} |
||||
} |
||||
|
||||
func UpdatePluginSetting(c *middleware.Context, cmd m.UpdatePluginSettingCmd) Response { |
||||
pluginId := c.Params(":pluginId") |
||||
|
||||
cmd.OrgId = c.OrgId |
||||
cmd.PluginId = pluginId |
||||
|
||||
if _, ok := plugins.Apps[cmd.PluginId]; !ok { |
||||
return ApiError(404, "Plugin not installed.", nil) |
||||
} |
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil { |
||||
return ApiError(500, "Failed to update plugin setting", err) |
||||
} |
||||
|
||||
return ApiSuccess("Plugin settings updated") |
||||
} |
@ -1,70 +0,0 @@ |
||||
package sqlstore |
||||
|
||||
import ( |
||||
"time" |
||||
|
||||
"github.com/grafana/grafana/pkg/bus" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
"github.com/grafana/grafana/pkg/setting" |
||||
"github.com/grafana/grafana/pkg/util" |
||||
) |
||||
|
||||
func init() { |
||||
bus.AddHandler("sql", GetAppSettings) |
||||
bus.AddHandler("sql", GetAppSettingByAppId) |
||||
bus.AddHandler("sql", UpdateAppSettings) |
||||
} |
||||
|
||||
func GetAppSettings(query *m.GetAppSettingsQuery) error { |
||||
sess := x.Where("org_id=?", query.OrgId) |
||||
|
||||
query.Result = make([]*m.AppSettings, 0) |
||||
return sess.Find(&query.Result) |
||||
} |
||||
|
||||
func GetAppSettingByAppId(query *m.GetAppSettingByAppIdQuery) error { |
||||
appSetting := m.AppSettings{OrgId: query.OrgId, AppId: query.AppId} |
||||
has, err := x.Get(&appSetting) |
||||
if err != nil { |
||||
return err |
||||
} else if has == false { |
||||
return m.ErrAppSettingNotFound |
||||
} |
||||
query.Result = &appSetting |
||||
return nil |
||||
} |
||||
|
||||
func UpdateAppSettings(cmd *m.UpdateAppSettingsCmd) error { |
||||
return inTransaction2(func(sess *session) error { |
||||
var app m.AppSettings |
||||
|
||||
exists, err := sess.Where("org_id=? and app_id=?", cmd.OrgId, cmd.AppId).Get(&app) |
||||
sess.UseBool("enabled") |
||||
sess.UseBool("pinned") |
||||
if !exists { |
||||
app = m.AppSettings{ |
||||
AppId: cmd.AppId, |
||||
OrgId: cmd.OrgId, |
||||
Enabled: cmd.Enabled, |
||||
Pinned: cmd.Pinned, |
||||
JsonData: cmd.JsonData, |
||||
SecureJsonData: cmd.GetEncryptedJsonData(), |
||||
Created: time.Now(), |
||||
Updated: time.Now(), |
||||
} |
||||
_, err = sess.Insert(&app) |
||||
return err |
||||
} else { |
||||
for key, data := range cmd.SecureJsonData { |
||||
app.SecureJsonData[key] = util.Encrypt([]byte(data), setting.SecretKey) |
||||
} |
||||
app.SecureJsonData = cmd.GetEncryptedJsonData() |
||||
app.Updated = time.Now() |
||||
app.Enabled = cmd.Enabled |
||||
app.JsonData = cmd.JsonData |
||||
app.Pinned = cmd.Pinned |
||||
_, err = sess.Id(app.Id).Update(&app) |
||||
return err |
||||
} |
||||
}) |
||||
} |
@ -0,0 +1,70 @@ |
||||
package sqlstore |
||||
|
||||
import ( |
||||
"time" |
||||
|
||||
"github.com/grafana/grafana/pkg/bus" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
"github.com/grafana/grafana/pkg/setting" |
||||
"github.com/grafana/grafana/pkg/util" |
||||
) |
||||
|
||||
func init() { |
||||
bus.AddHandler("sql", GetPluginSettings) |
||||
bus.AddHandler("sql", GetPluginSettingById) |
||||
bus.AddHandler("sql", UpdatePluginSetting) |
||||
} |
||||
|
||||
func GetPluginSettings(query *m.GetPluginSettingsQuery) error { |
||||
sess := x.Where("org_id=?", query.OrgId) |
||||
|
||||
query.Result = make([]*m.PluginSetting, 0) |
||||
return sess.Find(&query.Result) |
||||
} |
||||
|
||||
func GetPluginSettingById(query *m.GetPluginSettingByIdQuery) error { |
||||
pluginSetting := m.PluginSetting{OrgId: query.OrgId, PluginId: query.PluginId} |
||||
has, err := x.Get(&pluginSetting) |
||||
if err != nil { |
||||
return err |
||||
} else if has == false { |
||||
return m.ErrPluginSettingNotFound |
||||
} |
||||
query.Result = &pluginSetting |
||||
return nil |
||||
} |
||||
|
||||
func UpdatePluginSetting(cmd *m.UpdatePluginSettingCmd) error { |
||||
return inTransaction2(func(sess *session) error { |
||||
var pluginSetting m.PluginSetting |
||||
|
||||
exists, err := sess.Where("org_id=? and plugin_id=?", cmd.OrgId, cmd.PluginId).Get(&pluginSetting) |
||||
sess.UseBool("enabled") |
||||
sess.UseBool("pinned") |
||||
if !exists { |
||||
pluginSetting = m.PluginSetting{ |
||||
PluginId: cmd.PluginId, |
||||
OrgId: cmd.OrgId, |
||||
Enabled: cmd.Enabled, |
||||
Pinned: cmd.Pinned, |
||||
JsonData: cmd.JsonData, |
||||
SecureJsonData: cmd.GetEncryptedJsonData(), |
||||
Created: time.Now(), |
||||
Updated: time.Now(), |
||||
} |
||||
_, err = sess.Insert(&pluginSetting) |
||||
return err |
||||
} else { |
||||
for key, data := range cmd.SecureJsonData { |
||||
pluginSetting.SecureJsonData[key] = util.Encrypt([]byte(data), setting.SecretKey) |
||||
} |
||||
pluginSetting.SecureJsonData = cmd.GetEncryptedJsonData() |
||||
pluginSetting.Updated = time.Now() |
||||
pluginSetting.Enabled = cmd.Enabled |
||||
pluginSetting.JsonData = cmd.JsonData |
||||
pluginSetting.Pinned = cmd.Pinned |
||||
_, err = sess.Id(pluginSetting.Id).Update(&pluginSetting) |
||||
return err |
||||
} |
||||
}) |
||||
} |
@ -1,49 +0,0 @@ |
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular'; |
||||
import _ from 'lodash'; |
||||
|
||||
export class AppEditCtrl { |
||||
appModel: any; |
||||
appId: any; |
||||
includedPanels: any; |
||||
includedDatasources: any; |
||||
|
||||
/** @ngInject */ |
||||
constructor(private backendSrv: any, private $routeParams: any) { |
||||
this.appModel = {}; |
||||
this.appId = $routeParams.appId; |
||||
|
||||
this.backendSrv.get(`/api/org/apps/${this.appId}/settings`).then(result => { |
||||
this.appModel = result; |
||||
this.includedPanels = _.where(result.includes, {type: 'panel'}); |
||||
this.includedDatasources = _.where(result.includes, {type: 'datasource'}); |
||||
}); |
||||
} |
||||
|
||||
update() { |
||||
var updateCmd = _.extend({ |
||||
appId: this.appModel.appId, |
||||
orgId: this.appModel.orgId, |
||||
enabled: this.appModel.enabled, |
||||
pinned: this.appModel.pinned, |
||||
jsonData: this.appModel.jsonData, |
||||
secureJsonData: this.appModel.secureJsonData, |
||||
}, {}); |
||||
|
||||
this.backendSrv.post(`/api/org/apps/${this.appId}/settings`, updateCmd).then(function() { |
||||
window.location.href = window.location.href; |
||||
}); |
||||
} |
||||
|
||||
toggleEnabled() { |
||||
this.update(); |
||||
} |
||||
|
||||
togglePinned() { |
||||
this.update(); |
||||
} |
||||
} |
||||
|
||||
angular.module('grafana.controllers').controller('AppEditCtrl', AppEditCtrl); |
||||
|
@ -1,17 +0,0 @@ |
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular'; |
||||
|
||||
export class AppListCtrl { |
||||
apps: any[]; |
||||
|
||||
/** @ngInject */ |
||||
constructor(private backendSrv: any) { |
||||
|
||||
this.backendSrv.get('api/org/apps').then(apps => { |
||||
this.apps = apps; |
||||
}); |
||||
} |
||||
} |
||||
|
||||
angular.module('grafana.controllers').controller('AppListCtrl', AppListCtrl); |
@ -1,47 +0,0 @@ |
||||
<navbar title="Plugins" icon="icon-gf icon-gf-apps" title-url="apps"> |
||||
</navbar> |
||||
|
||||
<div class="page-container"> |
||||
<div class="page-header"> |
||||
<h1>Plugins</h1> |
||||
</div> |
||||
<div ng-if="!ctrl.apps"> |
||||
<em>No apps defined</em> |
||||
</div> |
||||
|
||||
<ul class="filter-list"> |
||||
<li ng-repeat="app in ctrl.apps"> |
||||
<ul class="filter-list-card"> |
||||
<li class="filter-list-card-image"> |
||||
<img ng-src="{{app.info.logos.small}}"> |
||||
</li> |
||||
<li> |
||||
<div class="filter-list-card-controls"> |
||||
<div class="filter-list-card-config"> |
||||
<a href="apps/{{app.appId}}/edit"> |
||||
<i class="fa fa-cog"></i> |
||||
</a> |
||||
</div> |
||||
</div> |
||||
<span class="filter-list-card-title"> |
||||
<a href="apps/{{app.appId}}/edit"> |
||||
{{app.name}} |
||||
</a> |
||||
|
||||
<span class="label label-info" ng-if="app.enabled"> |
||||
Enabled |
||||
</span> |
||||
|
||||
<span class="label label-info" ng-if="app.pinned"> |
||||
Pinned |
||||
</span> |
||||
|
||||
</span> |
||||
<span class="filter-list-card-status"> |
||||
<span class="filter-list-card-state">Dashboards: 1</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
</li> |
||||
</ul> |
||||
</div> |
@ -0,0 +1,49 @@ |
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular'; |
||||
import _ from 'lodash'; |
||||
|
||||
export class PluginEditCtrl { |
||||
model: any; |
||||
pluginId: any; |
||||
includedPanels: any; |
||||
includedDatasources: any; |
||||
|
||||
/** @ngInject */ |
||||
constructor(private backendSrv: any, private $routeParams: any) { |
||||
this.model = {}; |
||||
this.pluginId = $routeParams.pluginId; |
||||
|
||||
this.backendSrv.get(`/api/org/plugins/${this.pluginId}/settings`).then(result => { |
||||
this.model = result; |
||||
this.includedPanels = _.where(result.includes, {type: 'panel'}); |
||||
this.includedDatasources = _.where(result.includes, {type: 'datasource'}); |
||||
}); |
||||
} |
||||
|
||||
update() { |
||||
var updateCmd = _.extend({ |
||||
pluginId: this.model.pluginId, |
||||
orgId: this.model.orgId, |
||||
enabled: this.model.enabled, |
||||
pinned: this.model.pinned, |
||||
jsonData: this.model.jsonData, |
||||
secureJsonData: this.model.secureJsonData, |
||||
}, {}); |
||||
|
||||
this.backendSrv.post(`/api/org/plugins/${this.pluginId}/settings`, updateCmd).then(function() { |
||||
window.location.href = window.location.href; |
||||
}); |
||||
} |
||||
|
||||
toggleEnabled() { |
||||
this.update(); |
||||
} |
||||
|
||||
togglePinned() { |
||||
this.update(); |
||||
} |
||||
} |
||||
|
||||
angular.module('grafana.controllers').controller('PluginEditCtrl', PluginEditCtrl); |
||||
|
@ -0,0 +1,17 @@ |
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular'; |
||||
|
||||
export class PluginListCtrl { |
||||
plugins: any[]; |
||||
|
||||
/** @ngInject */ |
||||
constructor(private backendSrv: any) { |
||||
|
||||
this.backendSrv.get('api/org/plugins').then(plugins => { |
||||
this.plugins = plugins; |
||||
}); |
||||
} |
||||
} |
||||
|
||||
angular.module('grafana.controllers').controller('PluginListCtrl', PluginListCtrl); |
@ -0,0 +1,42 @@ |
||||
<navbar title="Plugins" icon="icon-gf icon-gf-apps" title-url="plugins"> |
||||
</navbar> |
||||
|
||||
<div class="page-container"> |
||||
<div class="page-header"> |
||||
<h1>Plugins</h1> |
||||
</div> |
||||
|
||||
<table class="filter-table"> |
||||
<thead> |
||||
<tr> |
||||
<th><strong>Name</strong></th> |
||||
<th><strong>Type</strong></th> |
||||
<th style="width: 60px;"></th> |
||||
<th style="width: 80px;"></th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<tr ng-repeat="plugin in ctrl.plugins"> |
||||
<td> |
||||
<a href="plugins/{{plugin.pluginId}}/edit"> |
||||
{{plugin.name}} |
||||
</a> |
||||
</td> |
||||
<td> |
||||
{{plugin.type}} |
||||
</td> |
||||
<td> |
||||
<span class="label label-info" ng-if="plugin.enabled">Enabled</span> |
||||
<span class="label label-info" ng-if="plugin.pinned">Pinned</span> |
||||
</td> |
||||
<td class="text-right"> |
||||
<a href="plugins/{{plugin.pluginId}}/edit" class="btn btn-inverse btn-small"> |
||||
<i class="fa fa-edit"></i> |
||||
Edit |
||||
</a> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
</div> |
Loading…
Reference in new issue