mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(plugins): a lot of work on #4298
This commit is contained in:
parent
7b1d827460
commit
dfaa6d8eb9
@ -171,7 +171,6 @@ func Register(r *macaron.Macaron) {
|
|||||||
r.Put("/:id", bind(m.UpdateDataSourceCommand{}), UpdateDataSource)
|
r.Put("/:id", bind(m.UpdateDataSourceCommand{}), UpdateDataSource)
|
||||||
r.Delete("/:id", DeleteDataSource)
|
r.Delete("/:id", DeleteDataSource)
|
||||||
r.Get("/:id", wrap(GetDataSourceById))
|
r.Get("/:id", wrap(GetDataSourceById))
|
||||||
r.Get("/plugins", GetDataSourcePlugins)
|
|
||||||
}, reqOrgAdmin)
|
}, reqOrgAdmin)
|
||||||
|
|
||||||
r.Group("/datasources/name/:name", func() {
|
r.Group("/datasources/name/:name", func() {
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
//"github.com/grafana/grafana/pkg/log"
|
//"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -100,24 +99,6 @@ func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) {
|
|||||||
c.JsonOK("Datasource updated")
|
c.JsonOK("Datasource updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDataSourcePlugins(c *middleware.Context) {
|
|
||||||
dsList := make(map[string]*plugins.DataSourcePlugin)
|
|
||||||
|
|
||||||
if enabledPlugins, err := plugins.GetEnabledPlugins(c.OrgId); err != nil {
|
|
||||||
c.JsonApiErr(500, "Failed to get org apps", err)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
|
|
||||||
for key, value := range enabledPlugins.DataSources {
|
|
||||||
if !value.BuiltIn {
|
|
||||||
dsList[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(200, dsList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get /api/datasources/name/:name
|
// Get /api/datasources/name/:name
|
||||||
func GetDataSourceByName(c *middleware.Context) Response {
|
func GetDataSourceByName(c *middleware.Context) Response {
|
||||||
query := m.GetDataSourceByNameQuery{Name: c.Params(":name"), OrgId: c.OrgId}
|
query := m.GetDataSourceByNameQuery{Name: c.Params(":name"), OrgId: c.OrgId}
|
||||||
|
@ -5,23 +5,23 @@ import "github.com/grafana/grafana/pkg/plugins"
|
|||||||
type PluginSetting struct {
|
type PluginSetting struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
PluginId string `json:"pluginId"`
|
Id string `json:"id"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Pinned bool `json:"pinned"`
|
Pinned bool `json:"pinned"`
|
||||||
Module string `json:"module"`
|
Module string `json:"module"`
|
||||||
BaseUrl string `json:"baseUrl"`
|
BaseUrl string `json:"baseUrl"`
|
||||||
Info *plugins.PluginInfo `json:"info"`
|
Info *plugins.PluginInfo `json:"info"`
|
||||||
Pages []*plugins.AppPluginPage `json:"pages"`
|
Pages []*plugins.AppPluginPage `json:"pages"`
|
||||||
Includes []*plugins.AppIncludeInfo `json:"includes"`
|
Includes []*plugins.PluginInclude `json:"includes"`
|
||||||
Dependencies *plugins.PluginDependencies `json:"dependencies"`
|
Dependencies *plugins.PluginDependencies `json:"dependencies"`
|
||||||
JsonData map[string]interface{} `json:"jsonData"`
|
JsonData map[string]interface{} `json:"jsonData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PluginListItem struct {
|
type PluginListItem struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
PluginId string `json:"pluginId"`
|
Id string `json:"id"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Pinned bool `json:"pinned"`
|
Pinned bool `json:"pinned"`
|
||||||
Info *plugins.PluginInfo `json:"info"`
|
Info *plugins.PluginInfo `json:"info"`
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func GetPluginList(c *middleware.Context) Response {
|
func GetPluginList(c *middleware.Context) Response {
|
||||||
|
typeFilter := c.Query("type")
|
||||||
|
enabledFilter := c.Query("enabled")
|
||||||
|
embeddedFilter := c.Query("embedded")
|
||||||
|
|
||||||
pluginSettingsMap, err := plugins.GetPluginSettings(c.OrgId)
|
pluginSettingsMap, err := plugins.GetPluginSettings(c.OrgId)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -17,16 +21,21 @@ func GetPluginList(c *middleware.Context) Response {
|
|||||||
|
|
||||||
result := make([]*dtos.PluginListItem, 0)
|
result := make([]*dtos.PluginListItem, 0)
|
||||||
for _, pluginDef := range plugins.Plugins {
|
for _, pluginDef := range plugins.Plugins {
|
||||||
// filter out plugin components
|
// filter out app sub plugins
|
||||||
if pluginDef.IncludedInAppId != "" {
|
if embeddedFilter == "0" && pluginDef.IncludedInAppId != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter on type
|
||||||
|
if typeFilter != "" && typeFilter != pluginDef.Type {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
listItem := &dtos.PluginListItem{
|
listItem := &dtos.PluginListItem{
|
||||||
PluginId: pluginDef.Id,
|
Id: pluginDef.Id,
|
||||||
Name: pluginDef.Name,
|
Name: pluginDef.Name,
|
||||||
Type: pluginDef.Type,
|
Type: pluginDef.Type,
|
||||||
Info: &pluginDef.Info,
|
Info: &pluginDef.Info,
|
||||||
}
|
}
|
||||||
|
|
||||||
if pluginSetting, exists := pluginSettingsMap[pluginDef.Id]; exists {
|
if pluginSetting, exists := pluginSettingsMap[pluginDef.Id]; exists {
|
||||||
@ -34,6 +43,11 @@ func GetPluginList(c *middleware.Context) Response {
|
|||||||
listItem.Pinned = pluginSetting.Pinned
|
listItem.Pinned = pluginSetting.Pinned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filter out disabled
|
||||||
|
if enabledFilter == "1" && !listItem.Enabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
result = append(result, listItem)
|
result = append(result, listItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,19 +60,20 @@ func GetPluginSettingById(c *middleware.Context) Response {
|
|||||||
if def, exists := plugins.Plugins[pluginId]; !exists {
|
if def, exists := plugins.Plugins[pluginId]; !exists {
|
||||||
return ApiError(404, "Plugin not found, no installed plugin with that id", nil)
|
return ApiError(404, "Plugin not found, no installed plugin with that id", nil)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
dto := &dtos.PluginSetting{
|
dto := &dtos.PluginSetting{
|
||||||
Type: def.Type,
|
Type: def.Type,
|
||||||
PluginId: def.Id,
|
Id: def.Id,
|
||||||
Name: def.Name,
|
Name: def.Name,
|
||||||
Info: &def.Info,
|
Info: &def.Info,
|
||||||
Dependencies: &def.Dependencies,
|
Dependencies: &def.Dependencies,
|
||||||
|
Includes: def.Includes,
|
||||||
|
BaseUrl: def.BaseUrl,
|
||||||
|
Module: def.Module,
|
||||||
}
|
}
|
||||||
|
|
||||||
if app, exists := plugins.Apps[pluginId]; exists {
|
if app, exists := plugins.Apps[pluginId]; exists {
|
||||||
dto.Pages = app.Pages
|
dto.Pages = app.Pages
|
||||||
dto.Includes = app.Includes
|
|
||||||
dto.BaseUrl = app.BaseUrl
|
|
||||||
dto.Module = app.Module
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query := m.GetPluginSettingByIdQuery{PluginId: pluginId, OrgId: c.OrgId}
|
query := m.GetPluginSettingByIdQuery{PluginId: pluginId, OrgId: c.OrgId}
|
||||||
|
@ -61,7 +61,14 @@ func (cmd *UpdatePluginSettingCmd) GetEncryptedJsonData() SecureJsonData {
|
|||||||
// QUERIES
|
// QUERIES
|
||||||
type GetPluginSettingsQuery struct {
|
type GetPluginSettingsQuery struct {
|
||||||
OrgId int64
|
OrgId int64
|
||||||
Result []*PluginSetting
|
Result []*PluginSettingInfoDTO
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginSettingInfoDTO struct {
|
||||||
|
OrgId int64
|
||||||
|
PluginId string
|
||||||
|
Enabled bool
|
||||||
|
Pinned bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetPluginSettingByIdQuery struct {
|
type GetPluginSettingByIdQuery struct {
|
||||||
|
@ -21,20 +21,13 @@ type AppPluginCss struct {
|
|||||||
Dark string `json:"dark"`
|
Dark string `json:"dark"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppIncludeInfo struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Id string `json:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AppPlugin struct {
|
type AppPlugin struct {
|
||||||
FrontendPluginBase
|
FrontendPluginBase
|
||||||
Pages []*AppPluginPage `json:"pages"`
|
Pages []*AppPluginPage `json:"pages"`
|
||||||
Routes []*AppPluginRoute `json:"routes"`
|
Routes []*AppPluginRoute `json:"routes"`
|
||||||
Includes []*AppIncludeInfo `json:"-"`
|
|
||||||
|
|
||||||
Pinned bool `json:"-"`
|
FoundChildPlugins []*PluginInclude `json:"-"`
|
||||||
Enabled bool `json:"-"`
|
Pinned bool `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppPluginRoute struct {
|
type AppPluginRoute struct {
|
||||||
@ -71,7 +64,7 @@ func (app *AppPlugin) initApp() {
|
|||||||
for _, panel := range Panels {
|
for _, panel := range Panels {
|
||||||
if strings.HasPrefix(panel.PluginDir, app.PluginDir) {
|
if strings.HasPrefix(panel.PluginDir, app.PluginDir) {
|
||||||
panel.setPathsBasedOnApp(app)
|
panel.setPathsBasedOnApp(app)
|
||||||
app.Includes = append(app.Includes, &AppIncludeInfo{
|
app.FoundChildPlugins = append(app.FoundChildPlugins, &PluginInclude{
|
||||||
Name: panel.Name,
|
Name: panel.Name,
|
||||||
Id: panel.Id,
|
Id: panel.Id,
|
||||||
Type: panel.Type,
|
Type: panel.Type,
|
||||||
@ -83,7 +76,7 @@ func (app *AppPlugin) initApp() {
|
|||||||
for _, ds := range DataSources {
|
for _, ds := range DataSources {
|
||||||
if strings.HasPrefix(ds.PluginDir, app.PluginDir) {
|
if strings.HasPrefix(ds.PluginDir, app.PluginDir) {
|
||||||
ds.setPathsBasedOnApp(app)
|
ds.setPathsBasedOnApp(app)
|
||||||
app.Includes = append(app.Includes, &AppIncludeInfo{
|
app.FoundChildPlugins = append(app.FoundChildPlugins, &PluginInclude{
|
||||||
Name: ds.Name,
|
Name: ds.Name,
|
||||||
Id: ds.Id,
|
Id: ds.Id,
|
||||||
Type: ds.Type,
|
Type: ds.Type,
|
||||||
|
@ -4,12 +4,11 @@ import "encoding/json"
|
|||||||
|
|
||||||
type DataSourcePlugin struct {
|
type DataSourcePlugin struct {
|
||||||
FrontendPluginBase
|
FrontendPluginBase
|
||||||
DefaultMatchFormat string `json:"defaultMatchFormat"`
|
Annotations bool `json:"annotations"`
|
||||||
Annotations bool `json:"annotations"`
|
Metrics bool `json:"metrics"`
|
||||||
Metrics bool `json:"metrics"`
|
BuiltIn bool `json:"builtIn"`
|
||||||
BuiltIn bool `json:"builtIn"`
|
Mixed bool `json:"mixed"`
|
||||||
Mixed bool `json:"mixed"`
|
App string `json:"app"`
|
||||||
App string `json:"app"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *DataSourcePlugin) Load(decoder *json.Decoder, pluginDir string) error {
|
func (p *DataSourcePlugin) Load(decoder *json.Decoder, pluginDir string) error {
|
||||||
|
@ -11,10 +11,6 @@ import (
|
|||||||
|
|
||||||
type FrontendPluginBase struct {
|
type FrontendPluginBase struct {
|
||||||
PluginBase
|
PluginBase
|
||||||
Module string `json:"module"`
|
|
||||||
BaseUrl string `json:"baseUrl"`
|
|
||||||
StaticRoot string `json:"staticRoot"`
|
|
||||||
StaticRootAbs string `json:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fp *FrontendPluginBase) initFrontendPlugin() {
|
func (fp *FrontendPluginBase) initFrontendPlugin() {
|
||||||
|
@ -14,11 +14,16 @@ type PluginLoader interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PluginBase struct {
|
type PluginBase struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Info PluginInfo `json:"info"`
|
Info PluginInfo `json:"info"`
|
||||||
Dependencies PluginDependencies `json:"dependencies"`
|
Dependencies PluginDependencies `json:"dependencies"`
|
||||||
|
Includes []*PluginInclude `json:"includes"`
|
||||||
|
Module string `json:"module"`
|
||||||
|
BaseUrl string `json:"baseUrl"`
|
||||||
|
StaticRoot string `json:"staticRoot"`
|
||||||
|
StaticRootAbs string `json:"-"`
|
||||||
|
|
||||||
IncludedInAppId string `json:"-"`
|
IncludedInAppId string `json:"-"`
|
||||||
PluginDir string `json:"-"`
|
PluginDir string `json:"-"`
|
||||||
@ -51,6 +56,13 @@ type PluginDependencies struct {
|
|||||||
Plugins []PluginDependencyItem `json:"plugins"`
|
Plugins []PluginDependencyItem `json:"plugins"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PluginInclude struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Id string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
type PluginDependencyItem struct {
|
type PluginDependencyItem struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
|
@ -5,61 +5,71 @@ import (
|
|||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetPluginSettings(orgId int64) (map[string]*m.PluginSetting, error) {
|
func GetPluginSettings(orgId int64) (map[string]*m.PluginSettingInfoDTO, error) {
|
||||||
query := m.GetPluginSettingsQuery{OrgId: orgId}
|
query := m.GetPluginSettingsQuery{OrgId: orgId}
|
||||||
|
|
||||||
if err := bus.Dispatch(&query); err != nil {
|
if err := bus.Dispatch(&query); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginMap := make(map[string]*m.PluginSetting)
|
pluginMap := make(map[string]*m.PluginSettingInfoDTO)
|
||||||
for _, plug := range query.Result {
|
for _, plug := range query.Result {
|
||||||
pluginMap[plug.PluginId] = plug
|
pluginMap[plug.PluginId] = plug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, pluginDef := range Plugins {
|
||||||
|
// ignore entries that exists
|
||||||
|
if _, ok := pluginMap[pluginDef.Id]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to enabled true
|
||||||
|
opt := &m.PluginSettingInfoDTO{Enabled: true}
|
||||||
|
|
||||||
|
// if it's included in app check app settings
|
||||||
|
if pluginDef.IncludedInAppId != "" {
|
||||||
|
// app componets are by default disabled
|
||||||
|
opt.Enabled = false
|
||||||
|
|
||||||
|
if appSettings, ok := pluginMap[pluginDef.IncludedInAppId]; ok {
|
||||||
|
opt.Enabled = appSettings.Enabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginMap[pluginDef.Id] = opt
|
||||||
|
}
|
||||||
|
|
||||||
return pluginMap, nil
|
return pluginMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetEnabledPlugins(orgId int64) (*EnabledPlugins, error) {
|
func GetEnabledPlugins(orgId int64) (*EnabledPlugins, error) {
|
||||||
enabledPlugins := NewEnabledPlugins()
|
enabledPlugins := NewEnabledPlugins()
|
||||||
orgPlugins, err := GetPluginSettings(orgId)
|
pluginSettingMap, err := GetPluginSettings(orgId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledApps := make(map[string]bool)
|
isPluginEnabled := func(pluginId string) bool {
|
||||||
|
_, ok := pluginSettingMap[pluginId]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
for pluginId, app := range Apps {
|
for pluginId, app := range Apps {
|
||||||
|
if b, ok := pluginSettingMap[pluginId]; ok {
|
||||||
if b, ok := orgPlugins[pluginId]; ok {
|
|
||||||
app.Enabled = b.Enabled
|
|
||||||
app.Pinned = b.Pinned
|
app.Pinned = b.Pinned
|
||||||
}
|
|
||||||
|
|
||||||
if app.Enabled {
|
|
||||||
enabledApps[pluginId] = true
|
|
||||||
enabledPlugins.Apps = append(enabledPlugins.Apps, app)
|
enabledPlugins.Apps = append(enabledPlugins.Apps, app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isPluginEnabled := func(appId string) bool {
|
|
||||||
if appId == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
_, ok := enabledApps[appId]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// add all plugins that are not part of an App.
|
// add all plugins that are not part of an App.
|
||||||
for dsId, ds := range DataSources {
|
for dsId, ds := range DataSources {
|
||||||
if isPluginEnabled(ds.IncludedInAppId) {
|
if isPluginEnabled(ds.Id) {
|
||||||
enabledPlugins.DataSources[dsId] = ds
|
enabledPlugins.DataSources[dsId] = ds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, panel := range Panels {
|
for _, panel := range Panels {
|
||||||
if isPluginEnabled(panel.IncludedInAppId) {
|
if isPluginEnabled(panel.Id) {
|
||||||
enabledPlugins.Panels = append(enabledPlugins.Panels, panel)
|
enabledPlugins.Panels = append(enabledPlugins.Panels, panel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,12 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetPluginSettings(query *m.GetPluginSettingsQuery) error {
|
func GetPluginSettings(query *m.GetPluginSettingsQuery) error {
|
||||||
sess := x.Where("org_id=?", query.OrgId)
|
sql := `SELECT org_id, plugin_id, enabled, pinned
|
||||||
|
FROM plugin_setting
|
||||||
|
WHERE org_id=?`
|
||||||
|
|
||||||
query.Result = make([]*m.PluginSetting, 0)
|
sess := x.Sql(sql, query.OrgId)
|
||||||
|
query.Result = make([]*m.PluginSettingInfoDTO, 0)
|
||||||
return sess.Find(&query.Result)
|
return sess.Find(&query.Result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,10 @@ export class DashImportListCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var template = `
|
var template = `
|
||||||
<button class="btn btn-mini btn-inverse" ng-click="ctrl.import(dash)">Import</span>
|
<h3 class="page-heading">Dashboards</h3>
|
||||||
|
<div class="gf-form-group">
|
||||||
|
<button class="btn btn-mini btn-inverse" ng-click="ctrl.import(dash)">Import</button>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function dashboardImportList() {
|
export function dashboardImportList() {
|
||||||
|
@ -40,7 +40,7 @@ function (angular, _, config) {
|
|||||||
return $q.when(null);
|
return $q.when(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return backendSrv.get('/api/datasources/plugins').then(function(plugins) {
|
return backendSrv.get('/api/org/plugins', {enabled: 1, type: 'datasource'}).then(function(plugins) {
|
||||||
datasourceTypes = plugins;
|
datasourceTypes = plugins;
|
||||||
$scope.types = plugins;
|
$scope.types = plugins;
|
||||||
});
|
});
|
||||||
@ -55,7 +55,9 @@ function (angular, _, config) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.typeChanged = function() {
|
$scope.typeChanged = function() {
|
||||||
$scope.datasourceMeta = $scope.types[$scope.current.type];
|
return backendSrv.get('/api/org/plugins/' + $scope.current.type + '/settings').then(function(pluginInfo) {
|
||||||
|
$scope.datasourceMeta = pluginInfo;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.updateFrontendSettings = function() {
|
$scope.updateFrontendSettings = function() {
|
||||||
|
@ -27,34 +27,36 @@ icon="icon-gf icon-gf-datasources">
|
|||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-7">Type</span>
|
<span class="gf-form-label width-7">Type</span>
|
||||||
<div class="gf-form-select-wrapper">
|
<div class="gf-form-select-wrapper">
|
||||||
<select class="gf-form-input gf-size-auto" ng-model="current.type" ng-options="k as v.name for (k, v) in types" ng-change="typeChanged()"></select>
|
<select class="gf-form-input gf-size-auto" ng-model="current.type" ng-options="v.id as v.name for v in types" ng-change="typeChanged()"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<dashboard-import-list plugin="current"></dashboard-import-list>
|
|
||||||
|
|
||||||
<rebuild-on-change property="datasourceMeta.id">
|
<rebuild-on-change property="datasourceMeta.id">
|
||||||
<plugin-component type="datasource-config-ctrl">
|
<plugin-component type="datasource-config-ctrl">
|
||||||
</plugin-component>
|
</plugin-component>
|
||||||
</rebuild-on-change>
|
</rebuild-on-change>
|
||||||
|
|
||||||
<div ng-if="testing" style="margin-top: 25px">
|
<div ng-if="testing" style="margin-top: 25px">
|
||||||
<h5 ng-show="!testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
|
<h5 ng-show="!testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
|
||||||
<h5 ng-show="testing.done">Test results</h5>
|
<h5 ng-show="testing.done">Test results</h5>
|
||||||
<div class="alert-{{testing.status}} alert">
|
<div class="alert-{{testing.status}} alert">
|
||||||
<div class="alert-title">{{testing.title}}</div>
|
<div class="alert-title">{{testing.title}}</div>
|
||||||
<div ng-bind='testing.message'></div>
|
<div ng-bind='testing.message'></div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-button-row">
|
<dashboard-import-list plugin="current"></dashboard-import-list>
|
||||||
<button type="submit" class="btn btn-success" ng-show="isNew" ng-click="saveChanges()">Add</button>
|
|
||||||
<button type="submit" class="btn btn-success" ng-show="!isNew" ng-click="saveChanges()">Save</button>
|
<div class="gf-form-button-row">
|
||||||
<button type="submit" class="btn btn-secondary" ng-show="!isNew" ng-click="saveChanges(true)">
|
<button type="submit" class="btn btn-success" ng-show="isNew" ng-click="saveChanges()">Add</button>
|
||||||
Test Connection
|
<button type="submit" class="btn btn-success" ng-show="!isNew" ng-click="saveChanges()">Save</button>
|
||||||
</button>
|
<button type="submit" class="btn btn-secondary" ng-show="!isNew" ng-click="saveChanges(true)">
|
||||||
<a class="btn btn-link" href="datasources">Cancel</a>
|
Test Connection
|
||||||
</div>
|
</button>
|
||||||
|
<a class="btn btn-link" href="datasources">Cancel</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -72,8 +72,6 @@ export class PluginEditCtrl {
|
|||||||
// Perform the core update procedure
|
// Perform the core update procedure
|
||||||
chain = chain.then(function() {
|
chain = chain.then(function() {
|
||||||
var updateCmd = _.extend({
|
var updateCmd = _.extend({
|
||||||
pluginId: self.model.pluginId,
|
|
||||||
orgId: self.model.orgId,
|
|
||||||
enabled: self.model.enabled,
|
enabled: self.model.enabled,
|
||||||
pinned: self.model.pinned,
|
pinned: self.model.pinned,
|
||||||
jsonData: self.model.jsonData,
|
jsonData: self.model.jsonData,
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-if="ctrl.model.pluginId">
|
<div ng-if="ctrl.model.id">
|
||||||
<plugin-component type="app-config-ctrl"></plugin-component>
|
<plugin-component type="app-config-ctrl"></plugin-component>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
<button type="submit" class="btn btn-success" ng-click="ctrl.update()">Save</button>
|
<button type="submit" class="btn btn-success" ng-click="ctrl.update()">Save</button>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li ng-repeat="page in ctrl.model.pages" class="plugin-info-list-item">
|
<li ng-repeat="page in ctrl.model.pages" class="plugin-info-list-item">
|
||||||
<i class="icon-gf icon-gf-share"></i>
|
<i class="icon-gf icon-gf-share"></i>
|
||||||
<a href="plugins/{{ctrl.pluginId}}/page/{{page.slug}}">{{page.name}}</a>
|
<a href="plugins/{{ctrl.model.id}}/page/{{page.slug}}">{{page.name}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="plugin in ctrl.plugins">
|
<tr ng-repeat="plugin in ctrl.plugins">
|
||||||
<td>
|
<td>
|
||||||
<a href="plugins/{{plugin.pluginId}}/edit">
|
<a href="plugins/{{plugin.id}}/edit">
|
||||||
{{plugin.name}}
|
{{plugin.name}}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<span class="label label-info" ng-if="plugin.pinned">Pinned</span>
|
<span class="label label-info" ng-if="plugin.pinned">Pinned</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<a href="plugins/{{plugin.pluginId}}/edit" class="btn btn-inverse btn-small">
|
<a href="plugins/{{plugin.id}}/edit" class="btn btn-inverse btn-small">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i>
|
||||||
Edit
|
Edit
|
||||||
</a>
|
</a>
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
"type": "datasource",
|
"type": "datasource",
|
||||||
"id": "graphite",
|
"id": "graphite",
|
||||||
|
|
||||||
"defaultMatchFormat": "glob",
|
"includes": [
|
||||||
|
{"type": "dashboard", "name": "Carbon Stats", "path": "dashboards/carbon_stats.json"}
|
||||||
|
],
|
||||||
|
|
||||||
"metrics": true,
|
"metrics": true,
|
||||||
"annotations": true
|
"annotations": true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user