Commit b9f6daf63e63ab7fbd937504a85d1ec69035e37d

Authored by Ábner Oliveira
1 parent bbeb5848

better css definition to the design toggler. increased the test coverage to the …

…designModeToggler Component
src/app/admin/designMode.service.spec.ts 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +import {DesignModeService} from './designMode.service';
  2 +
  3 +describe('DesignMode Service', () => {
  4 + let service: DesignModeService;
  5 +
  6 + beforeEach(() => {
  7 + service = new DesignModeService();
  8 + });
  9 +
  10 + it('has the designModeOn equals false as default', () => {
  11 + expect(service.isInDesignMode()).toBeFalsy();
  12 + });
  13 +
  14 + it('allows set the designMode value', () => {
  15 + spyOn(service.onToggle, 'next').and.stub();
  16 + service.setInDesignMode(true);
  17 + expect(service.isInDesignMode).toBeTruthy();
  18 + });
  19 +
  20 + it('emits the onToggle event when changing the designModeOn property', () => {
  21 + spyOn(service.onToggle, 'next').and.stub();
  22 + service.setInDesignMode(true);
  23 + expect(service.onToggle.next).toHaveBeenCalled();
  24 + });
  25 +
  26 + it('does not emit onToggle event when there is no change on designModeOn property', () => {
  27 + spyOn(service.onToggle, 'next').and.stub();
  28 + service.setInDesignMode(false);
  29 + expect(service.onToggle.next).not.toHaveBeenCalled();
  30 + });
  31 +});
0 \ No newline at end of file 32 \ No newline at end of file
src/app/admin/designMode.service.ts
@@ -12,8 +12,10 @@ export class DesignModeService { @@ -12,8 +12,10 @@ export class DesignModeService {
12 } 12 }
13 13
14 setInDesignMode(value: boolean) { 14 setInDesignMode(value: boolean) {
15 - this.designModeOn = value;  
16 - this.onToggle.next(this.designModeOn); 15 + if (this.designModeOn !== value) {
  16 + this.designModeOn = value;
  17 + this.onToggle.next(this.designModeOn);
  18 + }
17 } 19 }
18 20
19 constructor() { 21 constructor() {
src/app/admin/designModeToggler.component.spec.ts 0 → 100644
@@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
  1 +import {ComponentTestHelper, createClass} from './../../spec/component-test-helper';
  2 +import * as helpers from './../../spec/helpers';
  3 +import {DesignModeTogglerComponent} from './designModeToggler.component';
  4 +import {DesignModeService} from './designMode.service';
  5 +
  6 +describe('DesignModeToggler Component', () => {
  7 + const htmlTemplate: string = '<noosfero-design-toggler></noosfero-design-toggler>';
  8 +
  9 + let helper: ComponentTestHelper<DesignModeTogglerComponent>;
  10 + beforeEach(() => {
  11 + angular.mock.module('templates');
  12 + angular.mock.module('ngSanitize');
  13 + angular.mock.module('toggle-switch');
  14 + });
  15 +
  16 + let designModeService: DesignModeService;
  17 + beforeEach((done) => {
  18 + designModeService = new DesignModeService();
  19 + let cls = createClass({
  20 + template: htmlTemplate,
  21 + directives: [DesignModeTogglerComponent],
  22 + providers: [
  23 + helpers.createProviderToValue('DesignModeService', designModeService)
  24 + ]
  25 + });
  26 + helper = new ComponentTestHelper<DesignModeTogglerComponent>(cls, done);
  27 + });
  28 +
  29 + it('changes css classes representing the switch is on or off', () => {
  30 + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeTruthy();
  31 + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeFalsy();
  32 + helper.component.inDesignMode = true;
  33 + helper.detectChanges();
  34 + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeTruthy();
  35 + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeFalsy();
  36 + });
  37 +
  38 + it('emits event with value "true" when changing inDesignMode to On', (done) => {
  39 + designModeService.onToggle.subscribe((designModeOn: boolean) => {
  40 + expect(designModeOn).toBeTruthy();
  41 + done();
  42 + });
  43 + helper.component.inDesignMode = true;
  44 + helper.detectChanges();
  45 + });
  46 +
  47 + it('emits events with value "false" when changing inDesignMode to Off', (done) => {
  48 + helper.component.inDesignMode = true;
  49 + helper.detectChanges();
  50 +
  51 + designModeService.onToggle.subscribe((designModeOn: boolean) => {
  52 + expect(designModeOn).toBeFalsy();
  53 + done();
  54 + });
  55 +
  56 + helper.component.inDesignMode = false;
  57 + helper.detectChanges();
  58 + });
  59 +});
0 \ No newline at end of file 60 \ No newline at end of file
src/app/admin/designModeToggler.component.ts
@@ -4,11 +4,12 @@ import {DesignModeService} from &#39;./designMode.service&#39;; @@ -4,11 +4,12 @@ import {DesignModeService} from &#39;./designMode.service&#39;;
4 selector: 'noosfero-design-toggler', 4 selector: 'noosfero-design-toggler',
5 templateUrl: 'app/admin/designModeToggler.html' 5 templateUrl: 'app/admin/designModeToggler.html'
6 }) 6 })
7 -@Inject(DesignModeService, '$scope') 7 +@Inject(DesignModeService)
8 export class DesignModeTogglerComponent { 8 export class DesignModeTogglerComponent {
9 9
  10 + icon: string = "&nbsp;<i class='glyphicon glyphicon-wrench'></i>&nbsp;";
10 11
11 - constructor(private designModeService: DesignModeService, private $scope: ng.IScope) { 12 + constructor(private designModeService: DesignModeService) {
12 } 13 }
13 14
14 private _inDesignMode: boolean = false; 15 private _inDesignMode: boolean = false;
@@ -20,5 +21,4 @@ export class DesignModeTogglerComponent { @@ -20,5 +21,4 @@ export class DesignModeTogglerComponent {
20 set inDesignMode(value: boolean) { 21 set inDesignMode(value: boolean) {
21 this.designModeService.setInDesignMode(value); 22 this.designModeService.setInDesignMode(value);
22 }; 23 };
23 -  
24 } 24 }
25 \ No newline at end of file 25 \ No newline at end of file
src/app/admin/designModeToggler.html
@@ -3,5 +3,6 @@ @@ -3,5 +3,6 @@
3 ng-model="ctrl.inDesignMode" 3 ng-model="ctrl.inDesignMode"
4 on-label="{{'designMode.toggle.ON' | translate}}" 4 on-label="{{'designMode.toggle.ON' | translate}}"
5 off-label="{{'designMode.toggle.OFF' | translate}}" 5 off-label="{{'designMode.toggle.OFF' | translate}}"
6 - knob-label="{{'designMode.label' | translate}}"> 6 + class="switch-small"
  7 + knob-label="{{ ctrl.icon + ('designMode.label' | translate) }}">
7 </toggle-switch> 8 </toggle-switch>
8 \ No newline at end of file 9 \ No newline at end of file
src/app/layout/scss/skins/_whbl.scss
@@ -289,6 +289,31 @@ $whbl-font-color: #16191c; @@ -289,6 +289,31 @@ $whbl-font-color: #16191c;
289 .pace .pace-progress { 289 .pace .pace-progress {
290 background-color: #fff; 290 background-color: #fff;
291 } 291 }
  292 +
  293 + noosfero-design-toggler .ats-switch .knob i {
  294 + color: #999999;
  295 + }
  296 +
  297 + .ats-switch .knob {
  298 + padding-right: 15px;
  299 + }
  300 +
  301 + .ats-switch .glyphicon {
  302 + top: 2px;
  303 + }
  304 +
  305 + .ats-switch .switch-left {
  306 + background-color: #41b941;
  307 + font-weight: bold;
  308 + color: white;
  309 + }
  310 +
  311 + .ats-switch .switch-right {
  312 + background-color: #ce3b3b;
  313 + font-weight: bold;
  314 + color: white;
  315 + }
  316 +
292 } 317 }
293 .rtl.skin-whbl #content-wrapper { 318 .rtl.skin-whbl #content-wrapper {
294 border-left: 0; 319 border-left: 0;
src/app/layout/services/body-state-classes.service.spec.ts
@@ -4,7 +4,7 @@ import {AuthService} from &quot;./../../login/auth.service&quot;; @@ -4,7 +4,7 @@ import {AuthService} from &quot;./../../login/auth.service&quot;;
4 import {AuthEvents} from "./../../login/auth-events"; 4 import {AuthEvents} from "./../../login/auth-events";
5 5
6 import {EventEmitter} from 'ng-forward'; 6 import {EventEmitter} from 'ng-forward';
7 - 7 +import {DesignModeService} from './../../admin/designMode.service';
8 8
9 describe("BodyStateClasses Service", () => { 9 describe("BodyStateClasses Service", () => {
10 10
@@ -19,10 +19,13 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; { @@ -19,10 +19,13 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; {
19 }, 19 },
20 authService: any = helpers.mocks.authService, 20 authService: any = helpers.mocks.authService,
21 bodyEl: { className: string }, 21 bodyEl: { className: string },
22 - bodyElJq: any; 22 + bodyElJq: any,
  23 + designModeService = new DesignModeService();
  24 +
  25 +
23 26
24 let getService = (): BodyStateClassesService => { 27 let getService = (): BodyStateClassesService => {
25 - return new BodyStateClassesService($rootScope, $document, $state, authService); 28 + return new BodyStateClassesService($rootScope, $document, $state, authService, designModeService);
26 }; 29 };
27 30
28 beforeEach(() => { 31 beforeEach(() => {
@@ -168,4 +171,30 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; { @@ -168,4 +171,30 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; {
168 171
169 expect(contentWrapperMock.removeClass).toHaveBeenCalledWith(BodyStateClassesService.CONTENT_WRAPPER_FULL); 172 expect(contentWrapperMock.removeClass).toHaveBeenCalledWith(BodyStateClassesService.CONTENT_WRAPPER_FULL);
170 }); 173 });
  174 +
  175 + it("should add the class noosfero-design-on when designMode is changed to true", () => {
  176 + let fnOnToggle: Function = null;
  177 + designModeService.onToggle = <any> {
  178 + subscribe: (fn: Function) => {
  179 + fnOnToggle = fn;
  180 + },
  181 + next: (value: boolean) => {
  182 + fnOnToggle.apply(designModeService, [value]);
  183 + }
  184 + };
  185 +
  186 + let service = getService();
  187 +
  188 + bodyElJq.addClass = jasmine.createSpy("addClass");
  189 + bodyElJq.removeClass = jasmine.createSpy("removeClass");
  190 + service["bodyElement"] = bodyElJq;
  191 +
  192 + service.start();
  193 +
  194 + debugger;
  195 + designModeService.setInDesignMode(true);
  196 +
  197 +
  198 + expect(bodyElJq.addClass).toHaveBeenCalledWith(BodyStateClassesService.DESIGN_MODE_ON_CLASSNAME);
  199 + });
171 }); 200 });
src/app/shared/components/bootstrap-switcher/bootstrap-switcher.component.ts 0 → 100644
@@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
  1 +import {Component, Input, Output, EventEmitter} from 'ng-forward';
  2 +
  3 +
  4 +export interface BootstrapSwitcherItem {
  5 + value: any;
  6 + label: string;
  7 +}
  8 +@Component({
  9 + selector: 'noosfero-bootstrap-switcher',
  10 + template: `
  11 + <span class="switcher-label" ng-bind="ctrl.label | translate"></span>
  12 + <div class="btn-group switcher">
  13 + <button ng-repeat="option in ctrl.options track by $index"
  14 + (click)="ctrl.switcherClick(option)"
  15 + ng-class="ctrl.getCssClassForItem(option)"
  16 + class="btn btn-xs" ng-bind="option.label | translate">
  17 + </button>
  18 + </div>
  19 + `,
  20 + inputs: ['label', 'options', 'defaultOption'],
  21 + outputs: ['onSwitch']
  22 +})
  23 +export class BootstrapSwitcherComponent {
  24 + @Input('activeClass') activeClass: string = 'active btn-danger';
  25 + @Input('defaultClass') defaultClass: string = 'btn-default';
  26 + @Input('label') label: string;
  27 + @Input('options') options: BootstrapSwitcherItem[];
  28 + @Input('defaultOption') defaultOption: BootstrapSwitcherItem;
  29 + @Output('onSwitch') onSwitch: EventEmitter<BootstrapSwitcherItem> = new EventEmitter<BootstrapSwitcherItem>();
  30 +
  31 + selectedOption: BootstrapSwitcherItem = null;
  32 +
  33 + constructor() { }
  34 +
  35 + ngOnInit() {
  36 + this.selectedOption = this.defaultOption;
  37 + }
  38 +
  39 + isSelectedOption(value: BootstrapSwitcherItem): boolean {
  40 + return this.selectedOption === value;
  41 + }
  42 +
  43 + getCssClassForItem(value: BootstrapSwitcherItem): string {
  44 + return this.isSelectedOption(value) ? this.activeClass : this.defaultClass;
  45 + }
  46 +
  47 + switcherClick(value: BootstrapSwitcherItem) {
  48 + this.selectedOption = value;
  49 + this.onSwitch.next(value);
  50 + }
  51 +}
0 \ No newline at end of file 52 \ No newline at end of file
themes/angular-participa-consulta/app/participa-consulta.scss
@@ -33,3 +33,8 @@ @@ -33,3 +33,8 @@
33 background-color: #7E7E7E; 33 background-color: #7E7E7E;
34 } 34 }
35 } 35 }
  36 +
  37 +.ats-switch {
  38 + border: 0px;
  39 + border-color: transparent;
  40 +}