Browse Source

Merge branch 'master' of https://github.com/utkarshcmu/grafana into snapshot-view

utkarshcmu 10 năm trước cách đây
mục cha
commit
09f5e6f4dc

+ 8 - 6
pkg/api/dtos/apps.go

@@ -12,17 +12,19 @@ type AppSettings struct {
 	Pinned   bool                     `json:"pinned"`
 	Module   string                   `json:"module"`
 	Info     *plugins.PluginInfo      `json:"info"`
-	Pages    []*plugins.AppPluginPage `json:"pages"`
+	Pages    []plugins.AppPluginPage  `json:"pages"`
+	Includes []plugins.AppIncludeInfo `json:"includes"`
 	JsonData map[string]interface{}   `json:"jsonData"`
 }
 
 func NewAppSettingsDto(def *plugins.AppPlugin, data *models.AppSettings) *AppSettings {
 	dto := &AppSettings{
-		AppId:  def.Id,
-		Name:   def.Name,
-		Info:   &def.Info,
-		Module: def.Module,
-		Pages:  def.Pages,
+		AppId:    def.Id,
+		Name:     def.Name,
+		Info:     &def.Info,
+		Module:   def.Module,
+		Pages:    def.Pages,
+		Includes: def.Includes,
 	}
 
 	if data != nil {

+ 23 - 2
pkg/plugins/app_plugin.go

@@ -2,6 +2,7 @@ package plugins
 
 import (
 	"encoding/json"
+	"strings"
 
 	"github.com/grafana/grafana/pkg/models"
 )
@@ -17,10 +18,17 @@ type AppPluginCss struct {
 	Dark  string `json:"dark"`
 }
 
+type AppIncludeInfo struct {
+	Name string `json:"name"`
+	Type string `json:"type"`
+	Id   string `json:"id"`
+}
+
 type AppPlugin struct {
 	FrontendPluginBase
-	Css   *AppPluginCss    `json:"css"`
-	Pages []*AppPluginPage `json:"pages"`
+	Css      *AppPluginCss    `json:"css"`
+	Pages    []AppPluginPage  `json:"pages"`
+	Includes []AppIncludeInfo `json:"-"`
 
 	Pinned  bool `json:"-"`
 	Enabled bool `json:"-"`
@@ -38,6 +46,19 @@ func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error {
 
 	app.PluginDir = pluginDir
 	app.initFrontendPlugin()
+
+	// check if we have child panels
+	for _, panel := range Panels {
+		if strings.HasPrefix(panel.PluginDir, app.PluginDir) {
+			panel.IncludedInAppId = app.Id
+			app.Includes = append(app.Includes, AppIncludeInfo{
+				Name: panel.Name,
+				Id:   panel.Id,
+				Type: panel.Type,
+			})
+		}
+	}
+
 	Apps[app.Id] = app
 	return nil
 }

+ 5 - 4
pkg/plugins/frontend_plugin.go

@@ -8,21 +8,22 @@ import (
 
 type FrontendPluginBase struct {
 	PluginBase
-	Module     string `json:"module"`
-	StaticRoot string `json:"staticRoot"`
+	Module        string `json:"module"`
+	StaticRoot    string `json:"staticRoot"`
+	StaticRootAbs string `json:"-"`
 }
 
 func (fp *FrontendPluginBase) initFrontendPlugin() {
 	if fp.StaticRoot != "" {
+		fp.StaticRootAbs = filepath.Join(fp.PluginDir, fp.StaticRoot)
 		StaticRoutes = append(StaticRoutes, &PluginStaticRoute{
-			Directory: filepath.Join(fp.PluginDir, fp.StaticRoot),
+			Directory: fp.StaticRootAbs,
 			PluginId:  fp.Id,
 		})
 	}
 
 	fp.Info.Logos.Small = evalRelativePluginUrlPath(fp.Info.Logos.Small, fp.Id)
 	fp.Info.Logos.Large = evalRelativePluginUrlPath(fp.Info.Logos.Large, fp.Id)
-
 	fp.handleModuleDefaults()
 }
 

+ 7 - 6
pkg/plugins/models.go

@@ -11,12 +11,13 @@ type PluginLoader interface {
 }
 
 type PluginBase struct {
-	Type      string     `json:"type"`
-	Name      string     `json:"name"`
-	Id        string     `json:"id"`
-	App       string     `json:"app"`
-	Info      PluginInfo `json:"info"`
-	PluginDir string     `json:"-"`
+	Type string     `json:"type"`
+	Name string     `json:"name"`
+	Id   string     `json:"id"`
+	Info PluginInfo `json:"info"`
+
+	IncludedInAppId string `json:"-"`
+	PluginDir       string `json:"-"`
 }
 
 type PluginInfo struct {

+ 1 - 33
pkg/plugins/plugins.go

@@ -1,16 +1,13 @@
 package plugins
 
 import (
-	"bytes"
 	"encoding/json"
 	"errors"
-	"io"
 	"os"
 	"path"
 	"path/filepath"
 	"reflect"
 	"strings"
-	"text/template"
 
 	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/setting"
@@ -122,28 +119,6 @@ func (scanner *PluginScanner) walker(currentPath string, f os.FileInfo, err erro
 	return nil
 }
 
-func interpolatePluginJson(reader io.Reader, pluginCommon *PluginBase) (io.Reader, error) {
-	buf := new(bytes.Buffer)
-	buf.ReadFrom(reader)
-	jsonStr := buf.String() //
-
-	tmpl, err := template.New("json").Parse(jsonStr)
-	if err != nil {
-		return nil, err
-	}
-
-	data := map[string]interface{}{
-		"PluginPublicRoot": "public/plugins/" + pluginCommon.Id,
-	}
-
-	var resultBuffer bytes.Buffer
-	if err := tmpl.ExecuteTemplate(&resultBuffer, "json", data); err != nil {
-		return nil, err
-	}
-
-	return bytes.NewReader(resultBuffer.Bytes()), nil
-}
-
 func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 	currentDir := filepath.Dir(pluginJsonFilePath)
 	reader, err := os.Open(pluginJsonFilePath)
@@ -163,20 +138,13 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 		return errors.New("Did not find type and id property in plugin.json")
 	}
 
-	reader.Seek(0, 0)
-	if newReader, err := interpolatePluginJson(reader, &pluginCommon); err != nil {
-		return err
-	} else {
-		jsonParser = json.NewDecoder(newReader)
-	}
-
 	var loader PluginLoader
-
 	if pluginGoType, exists := PluginTypes[pluginCommon.Type]; !exists {
 		return errors.New("Unkown plugin type " + pluginCommon.Type)
 	} else {
 		loader = reflect.New(reflect.TypeOf(pluginGoType)).Interface().(PluginLoader)
 	}
 
+	reader.Seek(0, 0)
 	return loader.Load(jsonParser, currentDir)
 }

+ 20 - 17
pkg/plugins/queries.go

@@ -27,8 +27,7 @@ func GetEnabledPlugins(orgId int64) (*EnabledPlugins, error) {
 		return nil, err
 	}
 
-	seenPanels := make(map[string]bool)
-	seenApi := make(map[string]bool)
+	enabledApps := make(map[string]bool)
 
 	for appId, installedApp := range Apps {
 		var app AppPlugin
@@ -42,32 +41,36 @@ func GetEnabledPlugins(orgId int64) (*EnabledPlugins, error) {
 		}
 
 		if app.Enabled {
+			enabledApps[app.Id] = true
 			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.
-	for d, installedDs := range DataSources {
-		if installedDs.App == "" {
-			enabledPlugins.DataSources[d] = installedDs
+	for dsId, ds := range DataSources {
+		if isPluginEnabled(ds.IncludedInAppId) {
+			enabledPlugins.DataSources[dsId] = ds
 		}
 	}
 
-	for p, panel := range Panels {
-		if panel.App == "" {
-			if _, ok := seenPanels[p]; !ok {
-				seenPanels[p] = true
-				enabledPlugins.Panels = append(enabledPlugins.Panels, panel)
-			}
+	for _, panel := range Panels {
+		if isPluginEnabled(panel.IncludedInAppId) {
+			enabledPlugins.Panels = append(enabledPlugins.Panels, panel)
 		}
 	}
 
-	for a, api := range ApiPlugins {
-		if api.App == "" {
-			if _, ok := seenApi[a]; !ok {
-				seenApi[a] = true
-				enabledPlugins.ApiList = append(enabledPlugins.ApiList, api)
-			}
+	for _, api := range ApiPlugins {
+		if isPluginEnabled(api.IncludedInAppId) {
+			enabledPlugins.ApiList = append(enabledPlugins.ApiList, api)
 		}
 	}
 

+ 2 - 0
public/app/features/apps/edit_ctrl.ts

@@ -5,6 +5,7 @@ import _ from 'lodash';
 
 export class AppEditCtrl {
   appModel: any;
+  includedPanels: any;
 
   /** @ngInject */
   constructor(private backendSrv: any, private $routeParams: any) {
@@ -12,6 +13,7 @@ export class AppEditCtrl {
 
     this.backendSrv.get(`/api/org/apps/${this.$routeParams.appId}/settings`).then(result => {
       this.appModel = result;
+      this.includedPanels = _.where(result.includes, {type: 'panel'});
     });
   }
 

+ 4 - 1
public/app/features/apps/partials/edit.html

@@ -56,7 +56,10 @@
 					Panels
 				</div>
 				<ul>
-					<li><em class="small">None</em></li>
+					<li ng-show="!ctrl.includedPanels.length"><em class="small">None</em></li>
+					<li ng-repeat="panel in ctrl.includedPanels">
+						{{panel.name}}
+					</li>
 				</ul>
 			</div>
 			<div class="simple-box-body simple-box-column">

+ 10 - 2
public/app/features/panel/panel_loader.ts

@@ -3,13 +3,21 @@
 import angular from 'angular';
 import config from 'app/core/config';
 
+import {unknownPanelDirective} from '../../plugins/panel/unknown/module';
+
 /** @ngInject */
 function panelLoader($parse, dynamicDirectiveSrv) {
   return dynamicDirectiveSrv.create({
     directive: scope => {
-      let modulePath = config.panels[scope.panel.type].module;
+      let panelInfo = config.panels[scope.panel.type];
+      if (!panelInfo) {
+        return Promise.resolve({
+          name: 'panel-directive-' + scope.panel.type,
+          fn: unknownPanelDirective
+        });
+      }
 
-      return System.import(modulePath).then(function(panelModule) {
+      return System.import(panelInfo.module).then(function(panelModule) {
         return {
           name: 'panel-directive-' + scope.panel.type,
           fn: panelModule.panel,

+ 15 - 0
public/app/plugins/panel/unknown/module.ts

@@ -0,0 +1,15 @@
+///<reference path="../../../headers/common.d.ts" />
+
+export function unknownPanelDirective() {
+  return {
+    restrict: 'E',
+    template: `
+    <grafana-panel>
+      <div class="text-center" style="padding-top: 2rem">
+          Unknown panel type: <strong>{{panel.type}}</strong>
+      </div>
+    </grafana-panel>
+    `,
+  };
+}
+

+ 1 - 1
public/less/simple-box.less

@@ -1,7 +1,7 @@
 
 @simpleBoxBorderWidth:  0.2rem;
 @simpleBoxMargin:  1.5rem;
-@simpleBoxBodyPadding:  0.5rem 0 0.5rem 1rem;
+@simpleBoxBodyPadding:  1rem 0 0.5rem 1rem;
 
 .simple-box {
   margin-top: @simpleBoxMargin;

+ 1 - 1
symlink_git_hooks.sh

@@ -1,3 +1,3 @@
 #/bin/bash
 
-ln -s .hooks/* .git/hooks/
+ln -s -f .hooks/* .git/hooks/