Commit e59add5d463dc82869a146b91e52fd58cb178b63

Authored by Michel Felipe
1 parent 8362948a

Created sidebar component with sass and a service to show/hide using Angular 2 EventEmitter sintax

src/app/index.scss
... ... @@ -28,12 +28,16 @@ $primary-color-dark: #0288d1;
28 28 $default-bg-hover-color: #f8f8f8;
29 29 $red-color: #e84e40;
30 30 $red-color-dark: #dd191d;
  31 +$green-color: #8bc34a;
  32 +$green-color-dark: #689f38;
31 33  
32 34 //GRID - media queries breakpoints
33 35 $break-xxs-min: 420px;
34 36 $break-xs-min: 768px;
  37 +$break-sm-min: 992px;
35 38  
36 39 $break-xxs-max: ($break-xxs-min - 1);
  40 +$break-sm-max: ($break-sm-min - 1);
37 41 $break-xs-max: ($break-xs-min - 1);
38 42  
39 43  
... ... @@ -76,4 +80,5 @@ h1, h2, h3, h4, h5 {
76 80 @import "layout/scss/mixins";
77 81 @import "layout/scss/bootstrap-overrides";
78 82 @import "layout/scss/layout";
  83 +@import "layout/scss/sidebar";
79 84 @import "layout/scss/tables";
... ...
src/app/layout/navbar/navbar.html
1 1 <nav class="navbar navbar-static-top navbar-inverse">
2 2 <div class="container-fluid">
3 3 <div class="navbar-header">
4   - <button type="button" class="navbar-toggle collapsed" ng-click="isCollapsed = !isCollapsed">
  4 + <button type="button" class="navbar-toggle collapsed" (click)="ctrl.toggleCollapse()">
5 5 <span class="sr-only">{{"navbar.toggle_menu" | translate}}</span>
6   - <span class="icon-bar"></span>
7   - <span class="icon-bar"></span>
8   - <span class="icon-bar"></span>
  6 + <i class="fa fa-bars"></i>
9 7 </button>
10 8 <a class="navbar-brand" ui-sref="main.environment.home">
11 9 <span class="noosfero-logo"> </span>
... ...
src/app/layout/navbar/navbar.scss
1 1 .navbar {
2 2  
  3 + margin-bottom: 0px;
  4 +
3 5 .container-fluid {
4   - padding-right: 12%;
5   - padding-left: 12%;
6   - @media (max-width: 978px) {
7   - padding-right: 2%;
8   - padding-left: 2%;
9   - }
10 6  
11 7 .navbar-brand {
12 8 .noosfero-logo {
13   - background:url("../assets/images/logo-noosfero.png") no-repeat;
  9 + background: url("../assets/images/logo-noosfero.png") no-repeat;
14 10 padding: 0px 62px 64px 15px;
15 11 }
16 12 }
... ... @@ -28,5 +24,19 @@
28 24 }
29 25 }
30 26 }
  27 +
  28 + .navbar-toggle {
  29 + display: block;
  30 + color: #fff;
  31 + padding: 4px 12px;
  32 + margin: 10px 10px;
  33 + text-align: center;
  34 + }
  35 +
  36 + @media (max-width: $break-sm-max) {
  37 + .navbar-toggle .fa-bars{
  38 + font-size: 14pt;
  39 + }
  40 + }
31 41 }
32 42 }
... ...
src/app/layout/navbar/navbar.ts
1   -import {Component, Inject} from "ng-forward";
  1 +import {Component, Inject, EventEmitter, Input} from "ng-forward";
2 2 import {LanguageSelectorComponent} from "../language-selector/language-selector.component";
3   -
4   -
5 3 import {SessionService, AuthService, AuthController, IAuthEvents, AUTH_EVENTS} from "./../../login";
  4 +import {SidebarNotificationService} from "../sidebar/sidebar.notification.service";
6 5  
7 6 @Component({
8 7 selector: "acme-navbar",
9 8 templateUrl: "app/layout/navbar/navbar.html",
10 9 directives: [LanguageSelectorComponent],
11   - providers: [AuthService, SessionService]
  10 + providers: [AuthService, SessionService, SidebarNotificationService]
12 11 })
13   -@Inject("$uibModal", AuthService, "SessionService", "$scope", "$state")
  12 +@Inject("$uibModal", AuthService, "SessionService", "$scope", "$state", SidebarNotificationService)
14 13 export class Navbar {
15 14  
16 15 private currentUser: noosfero.User;
... ... @@ -23,7 +22,8 @@ export class Navbar {
23 22 private authService: AuthService,
24 23 private session: SessionService,
25 24 private $scope: ng.IScope,
26   - private $state: ng.ui.IStateService
  25 + private $state: ng.ui.IStateService,
  26 + private sidebarNotificationService: SidebarNotificationService
27 27 ) {
28 28 this.currentUser = this.session.currentUser();
29 29  
... ... @@ -39,6 +39,11 @@ export class Navbar {
39 39 this.$scope.$on(AUTH_EVENTS.logoutSuccess, () => {
40 40 this.currentUser = this.session.currentUser();
41 41 });
  42 +
  43 + }
  44 +
  45 + public toggleCollapse() {
  46 + this.sidebarNotificationService.alternateVisibility();
42 47 }
43 48  
44 49 openLogin() {
... ...
src/app/layout/scss/_bootstrap-overrides.scss
... ... @@ -54,3 +54,19 @@
54 54 .tabs-wrapper.tabs-no-header .tab-content {
55 55 padding: 0 20px 20px;
56 56 }
  57 +
  58 +/* LABELS */
  59 +.label {
  60 + @include border-radius($border-radius-base);
  61 + font-size: 0.875em;
  62 + font-weight: 600;
  63 +}
  64 +.label-default,
  65 +.label.label-large {
  66 + font-size: 1em;
  67 + padding: 0.4em 0.8em 0.5em;
  68 +}
  69 +.label.label-circle {
  70 + @include border-radius(50%);
  71 + padding: 4px !important;
  72 +}
... ...
src/app/layout/scss/_sidebar.scss 0 → 100644
... ... @@ -0,0 +1,291 @@
  1 +#col-left {
  2 + position: relative;
  3 + color: #003940;
  4 + height: 100%;
  5 +
  6 + a {
  7 + color: #e1e1e1;
  8 + }
  9 + a:hover,
  10 + .nav-active a.nav-link,
  11 + a.active {
  12 + color: #fff;
  13 + }
  14 + * {
  15 + outline: none;
  16 + }
  17 +}
  18 +#nav-col {
  19 + padding: 0;
  20 + z-index: 100;
  21 + position: absolute;
  22 + background: #2c3e50;
  23 + width: 220px;
  24 +
  25 + @media (max-width: $break-sm-max) {
  26 + position: relative;
  27 + width: auto;
  28 + }
  29 +}
  30 +#sidebar-nav {
  31 + max-height: 100%;
  32 + padding-left: 0;
  33 + padding-right: 0;
  34 +
  35 + .nav {
  36 + > li {
  37 + margin: 0;
  38 +
  39 + &.nav-header {
  40 + color: lighten(#2c3e50, 40%);
  41 + font-size: 0.8em;
  42 + padding: 12px 15px 6px 14px;
  43 + border-top: 2px solid darken(#2c3e50, 4%);
  44 +
  45 + &.nav-header-first {
  46 + padding-top: 4px;
  47 + border-top: 0;
  48 + }
  49 + }
  50 +
  51 + > a {
  52 + color: #fff;
  53 + height: 44px;
  54 + line-height: 28px;
  55 + @include transition(border-color 0.1s ease-in-out 0s, background-color 0.1s ease-in-out 0s, box-shadow 0.1s ease-in-out 0s);
  56 + overflow: hidden;
  57 + padding: 8px 15px 8px 20px;
  58 + border-left: 0 solid transparent;
  59 +
  60 + &:hover {
  61 + border-left-color: $primary-color;
  62 + }
  63 + > i {
  64 + position: absolute;
  65 + margin-top: 6px;
  66 + }
  67 + > span {
  68 + margin-left: 35px;
  69 + font-size: 0.875em;
  70 + font-weight: 700;
  71 +
  72 + &.label {
  73 + font-size: 0.75em;
  74 + margin: 5px 0 0 0;
  75 + padding: 4px 0.6em;
  76 + }
  77 + &.label.label-circle {
  78 + margin-right: 5px;
  79 + }
  80 + }
  81 + }
  82 + &.open > a {
  83 + border-bottom-color: #252525;
  84 + outline: none;
  85 + text-decoration: none;
  86 + }
  87 + &.active > .submenu > li.active > .submenu {
  88 + display: block;
  89 + }
  90 + }
  91 + li {
  92 + @import "sidebar/submenu";
  93 +
  94 + &.active > .submenu {
  95 + display: block;
  96 + }
  97 + }
  98 + }
  99 +}
  100 +.navbar-nav .open .dropdown-menu {
  101 + background-color: #FFFFFF;
  102 + border: none;
  103 + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.176);
  104 + position: absolute;
  105 +}
  106 +#user-left-box {
  107 + padding: 20px 15px 20px 25px;
  108 +
  109 + img {
  110 + @include border-radius(18%);
  111 + border: 3px solid #fff;
  112 + float: left;
  113 + width: 70px;
  114 + }
  115 + .user-box {
  116 + color: #fff;
  117 + float: left;
  118 + padding-left: 15px;
  119 + padding-top: 18px;
  120 +
  121 + > .name {
  122 + display: block;
  123 + font-size: 1em;
  124 + font-weight: 600;
  125 + line-height: 1.2;
  126 +
  127 + > a {
  128 + color: #fff;
  129 +
  130 + &:hover,
  131 + &:focus {
  132 + color: #E1E1E1;
  133 + text-decoration: none;
  134 + }
  135 + }
  136 + }
  137 + > .status {
  138 + display: block;
  139 + font-size: 0.75em;
  140 + padding-top: 3px;
  141 + }
  142 + > .status > i {
  143 + color: $green-color;
  144 + margin-right: 4px;
  145 + }
  146 + }
  147 + &.dropdown {
  148 + .dropdown-menu {
  149 + top: 55px;
  150 + left: 30px;
  151 +
  152 + a {
  153 + color: #707070;
  154 + font-size: 0.875em;
  155 +
  156 + &:hover {
  157 + background-color: #f6f6f6;
  158 + color: #707070;
  159 + }
  160 + }
  161 + }
  162 + }
  163 +}
  164 +@media (min-width: $break-sm-min) {
  165 + .nav-small {
  166 + #nav-col {
  167 + width: 64px;
  168 + }
  169 + #content-wrapper {
  170 + margin-left: 64px;
  171 + }
  172 + #nav-col {
  173 + #user-left-box {
  174 + display: none;
  175 + }
  176 + #sidebar-nav {
  177 + .nav > li > a {
  178 + padding-left: 15px !important;
  179 + padding-right: 15px;
  180 + text-align: center;
  181 +
  182 + > i {
  183 + position: relative;
  184 + font-size: 1.25em;
  185 + }
  186 + > span {
  187 + display: none;
  188 + }
  189 + }
  190 + .nav > li.nav-header {
  191 + display: none;
  192 + }
  193 + .nav li > a.dropdown-toggle > .drop-icon {
  194 + display: none;
  195 + }
  196 + .nav .submenu > li > a.dropdown-toggle > .drop-icon {
  197 + display: block;
  198 + }
  199 + .nav li .submenu {
  200 + left: 64px;
  201 + position: absolute;
  202 + top: 0;
  203 + width: 210px;
  204 +
  205 + > li > a {
  206 + padding-left: 28px;
  207 + }
  208 + }
  209 + .nav > .active > .submenu > li > .submenu {
  210 + left: auto;
  211 + position: relative;
  212 + top: auto;
  213 + width: 100%;
  214 +
  215 + a {
  216 + padding-left: 48px
  217 + }
  218 + }
  219 + }
  220 + }
  221 +
  222 + #nav-col-submenu {
  223 + @import "sidebar/submenu";
  224 +
  225 + .submenu {
  226 + position: absolute;
  227 + top: 60px;
  228 + left: 64px;
  229 + width: 210px;
  230 +
  231 + > li > a {
  232 + padding-left: 28px;
  233 +
  234 + &.dropdown-toggle > .drop-icon {
  235 + display: block;
  236 + }
  237 + }
  238 + }
  239 + > .submenu {
  240 + display: block !important;
  241 + }
  242 + .submenu > li > .submenu,
  243 + .submenu > li > .submenu {
  244 + left: auto;
  245 + position: relative;
  246 + top: auto;
  247 + width: 100%;
  248 +
  249 + a {
  250 + padding-left: 48px
  251 + }
  252 + }
  253 + }
  254 + }
  255 +}
  256 +@media (max-width: $break-sm-max) {
  257 +
  258 + #sidebar-nav.navbar-collapse {
  259 + max-height: 336px;
  260 + }
  261 +}
  262 +
  263 +/* Extracted from original _header.scss */
  264 +#sidebar-nav .nav a {
  265 + > i {
  266 + font-size: 1.125em;
  267 + }
  268 + > .open > &, .open > &:focus {
  269 + background: inherit;
  270 + }
  271 + &:hover, .open > &:hover {
  272 + background: darken(#2c3e50, 4%);
  273 + color: #fff;
  274 + outline: none;
  275 + }
  276 +}
  277 +
  278 +#sidebar-nav .nav-pills > li.active > a,
  279 +#sidebar-nav .nav-pills > li.active > a:hover,
  280 +#sidebar-nav .nav-pills > li.active > a:focus,
  281 +.nav-pills > li.open > a,
  282 +.nav-pills > li.open > a:hover,
  283 +.nav-pills > li.open > a:focus,
  284 +#sidebar-nav .nav-pills > li.open > a,
  285 +#sidebar-nav .nav-pills > li.open > a:hover,
  286 +#sidebar-nav .nav-pills > li > a:focus,
  287 +.nav-small #nav-col #sidebar-nav .nav-pills > li.open > a {
  288 + background-color: darken(#2c3e50, 4%);
  289 + color: #fff;
  290 + border-left-color: $primary-color;
  291 +}
