mirror of
https://github.com/grafana/grafana.git
synced 2025-09-21 07:32:52 +08:00
refactor(apps): more WIP work on apps
This commit is contained in:
@ -18,11 +18,11 @@ func GetAppPlugins(c *middleware.Context) Response {
|
|||||||
installedAppsMap := make(map[string]*dtos.AppPlugin)
|
installedAppsMap := make(map[string]*dtos.AppPlugin)
|
||||||
for t, a := range plugins.Apps {
|
for t, a := range plugins.Apps {
|
||||||
installedAppsMap[t] = &dtos.AppPlugin{
|
installedAppsMap[t] = &dtos.AppPlugin{
|
||||||
Type: a.Type,
|
Type: a.Type,
|
||||||
Enabled: a.Enabled,
|
Enabled: a.Enabled,
|
||||||
PinNavLinks: a.PinNavLinks,
|
Pinned: a.Pinned,
|
||||||
Module: a.Module,
|
Module: a.Module,
|
||||||
JsonData: make(map[string]interface{}),
|
JsonData: make(map[string]interface{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,11 +32,11 @@ func GetAppPlugins(c *middleware.Context) Response {
|
|||||||
for _, b := range query.Result {
|
for _, b := range query.Result {
|
||||||
if def, ok := installedAppsMap[b.Type]; ok {
|
if def, ok := installedAppsMap[b.Type]; ok {
|
||||||
result = append(result, &dtos.AppPlugin{
|
result = append(result, &dtos.AppPlugin{
|
||||||
Type: b.Type,
|
Type: b.Type,
|
||||||
Enabled: b.Enabled,
|
Enabled: b.Enabled,
|
||||||
PinNavLinks: b.PinNavLinks,
|
Pinned: b.Pinned,
|
||||||
Module: def.Module,
|
Module: def.Module,
|
||||||
JsonData: b.JsonData,
|
JsonData: b.JsonData,
|
||||||
})
|
})
|
||||||
seenApps[b.Type] = true
|
seenApps[b.Type] = true
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ func GetDataSourcePlugins(c *middleware.Context) {
|
|||||||
}
|
}
|
||||||
enabledPlugins := plugins.GetEnabledPlugins(orgApps.Result)
|
enabledPlugins := plugins.GetEnabledPlugins(orgApps.Result)
|
||||||
|
|
||||||
for key, value := range enabledPlugins.DataSourcePlugins {
|
for key, value := range enabledPlugins.DataSources {
|
||||||
if !value.BuiltIn {
|
if !value.BuiltIn {
|
||||||
dsList[key] = value
|
dsList[key] = value
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package dtos
|
package dtos
|
||||||
|
|
||||||
type AppPlugin struct {
|
type AppPlugin struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
PinNavLinks bool `json:"pin_nav_links"`
|
Pinned bool `json:"pinned"`
|
||||||
Module string `json:"module"`
|
Module string `json:"module"`
|
||||||
JsonData map[string]interface{} `json:"jsonData"`
|
JsonData map[string]interface{} `json:"jsonData"`
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledPlugins := plugins.GetEnabledPlugins(orgApps.Result)
|
enabledPlugins := plugins.GetEnabledPlugins(orgApps.Result)
|
||||||
|
|
||||||
for _, ds := range orgDataSources {
|
for _, ds := range orgDataSources {
|
||||||
@ -49,7 +50,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
|
|||||||
"url": url,
|
"url": url,
|
||||||
}
|
}
|
||||||
|
|
||||||
meta, exists := enabledPlugins.DataSourcePlugins[ds.Type]
|
meta, exists := enabledPlugins.DataSources[ds.Type]
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Error(3, "Could not find plugin definition for data source: %v", ds.Type)
|
log.Error(3, "Could not find plugin definition for data source: %v", ds.Type)
|
||||||
continue
|
continue
|
||||||
@ -117,7 +118,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
panels := map[string]interface{}{}
|
panels := map[string]interface{}{}
|
||||||
for _, panel := range enabledPlugins.PanelPlugins {
|
for _, panel := range enabledPlugins.Panels {
|
||||||
panels[panel.Type] = map[string]interface{}{
|
panels[panel.Type] = map[string]interface{}{
|
||||||
"module": panel.Module,
|
"module": panel.Module,
|
||||||
"name": panel.Name,
|
"name": panel.Name,
|
||||||
|
@ -52,7 +52,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
|||||||
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
||||||
Text: "Dashboards",
|
Text: "Dashboards",
|
||||||
Icon: "fa fa-fw fa-th-large",
|
Icon: "fa fa-fw fa-th-large",
|
||||||
Href: "/",
|
Url: "/",
|
||||||
})
|
})
|
||||||
|
|
||||||
orgApps := m.GetAppPluginsQuery{OrgId: c.OrgId}
|
orgApps := m.GetAppPluginsQuery{OrgId: c.OrgId}
|
||||||
@ -73,7 +73,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if plugin.Pinned && plugin.Page != nil {
|
if plugin.Pinned && plugin.Page != nil {
|
||||||
if c.userHasRole(plugin.Page.reqRole) {
|
if c.HasUserRole(plugin.Page.ReqRole) {
|
||||||
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
||||||
Text: plugin.Page.Text,
|
Text: plugin.Page.Text,
|
||||||
Url: plugin.Page.Url,
|
Url: plugin.Page.Url,
|
||||||
|
@ -30,9 +30,9 @@ func newMacaron() *macaron.Macaron {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, route := range plugins.StaticRoutes {
|
for _, route := range plugins.StaticRoutes {
|
||||||
pluginRoute := path.Join("/public/plugins/", route.Url)
|
pluginRoute := path.Join("/public/plugins/", route.UrlFragment)
|
||||||
log.Info("Plugin: Adding static route %s -> %s", pluginRoute, route.Path)
|
log.Info("Plugin: Adding static route %s -> %s", pluginRoute, route.Dir)
|
||||||
mapStatic(m, route.Path, "", pluginRoute)
|
mapStatic(m, route.Dir, "", pluginRoute)
|
||||||
}
|
}
|
||||||
|
|
||||||
mapStatic(m, setting.StaticRootPath, "", "public")
|
mapStatic(m, setting.StaticRootPath, "", "public")
|
||||||
|
@ -254,6 +254,6 @@ func (ctx *Context) JsonApiErr(status int, message string, err error) {
|
|||||||
ctx.JSON(status, resp)
|
ctx.JSON(status, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) hasUserRole(role m.RoleType) bool {
|
func (ctx *Context) HasUserRole(role m.RoleType) bool {
|
||||||
return ctx.OrgRole.Includes(role)
|
return ctx.OrgRole.Includes(role)
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ type ApiPluginRoute struct {
|
|||||||
type AppPluginPage struct {
|
type AppPluginPage struct {
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
Href string `json:"url"`
|
Url string `json:"url"`
|
||||||
ReqRole models.RoleType `json:"reqRole"`
|
ReqRole models.RoleType `json:"reqRole"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
|||||||
|
|
||||||
func addAppPluginMigration(mg *Migrator) {
|
func addAppPluginMigration(mg *Migrator) {
|
||||||
|
|
||||||
var appPluginV1 = Table{
|
var appPluginV2 = Table{
|
||||||
Name: "app_plugin",
|
Name: "app_plugin",
|
||||||
Columns: []*Column{
|
Columns: []*Column{
|
||||||
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
||||||
@ -20,8 +20,9 @@ func addAppPluginMigration(mg *Migrator) {
|
|||||||
{Cols: []string{"org_id", "type"}, Type: UniqueIndex},
|
{Cols: []string{"org_id", "type"}, Type: UniqueIndex},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
mg.AddMigration("create app_plugin table v1", NewAddTableMigration(appPluginV1))
|
|
||||||
|
mg.AddMigration("create app_plugin table v2", NewAddTableMigration(appPluginV2))
|
||||||
|
|
||||||
//------- indexes ------------------
|
//------- indexes ------------------
|
||||||
addTableIndicesMigrations(mg, "v1", appPluginV1)
|
addTableIndicesMigrations(mg, "v2", appPluginV2)
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
define([
|
///<reference path="../../headers/common.d.ts" />
|
||||||
'angular',
|
|
||||||
'lodash',
|
|
||||||
'app/core/config',
|
|
||||||
],
|
|
||||||
function (angular, _, config) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var module = angular.module('grafana.controllers');
|
import config = require('app/core/config');
|
||||||
|
import angular from 'angular';
|
||||||
|
|
||||||
|
export class AppEditCtrl {
|
||||||
|
|
||||||
|
/** @ngInject */
|
||||||
|
constructor(private $scope: any, private appSrv: any, private $routeParams: any) {
|
||||||
|
|
||||||
module.controller('AppEditCtrl', function($scope, appSrv, $routeParams) {
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.current = {};
|
$scope.current = {};
|
||||||
$scope.getApps();
|
$scope.getApps();
|
||||||
@ -31,5 +30,8 @@ function (angular, _, config) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.init();
|
$scope.init();
|
||||||
});
|
}
|
||||||
});
|
|
||||||
|
}
|
||||||
|
|
||||||
|
angular.module('grafana.controllers').controller('AppEditCtrl', AppEditCtrl);
|
@ -1,58 +0,0 @@
|
|||||||
define([
|
|
||||||
'angular',
|
|
||||||
'lodash',
|
|
||||||
],
|
|
||||||
function (angular, _) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var module = angular.module('grafana.services');
|
|
||||||
|
|
||||||
module.service('appSrv', function($rootScope, $timeout, $q, backendSrv) {
|
|
||||||
var self = this;
|
|
||||||
this.init = function() {
|
|
||||||
console.log("appSrv init");
|
|
||||||
this.apps = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
this.get = function(type) {
|
|
||||||
return $q(function(resolve) {
|
|
||||||
if (type in self.apps) {
|
|
||||||
return resolve(self.apps[type]);
|
|
||||||
}
|
|
||||||
backendSrv.get('api/org/apps').then(function(results) {
|
|
||||||
_.forEach(results, function(p) {
|
|
||||||
self.apps[p.type] = p;
|
|
||||||
});
|
|
||||||
return resolve(self.apps[type]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getAll = function() {
|
|
||||||
return $q(function(resolve) {
|
|
||||||
if (!_.isEmpty(self.apps)) {
|
|
||||||
return resolve(self.apps);
|
|
||||||
}
|
|
||||||
backendSrv.get('api/org/apps').then(function(results) {
|
|
||||||
_.forEach(results, function(p) {
|
|
||||||
self.apps[p.type] = p;
|
|
||||||
});
|
|
||||||
return resolve(self.apps);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.update = function(app) {
|
|
||||||
return $q(function(resolve, reject) {
|
|
||||||
backendSrv.post('api/org/apps', app).then(function(resp) {
|
|
||||||
self.apps[app.type] = app;
|
|
||||||
resolve(resp);
|
|
||||||
}, function(resp) {
|
|
||||||
reject(resp);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
});
|
|
||||||
});
|
|
47
public/app/features/org/app_srv.ts
Normal file
47
public/app/features/org/app_srv.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import config = require('app/core/config');
|
||||||
|
import angular from 'angular';
|
||||||
|
|
||||||
|
export class AppSrv {
|
||||||
|
apps: any = {};
|
||||||
|
|
||||||
|
/** @ngInject */
|
||||||
|
constructor(
|
||||||
|
private $rootScope,
|
||||||
|
private $timeout,
|
||||||
|
private $q,
|
||||||
|
private backendSrv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
get(type) {
|
||||||
|
if (this.apps[type]) {
|
||||||
|
return this.$q.when(this.apps[type]);
|
||||||
|
}
|
||||||
|
return this.getAll().then(() => {
|
||||||
|
return this.apps[type];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getAll() {
|
||||||
|
if (!_.isEmpty(this.apps)) {
|
||||||
|
return this.$q.when(this.apps);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.backendSrv.get('api/org/apps').then(results => {
|
||||||
|
this.apps = results.reduce((prev, current) => {
|
||||||
|
prev[current.type] = current;
|
||||||
|
}, {});
|
||||||
|
return this.apps;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
update(app) {
|
||||||
|
return this.backendSrv.post('api/org/apps', app).then(resp => {
|
||||||
|
this.apps[app.type] = app;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
angular.module('grafana.services').service('appSrv', AppSrv);
|
@ -19,7 +19,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li ng-repeat="item in mainLinks">
|
<li ng-repeat="item in mainLinks">
|
||||||
<a href="{{item.href}}" class="sidemenu-item" target="{{item.target}}">
|
<a href="{{item.url}}" class="sidemenu-item" target="{{item.target}}">
|
||||||
<span class="icon-circle sidemenu-icon"><i class="{{item.icon}}"></i></span>
|
<span class="icon-circle sidemenu-icon"><i class="{{item.icon}}"></i></span>
|
||||||
<span class="sidemenu-item-text">{{item.text}}</span>
|
<span class="sidemenu-item-text">{{item.text}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
window.grafanaBootData = {
|
window.grafanaBootData = {
|
||||||
user:[[.User]],
|
user:[[.User]],
|
||||||
settings: [[.Settings]],
|
settings: [[.Settings]],
|
||||||
pluginModules: [[.PluginJs]],
|
pluginModules: [[.PluginModules]],
|
||||||
mainNavLinks: [[.MainNavLinks]]
|
mainNavLinks: [[.MainNavLinks]]
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
Reference in New Issue
Block a user