Commit c14a90a3 by Torkel Ödegaard

A lot of work on new organization selection and sidenav dropdown, #1506

parent 528f5415
...@@ -9,7 +9,7 @@ function (angular, _, $, config) { ...@@ -9,7 +9,7 @@ function (angular, _, $, config) {
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('SideMenuCtrl', function($scope, $location, contextSrv) { module.controller('SideMenuCtrl', function($scope, $location, contextSrv, backendSrv) {
$scope.getUrl = function(url) { $scope.getUrl = function(url) {
return config.appSubUrl + url; return config.appSubUrl + url;
...@@ -29,35 +29,57 @@ function (angular, _, $, config) { ...@@ -29,35 +29,57 @@ function (angular, _, $, config) {
href: $scope.getUrl("/datasources"), href: $scope.getUrl("/datasources"),
}); });
} }
};
if (contextSrv.user.isSignedIn) { $scope.loadOrgs = function() {
$scope.bottomLinks.push({ $scope.orgMenu = [];
text: contextSrv.user.name,
imgSrc: contextSrv.user.gravatarUrl,
href: $scope.getUrl("/profile"),
});
$scope.bottomLinks.push({ if (contextSrv.hasRole('Admin')) {
text: contextSrv.user.orgName, $scope.orgMenu.push({
text: "Organization settings",
href: $scope.getUrl("/org"), href: $scope.getUrl("/org"),
icon: "fa fa-fw fa-users",
}); });
$scope.orgMenu.push({
if (contextSrv.hasRole('Admin')) { text: "Users",
$scope.bottomLinks.push({ href: $scope.getUrl("/org/users"),
text: "Grafana admin", });
icon: "fa fa-fw fa-cog", $scope.orgMenu.push({
href: $scope.getUrl("/admin/settings"), text: "API Keys",
href: $scope.getUrl("/org/apikeys"),
}); });
} }
$scope.bottomLinks.push({ if ($scope.orgMenu.length > 0) {
text: "Sign out", $scope.orgMenu.push({ cssClass: 'divider' });
target: "_self", }
icon: "fa fa-fw fa-sign-out",
href: $scope.getUrl("/logout"), backendSrv.get('/api/user/orgs').then(function(orgs) {
}); _.each(orgs, function(org) {
if (org.isUsing) {
return;
}
$scope.orgMenu.push({
text: "Switch to " + org.name,
icon: "fa fa-fw fa-random",
click: function() {
$scope.switchOrg(org.orgId);
} }
});
});
$scope.orgMenu.push({
text: "New Organization",
icon: "fa fa-fw fa-plus",
href: $scope.getUrl('/org/new')
});
});
};
$scope.switchOrg = function(orgId) {
backendSrv.post('/api/user/using/' + orgId).then(function() {
window.location.href = $scope.getUrl('/');
});
}; };
$scope.setupAdminNav = function() { $scope.setupAdminNav = function() {
...@@ -81,25 +103,12 @@ function (angular, _, $, config) { ...@@ -81,25 +103,12 @@ function (angular, _, $, config) {
icon: "fa fa-fw fa-users", icon: "fa fa-fw fa-users",
href: $scope.getUrl("/admin/orgs"), href: $scope.getUrl("/admin/orgs"),
}); });
$scope.bottomLinks.push({
text: "Exit admin",
icon: "fa fa-fw fa-backward",
href: $scope.getUrl("/"),
});
$scope.bottomLinks.push({
text: "Sign out",
icon: "fa fa-fw fa-sign-out",
target: "_self",
href: $scope.getUrl("/logout"),
});
}; };
$scope.updateMenu = function() { $scope.updateMenu = function() {
$scope.systemSection = false; $scope.systemSection = false;
$scope.mainLinks = []; $scope.mainLinks = [];
$scope.bottomLinks = []; $scope.orgMenu = [];
var currentPath = $location.path(); var currentPath = $location.path();
if (currentPath.indexOf('/admin') === 0) { if (currentPath.indexOf('/admin') === 0) {
......
...@@ -2,6 +2,7 @@ define([ ...@@ -2,6 +2,7 @@ define([
'./datasourcesCtrl', './datasourcesCtrl',
'./datasourceEditCtrl', './datasourceEditCtrl',
'./orgUsersCtrl', './orgUsersCtrl',
'./newOrgCtrl',
'./orgApiKeysCtrl', './orgApiKeysCtrl',
'./orgDetailsCtrl', './orgDetailsCtrl',
], function () {}); ], function () {});
define([
'angular',
],
function (angular) {
'use strict';
var module = angular.module('grafana.controllers');
module.controller('NewOrgCtrl', function($scope, $http, backendSrv) {
$scope.newOrg = {name: ''};
$scope.createOrg = function() {
backendSrv.post('/api/org/', $scope.newOrg).then($scope.getUserOrgs);
};
});
});
<topnav title="Organization" icon="fa fa-fw fa-users" subnav="true">
<ul class="nav">
<li class="active"><a href="org/new">New organization</a></li>
</ul>
</topnav>
<div class="page-container">
<div class="page">
<h2 style="margin-top: 30px;">Add Organization</h2>
<form name="form">
<div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px;">
<strong>Org. name</strong>
</li>
<li>
<input type="text" ng-model="newOrg.name" required class="input-xxlarge tight-form-input last" placeholder="organization name">
</li>
<li>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
<br>
<button class="btn btn-success pull-right" ng-click="createOrg()">Create</button>
</form>
</div>
</div>
<topnav title="API Keys" <topnav icon="fa fa-fw fa-users" title="Organization" subnav="true">
icon="fa fa-shield" <ul class="nav">
section="Account"> <li class="active"><a href="org/apikeys">API Keys</a></li>
</ul>
</topnav> </topnav>
<div class="gf-box" style="min-height: 500px"> <div class="page-container">
<div class="gf-box-body"> <div class="page">
<div class="editor-row">
<div class="section"> <h2>
<form name="addTokenrForm" class="form-inline tight-form"> API Keys
</h2>
<form name="addTokenrForm" class="form-inline tight-form last">
<ul class="tight-form-list"> <ul class="tight-form-list">
<li class="tight-form-item"> <li class="tight-form-item" style="width: 100px">
Add a key Add a key
</li> </li>
<li> <li>
...@@ -21,15 +25,14 @@ ...@@ -21,15 +25,14 @@
<li> <li>
<select class="input-small tight-form-input" ng-model="token.role" ng-options="r for r in roleTypes"></select> <select class="input-small tight-form-input" ng-model="token.role" ng-options="r for r in roleTypes"></select>
</li> </li>
<li style="float: right">
<button class="btn btn-success tight-form-btn" ng-click="addToken()">Add</button> <button class="btn btn-success tight-form-btn" ng-click="addToken()">Add</button>
</li> </li>
</ul>
<div class="clearfix"></div> <div class="clearfix"></div>
</ul>
</form> </form>
</div> <br>
<div class="editor-row row">
<div class="section span6">
<table class="grafana-options-table"> <table class="grafana-options-table">
<tr ng-repeat="t in tokens"> <tr ng-repeat="t in tokens">
<td>{{t.name}}</td> <td>{{t.name}}</td>
...@@ -43,9 +46,7 @@ ...@@ -43,9 +46,7 @@
</tr> </tr>
</table> </table>
</div> </div>
</div>
</div>
</div>
</div>
<topnav icon="fa fa-fw fa-users" title="Organization" subnav="true"> <topnav icon="fa fa-fw fa-users" title="Organization" subnav="true">
<ul class="nav"> <ul class="nav">
<li class="active"><a href="org">Overview</a></li> <li class="active"><a href="org">Info</a></li>
<li><a href="org/users">Users</a></li>
</ul> </ul>
</topnav> </topnav>
<div class="page-container"> <div class="page-container">
<div class="page"> <div class="page">
<h2>Organization Details</h2> <h2>Organization info</h2>
<form name="orgForm"> <form name="orgForm">
<div> <div>
<div class="tight-form"> <div class="tight-form">
<ul class="tight-form-list"> <ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px"> <li class="tight-form-item" style="width: 100px">
<strong>Name</strong> <strong>Org. name</strong>
</li> </li>
<li> <li>
<input type="text" required ng-model="org.name" class="input-xxlarge tight-form-input last" > <input type="text" required ng-model="org.name" class="input-xxlarge tight-form-input last" >
...@@ -23,51 +22,44 @@ ...@@ -23,51 +22,44 @@
</ul> </ul>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> <div class="tight-form">
<br>
<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
</form>
<h2>
API Keys
</h2>
<div ng-controller="OrgApiKeysCtrl">
<form name="addTokenrForm" class="form-inline tight-form last">
<ul class="tight-form-list"> <ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px"> <li class="tight-form-item" style="width: 100px">
Add a key <strong>Address 1</strong>
</li> </li>
<li> <li>
<input type="text" class="input-xlarge tight-form-input" ng-model='token.name' placeholder="Name"></input> <input type="text" required ng-model="org.address1" class="input-xxlarge tight-form-input last" >
</li> </li>
<li class="tight-form-item"> </ul>
Role <div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px">
<strong>Address 2</strong>
</li> </li>
<li> <li>
<select class="input-small tight-form-input" ng-model="token.role" ng-options="r for r in roleTypes"></select> <input type="text" required ng-model="org.address2" class="input-xxlarge tight-form-input last" >
</li>
<li style="float: right">
<button class="btn btn-success tight-form-btn" ng-click="addToken()">Add</button>
</li> </li>
</ul>
<div class="clearfix"></div> <div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px">
<strong>City</strong>
</li>
<li>
<input type="text" required ng-model="org.city" class="input-xxlarge tight-form-input last" >
</li>
</ul> </ul>
</form> <div class="clearfix"></div>
<br> </div>
<table class="grafana-options-table">
<tr ng-repeat="t in tokens">
<td>{{t.name}}</td>
<td>{{t.role}}</td>
<td>{{t.key}}</td>
<td style="width: 1%">
<a ng-click="removeToken(t.id)" class="btn btn-danger btn-mini">
<i class="fa fa-remove"></i>
</a>
</td>
</tr>
</table>
</div> </div>
<br>
<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
</form>
</div> </div>
</div> </div>
......
<topnav title="Organization" icon="fa fa-fw fa-users" subnav="true"> <topnav title="Organization" icon="fa fa-fw fa-users" subnav="true">
<ul class="nav"> <ul class="nav">
<li><a href="org">Overview</a></li>
<li class="active"><a href="org/users">Users</a></li> <li class="active"><a href="org/users">Users</a></li>
</ul> </ul>
</topnav> </topnav>
......
<topnav title="{{contextSrv.user.name}}" section="Profile" icon="fa fa-user" subnav="true"> <topnav title="{{contextSrv.user.name}}" section="Profile" icon="fa fw fa-user" subnav="true">
<ul class="nav"> <ul class="nav">
<li class="active"><a href="profile">Overview</a></li> <li class="active"><a href="profile">Overview</a></li>
<li><a href="profile/password">Change password</a></li> <li><a href="profile/password">Change password</a></li>
...@@ -68,28 +68,6 @@ ...@@ -68,28 +68,6 @@
</tr> </tr>
</table> </table>
<h2 style="margin-top: 30px;">Add Organization</h2>
<form name="form">
<div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px;">
<strong>Org. name</strong>
</li>
<li>
<input type="text" ng-model="newOrg.name" required class="input-xxlarge tight-form-input last" placeholder="organization name">
</li>
<li>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
<br>
<button class="btn btn-success pull-right" ng-click="createOrg()">Create</button>
</form>
</div> </div>
</div> </div>
...@@ -9,8 +9,6 @@ function (angular, config) { ...@@ -9,8 +9,6 @@ function (angular, config) {
module.controller('ProfileCtrl', function($scope, backendSrv) { module.controller('ProfileCtrl', function($scope, backendSrv) {
$scope.newOrg = {name: ''};
$scope.init = function() { $scope.init = function() {
$scope.getUser(); $scope.getUser();
$scope.getUserOrgs(); $scope.getUserOrgs();
...@@ -39,10 +37,6 @@ function (angular, config) { ...@@ -39,10 +37,6 @@ function (angular, config) {
backendSrv.put('/api/user/', $scope.user); backendSrv.put('/api/user/', $scope.user);
}; };
$scope.createOrg = function() {
backendSrv.post('/api/org/', $scope.newOrg).then($scope.getUserOrgs);
};
$scope.init(); $scope.init();
}); });
......
<div ng-controller="SideMenuCtrl" ng-init="init()"> <div ng-controller="SideMenuCtrl" ng-init="init()">
<ul class="sidemenu sidemenu-main"> <ul class="sidemenu sidemenu-main">
...@@ -27,13 +26,65 @@ ...@@ -27,13 +26,65 @@
</li> </li>
</ul> </ul>
<ul class="sidemenu sidemenu-small" style="margin-top:50px"> <ul class="sidemenu sidemenu-small" style="margin-top:50px" ng-if="!systemSection">
<li ng-repeat="item in bottomLinks">
<a href="{{item.href}}" class="sidemenu-item" target="{{item.target}}"> <li>
<img ng-if="item.imgSrc" ng-src="{{item.imgSrc}}"> <a href="profile" class="sidemenu-item">
<span class="icon-circle sidemenu-icon" ng-if="item.icon"><i class="{{item.icon}}"></i></span> <img ng-src="{{contextSrv.user.gravatarUrl}}">
<span class="sidemenu-item-text">{{item.text}}</span> <span class="sidemenu-item-text">{{contextSrv.user.name}}</span>
</a>
</li>
<li class="dropdown">
<a class="sidemenu-item pointer" data-toggle="dropdown" ng-click="loadOrgs()">
<span class="icon-circle sidemenu-icon"><i class="fa fa-fw fa-users"></i></span>
<span class="sidemenu-item-text">
{{contextSrv.user.orgName}}
<i class="fa fa-caret-down small"></i>
</span>
</a>
<ul class="dropdown-menu" role="menu" style="left: 65px">
<li ng-repeat="menuItem in orgMenu" ng-class="menuItem.cssClass">
<a href="{{menuItem.href}}" ng-if="menuItem.href">
<i class="{{menuItem.icon}}" ng-if="menuItem.icon"></i>
{{menuItem.text}}
</a>
<a ng-click="menuItem.click()" ng-if="menuItem.click">
<i class="{{menuItem.icon}}"></i>
{{menuItem.text}}
</a>
</li>
</ul>
</li>
<li ng-if="contextSrv.isGrafanaAdmin">
<a href="admin/settings" class="sidemenu-item">
<span class="icon-circle sidemenu-icon"><i class="fa fa-fw fa-cog"></i></span>
<span class="sidemenu-item-text">Grafana admin</span>
</a>
</li>
<li>
<a href="logout" class="sidemenu-item" target="_self">
<span class="icon-circle sidemenu-icon"><i class="fa fa-fw fa-sign-out"></i></span>
<span class="sidemenu-item-text">Sign out</span>
</a>
</li>
</ul>
<ul class="sidemenu sidemenu-small" style="margin-top:50px" ng-if="systemSection">
<li>
<a href="{{appSubUrl}}/" class="sidemenu-item">
<span class="icon-circle sidemenu-icon"><i class="fa fa-fw fa-backward"></i></span>
<span class="sidemenu-item-text">Exit admin</span>
</a>
</li>
<li>
<a href="logout" class="sidemenu-item" target="_self">
<span class="icon-circle sidemenu-icon"><i class="fa fa-fw fa-sign-out"></i></span>
<span class="sidemenu-item-text">Sign out</span>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
...@@ -50,13 +50,17 @@ define([ ...@@ -50,13 +50,17 @@ define([
templateUrl: 'app/features/org/partials/orgDetails.html', templateUrl: 'app/features/org/partials/orgDetails.html',
controller : 'OrgDetailsCtrl', controller : 'OrgDetailsCtrl',
}) })
.when('/org/new', {
templateUrl: 'app/features/org/partials/newOrg.html',
controller : 'NewOrgCtrl',
})
.when('/org/users', { .when('/org/users', {
templateUrl: 'app/features/org/partials/orgUsers.html', templateUrl: 'app/features/org/partials/orgUsers.html',
controller : 'OrgUsersCtrl', controller : 'OrgUsersCtrl',
}) })
.when('/org/apikeys', { .when('/org/apikeys', {
templateUrl: 'app/features/org/partials/orgApiKeys.html', templateUrl: 'app/features/org/partials/orgApiKeys.html',
controller : 'ApiKeysCtrl', controller : 'OrgApiKeysCtrl',
}) })
.when('/profile', { .when('/profile', {
templateUrl: 'app/features/profile/partials/profile.html', templateUrl: 'app/features/profile/partials/profile.html',
......
...@@ -20,6 +20,8 @@ function (angular, _, store) { ...@@ -20,6 +20,8 @@ function (angular, _, store) {
this.version = grafanaVersion; this.version = grafanaVersion;
this.lightTheme = false; this.lightTheme = false;
this.user = new User(); this.user = new User();
this.isSignedIn = this.user.isSignedIn;
this.isGrafanaAdmin = this.user.isGrafanaAdmin;
this.sidemenu = store.getBool('grafana.sidemenu'); this.sidemenu = store.getBool('grafana.sidemenu');
// events // events
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
li { >li {
margin-bottom: 9px; margin-bottom: 9px;
} }
......
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
@dropdownBackground: @heroUnitBackground; @dropdownBackground: @heroUnitBackground;
@dropdownBorder: rgba(0,0,0,.2); @dropdownBorder: rgba(0,0,0,.2);
@dropdownDividerTop: transparent; @dropdownDividerTop: transparent;
@dropdownDividerBottom: #222; @dropdownDividerBottom: #444;
@dropdownLinkColor: @textColor; @dropdownLinkColor: @textColor;
@dropdownLinkColorHover: @white; @dropdownLinkColorHover: @white;
......
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