... ...
src/app/layout/scss/sidebar/_submenu.scss 0 → 100644
... ... @@ -0,0 +1,52 @@
  1 +a.dropdown-toggle > .drop-icon {
  2 + color: #868b98;
  3 + font-size: 12px;
  4 + margin-top: -6px;
  5 + position: absolute;
  6 + right: 25px;
  7 + top: 50%;
  8 + @include transition(transform 0.2s ease-in-out 0.1s);
  9 +}
  10 +&.open a.dropdown-toggle > .drop-icon,
  11 +&.active > a.dropdown-toggle > .drop-icon {
  12 + color: #fff;
  13 + transform:rotate(90deg);
  14 +}
  15 +
  16 +.submenu {
  17 + background: darken(#2c3e50, 4%);
  18 + padding-left: 0;
  19 + margin: 0;
  20 + list-style: none;
  21 +
  22 + li {
  23 + position: relative;
  24 +
  25 + > a {
  26 + display: block;
  27 + font-size: 0.875em;
  28 + line-height: 38px;
  29 + padding-left: 60px;
  30 + color: #fff;
  31 + outline: none;
  32 + text-decoration: none;
  33 + @include transition(border-color 0.1s ease-in-out 0s, background-color 0.1s ease-in-out 0s, box-shadow 0.1s ease-in-out 0s);
  34 +
  35 + &:hover {
  36 + background-color: #1f2c39;
  37 + }
  38 + }
  39 + &:first-of-type > a {
  40 + border-top: 0;
  41 + }
  42 + > a:hover,
  43 + > a:focus,
  44 + > a.active,
  45 + &.active > a,
  46 + &.open > a {
  47 + text-decoration: none;
  48 + color: #fff;
  49 + background-color: darken(#2c3e50, 7%);
  50 + }
  51 + }
  52 +}
... ...
src/app/layout/sidebar/sidebar.component.ts 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +import {Component, Inject, Input} from "ng-forward";
  2 +import {SidebarNotificationService} from "./sidebar.notification.service";
  3 +
  4 +@Component({
  5 + selector: 'sidebar',
  6 + templateUrl: 'app/layout/sidebar/sidebar.html'
  7 +})
  8 +@Inject(SidebarNotificationService)
  9 +export class SidebarComponent {
  10 +
  11 + @Input('visible')
  12 + private isVisible: boolean = false;
  13 +
  14 + constructor(private notificationService: SidebarNotificationService) { }
  15 +
  16 + ngOnInit() {
  17 +
  18 + this.notificationService.setVisibility(this.isVisible);
  19 + this.notificationService.subscribe((visible) => {
  20 + this.isVisible = visible;
  21 + })
  22 + }
  23 +}
... ...
src/app/layout/sidebar/sidebar.html 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +<div id="nav-col" ng-show="ctrl.isVisible">
  2 + <section id="col-left" class="col-left-nano">
  3 + <div id="col-left-inner" class="col-left-nano-content">
  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>
  6 + <div class="user-box">
  7 + <span class="name">
  8 + <a href="#" class="dropdown-toggle" data-toggle="dropdown">
  9 + Scarlett J.
  10 + <i class="fa fa-angle-down"></i>
  11 + </a>
  12 + <ul class="dropdown-menu">
  13 + <li><a href="user-profile.html"><i class="fa fa-user"></i>Profile</a></li>
  14 + <li><a href="#"><i class="fa fa-cog"></i>Settings</a></li>
  15 + <li><a href="#"><i class="fa fa-envelope-o"></i>Messages</a></li>
  16 + <li><a href="#"><i class="fa fa-power-off"></i>Logout</a></li>
  17 + </ul>
  18 + </span>
  19 + <span class="status">
  20 + <i class="fa fa-circle"></i> Online
  21 + </span>
  22 + </div>
  23 + </div>
  24 +
  25 + <div class="collapse navbar-collapse navbar-ex1-collapse" id="sidebar-nav">
  26 + <ul class="nav nav-pills nav-stacked">
  27 + <li class="nav-header nav-header-first hidden-sm hidden-xs">
  28 + Navigation
  29 + </li>
  30 + <li class="active">
  31 + <a href="index.html">
  32 + <i class="fa fa-dashboard"></i>
  33 + <span>Dashboard</span>
  34 + <span class="label label-primary label-circle pull-right">28</span>
  35 + </a>
  36 + </li>
  37 + <li ng-click="widgetExpanded = !widgetExpanded">
  38 + <a href="#" class="dropdown-toggle">
  39 + <i class="fa fa-table"></i>
  40 + <span>Tables</span>
  41 + <i class="fa fa-angle-right drop-icon"></i>
  42 + </a>
  43 + <ul class="submenu" ng-show="widgetExpanded">
  44 + <li>
  45 + <a href="tables.html">
  46 + Simple
  47 + </a>
  48 + </li>
  49 + <li>
  50 + <a href="tables-advanced.html">
  51 + Advanced
  52 + </a>
  53 + </li>
  54 + <li>
  55 + <a href="users.html">
  56 + Users
  57 + </a>
  58 + </li>
  59 + </ul>
  60 + </li>
  61 + </ul>
  62 + </div>
  63 + </div>
  64 + </section>
  65 + </div>
... ...
src/app/layout/sidebar/sidebar.notification.service.ts 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +import {Injectable, EventEmitter} from "ng-forward";
  2 +
  3 +
  4 +@Injectable()
  5 +export class SidebarNotificationService {
  6 + private alternateVisibilityEvent: EventEmitter<boolean> = new EventEmitter<boolean>();
  7 + private sidebarVisible: boolean = false;
  8 +
  9 + getCurrentVisibility() {
  10 + return this.sidebarVisible;
  11 + }
  12 +
  13 + alternateVisibility() {
  14 + this.sidebarVisible = !this.sidebarVisible;
  15 + this.alternateVisibilityEvent.next(this.sidebarVisible);
  16 + }
  17 +
  18 + setVisibility(visibility: boolean) {
  19 + this.sidebarVisible = visibility;
  20 + this.alternateVisibilityEvent.next(this.sidebarVisible);
  21 + }
  22 +
  23 + subscribe(fn: (visible: boolean) => void) {
  24 + this.alternateVisibilityEvent.subscribe(fn);
  25 + }
  26 +
  27 +}
... ...
src/app/main/main.component.ts
... ... @@ -28,6 +28,8 @@ import {BodyStateClassesService} from &quot;./../layout/services/body-state-classes.s
28 28  
29 29 import {Navbar} from "../layout/navbar/navbar";
30 30  
  31 +import {SidebarComponent} from "../layout/sidebar/sidebar.component";
  32 +
31 33 import {MainBlockComponent} from "../layout/blocks/main-block/main-block.component";
32 34 import {HtmlEditorComponent} from "../shared/components/html-editor/html-editor.component";
33 35  
... ... @@ -84,7 +86,7 @@ export class EnvironmentContent {
84 86 ArticleBlogComponent, ArticleViewComponent, BoxesComponent, BlockComponent,
85 87 EnvironmentComponent, PeopleBlockComponent,
86 88 LinkListBlockComponent, CommunitiesBlockComponent, HtmlEditorComponent,
87   - MainBlockComponent, RecentDocumentsBlockComponent, Navbar, ProfileImageBlockComponent,
  89 + MainBlockComponent, RecentDocumentsBlockComponent, Navbar, SidebarComponent, ProfileImageBlockComponent,
88 90 MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent
89 91 ],
90 92 providers: [AuthService, SessionService, NotificationService, BodyStateClassesService]
... ...
src/app/main/main.html
1 1 <acme-navbar></acme-navbar>
2   -<div ui-view="content"></div>
  2 +<!-- Sidebar Left -->
  3 +<sidebar [visible]="true"></sidebar>
  4 +<div class="content" ui-view="content"></div>
... ...
src/app/main/main.scss 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +.content {
  2 + margin-top: 32px;
  3 +}
... ...