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 @@
  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 18 \ No newline at end of file
... ...
src/app/admin/designModeToggler.component.ts 0 → 100644
... ... @@ -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 34 \ No newline at end of file
... ...
src/app/admin/designModeToggler.html 0 → 100644
... ... @@ -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 39 </ul>
40 40 </li>
41 41 </ul>
  42 +
42 43 <ul class="nav navbar-nav navbar-right">
43 44 <language-selector class="nav navbar-nav navbar-right"></language-selector>
44 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 51 <div ui-view="actions"></div>
46 52 </div>
47 53 </div>
... ...
src/app/layout/navbar/navbar.ts
... ... @@ -4,11 +4,12 @@ import {SessionService, AuthService, AuthController, AuthEvents} from &quot;./../../l
4 4 import {EnvironmentService} from "./../../../lib/ng-noosfero-api/http/environment.service";
5 5 import {SidebarNotificationService} from "../sidebar/sidebar.notification.service";
6 6 import {BodyStateClassesService} from '../services/body-state-classes.service';
  7 +import {DesignModeTogglerComponent} from './../../admin/designModeToggler.component';
7 8  
8 9 @Component({
9 10 selector: "acme-navbar",
10 11 templateUrl: "app/layout/navbar/navbar.html",
11   - directives: [LanguageSelectorComponent],
  12 + directives: [LanguageSelectorComponent, DesignModeTogglerComponent],
12 13 providers: [AuthService, SessionService, SidebarNotificationService, EnvironmentService]
13 14 })
14 15 @Inject("$uibModal", AuthService, "SessionService", "$state", SidebarNotificationService, BodyStateClassesService, EnvironmentService)
... ...
src/app/layout/scss/_layout.scss
... ... @@ -35,3 +35,17 @@
35 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 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 3 import {AuthService} from "./../../login/auth.service";
4 4 import {HtmlUtils} from "../html-utils";
5 5 import {INgForwardJQuery} from 'ng-forward/cjs/util/jqlite-extensions';
  6 +import {DesignModeService} from './../../admin/designMode.service';
6 7  
7 8 export interface StartParams {
8 9 skin?: string;
... ... @@ -22,12 +23,13 @@ export interface StartParams {
22 23 * - full-content
23 24 */
24 25 @Injectable()
25   -@Inject("$rootScope", "$document", "$state", AuthService)
  26 +@Inject("$rootScope", "$document", "$state", AuthService, DesignModeService)
26 27 export class BodyStateClassesService {
27 28  
28 29 private started: boolean = false;
29 30 private skin: string;
30 31  
  32 + public static get DESIGN_MODE_ON_CLASSNAME(): string { return "noosfero-design-on"; }
31 33 public static get USER_LOGGED_CLASSNAME(): string { return "noosfero-user-logged"; }
32 34 public static get ROUTE_STATE_CLASSNAME_PREFIX(): string { return "noosfero-route-"; }
33 35 public static get CONTENT_WRAPPER_FULL(): string { return "full-content"; }
... ... @@ -38,16 +40,16 @@ export class BodyStateClassesService {
38 40 private $rootScope: ng.IRootScopeService,
39 41 private $document: ng.IDocumentService,
40 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 48 start(config?: StartParams) {
47 49 if (!this.started) {
48 50 this.setupUserLoggedClassToggle();
49 51 this.setupStateClassToggle();
50   -
  52 + this.setupDesignModeClassToggle();
51 53 if (config) {
52 54 this.setThemeSkin(config.skin);
53 55 }
... ... @@ -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 105 private setupStateClassToggle() {
94 106 let bodyElement = this.getBodyElement();
95 107 bodyElement.addClass(BodyStateClassesService.ROUTE_STATE_CLASSNAME_PREFIX + this.$state.current.name);
... ...
src/languages/en.json
... ... @@ -74,5 +74,8 @@
74 74 "profile.content.success.message": "Profile saved!",
75 75 "custom_content.title": "Edit content",
76 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 58 "article.remove.success.title": "Bom trabalho!",
59 59 "article.remove.success.message": "Artigo removido!",
60 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 62 "article.basic_editor.visibility": "Visibilidade",
63 63 "article.basic_editor.visibility.public": "Público",
64 64 "article.basic_editor.visibility.private": "Privado",
... ... @@ -74,5 +74,8 @@
74 74 "profile.content.success.message": "Perfil salvo!",
75 75 "custom_content.title": "Editar conteúdo",
76 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 }
... ...