diff --git a/pkg/api/api.go b/pkg/api/api.go
index c91779cb193..f16f85e7c8f 100644
--- a/pkg/api/api.go
+++ b/pkg/api/api.go
@@ -41,6 +41,7 @@ func (hs *HttpServer) registerRoutes() {
r.Get("/org/users/", reqSignedIn, Index)
r.Get("/org/apikeys/", reqSignedIn, Index)
r.Get("/dashboard/import/", reqSignedIn, Index)
+ r.Get("/configuration", reqGrafanaAdmin, Index)
r.Get("/admin", reqGrafanaAdmin, Index)
r.Get("/admin/settings", reqGrafanaAdmin, Index)
r.Get("/admin/users", reqGrafanaAdmin, Index)
diff --git a/pkg/api/avatar/avatar.go b/pkg/api/avatar/avatar.go
index 41ce857db4f..69926bce492 100644
--- a/pkg/api/avatar/avatar.go
+++ b/pkg/api/avatar/avatar.go
@@ -146,7 +146,7 @@ func CacheServer() http.Handler {
}
func newNotFound() *Avatar {
- avatar := &Avatar{}
+ avatar := &Avatar{notFound: true}
// load transparent png into buffer
path := filepath.Join(setting.StaticRootPath, "img", "transparent.png")
diff --git a/pkg/api/index.go b/pkg/api/index.go
index db8e51db9af..3afff3bb144 100644
--- a/pkg/api/index.go
+++ b/pkg/api/index.go
@@ -124,28 +124,6 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
})
}
- if c.OrgRole == m.ROLE_ADMIN {
- data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
- Text: "Data Sources",
- Icon: "icon-gf icon-gf-datasources",
- Url: setting.AppSubUrl + "/datasources",
- Children: []*dtos.NavLink{
- {Text: "List", Url: setting.AppSubUrl + "/datasources", Icon: "icon-gf icon-gf-datasources"},
- {Text: "New", Url: setting.AppSubUrl + "/datasources", Icon: "fa fa-fw fa-plus"},
- },
- })
- data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
- Text: "Plugins",
- Icon: "icon-gf icon-gf-apps",
- Url: setting.AppSubUrl + "/plugins",
- Children: []*dtos.NavLink{
- {Text: "Panels", Url: setting.AppSubUrl + "/plugins?type=panel", Icon: "fa fa-fw fa-stop"},
- {Text: "Data sources", Url: setting.AppSubUrl + "/plugins?type=datasource", Icon: "icon-gf icon-gf-datasources"},
- {Text: "Apps", Url: setting.AppSubUrl + "/plugins?type=app", Icon: "icon-gf icon-gf-apps"},
- },
- })
- }
-
enabledPlugins, err := plugins.GetEnabledPlugins(c.OrgId)
if err != nil {
return nil, err
@@ -192,18 +170,49 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
}
}
- if c.IsGrafanaAdmin {
- data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
- Text: "Admin",
+ if c.OrgRole == m.ROLE_ADMIN {
+ cfgNode := &dtos.NavLink{
+ Text: "Configuration",
Icon: "fa fa-fw fa-cogs",
- Url: setting.AppSubUrl + "/admin",
+ Url: setting.AppSubUrl + "/configuration",
Children: []*dtos.NavLink{
- {Text: "Global Users", Url: setting.AppSubUrl + "/admin/users"},
- {Text: "Global Orgs", Url: setting.AppSubUrl + "/admin/orgs"},
- {Text: "Server Settings", Url: setting.AppSubUrl + "/admin/settings"},
- {Text: "Server Stats", Url: setting.AppSubUrl + "/admin/stats"},
+ {
+ Text: "Data Sources",
+ Icon: "icon-gf icon-gf-datasources",
+ Url: setting.AppSubUrl + "/datasources",
+ Children: []*dtos.NavLink{
+ {Text: "List", Url: setting.AppSubUrl + "/datasources", Icon: "icon-gf icon-gf-datasources"},
+ {Text: "New", Url: setting.AppSubUrl + "/datasources", Icon: "fa fa-fw fa-plus"},
+ },
+ },
+ {
+ Text: "Plugins",
+ Icon: "icon-gf icon-gf-apps",
+ Url: setting.AppSubUrl + "/plugins",
+ Children: []*dtos.NavLink{
+ {Text: "Panels", Url: setting.AppSubUrl + "/plugins?type=panel", Icon: "fa fa-fw fa-stop"},
+ {Text: "Data sources", Url: setting.AppSubUrl + "/plugins?type=datasource", Icon: "icon-gf icon-gf-datasources"},
+ {Text: "Apps", Url: setting.AppSubUrl + "/plugins?type=app", Icon: "icon-gf icon-gf-apps"},
+ },
+ },
},
- })
+ }
+
+ if c.IsGrafanaAdmin {
+ cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{
+ Text: "Server Admin",
+ Icon: "fa fa-fw fa-shield",
+ Url: setting.AppSubUrl + "/admin",
+ Children: []*dtos.NavLink{
+ {Text: "Global Users", Url: setting.AppSubUrl + "/admin/users"},
+ {Text: "Global Orgs", Url: setting.AppSubUrl + "/admin/orgs"},
+ {Text: "Server Settings", Url: setting.AppSubUrl + "/admin/settings"},
+ {Text: "Server Stats", Url: setting.AppSubUrl + "/admin/stats"},
+ },
+ })
+ }
+
+ data.MainNavLinks = append(data.MainNavLinks, cfgNode)
}
return &data, nil
diff --git a/public/app/core/components/sidemenu/sidemenu.html b/public/app/core/components/sidemenu/sidemenu.html
index bc22d6cfb4e..55611dab103 100644
--- a/public/app/core/components/sidemenu/sidemenu.html
+++ b/public/app/core/components/sidemenu/sidemenu.html
@@ -1,77 +1,89 @@
-
-
-
-
-
+
-
+
diff --git a/public/app/core/components/sidemenu/sidemenu.ts b/public/app/core/components/sidemenu/sidemenu.ts
index 923b080ed92..e371429dc91 100644
--- a/public/app/core/components/sidemenu/sidemenu.ts
+++ b/public/app/core/components/sidemenu/sidemenu.ts
@@ -10,7 +10,7 @@ export class SideMenuCtrl {
showSignout: boolean;
user: any;
mainLinks: any;
- orgMenu: any;
+ userMenu: any;
appSubUrl: string;
loginUrl: string;
orgFilter: string;
@@ -49,40 +49,39 @@ export class SideMenuCtrl {
}
openUserDropdown() {
- this.orgMenu = [
- {section: 'You', cssClass: 'dropdown-menu-title'},
- {text: 'Profile', url: this.getUrl('/profile')},
- ];
+ this.userMenu = [ ];
if (this.showSignout) {
- this.orgMenu.push({text: "Sign out", url: this.getUrl("/logout"), target: "_self"});
+ this.userMenu.push({text: "Sign out", url: this.getUrl("/logout"), target: "_self", icon: 'fa fa-sign-out'});
}
- if (this.contextSrv.hasRole('Admin')) {
- this.orgMenu.push({section: this.user.orgName, cssClass: 'dropdown-menu-title'});
- this.orgMenu.push({
- text: "Preferences",
- url: this.getUrl("/org")
- });
- this.orgMenu.push({
- text: "Users",
- url: this.getUrl("/org/users")
- });
- this.orgMenu.push({
- text: "User Groups",
- url: this.getUrl("/org/user-groups")
- });
- this.orgMenu.push({
- text: "API Keys",
- url: this.getUrl("/org/apikeys")
- });
- }
+ this.userMenu.push({text: 'Profile', url: this.getUrl('/profile'), icon: 'fa fa-user'});
- this.orgMenu.push({cssClass: "divider"});
- this.backendSrv.get('/api/user/orgs').then(orgs => {
- this.orgs = orgs;
- this.loadOrgsItems();
- });
+ // if (this.contextSrv.hasRole('Admin')) {
+ // this.orgMenu.push({section: this.user.orgName, cssClass: 'dropdown-menu-title'});
+ // this.orgMenu.push({
+ // text: "Preferences",
+ // url: this.getUrl("/org")
+ // });
+ // this.orgMenu.push({
+ // text: "Users",
+ // url: this.getUrl("/org/users")
+ // });
+ // this.orgMenu.push({
+ // text: "User Groups",
+ // url: this.getUrl("/org/user-groups")
+ // });
+ // this.orgMenu.push({
+ // text: "API Keys",
+ // url: this.getUrl("/org/apikeys")
+ // });
+ // }
+
+ // this.orgMenu.push({cssClass: "divider"});
+ // this.backendSrv.get('/api/user/orgs').then(orgs => {
+ // this.orgs = orgs;
+ // this.loadOrgsItems();
+ // });
}
loadOrgsItems(){
diff --git a/public/app/core/routes/routes.ts b/public/app/core/routes/routes.ts
index 0bf0a03bf7a..8999df32d7f 100644
--- a/public/app/core/routes/routes.ts
+++ b/public/app/core/routes/routes.ts
@@ -44,6 +44,12 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
templateUrl: 'public/app/features/dashboard/partials/dash_list.html',
controller : 'DashListCtrl',
})
+ .when('/configuration', {
+ templateUrl: 'public/app/features/admin/partials/configuration_home.html',
+ controller : 'ConfigurationHomeCtrl',
+ controllerAs: 'ctrl',
+ resolve: loadAdminBundle,
+ })
.when('/datasources', {
templateUrl: 'public/app/features/plugins/partials/ds_list.html',
controller : 'DataSourcesCtrl',
diff --git a/public/app/features/admin/admin.ts b/public/app/features/admin/admin.ts
index 669e4a9c982..75af2f41506 100644
--- a/public/app/features/admin/admin.ts
+++ b/public/app/features/admin/admin.ts
@@ -2,6 +2,7 @@ import AdminListUsersCtrl from './admin_list_users_ctrl';
import './adminListOrgsCtrl';
import './adminEditOrgCtrl';
import './adminEditUserCtrl';
+import './configuration_home_ctrl';
import coreModule from 'app/core/core_module';
@@ -42,6 +43,16 @@ export class AdminStatsCtrl {
}
}
+export class ConfigurationHomeCtrl {
+ navModel: any;
+
+ /** @ngInject */
+ constructor(private $scope, private backendSrv, private navModelSrv) {
+ this.navModel = navModelSrv.getAdminNav();
+ }
+}
+
+coreModule.controller('ConfigurationHomeCtrl', ConfigurationHomeCtrl);
coreModule.controller('AdminSettingsCtrl', AdminSettingsCtrl);
coreModule.controller('AdminHomeCtrl', AdminHomeCtrl);
coreModule.controller('AdminStatsCtrl', AdminStatsCtrl);
diff --git a/public/app/features/admin/partials/configuration_home.html b/public/app/features/admin/partials/configuration_home.html
new file mode 100644
index 00000000000..6008ca6bda9
--- /dev/null
+++ b/public/app/features/admin/partials/configuration_home.html
@@ -0,0 +1,48 @@
+
+
+
diff --git a/public/sass/_variables.scss b/public/sass/_variables.scss
index c80bbf9148f..204fcc5a8b1 100644
--- a/public/sass/_variables.scss
+++ b/public/sass/_variables.scss
@@ -219,7 +219,7 @@ $btn-padding-y-lg: .75rem !default;
$btn-border-radius: 2px;
// sidemenu
-$side-menu-width: 68px;
+$side-menu-width: 60px;
// dashboard
$panel-margin: 0.4rem;
diff --git a/public/sass/components/_dropdown.scss b/public/sass/components/_dropdown.scss
index 8dee2bcc2b9..3e4ed5cfd09 100644
--- a/public/sass/components/_dropdown.scss
+++ b/public/sass/components/_dropdown.scss
@@ -217,7 +217,7 @@
// Different positioning for bottom up menu
.dropdown-menu {
top: auto;
- bottom: 100%;
+ bottom: 0;
margin-bottom: 1px;
}
}
diff --git a/public/sass/components/_navbar.scss b/public/sass/components/_navbar.scss
index 357b2be3ce0..c4cb51cf6a4 100644
--- a/public/sass/components/_navbar.scss
+++ b/public/sass/components/_navbar.scss
@@ -59,7 +59,7 @@
display: block;
margin-bottom: 3rem;
background-color: $side-menu-bg;
- padding: 0.4rem 1.0rem 0.4rem 1rem;
+ padding: 0.4rem 1.0rem 0.4rem 0.65rem;
min-height: $navbarHeight;
.fa-caret-down {
diff --git a/public/sass/components/_scrollbar.scss b/public/sass/components/_scrollbar.scss
index b16acb75475..78cbd6cb18a 100644
--- a/public/sass/components/_scrollbar.scss
+++ b/public/sass/components/_scrollbar.scss
@@ -107,9 +107,9 @@
}
-// // Srollbars
-// //
+// Srollbars
//
+
// ::-webkit-scrollbar {
// width: 8px;
// height: 8px;
diff --git a/public/sass/components/_sidemenu.scss b/public/sass/components/_sidemenu.scss
index 65e3e8d52da..8fb6845881f 100644
--- a/public/sass/components/_sidemenu.scss
+++ b/public/sass/components/_sidemenu.scss
@@ -12,34 +12,62 @@
}
.sidemenu {
- list-style: none;
- margin: 0;
- padding: 0;
+ display: flex;
+ flex-flow: column;
+}
- > li {
- position: relative;
- @include left-brand-border();
+.sidemenu__top {
+ flex-grow: 1;
+}
- &.active,
- &:hover {
- background-color: $side-menu-item-hover-bg;
- @include left-brand-border-gradient();
+.sidemenu__bottom {
+ padding-bottom: $spacer;
+}
- .dropdown-menu {
- margin: 0;
- display: block;
- opacity: 0;
- top: 0px;
- // important to overlap it otherwise it can be hidden
- // again by the mouse getting outside the hover space
- left: $side-menu-width - 2px;
- @include animation('dropdown-anim 0ms ease-in-out 0ms forwards');
- z-index: -9999;
- }
+.sidemenu-item {
+ position: relative;
+ @include left-brand-border();
+
+ &.active,
+ &:hover {
+ background-color: $side-menu-item-hover-bg;
+ @include left-brand-border-gradient();
+
+ .dropdown-menu {
+ margin: 0;
+ display: block;
+ opacity: 0;
+ top: 0px;
+ // important to overlap it otherwise it can be hidden
+ // again by the mouse getting outside the hover space
+ left: $side-menu-width - 2px;
+ @include animation('dropdown-anim 0ms ease-in-out 0ms forwards');
+ z-index: 1;
}
}
}
+.dropup.sidemenu-item:hover .dropdown-menu {
+ top: auto !important;
+}
+
+.sidemenu-link {
+ color: $link-color;
+ line-height: 42px;
+ padding: 0px 10px 0px 10px;
+ display: block;
+ position: relative;
+ font-size: 16px;
+ border: 1px solid transparent;
+
+ img {
+ border-radius: 50%;
+ width: 28px;
+ height: 28px;
+ box-shadow: 0 0 14px 2px rgba(255,255,255, 0.05);
+ }
+}
+
@include keyframes(dropdown-anim) {
0% {
opacity: 0;
@@ -59,7 +87,7 @@
color: $link-color;
opacity: .7;
position: relative;
- left: 7px;
+ left: 3px;
font-size: 130%;
}
@@ -72,67 +100,17 @@
}
img {
- left: 7px;
+ left: 3px;
position: relative;
}
}
-.sidemenu-item {
- color: $link-color;
- line-height: 42px;
- padding: 0px 10px 0px 10px;
- display: block;
- position: relative;
- font-size: 16px;
- border: 1px solid transparent;
-
- img {
- border-radius: 50%;
- width: 28px;
- height: 28px;
- box-shadow: 0 0 14px 2px rgba(255,255,255, 0.05);
- }
-}
-
.side-menu-header {
padding: 10px 10px 10px 20px;
white-space: nowrap;
background-color: $side-menu-item-hover-bg;
- font-size: 18px;
-}
-
-.sidemenu-org-section .dropdown-menu-title {
- margin: 0 10px 0 6px;
- padding: 7px 0 7px;
- overflow: hidden;
- color: $dropdownTitle;
-}
-
-.sidemenu-org-section .dropdown-menu-title > span {
- display: inline-block;
- position: relative;
-
- &::after {
- display: block;
- position: absolute;
- top: 50%;
- right: 0;
- left: 100%;
- width: 200px;
- height: 1px;
- margin-left: 5px;
- background: $dropdownDivider;
- content: '';
- }
-}
-
-.sidemenu-org {
- padding: 17px 10px 15px 14px;
- box-sizing: border-box;
- cursor: pointer;
- display: table;
- position: relative;
- width: 100%;
+ font-size: 17px;
+ font-weight: normal;
}
.sidemenu .fa-caret-right {
@@ -143,20 +121,14 @@
color: $text-color-faint;
}
-.sidemenu-org-avatar,
-.sidemenu-org-details {
- display: table-cell;
- vertical-align: top;
-}
-
.sidemenu-org-avatar {
>img {
position: absolute;
- width: 35px;
- height: 35px;
+ width: 30px;
+ height: 30px;
border-radius: 50%;
left: 14px;
- top: 12px;
+ top: 6px;
z-index: 10;
}
}
@@ -168,19 +140,3 @@
font-size: $font-size-lg;
}
-.sidemenu-org-details {
- padding-left: 10px;
- color: $link-color;
- display: none;
-}
-
-.sidemenu-org-name {
- display: block;
- font-size: 13px;
- color: $link-color-disabled;
-}
-
-.sidemenu-org-user {
- display: block;
-}
-
diff --git a/public/views/index.html b/public/views/index.html
index ad47baa3465..7fa2f0fa1e2 100644
--- a/public/views/index.html
+++ b/public/views/index.html
@@ -25,7 +25,7 @@
-
+