mirror of
https://github.com/grafana/grafana.git
synced 2024-11-23 09:26:43 -06:00
ux: making org visibile in profile view
This commit is contained in:
parent
7f0f0eb617
commit
95f5c84a57
134
'
Normal file
134
'
Normal file
@ -0,0 +1,134 @@
|
||||
|
||||
|
||||
.sidemenu {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
flex-direction: column;
|
||||
width: $side-menu-width;
|
||||
background-color: $side-menu-bg;
|
||||
z-index: 1;
|
||||
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu__top {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.sidemenu__bottom {
|
||||
padding-bottom: $spacer;
|
||||
}
|
||||
|
||||
.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 100ms ease-in-out 100ms 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;
|
||||
//transform: translate3d(-5%,0,0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
//transform: translate3d(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-circle {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
display: inline-block;
|
||||
i {
|
||||
color: $link-color;
|
||||
opacity: .7;
|
||||
position: relative;
|
||||
left: 3px;
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
.fa {
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.icon-gf {
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
img {
|
||||
left: 3px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.side-menu-header {
|
||||
padding: 10px 10px 10px 20px;
|
||||
white-space: nowrap;
|
||||
background-color: $side-menu-item-hover-bg;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
li.sidemenu-org-switcher {
|
||||
border-bottom: 1px solid $dropdownDividerBottom;
|
||||
}
|
||||
|
||||
.sidemenu-org-switcher__org-name {
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
|
||||
.sidemenu-org-switcher__org-current {
|
||||
font-size: $font-size-xs;
|
||||
color: $text-color-weak;
|
||||
}
|
||||
|
||||
.sidemenu-org-switcher__switch {
|
||||
font-size: $font-size-sm;
|
||||
padding-left: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
i.fa > {
|
||||
margin-right: 5px;
|
||||
top: 0;
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ type CurrentUser struct {
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
LightTheme bool `json:"lightTheme"`
|
||||
OrgCount int `json:"orgCount"`
|
||||
OrgId int64 `json:"orgId"`
|
||||
OrgName string `json:"orgName"`
|
||||
OrgRole m.RoleType `json:"orgRole"`
|
||||
|
@ -141,7 +141,6 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
|
||||
"alertingEnabled": setting.AlertingEnabled,
|
||||
"googleAnalyticsId": setting.GoogleAnalyticsId,
|
||||
"disableLoginForm": setting.DisableLoginForm,
|
||||
"disableSignoutMenu": setting.DisableSignoutMenu,
|
||||
"externalUserMngInfo": setting.ExternalUserMngInfo,
|
||||
"externalUserMngLinkUrl": setting.ExternalUserMngLinkUrl,
|
||||
"externalUserMngLinkName": setting.ExternalUserMngLinkName,
|
||||
|
@ -50,6 +50,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
||||
Login: c.Login,
|
||||
Email: c.Email,
|
||||
Name: c.Name,
|
||||
OrgCount: c.OrgCount,
|
||||
OrgId: c.OrgId,
|
||||
OrgName: c.OrgName,
|
||||
OrgRole: c.OrgRole,
|
||||
@ -86,9 +87,9 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
||||
|
||||
if c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR {
|
||||
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
||||
Text: "New",
|
||||
Text: "Create",
|
||||
Icon: "fa fa-fw fa-plus",
|
||||
Url: "",
|
||||
Url: "#",
|
||||
Children: []*dtos.NavLink{
|
||||
{Text: "Dashboard", Icon: "fa fa-fw fa-plus", Url: setting.AppSubUrl + "/dashboard/new"},
|
||||
{Text: "Folder", Icon: "fa fa-fw fa-plus", Url: setting.AppSubUrl + "/dashboard/new/?editview=new-folder"},
|
||||
@ -112,17 +113,33 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
||||
})
|
||||
|
||||
if c.IsSignedIn {
|
||||
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
||||
profileNode := &dtos.NavLink{
|
||||
Text: c.SignedInUser.Login,
|
||||
Id: "profile",
|
||||
Img: data.User.GravatarUrl,
|
||||
Url: setting.AppSubUrl + "/profile",
|
||||
HideFromMenu: true,
|
||||
Children: []*dtos.NavLink{
|
||||
{Text: "Signout", Url: setting.AppSubUrl + "/logout", Icon: "fa fa-fw fa-sign-out", Target: "_self"},
|
||||
{Text: "Your profile", Url: setting.AppSubUrl + "/profile", Icon: "fa fa-fw fa-sliders"},
|
||||
{Text: "Change Password", Id: "change-password", Url: setting.AppSubUrl + "/profile/password", Icon: "fa fa-fw fa-lock", HideFromMenu: true},
|
||||
},
|
||||
}
|
||||
|
||||
if !setting.DisableSignoutMenu {
|
||||
// add sign out first
|
||||
profileNode.Children = append([]*dtos.NavLink{
|
||||
{Text: "Sign out", Url: setting.AppSubUrl + "/logout", Icon: "fa fa-fw fa-sign-out", Target: "_self"},
|
||||
}, profileNode.Children...)
|
||||
}
|
||||
|
||||
data.NavTree = append(data.NavTree, profileNode)
|
||||
} else {
|
||||
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
||||
Text: "Sign in",
|
||||
Id: "sign-in",
|
||||
Icon: "fa fa-fw fa-sign-in",
|
||||
Url: setting.AppSubUrl + "/login",
|
||||
HideFromMenu: true,
|
||||
})
|
||||
}
|
||||
|
||||
@ -226,7 +243,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Text: "User Management",
|
||||
Text: "Users",
|
||||
Id: "users",
|
||||
Description: "Manage users & user groups",
|
||||
Icon: "fa fa-fw fa-users",
|
||||
@ -258,21 +275,22 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
||||
})
|
||||
}
|
||||
|
||||
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
||||
Text: "Help",
|
||||
Id: "help",
|
||||
Url: "/help",
|
||||
Icon: "fa fa-fw fa-question",
|
||||
HideFromMenu: true,
|
||||
Children: []*dtos.NavLink{
|
||||
{Text: "Shortcuts", Url: "/shortcuts", Icon: "fa fa-fw fa-keyboard-o", Target: "_self"},
|
||||
{Text: "Community site", Url: "http://community.grafana.com", Icon: "fa fa-fw fa-comment", Target: "_blank"},
|
||||
{Text: "Documentation", Url: "http://docs.grafana.org", Icon: "fa fa-fw fa-file", Target: "_blank"},
|
||||
},
|
||||
})
|
||||
data.NavTree = append(data.NavTree, cfgNode)
|
||||
}
|
||||
|
||||
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
||||
Text: "Help",
|
||||
Id: "help",
|
||||
Url: "#",
|
||||
Icon: "fa fa-fw fa-question",
|
||||
HideFromMenu: true,
|
||||
Children: []*dtos.NavLink{
|
||||
{Text: "Keyboard shortcuts", Url: "/shortcuts", Icon: "fa fa-fw fa-keyboard-o", Target: "_self"},
|
||||
{Text: "Community site", Url: "http://community.grafana.com", Icon: "fa fa-fw fa-comment", Target: "_blank"},
|
||||
{Text: "Documentation", Url: "http://docs.grafana.org", Icon: "fa fa-fw fa-file", Target: "_blank"},
|
||||
},
|
||||
})
|
||||
|
||||
return &data, nil
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,7 @@ type SignedInUser struct {
|
||||
Name string
|
||||
Email string
|
||||
ApiKeyId int64
|
||||
OrgCount int
|
||||
IsGrafanaAdmin bool
|
||||
HelpFlags1 HelpFlags1
|
||||
LastSeenAt time.Time
|
||||
|
@ -350,6 +350,7 @@ func GetSignedInUser(query *m.GetSignedInUserQuery) error {
|
||||
u.name as name,
|
||||
u.help_flags1 as help_flags1,
|
||||
u.last_seen_at as last_seen_at,
|
||||
(SELECT COUNT(*) FROM org_user where org_user.user_id = u.id) as org_count,
|
||||
org.name as org_name,
|
||||
org_user.role as org_role,
|
||||
org.id as org_id
|
||||
|
@ -11,7 +11,6 @@ export class NavbarCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $rootScope, private contextSrv) {
|
||||
console.log(this.model);
|
||||
}
|
||||
|
||||
showSearch() {
|
||||
|
@ -36,7 +36,16 @@
|
||||
<img ng-src="{{::item.img}}" ng-show="::item.img">
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu--sidemenu" role="menu" ng-if="::item.children">
|
||||
<ul class="dropdown-menu dropdown-menu--sidemenu" role="menu">
|
||||
<li ng-if="item.showOrgSwitcher" class="sidemenu-org-switcher">
|
||||
<a ng-click="ctrl.switchOrg()">
|
||||
<div>
|
||||
<div class="sidemenu-org-switcher__org-name">{{ctrl.contextSrv.user.orgName}}</div>
|
||||
<div class="sidemenu-org-switcher__org-current">Current Org:</div>
|
||||
</div>
|
||||
<div class="sidemenu-org-switcher__switch"><i class="fa fa-fw fa-random"></i>Switch</div>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-repeat="child in ::item.children" ng-class="{divider: child.divider}" ng-hide="::child.hideFromMenu">
|
||||
<a href="{{::child.url}}" target="{{::child.target}}">
|
||||
<i class="{{::child.icon}}" ng-show="::child.icon"></i>
|
||||
|
@ -6,7 +6,6 @@ import $ from 'jquery';
|
||||
import coreModule from '../../core_module';
|
||||
|
||||
export class SideMenuCtrl {
|
||||
isSignedIn: boolean;
|
||||
user: any;
|
||||
mainLinks: any;
|
||||
bottomNav: any;
|
||||
@ -19,7 +18,6 @@ export class SideMenuCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $rootScope, private $location, private contextSrv, private backendSrv, private $element) {
|
||||
this.isSignedIn = contextSrv.isSignedIn;
|
||||
this.user = contextSrv.user;
|
||||
this.appSubUrl = config.appSubUrl;
|
||||
this.maxShownOrgs = 10;
|
||||
@ -27,6 +25,13 @@ export class SideMenuCtrl {
|
||||
this.bottomNav = _.filter(config.bootData.navTree, item => item.hideFromMenu);
|
||||
this.loginUrl = 'login?redirect=' + encodeURIComponent(this.$location.path());
|
||||
|
||||
if (contextSrv.user.orgCount > 1) {
|
||||
let profileNode = _.find(this.bottomNav, {id: 'profile'});
|
||||
if (profileNode) {
|
||||
profileNode.showOrgSwitcher = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.$scope.$on('$routeChangeSuccess', () => {
|
||||
if (!this.contextSrv.pinned) {
|
||||
this.contextSrv.sidemenu = false;
|
||||
@ -44,60 +49,6 @@ export class SideMenuCtrl {
|
||||
search() {
|
||||
this.$rootScope.appEvent('show-dash-search');
|
||||
}
|
||||
|
||||
openUserDropdown() {
|
||||
|
||||
// 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(){
|
||||
this.orgItems = [];
|
||||
this.orgs.forEach(org => {
|
||||
if (org.orgId === this.contextSrv.user.orgId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.orgItems.length === this.maxShownOrgs) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.orgFilter === '' || (org.name.toLowerCase().indexOf(this.orgFilter.toLowerCase()) !== -1)) {
|
||||
this.orgItems.push({
|
||||
text: "Switch to " + org.name,
|
||||
icon: "fa fa-fw fa-random",
|
||||
url: this.getUrl('/profile/switch-org/' + org.orgId),
|
||||
target: '_self'
|
||||
});
|
||||
}
|
||||
});
|
||||
if (config.allowOrgCreate) {
|
||||
this.orgItems.push({text: "New organization", icon: "fa fa-fw fa-plus", url: this.getUrl('/org/new')});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function sideMenuDirective() {
|
||||
|
@ -6,7 +6,6 @@
|
||||
</div>
|
||||
|
||||
<section class="card-section card-list-layout-grid">
|
||||
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="navItem in ctrl.navModel.node.children">
|
||||
<a class="card-item" ng-href="{{::navItem.url}}">
|
||||
|
@ -120,6 +120,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--sidemenu {
|
||||
li.sidemenu-org-switcher {
|
||||
> a {
|
||||
padding: 8px 10px 8px 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item-text {
|
||||
|
@ -38,7 +38,7 @@
|
||||
// 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');
|
||||
@include animation('dropdown-anim 100ms ease-in-out 100ms forwards');
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
@ -68,11 +68,11 @@
|
||||
@include keyframes(dropdown-anim) {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translate3d(-5%,0,0);
|
||||
//transform: translate3d(-5%,0,0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translate3d(0,0,0);
|
||||
//transform: translate3d(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,30 +109,28 @@
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.sidemenu .fa-caret-right {
|
||||
position: absolute;
|
||||
top: 38%;
|
||||
right: 6px;
|
||||
font-size: 14px;
|
||||
color: $text-color-faint;
|
||||
li.sidemenu-org-switcher {
|
||||
border-bottom: 1px solid $dropdownDividerBottom;
|
||||
}
|
||||
|
||||
.sidemenu-org-avatar {
|
||||
>img {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
left: 14px;
|
||||
top: 6px;
|
||||
z-index: 10;
|
||||
.sidemenu-org-switcher__org-name {
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
|
||||
.sidemenu-org-switcher__org-current {
|
||||
font-size: $font-size-xs;
|
||||
color: $text-color-weak;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.sidemenu-org-switcher__switch {
|
||||
font-size: $font-size-sm;
|
||||
padding-left: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> i.fa.fa-random {
|
||||
margin-right: 4px;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu-org-avatar--missing {
|
||||
color: $gray-4;
|
||||
text-shadow: 0 1px 0 $dark-1;
|
||||
line-height: 28px;
|
||||
font-size: $font-size-lg;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user