Commit dd6a4819a8496f646b10095ecbac9be6d2c3f76a

Authored by Michel Felipe
1 parent f711ee9c

Added feature to sidebar pushing right content on show/hide

src/app/layout/navbar/navbar.ts
... ... @@ -2,6 +2,7 @@ import {Component, Inject, EventEmitter, Input} from "ng-forward";
2 2 import {LanguageSelectorComponent} from "../language-selector/language-selector.component";
3 3 import {SessionService, AuthService, AuthController, AuthEvents} from "./../../login";
4 4 import {SidebarNotificationService} from "../sidebar/sidebar.notification.service";
  5 +import {BodyStateClassesService} from '../services/body-state-classes.service';
5 6  
6 7 @Component({
7 8 selector: "acme-navbar",
... ... @@ -9,7 +10,7 @@ import {SidebarNotificationService} from "../sidebar/sidebar.notification.servic
9 10 directives: [LanguageSelectorComponent],
10 11 providers: [AuthService, SessionService, SidebarNotificationService]
11 12 })
12   -@Inject("$uibModal", AuthService, "SessionService", "$state", SidebarNotificationService)
  13 +@Inject("$uibModal", AuthService, "SessionService", "$state", SidebarNotificationService, BodyStateClassesService)
13 14 export class Navbar {
14 15  
15 16 private currentUser: noosfero.User;
... ... @@ -25,11 +26,13 @@ export class Navbar {
25 26 public authService: AuthService,
26 27 private session: SessionService,
27 28 private $state: ng.ui.IStateService,
28   - private sidebarNotificationService: SidebarNotificationService
  29 + private sidebarNotificationService: SidebarNotificationService,
  30 + private bodyStateService: BodyStateClassesService
29 31 ) {
30 32 this.currentUser = this.session.currentUser();
31 33  
32 34 this.showHamburguer = this.authService.isAuthenticated();
  35 + this.bodyStateService.addContentClass(!this.sidebarNotificationService.sidebarVisible);
33 36  
34 37 this.authService.subscribe(AuthEvents[AuthEvents.loginSuccess], () => {
35 38 if (this.modalInstance) {
... ... @@ -51,6 +54,8 @@ export class Navbar {
51 54  
52 55 public toggleCollapse() {
53 56 this.sidebarNotificationService.alternateVisibility();
  57 +
  58 + this.bodyStateService.addContentClass(!this.sidebarNotificationService.sidebarVisible);
54 59 }
55 60  
56 61 openLogin() {
... ...
src/app/layout/scss/_sidebar.scss
... ... @@ -21,6 +21,8 @@
21 21 position: absolute;
22 22 background: #2c3e50;
23 23 width: 220px;
  24 + border-right: 2px solid #e7ebee;
  25 + height: 200%;
24 26  
25 27 @media (max-width: $break-sm-max) {
26 28 position: relative;
... ... @@ -289,3 +291,17 @@
289 291 color: #fff;
290 292 border-left-color: $primary-color;
291 293 }
  294 +
  295 +#user-left-box {
  296 + .profile-image-wrap {
  297 + float:left;
  298 + width: 70px;
  299 + height: 70px;
  300 + }
  301 + i.profile-image {
  302 + border-radius: 18%;
  303 + border: 3px solid #fff;
  304 + background-color: #fff;
  305 + text-align: center;
  306 + }
  307 +}
... ...
src/app/layout/scss/skins/_whbl.scss 0 → 100644
... ... @@ -0,0 +1,310 @@
  1 +$whbl-nav-col-bg: #ffffff; //f3f5f6
  2 +$whbl-sidebar-linkColor: #484848;
  3 +$whbl-primary-color: #1E96D0; //blue
  4 +$whbl-font-color: #16191c;
  5 +
  6 +.skin-whbl {
  7 + #header-navbar {
  8 + background-color: $whbl-primary-color;
  9 + }
  10 + .navbar > .container .navbar-brand {
  11 + background-color: transparent;
  12 + width: 221px;
  13 + }
  14 + #nav-col,
  15 + #page-wrapper {
  16 + background-color: $whbl-nav-col-bg;
  17 + }
  18 + #sidebar-nav .nav > li > a {
  19 + color: $whbl-sidebar-linkColor;
  20 + /* border-bottom: 1px solid #e7ebee; */
  21 + }
  22 + #sidebar-nav .nav > .open > .submenu > li > .submenu,
  23 + #sidebar-nav .nav > .active > .submenu > li > .submenu,
  24 + #sidebar-nav .nav li .submenu > li.open a,
  25 + #nav-col-submenu .submenu > li > .submenu,
  26 + #nav-col-submenu li .submenu > li.open > a {
  27 + background-color: darken($whbl-nav-col-bg, 8%);
  28 + }
  29 + .nav-pills > li.active > a,
  30 + .nav-pills > li.active > a:hover,
  31 + .nav-pills > li.active > a:focus,
  32 + #sidebar-nav .nav-pills > li.active > a,
  33 + #sidebar-nav .nav-pills > li.active > a:hover,
  34 + #sidebar-nav .nav-pills > li.active > a:focus,
  35 + .nav-pills > li.open > a,
  36 + .nav-pills > li.open > a:hover,
  37 + .nav-pills > li.open > a:focus,
  38 + #sidebar-nav .nav-pills > li.open > a,
  39 + #sidebar-nav .nav-pills > li.open > a:hover,
  40 + #sidebar-nav .nav-pills > li.open > a:focus,
  41 + #sidebar-nav .nav-pills > li > a:focus {
  42 + background-color: darken($whbl-nav-col-bg, 4%);
  43 + border-color: $whbl-primary-color;
  44 + border-bottom-color: #e7ebee;
  45 + color: $whbl-sidebar-linkColor;
  46 + }
  47 + #sidebar-nav .nav-pills > li.active > a > i {
  48 + color: #2980b9;
  49 + }
  50 + #sidebar-nav .nav > li > a:hover {
  51 + background-color: darken($whbl-nav-col-bg, 4%);
  52 + border-color: $whbl-primary-color;
  53 + border-bottom-color: #e7ebee;
  54 + color: $whbl-sidebar-linkColor;
  55 + }
  56 +
  57 + #sidebar-nav .nav > li .submenu li > a:hover {
  58 + color: $whbl-font-color;
  59 + font-weight: bold;
  60 + }
  61 + #header-navbar .nav > li > a {
  62 + color: #fff;
  63 + }
  64 + #header-navbar .nav > li > a:hover,
  65 + #header-navbar .nav > li > a:focus,
  66 + #header-navbar .nav .open > a,
  67 + #header-navbar .nav .open > a:hover,
  68 + #header-navbar .nav .open > a:focus {
  69 + background-color: #2980b9;
  70 + }
  71 + #sidebar-nav .nav li .submenu,
  72 + #nav-col-submenu .submenu {
  73 + background-color: darken($whbl-nav-col-bg, 4%);
  74 + }
  75 + #sidebar-nav .nav li .submenu > li > a,
  76 + .nav-small #nav-col-submenu .submenu > li > a {
  77 + color: $whbl-font-color;
  78 + }
  79 + #sidebar-nav .nav > .open > .submenu > .open > a,
  80 + #sidebar-nav .nav > .active > .submenu > .open > a,
  81 + #sidebar-nav .nav > .active > .submenu > .active > a,
  82 + #nav-col-submenu .submenu > .open > a,
  83 + #nav-col-submenu .submenu > .active > a {
  84 + border-bottom-color: transparent;
  85 + box-shadow: 0 -1px 0 transparent inset;
  86 + }
  87 + #sidebar-nav .nav > .open > .submenu > .open > a {
  88 + border-bottom-color: #dcdfe6;
  89 + box-shadow: none;
  90 + }
  91 + #sidebar-nav .nav li.open > a.dropdown-toggle > .drop-icon,
  92 + #sidebar-nav .nav li.active > a.dropdown-toggle > .drop-icon {
  93 + color: $whbl-font-color;
  94 + }
  95 + #sidebar-nav .nav li .submenu > li > a:hover,
  96 + #sidebar-nav .nav li .submenu > li > a.active,
  97 + #sidebar-nav .nav li .submenu > li.active > a {
  98 + background-color: darken($whbl-nav-col-bg, 8%);
  99 + }
  100 + .navbar > .container .navbar-brand {
  101 + color: #fff;
  102 + }
  103 + .navbar-toggle {
  104 + color: #fff;
  105 + }
  106 + .graph-box {
  107 + background-color: $whbl-primary-color !important;
  108 + }
  109 + .content-wrapper {
  110 + background-color: #f9f9f9;
  111 + height: 100%;
  112 + margin-top: 0;
  113 + margin-bottom: 0;
  114 + position: relative;
  115 + min-height: 1200px;
  116 + padding: 15px 15px 35px 15px;
  117 + margin-left: 220px;
  118 + // border-left: 2px solid #e7ebee;
  119 + }
  120 + #user-left-box {
  121 +
  122 + .user-box {
  123 + color: $whbl-font-color;
  124 + > a {
  125 + color: $whbl-font-color;
  126 + }
  127 + > .name {
  128 + > a {
  129 + color: $whbl-font-color;
  130 +
  131 + &:hover, &:focus {
  132 + color: $whbl-font-color;
  133 + }
  134 + }
  135 + }
  136 + }
  137 + .user-box a:hover,
  138 + .user-box a:focus {
  139 + color: darken($whbl-font-color, 20%);
  140 + }
  141 + }
  142 + #sidebar-nav .nav > li.nav-header {
  143 + border-top-color: #e7ebee;
  144 + color: darken($whbl-nav-col-bg, 35%);
  145 + }
  146 + .nav-tabs {
  147 + background-color: #f9f9f9;
  148 + }
  149 + h1 {
  150 + color: $whbl-primary-color;
  151 + }
  152 + #header-navbar .nav > li > a:hover,
  153 + #header-navbar .nav > li > a:focus,
  154 + #header-navbar .nav .open > a,
  155 + #header-navbar .nav .open > a:hover,
  156 + #header-navbar .nav .open > a:focus,
  157 + .navbar-toggle:hover,
  158 + .navbar-toggle:focus,
  159 + .mobile-search.active > .btn {
  160 + background-color: #2980b9;
  161 + }
  162 + .main-box {
  163 + border: 1px solid $main-bg-color;
  164 + }
  165 + a,
  166 + .fc-state-default,
  167 + .jvectormap-zoomin,
  168 + .jvectormap-zoomout,
  169 + #user-profile .profile-details ul > li > span {
  170 + color: $whbl-primary-color;
  171 + }
  172 + a:hover,
  173 + a:focus,
  174 + .widget-users li > .details > .name > a:hover,
  175 + .widget-todo .actions > a:hover {
  176 + color: $whbl-primary-color;
  177 + }
  178 + .table a.table-link:hover {
  179 + color: #2980b9;
  180 + }
  181 + .pagination {
  182 + > li {
  183 + > a,
  184 + > span,
  185 + > a:hover,
  186 + > span:hover,
  187 + > a:focus,
  188 + > span:focus,
  189 + > a:active,
  190 + > span:active {
  191 + color: $whbl-primary-color;
  192 + }
  193 + }
  194 + > .active {
  195 + > a,
  196 + > span,
  197 + > a:hover,
  198 + > span:hover,
  199 + > a:focus,
  200 + > span:focus {
  201 + background-color: $whbl-primary-color;
  202 + border-color: $whbl-primary-color;
  203 + color: #fff;
  204 + }
  205 + }
  206 + }
  207 + .notifications-list {
  208 + .item-footer {
  209 + background-color: #272d33;
  210 +
  211 + a:hover {
  212 + background-color: #0f1114;
  213 + }
  214 + }
  215 + }
  216 + .btn-primary,
  217 + .btn-default,
  218 + .btn-info,
  219 + .btn-success,
  220 + .btn-warning,
  221 + .btn-danger,
  222 + .btn-primary:hover,
  223 + .btn-default:hover,
  224 + .btn-info:hover,
  225 + .btn-success:hover,
  226 + .btn-warning:hover,
  227 + .btn-danger:hover {
  228 + color: #fff;
  229 + }
  230 + .btn-primary {
  231 + background-color: $whbl-primary-color;
  232 + border-color: #2980b9;
  233 + }
  234 + .btn-primary:hover,
  235 + .btn-primary:focus,
  236 + .btn-primary:active,
  237 + .btn-primary.active,
  238 + .open .dropdown-toggle.btn-primary {
  239 + background-color: #2980b9;
  240 + border-color: #216897;
  241 + }
  242 + .btn-success {
  243 + background-color: $whbl-primary-color;
  244 + border-color: #2980b9;
  245 + }
  246 + .btn-success:hover,
  247 + .btn-success:focus,
  248 + .btn-success:active,
  249 + .btn-success.active,
  250 + .open .dropdown-toggle.btn-success {
  251 + background-color: #2980b9;
  252 + border-color: #1c5c87;
  253 + }
  254 + h1 {
  255 + color: $whbl-primary-color;
  256 + }
  257 + .widget-users li > .details > .time {
  258 + color: $whbl-primary-color;
  259 + }
  260 + blockquote,
  261 + blockquote.pull-right {
  262 + border-color: $whbl-primary-color;
  263 + }
  264 + a.list-group-item.active,
  265 + a.list-group-item.active:hover,
  266 + a.list-group-item.active:focus {
  267 + background-color: $whbl-primary-color;
  268 + border-color: $whbl-primary-color;
  269 + }
  270 + .nav .caret {
  271 + border-bottom-color: $whbl-primary-color;
  272 + border-top-color: $whbl-primary-color;
  273 + }
  274 + .panel-default > .panel-heading,
  275 + .notifications-list .item-footer {
  276 + background-color: $whbl-primary-color;
  277 + }
  278 + .notifications-list .item-footer a:hover {
  279 + background-color: #2980b9;
  280 + }
  281 + #invoice-companies .invoice-dates .invoice-number > span,
  282 + .notifications-list .item a .time {
  283 + color: $whbl-primary-color;
  284 + }
  285 + .table thead > tr > th > a:hover span {
  286 + color: $whbl-primary-color;
  287 + border-color: $whbl-primary-color;
  288 + }
  289 + .pace .pace-progress {
  290 + background-color: #fff;
  291 + }
  292 +}
  293 +.rtl.skin-whbl #content-wrapper {
  294 + border-left: 0;
  295 + border-right: 2px solid #e7ebee;
  296 +}
  297 +
  298 +@media (max-width: $break-sm-max) {
  299 + .skin-whbl {
  300 + #logo.navbar-brand > img.normal-logo.logo-white {
  301 + display: block;
  302 + }
  303 + #logo.navbar-brand > img.normal-logo.logo-black {
  304 + display: none;
  305 + }
  306 + .navbar > .container .navbar-brand {
  307 + background-color: $whbl-primary-color;
  308 + }
  309 + }
  310 +}
