Commit 1acbd5b7 by Torkel Ödegaard

:merge branch 'app-pages'

Conflicts:
	examples/nginx-app/module.js
	examples/nginx-app/partials/stream.html
	examples/nginx-app/plugin.json
parents 397e4e47 f0ecbd38
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,
}; };
}); });
<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 @@ ...@@ -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": {
......
...@@ -12,8 +12,8 @@ type AppSettings struct { ...@@ -12,8 +12,8 @@ type AppSettings struct {
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"`
} }
......
...@@ -23,4 +23,5 @@ type NavLink struct { ...@@ -23,4 +23,5 @@ type NavLink struct {
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) { ...@@ -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,21 +81,26 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) { ...@@ -86,21 +81,26 @@ 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)
}
} }
return &data, nil return &data, nil
......
...@@ -4,13 +4,15 @@ import ( ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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
......
<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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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'; ...@@ -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, $ ...@@ -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);
......
define([ ///<reference path="../../headers/common.d.ts" />
'angular',
'../core_module',
'./bundle_loader',
'./dashboard_loaders',
], function(angular, coreModule, BundleLoader) {
"use strict";
coreModule.default.config(function($routeProvider, $locationProvider) { 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); $locationProvider.html5Mode(true);
var loadOrgBundle = new BundleLoader.BundleLoader('app/features/org/all'); var loadOrgBundle = new BundleLoader('app/features/org/all');
var loadAppsBundle = new BundleLoader.BundleLoader('app/features/apps/all'); var loadAppsBundle = new BundleLoader('app/features/apps/all');
$routeProvider $routeProvider
.when('/', { .when('/', {
...@@ -148,12 +149,18 @@ define([ ...@@ -148,12 +149,18 @@ define([
controllerAs: 'ctrl', controllerAs: 'ctrl',
resolve: loadAppsBundle, resolve: loadAppsBundle,
}) })
.when('/apps/edit/:appId', { .when('/apps/:appId/edit', {
templateUrl: 'public/app/features/apps/partials/edit.html', templateUrl: 'public/app/features/apps/partials/edit.html',
controller: 'AppEditCtrl', controller: 'AppEditCtrl',
controllerAs: 'ctrl', controllerAs: 'ctrl',
resolve: loadAppsBundle, resolve: loadAppsBundle,
}) })
.when('/apps/:appId/page/:slug', {
templateUrl: 'public/app/features/apps/partials/page.html',
controller: 'AppPageCtrl',
controllerAs: 'ctrl',
resolve: loadAppsBundle,
})
.when('/global-alerts', { .when('/global-alerts', {
templateUrl: 'public/app/features/dashboard/partials/globalAlerts.html', templateUrl: 'public/app/features/dashboard/partials/globalAlerts.html',
}) })
...@@ -161,6 +168,6 @@ define([ ...@@ -161,6 +168,6 @@ define([
templateUrl: 'public/app/partials/error.html', templateUrl: 'public/app/partials/error.html',
controller: 'ErrorCtrl' controller: 'ErrorCtrl'
}); });
}); }
}); coreModule.config(setupAngularRoutes);
import './edit_ctrl'; import './edit_ctrl';
import './page_ctrl';
import './list_ctrl'; import './list_ctrl';
...@@ -5,19 +5,21 @@ import _ from 'lodash'; ...@@ -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 { ...@@ -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 { ...@@ -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;
}); });
......
///<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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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>
&nbsp; &nbsp; &nbsp; &nbsp;
......
<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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -50,7 +50,6 @@
window.grafanaBootData = { window.grafanaBootData = {
user:[[.User]], user:[[.User]],
settings: [[.Settings]], settings: [[.Settings]],
pluginModules: [[.PluginModules]],
mainNavLinks: [[.MainNavLinks]] mainNavLinks: [[.MainNavLinks]]
}; };
</script> </script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment