Commit 7057a9e1d1b55ee0b89712c54c1c300a9b5b7feb
1 parent
a7010295
Exists in
master
and in
11 other branches
initial commit for the design mode feature
Showing
9 changed files
with
105 additions
and
10 deletions
Show diff stats
@@ -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 |
@@ -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 |
@@ -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 "./../../l | @@ -4,11 +4,12 @@ import {SessionService, AuthService, AuthController, AuthEvents} from "./../../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 "../../login/auth-events"; | @@ -3,6 +3,7 @@ import {AuthEvents} from "../../login/auth-events"; | ||
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 | } |