Commit 7057a9e1d1b55ee0b89712c54c1c300a9b5b7feb

Authored by Ábner Oliveira
1 parent a7010295

initial commit for the design mode feature

src/app/admin/designMode.service.ts 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +import {Component, Injectable, Output, EventEmitter} from 'ng-forward';
  2 +import {BodyStateClassesService} from './../layout/services/body-state-classes.service';
  3 +
  4 +@Injectable()
  5 +export class DesignModeService {
  6 + @Output() onToggle: EventEmitter<boolean> = new EventEmitter<boolean>();
  7 +
  8 + private designModeOn: boolean = false;
  9 +
  10 + constructor() {
  11 + }
  12 +
  13 + toggle() {
  14 + this.designModeOn = !this.designModeOn;
  15 + this.onToggle.next(this.designModeOn);
  16 + }
  17 +}
0 \ No newline at end of file 18 \ No newline at end of file
src/app/admin/designModeToggler.component.ts 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +import {Component, Inject} from 'ng-forward';
  2 +import {DesignModeService} from './designMode.service';
  3 +@Component({
  4 + selector: 'noosfero-design-toggler',
  5 + templateUrl: 'app/admin/designModeToggler.html'
  6 +})
  7 +@Inject(DesignModeService, '$scope')
  8 +export class DesignModeTogglerComponent {
  9 +
  10 + inDesignMode: boolean = false;
  11 +
  12 + constructor(private designModeService: DesignModeService, private $scope: ng.IScope) {
  13 + }
  14 +
  15 + ngOnInit() {
  16 + this.designModeService.onToggle.subscribe((editOnOrFalse: boolean) => {
  17 + this.inDesignMode = editOnOrFalse;
  18 + this.$scope.$apply();
  19 + });
  20 + }
  21 +
  22 + toggleDesignModeOn() {
  23 + if (!this.inDesignMode) {
  24 + this.designModeService.toggle();
  25 + }
  26 + }
  27 +
  28 + toggleDesignModeOff() {
  29 + if (this.inDesignMode) {
  30 + this.designModeService.toggle();
  31 + }
  32 + }
  33 +}
0 \ No newline at end of file 34 \ No newline at end of file
src/app/admin/designModeToggler.html 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +
  2 + <span class="design-toggler-label" ng-bind="'designMode.label' | translate"></span>
  3 + <div class="btn-group design-toggler">
  4 + <button ng-click="ctrl.toggleDesignModeOff()" ng-class="{active: !ctrl.inDesignMode}" class="btn btn-xs btn-warning" ng-bind="'designMode.toggle.OFF' | translate"></button>
  5 + <button ng-click="ctrl.toggleDesignModeOn()" ng-class="{active: ctrl.inDesignMode}" class="btn btn-xs btn-warning" ng-bind="'designMode.toggle.ON' | translate "></button>
  6 + </div>
src/app/layout/navbar/navbar.html
@@ -39,9 +39,15 @@ @@ -39,9 +39,15 @@
39 </ul> 39 </ul>
40 </li> 40 </li>
41 </ul> 41 </ul>
  42 +
42 <ul class="nav navbar-nav navbar-right"> 43 <ul class="nav navbar-nav navbar-right">
43 <language-selector class="nav navbar-nav navbar-right"></language-selector> 44 <language-selector class="nav navbar-nav navbar-right"></language-selector>
44 </ul> 45 </ul>
  46 + <ul class="nav navbar-nav navbar-right">
  47 + <li class="toggler-container">
  48 + <noosfero-design-toggler></noosfero-design-toggler>
  49 + </li>
  50 + </ul>
45 <div ui-view="actions"></div> 51 <div ui-view="actions"></div>
46 </div> 52 </div>
47 </div> 53 </div>
src/app/layout/navbar/navbar.ts
@@ -4,11 +4,12 @@ import {SessionService, AuthService, AuthController, AuthEvents} from &quot;./../../l @@ -4,11 +4,12 @@ import {SessionService, AuthService, AuthController, AuthEvents} from &quot;./../../l
4 import {EnvironmentService} from "./../../../lib/ng-noosfero-api/http/environment.service"; 4 import {EnvironmentService} from "./../../../lib/ng-noosfero-api/http/environment.service";
5 import {SidebarNotificationService} from "../sidebar/sidebar.notification.service"; 5 import {SidebarNotificationService} from "../sidebar/sidebar.notification.service";
6 import {BodyStateClassesService} from '../services/body-state-classes.service'; 6 import {BodyStateClassesService} from '../services/body-state-classes.service';
  7 +import {DesignModeTogglerComponent} from './../../admin/designModeToggler.component';
7 8
8 @Component({ 9 @Component({
9 selector: "acme-navbar", 10 selector: "acme-navbar",
10 templateUrl: "app/layout/navbar/navbar.html", 11 templateUrl: "app/layout/navbar/navbar.html",
11 - directives: [LanguageSelectorComponent], 12 + directives: [LanguageSelectorComponent, DesignModeTogglerComponent],
12 providers: [AuthService, SessionService, SidebarNotificationService, EnvironmentService] 13 providers: [AuthService, SessionService, SidebarNotificationService, EnvironmentService]
13 }) 14 })
14 @Inject("$uibModal", AuthService, "SessionService", "$state", SidebarNotificationService, BodyStateClassesService, EnvironmentService) 15 @Inject("$uibModal", AuthService, "SessionService", "$state", SidebarNotificationService, BodyStateClassesService, EnvironmentService)
src/app/layout/scss/_layout.scss
@@ -35,3 +35,17 @@ @@ -35,3 +35,17 @@
35 padding: 0 20px 20px 20px; 35 padding: 0 20px 20px 20px;
36 } 36 }
37 } 37 }
  38 +
  39 +
  40 +body.noosfero-design-on {
  41 +
  42 + div.content-wrapper {
  43 + opacity: 0.5;
  44 + }
  45 +}
  46 +
  47 +ul.nav > li.toggler-container {
  48 + position: relative;
  49 + padding-top: 12px;
  50 + color: white;
  51 +}
38 \ No newline at end of file 52 \ No newline at end of file
src/app/layout/services/body-state-classes.service.ts
@@ -3,6 +3,7 @@ import {AuthEvents} from &quot;../../login/auth-events&quot;; @@ -3,6 +3,7 @@ import {AuthEvents} from &quot;../../login/auth-events&quot;;
3 import {AuthService} from "./../../login/auth.service"; 3 import {AuthService} from "./../../login/auth.service";
4 import {HtmlUtils} from "../html-utils"; 4 import {HtmlUtils} from "../html-utils";
5 import {INgForwardJQuery} from 'ng-forward/cjs/util/jqlite-extensions'; 5 import {INgForwardJQuery} from 'ng-forward/cjs/util/jqlite-extensions';
  6 +import {DesignModeService} from './../../admin/designMode.service';
6 7
7 export interface StartParams { 8 export interface StartParams {
8 skin?: string; 9 skin?: string;
@@ -22,12 +23,13 @@ export interface StartParams { @@ -22,12 +23,13 @@ export interface StartParams {
22 * - full-content 23 * - full-content
23 */ 24 */
24 @Injectable() 25 @Injectable()
25 -@Inject("$rootScope", "$document", "$state", AuthService) 26 +@Inject("$rootScope", "$document", "$state", AuthService, DesignModeService)
26 export class BodyStateClassesService { 27 export class BodyStateClassesService {
27 28
28 private started: boolean = false; 29 private started: boolean = false;
29 private skin: string; 30 private skin: string;
30 31
  32 + public static get DESIGN_MODE_ON_CLASSNAME(): string { return "noosfero-design-on"; }
31 public static get USER_LOGGED_CLASSNAME(): string { return "noosfero-user-logged"; } 33 public static get USER_LOGGED_CLASSNAME(): string { return "noosfero-user-logged"; }
32 public static get ROUTE_STATE_CLASSNAME_PREFIX(): string { return "noosfero-route-"; } 34 public static get ROUTE_STATE_CLASSNAME_PREFIX(): string { return "noosfero-route-"; }
33 public static get CONTENT_WRAPPER_FULL(): string { return "full-content"; } 35 public static get CONTENT_WRAPPER_FULL(): string { return "full-content"; }
@@ -38,16 +40,16 @@ export class BodyStateClassesService { @@ -38,16 +40,16 @@ export class BodyStateClassesService {
38 private $rootScope: ng.IRootScopeService, 40 private $rootScope: ng.IRootScopeService,
39 private $document: ng.IDocumentService, 41 private $document: ng.IDocumentService,
40 private $state: ng.ui.IStateService, 42 private $state: ng.ui.IStateService,
41 - private authService: AuthService 43 + private authService: AuthService,
  44 + private designModeService: DesignModeService
42 ) { 45 ) {
43 -  
44 } 46 }
45 47
46 start(config?: StartParams) { 48 start(config?: StartParams) {
47 if (!this.started) { 49 if (!this.started) {
48 this.setupUserLoggedClassToggle(); 50 this.setupUserLoggedClassToggle();
49 this.setupStateClassToggle(); 51 this.setupStateClassToggle();
50 - 52 + this.setupDesignModeClassToggle();
51 if (config) { 53 if (config) {
52 this.setThemeSkin(config.skin); 54 this.setThemeSkin(config.skin);
53 } 55 }
@@ -87,9 +89,19 @@ export class BodyStateClassesService { @@ -87,9 +89,19 @@ export class BodyStateClassesService {
87 } 89 }
88 90
89 /** 91 /**
90 - * Setup the initial class name on body element indicating the current route  
91 - * and adds event handler to swith this class when the current page/state changes 92 + * setup the listeners to the desigModeService to add class on the Body Element
  93 + * indicating the user activated the designMode
92 */ 94 */
  95 + private setupDesignModeClassToggle() {
  96 + this.designModeService.onToggle.subscribe((designOn: boolean) => {
  97 + if (designOn) {
  98 + this.getBodyElement().addClass(BodyStateClassesService.DESIGN_MODE_ON_CLASSNAME);
  99 + } else {
  100 + this.getBodyElement().removeClass(BodyStateClassesService.DESIGN_MODE_ON_CLASSNAME);
  101 + }
  102 + });
  103 + }
  104 +
93 private setupStateClassToggle() { 105 private setupStateClassToggle() {
94 let bodyElement = this.getBodyElement(); 106 let bodyElement = this.getBodyElement();
95 bodyElement.addClass(BodyStateClassesService.ROUTE_STATE_CLASSNAME_PREFIX + this.$state.current.name); 107 bodyElement.addClass(BodyStateClassesService.ROUTE_STATE_CLASSNAME_PREFIX + this.$state.current.name);
src/languages/en.json
@@ -74,5 +74,8 @@ @@ -74,5 +74,8 @@
74 "profile.content.success.message": "Profile saved!", 74 "profile.content.success.message": "Profile saved!",
75 "custom_content.title": "Edit content", 75 "custom_content.title": "Edit content",
76 "profile.custom_header.label": "Header", 76 "profile.custom_header.label": "Header",
77 - "profile.custom_footer.label": "Footer" 77 + "profile.custom_footer.label": "Footer",
  78 + "designMode.label": "Design Mode",
  79 + "designMode.toggle.ON": "ON",
  80 + "designMode.toggle.OFF": "OFF"
78 } 81 }
src/languages/pt.json
@@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
58 "article.remove.success.title": "Bom trabalho!", 58 "article.remove.success.title": "Bom trabalho!",
59 "article.remove.success.message": "Artigo removido!", 59 "article.remove.success.message": "Artigo removido!",
60 "article.remove.confirmation.title": "Tem certeza?", 60 "article.remove.confirmation.title": "Tem certeza?",
61 - "article.remove.confirmation.message": "Não será possível recuperar este artigo!", 61 + "article.remove.confirmation.message": "Não será possível recuperar este artigo!",
62 "article.basic_editor.visibility": "Visibilidade", 62 "article.basic_editor.visibility": "Visibilidade",
63 "article.basic_editor.visibility.public": "Público", 63 "article.basic_editor.visibility.public": "Público",
64 "article.basic_editor.visibility.private": "Privado", 64 "article.basic_editor.visibility.private": "Privado",
@@ -74,5 +74,8 @@ @@ -74,5 +74,8 @@
74 "profile.content.success.message": "Perfil salvo!", 74 "profile.content.success.message": "Perfil salvo!",
75 "custom_content.title": "Editar conteúdo", 75 "custom_content.title": "Editar conteúdo",
76 "profile.custom_header.label": "Cabeçalho", 76 "profile.custom_header.label": "Cabeçalho",
77 - "profile.custom_footer.label": "Rodapé" 77 + "profile.custom_footer.label": "Rodapé",
  78 + "designMode.label": "Modo de Edição",
  79 + "designMode.toggle.ON": "Ligado",
  80 + "designMode.toggle.OFF": "Desligado"
78 } 81 }