diff --git a/examples/nginx-app/module.js b/examples/nginx-app/module.js
index 9e061df04cc..1805d1a0fad 100644
--- a/examples/nginx-app/module.js
+++ b/examples/nginx-app/module.js
@@ -1,28 +1,20 @@
define([
- 'angular',
- 'app/app'
-], function(angular, app) {
+], function() {
+ 'use strict';
- var module = angular.module('nginx-app', []);
- app.default.useModule(module);
+ function StreamPageCtrl() {}
+ StreamPageCtrl.templateUrl = 'public/plugins/nginx-app/partials/stream.html';
- module.config(function($routeProvider) {
- $routeProvider
- .when('/nginx/stream', {
- templateUrl: 'public/plugins/nginx-app/partials/stream.html',
- });
- });
+ function LogsPageCtrl() {}
+ LogsPageCtrl.templateUrl = 'public/plugins/nginx-app/partials/logs.html';
- function NginxConfigCtrl() {
- this.appEditCtrl.beforeUpdate = function() {
- alert('before!');
- };
- }
+ function NginxConfigCtrl() {}
NginxConfigCtrl.templateUrl = 'public/plugins/nginx-app/partials/config.html';
-
return {
- ConfigCtrl: NginxConfigCtrl
+ ConfigCtrl: NginxConfigCtrl,
+ StreamPageCtrl: StreamPageCtrl,
+ LogsPageCtrl: LogsPageCtrl,
};
});
diff --git a/examples/nginx-app/partials/logs.html b/examples/nginx-app/partials/logs.html
new file mode 100644
index 00000000000..f6bef036395
--- /dev/null
+++ b/examples/nginx-app/partials/logs.html
@@ -0,0 +1,2 @@
+
+Logs!
diff --git a/examples/nginx-app/partials/stream.html b/examples/nginx-app/partials/stream.html
index a89afaced57..092c36cc24c 100644
--- a/examples/nginx-app/partials/stream.html
+++ b/examples/nginx-app/partials/stream.html
@@ -1,12 +1 @@
-
-
-
-
-
-
+streams!
diff --git a/examples/nginx-app/plugin.json b/examples/nginx-app/plugin.json
index 6941fe87f17..7e3cdd7ad08 100644
--- a/examples/nginx-app/plugin.json
+++ b/examples/nginx-app/plugin.json
@@ -6,8 +6,8 @@
"staticRoot": ".",
"pages": [
- {"name": "Live stream", "url": "nginx/stream", "reqRole": "Editor"},
- {"name": "Log view", "url": "nginx/log", "reqRole": "Editor"}
+ { "name": "Live stream", "component": "StreamPageCtrl", "role": "Editor"},
+ { "name": "Log view", "component": "LogsPageCtrl", "role": "Viewer"}
],
"css": {
diff --git a/pkg/api/dtos/apps.go b/pkg/api/dtos/apps.go
index d10883a26d7..7a1e18148e2 100644
--- a/pkg/api/dtos/apps.go
+++ b/pkg/api/dtos/apps.go
@@ -6,15 +6,15 @@ import (
)
type AppSettings struct {
- Name string `json:"name"`
- AppId string `json:"appId"`
- Enabled bool `json:"enabled"`
- Pinned bool `json:"pinned"`
- Module string `json:"module"`
- Info *plugins.PluginInfo `json:"info"`
- Pages []plugins.AppPluginPage `json:"pages"`
- Includes []plugins.AppIncludeInfo `json:"includes"`
- JsonData map[string]interface{} `json:"jsonData"`
+ Name string `json:"name"`
+ AppId string `json:"appId"`
+ Enabled bool `json:"enabled"`
+ Pinned bool `json:"pinned"`
+ Module string `json:"module"`
+ Info *plugins.PluginInfo `json:"info"`
+ 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 {
diff --git a/pkg/api/dtos/index.go b/pkg/api/dtos/index.go
index c5b81ee0e98..180ec767281 100644
--- a/pkg/api/dtos/index.go
+++ b/pkg/api/dtos/index.go
@@ -19,8 +19,9 @@ type PluginCss struct {
}
type NavLink struct {
- Text string `json:"text"`
- Icon string `json:"icon"`
- Img string `json:"img"`
- Url string `json:"url"`
+ Text string `json:"text"`
+ Icon string `json:"icon"`
+ Img string `json:"img"`
+ Url string `json:"url"`
+ Children []*NavLink `json:"children"`
}
diff --git a/pkg/api/index.go b/pkg/api/index.go
index 522b53b9026..094511df1ea 100644
--- a/pkg/api/index.go
+++ b/pkg/api/index.go
@@ -51,32 +51,27 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
Text: "Dashboards",
Icon: "fa fa-fw fa-th-large",
- Url: "/",
+ Url: setting.AppSubUrl + "/",
+ // Children: []*dtos.NavLink{
+ // {Text: "Playlists", Icon: "fa fa-fw fa-list", Url: setting.AppSubUrl + "/playlists"},
+ // {Text: "Snapshots", Icon: "fa-fw icon-gf icon-gf-snapshot", Url: setting.AppSubUrl + "/dashboard/snapshots"},
+ // },
})
- data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
- Text: "Playlists",
- Icon: "fa fa-fw fa-list",
- Url: "/playlists",
- })
-
- data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
- Text: "Snapshots",
- Icon: "fa-fw icon-gf icon-gf-snapshot",
- Url: "/dashboard/snapshots",
- })
+ data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{Text: "Playlists", Icon: "fa fa-fw fa-list", Url: setting.AppSubUrl + "/playlists"})
+ data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{Text: "Snapshots", Icon: "fa-fw icon-gf icon-gf-snapshot", Url: setting.AppSubUrl + "/dashboard/snapshots"})
if c.OrgRole == m.ROLE_ADMIN {
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
Text: "Data Sources",
Icon: "fa fa-fw fa-database",
- Url: "/datasources",
+ Url: setting.AppSubUrl + "/datasources",
})
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
Text: "Apps",
Icon: "fa fa-fw fa-cubes",
- Url: "/apps",
+ Url: setting.AppSubUrl + "/apps",
})
}
@@ -86,20 +81,25 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
}
for _, plugin := range enabledPlugins.Apps {
- if plugin.Module != "" {
- data.PluginModules = append(data.PluginModules, plugin.Module)
- }
-
if plugin.Css != nil {
data.PluginCss = append(data.PluginCss, &dtos.PluginCss{Light: plugin.Css.Light, Dark: plugin.Css.Dark})
}
if plugin.Pinned {
- data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
+ pageLink := &dtos.NavLink{
Text: plugin.Name,
- Url: "/apps/edit/" + plugin.Id,
+ Url: setting.AppSubUrl + "/apps/" + plugin.Id + "/edit",
Img: plugin.Info.Logos.Small,
- })
+ }
+
+ for _, page := range plugin.Pages {
+ pageLink.Children = append(pageLink.Children, &dtos.NavLink{
+ Url: setting.AppSubUrl + "/apps/" + plugin.Id + "/page/" + page.Slug,
+ Text: page.Name,
+ })
+ }
+
+ data.MainNavLinks = append(data.MainNavLinks, pageLink)
}
}
diff --git a/pkg/plugins/app_plugin.go b/pkg/plugins/app_plugin.go
index 547cd91283c..cb1349047da 100644
--- a/pkg/plugins/app_plugin.go
+++ b/pkg/plugins/app_plugin.go
@@ -4,13 +4,15 @@ import (
"encoding/json"
"strings"
+ "github.com/gosimple/slug"
"github.com/grafana/grafana/pkg/models"
)
type AppPluginPage struct {
- Name string `json:"name"`
- Url string `json:"url"`
- ReqRole models.RoleType `json:"reqRole"`
+ Name string `json:"name"`
+ Slug string `json:"slug"`
+ Component string `json:"component"`
+ Role models.RoleType `json:"role"`
}
type AppPluginCss struct {
@@ -27,9 +29,9 @@ type AppIncludeInfo struct {
type AppPlugin struct {
FrontendPluginBase
Css *AppPluginCss `json:"css"`
- Pages []AppPluginPage `json:"pages"`
+ Pages []*AppPluginPage `json:"pages"`
Routes []*AppPluginRoute `json:"routes"`
- Includes []AppIncludeInfo `json:"-"`
+ Includes []*AppIncludeInfo `json:"-"`
Pinned bool `json:"-"`
Enabled bool `json:"-"`
@@ -67,7 +69,7 @@ func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error {
for _, panel := range Panels {
if strings.HasPrefix(panel.PluginDir, app.PluginDir) {
panel.IncludedInAppId = app.Id
- app.Includes = append(app.Includes, AppIncludeInfo{
+ app.Includes = append(app.Includes, &AppIncludeInfo{
Name: panel.Name,
Id: panel.Id,
Type: panel.Type,
@@ -75,6 +77,12 @@ func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error {
}
}
+ for _, page := range app.Pages {
+ if page.Slug == "" {
+ page.Slug = slug.Make(page.Name)
+ }
+ }
+
Apps[app.Id] = app
return nil
}
diff --git a/public/app/app.ts b/public/app/app.ts
index d9ad3a449d3..a4e1bebca6e 100644
--- a/public/app/app.ts
+++ b/public/app/app.ts
@@ -72,12 +72,6 @@ export class GrafanaApp {
this.useModule(coreModule);
var preBootRequires = [System.import('app/features/all')];
- var pluginModules = config.bootData.pluginModules || [];
-
- // add plugin modules
- for (var i = 0; i < pluginModules.length; i++) {
- preBootRequires.push(System.import(pluginModules[i]));
- }
Promise.all(preBootRequires).then(() => {
// disable tool tip animation
diff --git a/public/app/core/components/sidemenu/sidemenu.html b/public/app/core/components/sidemenu/sidemenu.html
index a651c87aa7c..7fcd41a2824 100644
--- a/public/app/core/components/sidemenu/sidemenu.html
+++ b/public/app/core/components/sidemenu/sidemenu.html
@@ -1,6 +1,6 @@