mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
:merge branch 'app-pages'
Conflicts: examples/nginx-app/module.js examples/nginx-app/partials/stream.html examples/nginx-app/plugin.json
This commit is contained in:
@@ -1,28 +1,20 @@
|
|||||||
define([
|
define([
|
||||||
'angular',
|
], function() {
|
||||||
'app/app'
|
'use strict';
|
||||||
], function(angular, app) {
|
|
||||||
|
|
||||||
var module = angular.module('nginx-app', []);
|
function StreamPageCtrl() {}
|
||||||
app.default.useModule(module);
|
StreamPageCtrl.templateUrl = 'public/plugins/nginx-app/partials/stream.html';
|
||||||
|
|
||||||
module.config(function($routeProvider) {
|
function LogsPageCtrl() {}
|
||||||
$routeProvider
|
LogsPageCtrl.templateUrl = 'public/plugins/nginx-app/partials/logs.html';
|
||||||
.when('/nginx/stream', {
|
|
||||||
templateUrl: 'public/plugins/nginx-app/partials/stream.html',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function NginxConfigCtrl() {
|
function NginxConfigCtrl() {}
|
||||||
this.appEditCtrl.beforeUpdate = function() {
|
|
||||||
alert('before!');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
NginxConfigCtrl.templateUrl = 'public/plugins/nginx-app/partials/config.html';
|
NginxConfigCtrl.templateUrl = 'public/plugins/nginx-app/partials/config.html';
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ConfigCtrl: NginxConfigCtrl
|
ConfigCtrl: NginxConfigCtrl,
|
||||||
|
StreamPageCtrl: StreamPageCtrl,
|
||||||
|
LogsPageCtrl: LogsPageCtrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
2
examples/nginx-app/partials/logs.html
Normal file
2
examples/nginx-app/partials/logs.html
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
Logs!
|
||||||
@@ -1,12 +1 @@
|
|||||||
<topnav title="Nginx" icon="fa fa-fw fa-cubes" subnav="true">
|
streams!
|
||||||
<ul class="nav">
|
|
||||||
<li class="active" ><a href="org/apps">Overview</a></li>
|
|
||||||
</ul>
|
|
||||||
</topnav>
|
|
||||||
|
|
||||||
<div class="page-container" style="background: transparent; border: 0;">
|
|
||||||
<div class="page-wide" ng-init="ctrl.init()">
|
|
||||||
<h1>NGINX app</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
"staticRoot": ".",
|
"staticRoot": ".",
|
||||||
|
|
||||||
"pages": [
|
"pages": [
|
||||||
{"name": "Live stream", "url": "nginx/stream", "reqRole": "Editor"},
|
{ "name": "Live stream", "component": "StreamPageCtrl", "role": "Editor"},
|
||||||
{"name": "Log view", "url": "nginx/log", "reqRole": "Editor"}
|
{ "name": "Log view", "component": "LogsPageCtrl", "role": "Viewer"}
|
||||||
],
|
],
|
||||||
|
|
||||||
"css": {
|
"css": {
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type AppSettings struct {
|
type AppSettings struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
AppId string `json:"appId"`
|
AppId string `json:"appId"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Pinned bool `json:"pinned"`
|
Pinned bool `json:"pinned"`
|
||||||
Module string `json:"module"`
|
Module string `json:"module"`
|
||||||
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.AppIncludeInfo `json:"includes"`
|
||||||
JsonData map[string]interface{} `json:"jsonData"`
|
JsonData map[string]interface{} `json:"jsonData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAppSettingsDto(def *plugins.AppPlugin, data *models.AppSettings) *AppSettings {
|
func NewAppSettingsDto(def *plugins.AppPlugin, data *models.AppSettings) *AppSettings {
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ type PluginCss struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NavLink struct {
|
type NavLink struct {
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
Img string `json:"img"`
|
Img string `json:"img"`
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
|
Children []*NavLink `json:"children"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,32 +51,27 @@ 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",
|
||||||
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{
|
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{Text: "Playlists", Icon: "fa fa-fw fa-list", Url: setting.AppSubUrl + "/playlists"})
|
||||||
Text: "Playlists",
|
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{Text: "Snapshots", Icon: "fa-fw icon-gf icon-gf-snapshot", Url: setting.AppSubUrl + "/dashboard/snapshots"})
|
||||||
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",
|
|
||||||
})
|
|
||||||
|
|
||||||
if c.OrgRole == m.ROLE_ADMIN {
|
if c.OrgRole == m.ROLE_ADMIN {
|
||||||
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
||||||
Text: "Data Sources",
|
Text: "Data Sources",
|
||||||
Icon: "fa fa-fw fa-database",
|
Icon: "fa fa-fw fa-database",
|
||||||
Url: "/datasources",
|
Url: setting.AppSubUrl + "/datasources",
|
||||||
})
|
})
|
||||||
|
|
||||||
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
||||||
Text: "Apps",
|
Text: "Apps",
|
||||||
Icon: "fa fa-fw fa-cubes",
|
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 {
|
for _, plugin := range enabledPlugins.Apps {
|
||||||
if plugin.Module != "" {
|
|
||||||
data.PluginModules = append(data.PluginModules, plugin.Module)
|
|
||||||
}
|
|
||||||
|
|
||||||
if plugin.Css != nil {
|
if plugin.Css != nil {
|
||||||
data.PluginCss = append(data.PluginCss, &dtos.PluginCss{Light: plugin.Css.Light, Dark: plugin.Css.Dark})
|
data.PluginCss = append(data.PluginCss, &dtos.PluginCss{Light: plugin.Css.Light, Dark: plugin.Css.Dark})
|
||||||
}
|
}
|
||||||
|
|
||||||
if plugin.Pinned {
|
if plugin.Pinned {
|
||||||
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
pageLink := &dtos.NavLink{
|
||||||
Text: plugin.Name,
|
Text: plugin.Name,
|
||||||
Url: "/apps/edit/" + plugin.Id,
|
Url: setting.AppSubUrl + "/apps/" + plugin.Id + "/edit",
|
||||||
Img: plugin.Info.Logos.Small,
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gosimple/slug"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AppPluginPage struct {
|
type AppPluginPage struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Url string `json:"url"`
|
Slug string `json:"slug"`
|
||||||
ReqRole models.RoleType `json:"reqRole"`
|
Component string `json:"component"`
|
||||||
|
Role models.RoleType `json:"role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppPluginCss struct {
|
type AppPluginCss struct {
|
||||||
@@ -27,9 +29,9 @@ type AppIncludeInfo struct {
|
|||||||
type AppPlugin struct {
|
type AppPlugin struct {
|
||||||
FrontendPluginBase
|
FrontendPluginBase
|
||||||
Css *AppPluginCss `json:"css"`
|
Css *AppPluginCss `json:"css"`
|
||||||
Pages []AppPluginPage `json:"pages"`
|
Pages []*AppPluginPage `json:"pages"`
|
||||||
Routes []*AppPluginRoute `json:"routes"`
|
Routes []*AppPluginRoute `json:"routes"`
|
||||||
Includes []AppIncludeInfo `json:"-"`
|
Includes []*AppIncludeInfo `json:"-"`
|
||||||
|
|
||||||
Pinned bool `json:"-"`
|
Pinned bool `json:"-"`
|
||||||
Enabled bool `json:"-"`
|
Enabled bool `json:"-"`
|
||||||
@@ -67,7 +69,7 @@ func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error {
|
|||||||
for _, panel := range Panels {
|
for _, panel := range Panels {
|
||||||
if strings.HasPrefix(panel.PluginDir, app.PluginDir) {
|
if strings.HasPrefix(panel.PluginDir, app.PluginDir) {
|
||||||
panel.IncludedInAppId = app.Id
|
panel.IncludedInAppId = app.Id
|
||||||
app.Includes = append(app.Includes, AppIncludeInfo{
|
app.Includes = append(app.Includes, &AppIncludeInfo{
|
||||||
Name: panel.Name,
|
Name: panel.Name,
|
||||||
Id: panel.Id,
|
Id: panel.Id,
|
||||||
Type: panel.Type,
|
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
|
Apps[app.Id] = app
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,12 +72,6 @@ export class GrafanaApp {
|
|||||||
this.useModule(coreModule);
|
this.useModule(coreModule);
|
||||||
|
|
||||||
var preBootRequires = [System.import('app/features/all')];
|
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(() => {
|
Promise.all(preBootRequires).then(() => {
|
||||||
// disable tool tip animation
|
// disable tool tip animation
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<ul class="sidemenu sidemenu-main">
|
<ul class="sidemenu sidemenu-main">
|
||||||
|
|
||||||
<li class="sidemenu-org-section dropdown" ng-if="ctrl.isSignedIn">
|
<li class="sidemenu-org-section" ng-if="ctrl.isSignedIn">
|
||||||
<div class="sidemenu-org" data-toggle="dropdown" ng-click="ctrl.openUserDropdown()">
|
<div class="sidemenu-org" data-toggle="dropdown" ng-click="ctrl.openUserDropdown()">
|
||||||
<div class="sidemenu-org-avatar">
|
<div class="sidemenu-org-avatar">
|
||||||
<img ng-src="{{ctrl.user.gravatarUrl}}">
|
<img ng-src="{{ctrl.user.gravatarUrl}}">
|
||||||
@@ -44,6 +44,13 @@
|
|||||||
</span>
|
</span>
|
||||||
<span class="sidemenu-item-text">{{item.text}}</span>
|
<span class="sidemenu-item-text">{{item.text}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
<ul class="dropdown-menu" role="menu" ng-if="item.children">
|
||||||
|
<li ng-repeat="child in item.children">
|
||||||
|
<a href="{{child.url}}">
|
||||||
|
{{child.text}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<ul class="sidemenu sidemenu-small" style="margin-top:50px" ng-if="ctrl.systemSection">
|
<ul class="sidemenu sidemenu-small" style="margin-top:50px" ng-if="ctrl.systemSection">
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export class SideMenuCtrl {
|
|||||||
appSubUrl: string;
|
appSubUrl: string;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private $scope, private $location, private contextSrv, private backendSrv) {
|
constructor(private $scope, private $location, private contextSrv, private backendSrv, private $element) {
|
||||||
this.isSignedIn = contextSrv.isSignedIn;
|
this.isSignedIn = contextSrv.isSignedIn;
|
||||||
this.user = contextSrv.user;
|
this.user = contextSrv.user;
|
||||||
this.appSubUrl = config.appSubUrl;
|
this.appSubUrl = config.appSubUrl;
|
||||||
@@ -29,6 +29,7 @@ export class SideMenuCtrl {
|
|||||||
this.contextSrv.sidemenu = false;
|
this.contextSrv.sidemenu = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getUrl(url) {
|
getUrl(url) {
|
||||||
@@ -36,9 +37,7 @@ export class SideMenuCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupMainNav() {
|
setupMainNav() {
|
||||||
this.mainLinks = config.bootData.mainNavLinks.map(item => {
|
this.mainLinks = config.bootData.mainNavLinks;
|
||||||
return {text: item.text, icon: item.icon, img: item.img, url: this.getUrl(item.url)};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openUserDropdown() {
|
openUserDropdown() {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import {navbarDirective} from './components/navbar/navbar';
|
|||||||
import {arrayJoin} from './directives/array_join';
|
import {arrayJoin} from './directives/array_join';
|
||||||
import 'app/core/controllers/all';
|
import 'app/core/controllers/all';
|
||||||
import 'app/core/services/all';
|
import 'app/core/services/all';
|
||||||
import 'app/core/routes/all';
|
import 'app/core/routes/routes';
|
||||||
import './filters/filters';
|
import './filters/filters';
|
||||||
import coreModule from './core_module';
|
import coreModule from './core_module';
|
||||||
|
|
||||||
|
|||||||
@@ -143,15 +143,28 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
|||||||
}
|
}
|
||||||
// AppConfigCtrl
|
// AppConfigCtrl
|
||||||
case 'app-config-ctrl': {
|
case 'app-config-ctrl': {
|
||||||
return System.import(scope.ctrl.appModel.module).then(function(appModule) {
|
let appModel = scope.ctrl.appModel;
|
||||||
|
return System.import(appModel.module).then(function(appModule) {
|
||||||
return {
|
return {
|
||||||
name: 'app-config-' + scope.ctrl.appModel.appId,
|
name: 'app-config-' + appModel.appId,
|
||||||
bindings: {appModel: "=", appEditCtrl: "="},
|
bindings: {appModel: "=", appEditCtrl: "="},
|
||||||
attrs: {"app-model": "ctrl.appModel", "app-edit-ctrl": "ctrl"},
|
attrs: {"app-model": "ctrl.appModel", "app-edit-ctrl": "ctrl"},
|
||||||
Component: appModule.ConfigCtrl,
|
Component: appModule.ConfigCtrl,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// App Page
|
||||||
|
case 'app-page': {
|
||||||
|
let appModel = scope.ctrl.appModel;
|
||||||
|
return System.import(appModel.module).then(function(appModule) {
|
||||||
|
return {
|
||||||
|
name: 'app-page-' + appModel.appId + '-' + scope.ctrl.page.slug,
|
||||||
|
bindings: {appModel: "="},
|
||||||
|
attrs: {"app-model": "ctrl.appModel"},
|
||||||
|
Component: appModule[scope.ctrl.page.component],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
// Panel
|
// Panel
|
||||||
case 'panel': {
|
case 'panel': {
|
||||||
return loadPanelComponentInfo(scope, attrs);
|
return loadPanelComponentInfo(scope, attrs);
|
||||||
|
|||||||
@@ -1,166 +0,0 @@
|
|||||||
define([
|
|
||||||
'angular',
|
|
||||||
'../core_module',
|
|
||||||
'./bundle_loader',
|
|
||||||
'./dashboard_loaders',
|
|
||||||
], function(angular, coreModule, BundleLoader) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
coreModule.default.config(function($routeProvider, $locationProvider) {
|
|
||||||
$locationProvider.html5Mode(true);
|
|
||||||
|
|
||||||
var loadOrgBundle = new BundleLoader.BundleLoader('app/features/org/all');
|
|
||||||
var loadAppsBundle = new BundleLoader.BundleLoader('app/features/apps/all');
|
|
||||||
|
|
||||||
$routeProvider
|
|
||||||
.when('/', {
|
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
|
||||||
controller : 'LoadDashboardCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
})
|
|
||||||
.when('/dashboard/:type/:slug', {
|
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
|
||||||
controller : 'LoadDashboardCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
})
|
|
||||||
.when('/dashboard-solo/:type/:slug', {
|
|
||||||
templateUrl: 'public/app/features/panel/partials/soloPanel.html',
|
|
||||||
controller : 'SoloPanelCtrl',
|
|
||||||
})
|
|
||||||
.when('/dashboard-import/:file', {
|
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
|
||||||
controller : 'DashFromImportCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
})
|
|
||||||
.when('/dashboard/new', {
|
|
||||||
templateUrl: 'public/app/partials/dashboard.html',
|
|
||||||
controller : 'NewDashboardCtrl',
|
|
||||||
reloadOnSearch: false,
|
|
||||||
})
|
|
||||||
.when('/import/dashboard', {
|
|
||||||
templateUrl: 'public/app/features/dashboard/partials/import.html',
|
|
||||||
controller : 'DashboardImportCtrl',
|
|
||||||
})
|
|
||||||
.when('/datasources', {
|
|
||||||
templateUrl: 'public/app/features/datasources/partials/list.html',
|
|
||||||
controller : 'DataSourcesCtrl',
|
|
||||||
resolve: loadOrgBundle,
|
|
||||||
})
|
|
||||||
.when('/datasources/edit/:id', {
|
|
||||||
templateUrl: 'public/app/features/datasources/partials/edit.html',
|
|
||||||
controller : 'DataSourceEditCtrl',
|
|
||||||
resolve: loadOrgBundle,
|
|
||||||
})
|
|
||||||
.when('/datasources/new', {
|
|
||||||
templateUrl: 'public/app/features/datasources/partials/edit.html',
|
|
||||||
controller : 'DataSourceEditCtrl',
|
|
||||||
resolve: loadOrgBundle,
|
|
||||||
})
|
|
||||||
.when('/org', {
|
|
||||||
templateUrl: 'public/app/features/org/partials/orgDetails.html',
|
|
||||||
controller : 'OrgDetailsCtrl',
|
|
||||||
resolve: loadOrgBundle,
|
|
||||||
})
|
|
||||||
.when('/org/new', {
|
|
||||||
templateUrl: 'public/app/features/org/partials/newOrg.html',
|
|
||||||
controller : 'NewOrgCtrl',
|
|
||||||
resolve: loadOrgBundle,
|
|
||||||
})
|
|
||||||
.when('/org/users', {
|
|
||||||
templateUrl: 'public/app/features/org/partials/orgUsers.html',
|
|
||||||
controller : 'OrgUsersCtrl',
|
|
||||||
resolve: loadOrgBundle,
|
|
||||||
})
|
|
||||||
.when('/org/apikeys', {
|
|
||||||
templateUrl: 'public/app/features/org/partials/orgApiKeys.html',
|
|
||||||
controller : 'OrgApiKeysCtrl',
|
|
||||||
resolve: loadOrgBundle,
|
|
||||||
})
|
|
||||||
.when('/profile', {
|
|
||||||
templateUrl: 'public/app/features/profile/partials/profile.html',
|
|
||||||
controller : 'ProfileCtrl',
|
|
||||||
})
|
|
||||||
.when('/profile/password', {
|
|
||||||
templateUrl: 'public/app/features/profile/partials/password.html',
|
|
||||||
controller : 'ChangePasswordCtrl',
|
|
||||||
})
|
|
||||||
.when('/profile/select-org', {
|
|
||||||
templateUrl: 'public/app/features/profile/partials/select_org.html',
|
|
||||||
controller : 'SelectOrgCtrl',
|
|
||||||
})
|
|
||||||
.when('/admin/settings', {
|
|
||||||
templateUrl: 'public/app/features/admin/partials/settings.html',
|
|
||||||
controller : 'AdminSettingsCtrl',
|
|
||||||
})
|
|
||||||
.when('/admin/users', {
|
|
||||||
templateUrl: 'public/app/features/admin/partials/users.html',
|
|
||||||
controller : 'AdminListUsersCtrl',
|
|
||||||
})
|
|
||||||
.when('/admin/users/create', {
|
|
||||||
templateUrl: 'public/app/features/admin/partials/new_user.html',
|
|
||||||
controller : 'AdminEditUserCtrl',
|
|
||||||
})
|
|
||||||
.when('/admin/users/edit/:id', {
|
|
||||||
templateUrl: 'public/app/features/admin/partials/edit_user.html',
|
|
||||||
controller : 'AdminEditUserCtrl',
|
|
||||||
})
|
|
||||||
.when('/admin/orgs', {
|
|
||||||
templateUrl: 'public/app/features/admin/partials/orgs.html',
|
|
||||||
controller : 'AdminListOrgsCtrl',
|
|
||||||
})
|
|
||||||
.when('/admin/orgs/edit/:id', {
|
|
||||||
templateUrl: 'public/app/features/admin/partials/edit_org.html',
|
|
||||||
controller : 'AdminEditOrgCtrl',
|
|
||||||
})
|
|
||||||
.when('/admin/stats', {
|
|
||||||
templateUrl: 'public/app/features/admin/partials/stats.html',
|
|
||||||
controller : 'AdminStatsCtrl',
|
|
||||||
controllerAs: 'ctrl',
|
|
||||||
})
|
|
||||||
.when('/login', {
|
|
||||||
templateUrl: 'public/app/partials/login.html',
|
|
||||||
controller : 'LoginCtrl',
|
|
||||||
})
|
|
||||||
.when('/invite/:code', {
|
|
||||||
templateUrl: 'public/app/partials/signup_invited.html',
|
|
||||||
controller : 'InvitedCtrl',
|
|
||||||
})
|
|
||||||
.when('/signup', {
|
|
||||||
templateUrl: 'public/app/partials/signup_step2.html',
|
|
||||||
controller : 'SignUpCtrl',
|
|
||||||
})
|
|
||||||
.when('/user/password/send-reset-email', {
|
|
||||||
templateUrl: 'public/app/partials/reset_password.html',
|
|
||||||
controller : 'ResetPasswordCtrl',
|
|
||||||
})
|
|
||||||
.when('/user/password/reset', {
|
|
||||||
templateUrl: 'public/app/partials/reset_password.html',
|
|
||||||
controller : 'ResetPasswordCtrl',
|
|
||||||
})
|
|
||||||
.when('/dashboard/snapshots', {
|
|
||||||
templateUrl: 'public/app/features/snapshot/partials/snapshots.html',
|
|
||||||
controller : 'SnapshotsCtrl',
|
|
||||||
controllerAs: 'ctrl',
|
|
||||||
})
|
|
||||||
.when('/apps', {
|
|
||||||
templateUrl: 'public/app/features/apps/partials/list.html',
|
|
||||||
controller: 'AppListCtrl',
|
|
||||||
controllerAs: 'ctrl',
|
|
||||||
resolve: loadAppsBundle,
|
|
||||||
})
|
|
||||||
.when('/apps/edit/:appId', {
|
|
||||||
templateUrl: 'public/app/features/apps/partials/edit.html',
|
|
||||||
controller: 'AppEditCtrl',
|
|
||||||
controllerAs: 'ctrl',
|
|
||||||
resolve: loadAppsBundle,
|
|
||||||
})
|
|
||||||
.when('/global-alerts', {
|
|
||||||
templateUrl: 'public/app/features/dashboard/partials/globalAlerts.html',
|
|
||||||
})
|
|
||||||
.otherwise({
|
|
||||||
templateUrl: 'public/app/partials/error.html',
|
|
||||||
controller: 'ErrorCtrl'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
173
public/app/core/routes/routes.ts
Normal file
173
public/app/core/routes/routes.ts
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import './dashboard_loaders';
|
||||||
|
|
||||||
|
import angular from 'angular';
|
||||||
|
import coreModule from 'app/core/core_module';
|
||||||
|
import {BundleLoader} from './bundle_loader';
|
||||||
|
|
||||||
|
/** @ngInject **/
|
||||||
|
function setupAngularRoutes($routeProvider, $locationProvider) {
|
||||||
|
$locationProvider.html5Mode(true);
|
||||||
|
|
||||||
|
var loadOrgBundle = new BundleLoader('app/features/org/all');
|
||||||
|
var loadAppsBundle = new BundleLoader('app/features/apps/all');
|
||||||
|
|
||||||
|
$routeProvider
|
||||||
|
.when('/', {
|
||||||
|
templateUrl: 'public/app/partials/dashboard.html',
|
||||||
|
controller : 'LoadDashboardCtrl',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
})
|
||||||
|
.when('/dashboard/:type/:slug', {
|
||||||
|
templateUrl: 'public/app/partials/dashboard.html',
|
||||||
|
controller : 'LoadDashboardCtrl',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
})
|
||||||
|
.when('/dashboard-solo/:type/:slug', {
|
||||||
|
templateUrl: 'public/app/features/panel/partials/soloPanel.html',
|
||||||
|
controller : 'SoloPanelCtrl',
|
||||||
|
})
|
||||||
|
.when('/dashboard-import/:file', {
|
||||||
|
templateUrl: 'public/app/partials/dashboard.html',
|
||||||
|
controller : 'DashFromImportCtrl',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
})
|
||||||
|
.when('/dashboard/new', {
|
||||||
|
templateUrl: 'public/app/partials/dashboard.html',
|
||||||
|
controller : 'NewDashboardCtrl',
|
||||||
|
reloadOnSearch: false,
|
||||||
|
})
|
||||||
|
.when('/import/dashboard', {
|
||||||
|
templateUrl: 'public/app/features/dashboard/partials/import.html',
|
||||||
|
controller : 'DashboardImportCtrl',
|
||||||
|
})
|
||||||
|
.when('/datasources', {
|
||||||
|
templateUrl: 'public/app/features/datasources/partials/list.html',
|
||||||
|
controller : 'DataSourcesCtrl',
|
||||||
|
resolve: loadOrgBundle,
|
||||||
|
})
|
||||||
|
.when('/datasources/edit/:id', {
|
||||||
|
templateUrl: 'public/app/features/datasources/partials/edit.html',
|
||||||
|
controller : 'DataSourceEditCtrl',
|
||||||
|
resolve: loadOrgBundle,
|
||||||
|
})
|
||||||
|
.when('/datasources/new', {
|
||||||
|
templateUrl: 'public/app/features/datasources/partials/edit.html',
|
||||||
|
controller : 'DataSourceEditCtrl',
|
||||||
|
resolve: loadOrgBundle,
|
||||||
|
})
|
||||||
|
.when('/org', {
|
||||||
|
templateUrl: 'public/app/features/org/partials/orgDetails.html',
|
||||||
|
controller : 'OrgDetailsCtrl',
|
||||||
|
resolve: loadOrgBundle,
|
||||||
|
})
|
||||||
|
.when('/org/new', {
|
||||||
|
templateUrl: 'public/app/features/org/partials/newOrg.html',
|
||||||
|
controller : 'NewOrgCtrl',
|
||||||
|
resolve: loadOrgBundle,
|
||||||
|
})
|
||||||
|
.when('/org/users', {
|
||||||
|
templateUrl: 'public/app/features/org/partials/orgUsers.html',
|
||||||
|
controller : 'OrgUsersCtrl',
|
||||||
|
resolve: loadOrgBundle,
|
||||||
|
})
|
||||||
|
.when('/org/apikeys', {
|
||||||
|
templateUrl: 'public/app/features/org/partials/orgApiKeys.html',
|
||||||
|
controller : 'OrgApiKeysCtrl',
|
||||||
|
resolve: loadOrgBundle,
|
||||||
|
})
|
||||||
|
.when('/profile', {
|
||||||
|
templateUrl: 'public/app/features/profile/partials/profile.html',
|
||||||
|
controller : 'ProfileCtrl',
|
||||||
|
})
|
||||||
|
.when('/profile/password', {
|
||||||
|
templateUrl: 'public/app/features/profile/partials/password.html',
|
||||||
|
controller : 'ChangePasswordCtrl',
|
||||||
|
})
|
||||||
|
.when('/profile/select-org', {
|
||||||
|
templateUrl: 'public/app/features/profile/partials/select_org.html',
|
||||||
|
controller : 'SelectOrgCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/settings', {
|
||||||
|
templateUrl: 'public/app/features/admin/partials/settings.html',
|
||||||
|
controller : 'AdminSettingsCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/users', {
|
||||||
|
templateUrl: 'public/app/features/admin/partials/users.html',
|
||||||
|
controller : 'AdminListUsersCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/users/create', {
|
||||||
|
templateUrl: 'public/app/features/admin/partials/new_user.html',
|
||||||
|
controller : 'AdminEditUserCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/users/edit/:id', {
|
||||||
|
templateUrl: 'public/app/features/admin/partials/edit_user.html',
|
||||||
|
controller : 'AdminEditUserCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/orgs', {
|
||||||
|
templateUrl: 'public/app/features/admin/partials/orgs.html',
|
||||||
|
controller : 'AdminListOrgsCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/orgs/edit/:id', {
|
||||||
|
templateUrl: 'public/app/features/admin/partials/edit_org.html',
|
||||||
|
controller : 'AdminEditOrgCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/stats', {
|
||||||
|
templateUrl: 'public/app/features/admin/partials/stats.html',
|
||||||
|
controller : 'AdminStatsCtrl',
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
})
|
||||||
|
.when('/login', {
|
||||||
|
templateUrl: 'public/app/partials/login.html',
|
||||||
|
controller : 'LoginCtrl',
|
||||||
|
})
|
||||||
|
.when('/invite/:code', {
|
||||||
|
templateUrl: 'public/app/partials/signup_invited.html',
|
||||||
|
controller : 'InvitedCtrl',
|
||||||
|
})
|
||||||
|
.when('/signup', {
|
||||||
|
templateUrl: 'public/app/partials/signup_step2.html',
|
||||||
|
controller : 'SignUpCtrl',
|
||||||
|
})
|
||||||
|
.when('/user/password/send-reset-email', {
|
||||||
|
templateUrl: 'public/app/partials/reset_password.html',
|
||||||
|
controller : 'ResetPasswordCtrl',
|
||||||
|
})
|
||||||
|
.when('/user/password/reset', {
|
||||||
|
templateUrl: 'public/app/partials/reset_password.html',
|
||||||
|
controller : 'ResetPasswordCtrl',
|
||||||
|
})
|
||||||
|
.when('/dashboard/snapshots', {
|
||||||
|
templateUrl: 'public/app/features/snapshot/partials/snapshots.html',
|
||||||
|
controller : 'SnapshotsCtrl',
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
})
|
||||||
|
.when('/apps', {
|
||||||
|
templateUrl: 'public/app/features/apps/partials/list.html',
|
||||||
|
controller: 'AppListCtrl',
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
resolve: loadAppsBundle,
|
||||||
|
})
|
||||||
|
.when('/apps/:appId/edit', {
|
||||||
|
templateUrl: 'public/app/features/apps/partials/edit.html',
|
||||||
|
controller: 'AppEditCtrl',
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
resolve: loadAppsBundle,
|
||||||
|
})
|
||||||
|
.when('/apps/:appId/page/:slug', {
|
||||||
|
templateUrl: 'public/app/features/apps/partials/page.html',
|
||||||
|
controller: 'AppPageCtrl',
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
resolve: loadAppsBundle,
|
||||||
|
})
|
||||||
|
.when('/global-alerts', {
|
||||||
|
templateUrl: 'public/app/features/dashboard/partials/globalAlerts.html',
|
||||||
|
})
|
||||||
|
.otherwise({
|
||||||
|
templateUrl: 'public/app/partials/error.html',
|
||||||
|
controller: 'ErrorCtrl'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
coreModule.config(setupAngularRoutes);
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
import './edit_ctrl';
|
import './edit_ctrl';
|
||||||
|
import './page_ctrl';
|
||||||
import './list_ctrl';
|
import './list_ctrl';
|
||||||
|
|||||||
@@ -5,19 +5,21 @@ import _ from 'lodash';
|
|||||||
|
|
||||||
export class AppEditCtrl {
|
export class AppEditCtrl {
|
||||||
appModel: any;
|
appModel: any;
|
||||||
|
appId: any;
|
||||||
includedPanels: any;
|
includedPanels: any;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private backendSrv: any, private $routeParams: any) {
|
constructor(private backendSrv: any, private $routeParams: any) {
|
||||||
this.appModel = {};
|
this.appModel = {};
|
||||||
|
this.appId = $routeParams.appId;
|
||||||
|
|
||||||
this.backendSrv.get(`/api/org/apps/${this.$routeParams.appId}/settings`).then(result => {
|
this.backendSrv.get(`/api/org/apps/${this.appId}/settings`).then(result => {
|
||||||
this.appModel = result;
|
this.appModel = result;
|
||||||
this.includedPanels = _.where(result.includes, {type: 'panel'});
|
this.includedPanels = _.where(result.includes, {type: 'panel'});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update(options) {
|
update() {
|
||||||
var updateCmd = _.extend({
|
var updateCmd = _.extend({
|
||||||
appId: this.appModel.appId,
|
appId: this.appModel.appId,
|
||||||
orgId: this.appModel.orgId,
|
orgId: this.appModel.orgId,
|
||||||
@@ -25,19 +27,19 @@ export class AppEditCtrl {
|
|||||||
pinned: this.appModel.pinned,
|
pinned: this.appModel.pinned,
|
||||||
jsonData: this.appModel.jsonData,
|
jsonData: this.appModel.jsonData,
|
||||||
secureJsonData: this.appModel.secureJsonData,
|
secureJsonData: this.appModel.secureJsonData,
|
||||||
}, options);
|
}, {});
|
||||||
|
|
||||||
this.backendSrv.post(`/api/org/apps/${this.$routeParams.appId}/settings`, updateCmd).then(function() {
|
this.backendSrv.post(`/api/org/apps/${this.appId}/settings`, updateCmd).then(function() {
|
||||||
window.location.href = window.location.href;
|
window.location.href = window.location.href;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleEnabled() {
|
toggleEnabled() {
|
||||||
this.update({enabled: this.appModel.enabled});
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
togglePinned() {
|
togglePinned() {
|
||||||
this.update({pinned: this.appModel.pinned});
|
this.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ export class AppListCtrl {
|
|||||||
apps: any[];
|
apps: any[];
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private backendSrv: any) {}
|
constructor(private backendSrv: any) {
|
||||||
|
|
||||||
init() {
|
|
||||||
this.backendSrv.get('api/org/apps').then(apps => {
|
this.backendSrv.get('api/org/apps').then(apps => {
|
||||||
this.apps = apps;
|
this.apps = apps;
|
||||||
});
|
});
|
||||||
|
|||||||
26
public/app/features/apps/page_ctrl.ts
Normal file
26
public/app/features/apps/page_ctrl.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import angular from 'angular';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export class AppPageCtrl {
|
||||||
|
page: any;
|
||||||
|
appId: any;
|
||||||
|
appModel: any;
|
||||||
|
|
||||||
|
/** @ngInject */
|
||||||
|
constructor(private backendSrv, private $routeParams: any, private $rootScope) {
|
||||||
|
this.appId = $routeParams.appId;
|
||||||
|
|
||||||
|
this.backendSrv.get(`/api/org/apps/${this.appId}/settings`).then(app => {
|
||||||
|
this.appModel = app;
|
||||||
|
this.page = _.findWhere(app.pages, {slug: this.$routeParams.slug});
|
||||||
|
if (!this.page) {
|
||||||
|
$rootScope.appEvent('alert-error', ['App Page Not Found', '']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
angular.module('grafana.controllers').controller('AppPageCtrl', AppPageCtrl);
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li ng-repeat="page in ctrl.appModel.pages">
|
<li ng-repeat="page in ctrl.appModel.pages">
|
||||||
<a href="{{page.url}}" class="external-link">{{page.name}}</a>
|
<a href="apps/{{ctrl.appId}}/page/{{page.slug}}" class="external-link">{{page.name}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
</navbar>
|
</navbar>
|
||||||
|
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<div class="page-wide" ng-init="ctrl.init()">
|
<div class="page-wide">
|
||||||
<h1>Apps</h1>
|
<h1>Apps</h1>
|
||||||
|
|
||||||
<div ng-if="!ctrl.apps">
|
<div ng-if="!ctrl.apps">
|
||||||
@@ -18,13 +18,13 @@
|
|||||||
<li>
|
<li>
|
||||||
<div class="filter-list-card-controls">
|
<div class="filter-list-card-controls">
|
||||||
<div class="filter-list-card-config">
|
<div class="filter-list-card-config">
|
||||||
<a href="apps/edit/{{app.appId}}">
|
<a href="apps/{{app.appId}}/edit">
|
||||||
<i class="fa fa-cog"></i>
|
<i class="fa fa-cog"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="filter-list-card-title">
|
<span class="filter-list-card-title">
|
||||||
<a href="apps/edit/{{app.appId}}">
|
<a href="apps/{{app.appId}}/edit">
|
||||||
{{app.name}}
|
{{app.name}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|||||||
17
public/app/features/apps/partials/page.html
Normal file
17
public/app/features/apps/partials/page.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<navbar icon="fa fa-fw fa-cubes" title="{{ctrl.appModel.name}}" title-url="apps/{{ctrl.appId}}/edit" subnav="true">
|
||||||
|
<ul class="nav">
|
||||||
|
<li class="active"><a href="apps/{{ctrl.appId}}/ctrl.page.slug">{{ctrl.page.name}}</a></li>
|
||||||
|
</ul>
|
||||||
|
</navbar>
|
||||||
|
|
||||||
|
<div class="page-container">
|
||||||
|
<div class="page-wide">
|
||||||
|
<h1>{{ctrl.page.name}}</h1>
|
||||||
|
|
||||||
|
<div ng-if="ctrl.page">
|
||||||
|
<plugin-component type="app-page">
|
||||||
|
</plugin-component>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -84,7 +84,6 @@
|
|||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border: 1px solid lighten(@btnInverseBackground, 10%);
|
border: 1px solid lighten(@btnInverseBackground, 10%);
|
||||||
color: @grayLight;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,8 @@
|
|||||||
.top-nav-menu-btn {
|
.top-nav-menu-btn {
|
||||||
a {
|
a {
|
||||||
background-color: @sideMenuBackground;
|
background-color: @sideMenuBackground;
|
||||||
padding-right: 46px;
|
padding-right: 54px;
|
||||||
padding-left: 24px;
|
padding-left: 16px;
|
||||||
}
|
}
|
||||||
.icon-gf-grafana_wordmark {
|
.icon-gf-grafana_wordmark {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -88,6 +88,7 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-circle {
|
.icon-circle {
|
||||||
@@ -111,9 +112,8 @@
|
|||||||
.sidemenu-item {
|
.sidemenu-item {
|
||||||
color: @linkColor;
|
color: @linkColor;
|
||||||
line-height: 47px;
|
line-height: 47px;
|
||||||
padding: 0px 10px 0px 20px;
|
padding: 0px 10px 0px 10px;
|
||||||
display: block;
|
display: block;
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: @sideMenuBackgroundHighlight;
|
background-color: @sideMenuBackgroundHighlight;
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
.sidemenu-org {
|
.sidemenu-org {
|
||||||
border-bottom: @sideMenuBorder;
|
border-bottom: @sideMenuBorder;
|
||||||
border-top: @sideMenuBorder;
|
border-top: @sideMenuBorder;
|
||||||
padding: 17px 10px 15px 21px;
|
padding: 17px 10px 15px 14px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
window.grafanaBootData = {
|
window.grafanaBootData = {
|
||||||
user:[[.User]],
|
user:[[.User]],
|
||||||
settings: [[.Settings]],
|
settings: [[.Settings]],
|
||||||
pluginModules: [[.PluginModules]],
|
|
||||||
mainNavLinks: [[.MainNavLinks]]
|
mainNavLinks: [[.MainNavLinks]]
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user