... ...
src/app/layout/services/body-state-classes.service.spec.ts
... ... @@ -19,7 +19,9 @@ describe("BodyStateClasses Service", () => {
19 19 },
20 20 authService: any = helpers.mocks.authService,
21 21 bodyEl: { className: string },
22   - bodyElJq: any;
  22 + bodyElJq: any,
  23 + contentWrapperEl: { className: string },
  24 + contentWrapperElJq: any;
23 25  
24 26 let getService = (): BodyStateClassesService => {
25 27 return new BodyStateClassesService($rootScope, $document, $state, authService);
... ... @@ -29,6 +31,9 @@ describe("BodyStateClasses Service", () => {
29 31 authService.isAuthenticated = jasmine.createSpy("isAuthenticated").and.returnValue(true);
30 32 bodyEl = { className: "" };
31 33 bodyElJq = [bodyEl];
  34 +
  35 + contentWrapperEl = { className: "" };
  36 + contentWrapperElJq = [contentWrapperEl];
32 37 });
33 38  
34 39 it("should add the class noosfero-user-logged to the body element if the user is authenticated", () => {
... ... @@ -133,4 +138,43 @@ describe("BodyStateClasses Service", () => {
133 138 // and check now if the bodyEl has a class indicating the new state route
134 139 expect(bodyEl.className).toEqual(BodyStateClassesService.ROUTE_STATE_CLASSNAME_PREFIX + "new-route");
135 140 });
  141 +
  142 + it("add a css class theme skin to body element", () => {
  143 + let service = getService();
  144 + let skinClass: string = 'skin-test';
  145 +
  146 + bodyElJq.addClass = jasmine.createSpy("addClass");
  147 + bodyElJq.removeClass = jasmine.createSpy("removeClass");
  148 + service["bodyElement"] = bodyElJq;
  149 +
  150 + service.start({
  151 + skin: skinClass
  152 + });
  153 +
  154 + expect(bodyElJq.addClass).toHaveBeenCalledWith(skinClass);
  155 + });
  156 +
  157 + it("add a css class to content wrapper element", () => {
  158 + let service = getService();
  159 +
  160 + contentWrapperElJq.addClass = jasmine.createSpy("addClass");
  161 + contentWrapperElJq.removeClass = jasmine.createSpy("removeClass");
  162 +
  163 + service["contentWrapperElement"] = contentWrapperElJq;
  164 + service.addContentClass(true);
  165 +
  166 + expect(contentWrapperElJq.addClass).toHaveBeenCalledWith(BodyStateClassesService.CONTENT_WRAPPER_FULL);
  167 + });
  168 +
  169 + it("remove a css class from content wrapper element", () => {
  170 + let service = getService();
  171 +
  172 + contentWrapperElJq.addClass = jasmine.createSpy("addClass");
  173 + contentWrapperElJq.removeClass = jasmine.createSpy("removeClass");
  174 +
  175 + service["contentWrapperElement"] = contentWrapperElJq;
  176 + service.addContentClass(false);
  177 +
  178 + expect(contentWrapperElJq.removeClass).toHaveBeenCalledWith(BodyStateClassesService.CONTENT_WRAPPER_FULL);
  179 + });
136 180 });
... ...
src/app/layout/services/body-state-classes.service.ts
... ... @@ -2,6 +2,11 @@ import {Directive, Inject, Injectable} from "ng-forward";
2 2 import {AuthEvents} from "./../../login/auth-events";
3 3 import {AuthService} from "./../../login/auth.service";
4 4 import {HtmlUtils} from "../html-utils";
  5 +import {INgForwardJQuery} from 'ng-forward/cjs/util/jqlite-extensions';
  6 +
  7 +export interface StartParams {
  8 + skin?: string;
  9 +}
5 10  
6 11 /**
7 12 * This is a service which adds classes to the body element
... ... @@ -18,11 +23,14 @@ import {HtmlUtils} from "../html-utils";
18 23 export class BodyStateClassesService {
19 24  
20 25 private started: boolean = false;
  26 + private skin: string;
21 27  
22 28 public static get USER_LOGGED_CLASSNAME(): string { return "noosfero-user-logged"; }
23 29 public static get ROUTE_STATE_CLASSNAME_PREFIX(): string { return "noosfero-route-"; }
  30 + public static get CONTENT_WRAPPER_FULL(): string { return "full-content"; }
24 31  
25 32 private bodyElement: ng.IAugmentedJQuery = null;
  33 + private contentWrapperElement: INgForwardJQuery = null;
26 34  
27 35 constructor(
28 36 private $rootScope: ng.IRootScopeService,
... ... @@ -33,14 +41,37 @@ export class BodyStateClassesService {
33 41  
34 42 }
35 43  
36   - start() {
  44 + start(config?: StartParams) {
37 45 if (!this.started) {
38 46 this.setupUserLoggedClassToggle();
39 47 this.setupStateClassToggle();
  48 +
  49 + if (config) {
  50 + this.setThemeSkin(config.skin);
  51 + }
40 52 this.started = true;
41 53 }
42 54 }
43 55  
  56 + setThemeSkin(skin: string) {
  57 + this.getBodyElement().addClass(skin);
  58 + }
  59 +
  60 + addContentClass(addClass: boolean, className?: string): BodyStateClassesService {
  61 +
  62 + let fullContentClass: string = className || BodyStateClassesService.CONTENT_WRAPPER_FULL;
  63 + let contentWrapper = this.getContentWrapper();
  64 +
  65 + if (contentWrapper) {
  66 + if (addClass) {
  67 + contentWrapper.addClass(fullContentClass);
  68 + } else {
  69 + contentWrapper.removeClass(fullContentClass);
  70 + }
  71 + }
  72 + return this;
  73 + }
  74 +
44 75 private getStateChangeSuccessHandlerFunction(bodyElement: ng.IAugmentedJQuery): (event: ng.IAngularEvent, toState: ng.ui.IState) => void {
45 76 let self = this;
46 77 return (event: ng.IAngularEvent, toState: ng.ui.IState) => {
... ... @@ -95,4 +126,15 @@ export class BodyStateClassesService {
95 126 }
96 127 return this.bodyElement;
97 128 }
  129 +
  130 + private getContentWrapper(selector?: string): INgForwardJQuery {
  131 +
  132 + if (this.contentWrapperElement === null) {
  133 +
  134 + let doc = <INgForwardJQuery>angular.element(this.$document);
  135 + this.contentWrapperElement = doc.query(selector || '.content-wrapper');
  136 + }
  137 +
  138 + return this.contentWrapperElement;
  139 + }
98 140 }
... ...
src/app/layout/sidebar/sidebar.component.spec.ts
... ... @@ -2,6 +2,7 @@ import {provide} from &#39;ng-forward&#39;;
2 2 import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper';
3 3 import {providers} from 'ng-forward/cjs/testing/providers';
4 4 import {SidebarComponent} from './sidebar.component';
  5 +import * as helpers from '../../../spec/helpers';
5 6  
6 7 const htmlTemplate: string = '<sidebar [visible]="false"></sidebar>';
7 8  
... ...
src/app/layout/sidebar/sidebar.html
1   -<div id="nav-col" ng-show="ctrl.isVisible">
  1 +<div id="nav-col" ng-show="ctrl.isVisible()" ng-class="{'sidebar-hide':!ctrl.isVisible()}">
2 2 <section id="col-left" class="col-left-nano">
3 3 <div id="col-left-inner" class="col-left-nano-content">
4 4 <div id="user-left-box" class="clearfix hidden-sm hidden-xs dropdown profile2-dropdown">
5   - <noosfero-profile-image [profile]="ctrl.profile"></noosfero-profile-image>
  5 + <noosfero-profile-image [profile]="ctrl.user"></noosfero-profile-image>
6 6 <div class="user-box">
7 7 <span class="name">
8 8 <a href="#" class="dropdown-toggle" data-toggle="dropdown">
9   - Scarlett J.
  9 + {{ctrl.user.name}}
10 10 <i class="fa fa-angle-down"></i>
11 11 </a>
12 12 <ul class="dropdown-menu">
... ...
src/app/layout/sidebar/sidebar.notification.service.ts
... ... @@ -4,7 +4,7 @@ import {Injectable, EventEmitter} from &quot;ng-forward&quot;;
4 4 @Injectable()
5 5 export class SidebarNotificationService {
6 6 private alternateVisibilityEvent: EventEmitter<boolean> = new EventEmitter<boolean>();
7   - private sidebarVisible: boolean = false;
  7 + public sidebarVisible: boolean = false;
8 8  
9 9 getCurrentVisibility() {
10 10 return this.sidebarVisible;
... ...
src/app/login/auth.service.spec.ts
1 1 import {AuthService, AuthEvents} from "./";
  2 +import {SessionService} from './session.service';
2 3  
3 4 import {Injectable, Provider, provide, EventEmitter} from "ng-forward";
4 5 import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
... ...
src/app/login/auth.service.ts
... ... @@ -6,7 +6,7 @@ import {SessionService} from &quot;./session.service&quot;;
6 6 import {AuthEvents} from "./auth-events";
7 7  
8 8 @Injectable()
9   -@Inject("$http", "SessionService", "$log")
  9 +@Inject("$http", SessionService, "$log")
10 10 export class AuthService {
11 11  
12 12 public loginSuccess: EventEmitter<noosfero.User> = new EventEmitter<noosfero.User>();
... ...
src/app/main/main.component.ts
... ... @@ -51,8 +51,13 @@ import {HtmlEditorComponent} from &quot;../shared/components/html-editor/html-editor.
51 51 })
52 52 @Inject(BodyStateClassesService)
53 53 export class MainContentComponent {
  54 +
  55 + public themeSkin: string = 'skin-whbl';
  56 +
54 57 constructor(private bodyStateClassesService: BodyStateClassesService) {
55   - bodyStateClassesService.start();
  58 + bodyStateClassesService.start({
  59 + skin: this.themeSkin
  60 + });
56 61 }
57 62 }
58 63  
... ...
src/app/main/main.html
1 1 <acme-navbar></acme-navbar>
2 2 <!-- Sidebar Left -->
3 3 <sidebar [visible]="false"></sidebar>
4   -<div class="content" ui-view="content"></div>
  4 +<div class="content-wrapper" ui-view="content"></div>
... ...
src/app/main/main.scss
1   -.content {
  1 +.content-wrapper {
2 2 margin-top: 32px;
3 3 }
  4 +
  5 +.full-content {
  6 + margin-left: 0px !important;
  7 +}
... ...
src/app/profile/image/image.html
1   -<span title="{{ctrl.profile.name}}">
  1 +<span class="profile-image-wrap" title="{{ctrl.profile.name}}">
2 2 <img ng-if="ctrl.profile.image" ng-src="{{ctrl.profile.image.url}}" class="img-responsive profile-image">
3 3 <i ng-if="!ctrl.profile.image" class="fa {{ctrl.defaultIcon}} fa-5x profile-image"></i>
4 4 </span>
... ...