diff --git a/src/app/admin/designMode.service.spec.ts b/src/app/admin/designMode.service.spec.ts new file mode 100644 index 0000000..d67fe35 --- /dev/null +++ b/src/app/admin/designMode.service.spec.ts @@ -0,0 +1,31 @@ +import {DesignModeService} from './designMode.service'; + +describe('DesignMode Service', () => { + let service: DesignModeService; + + beforeEach(() => { + service = new DesignModeService(); + }); + + it('has the designModeOn equals false as default', () => { + expect(service.isInDesignMode()).toBeFalsy(); + }); + + it('allows set the designMode value', () => { + spyOn(service.onToggle, 'next').and.stub(); + service.setInDesignMode(true); + expect(service.isInDesignMode).toBeTruthy(); + }); + + it('emits the onToggle event when changing the designModeOn property', () => { + spyOn(service.onToggle, 'next').and.stub(); + service.setInDesignMode(true); + expect(service.onToggle.next).toHaveBeenCalled(); + }); + + it('does not emit onToggle event when there is no change on designModeOn property', () => { + spyOn(service.onToggle, 'next').and.stub(); + service.setInDesignMode(false); + expect(service.onToggle.next).not.toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/src/app/admin/designMode.service.ts b/src/app/admin/designMode.service.ts index 0028e01..6600880 100644 --- a/src/app/admin/designMode.service.ts +++ b/src/app/admin/designMode.service.ts @@ -12,8 +12,10 @@ export class DesignModeService { } setInDesignMode(value: boolean) { - this.designModeOn = value; - this.onToggle.next(this.designModeOn); + if (this.designModeOn !== value) { + this.designModeOn = value; + this.onToggle.next(this.designModeOn); + } } constructor() { diff --git a/src/app/admin/designModeToggler.component.spec.ts b/src/app/admin/designModeToggler.component.spec.ts new file mode 100644 index 0000000..e331f00 --- /dev/null +++ b/src/app/admin/designModeToggler.component.spec.ts @@ -0,0 +1,59 @@ +import {ComponentTestHelper, createClass} from './../../spec/component-test-helper'; +import * as helpers from './../../spec/helpers'; +import {DesignModeTogglerComponent} from './designModeToggler.component'; +import {DesignModeService} from './designMode.service'; + +describe('DesignModeToggler Component', () => { + const htmlTemplate: string = ''; + + let helper: ComponentTestHelper; + beforeEach(() => { + angular.mock.module('templates'); + angular.mock.module('ngSanitize'); + angular.mock.module('toggle-switch'); + }); + + let designModeService: DesignModeService; + beforeEach((done) => { + designModeService = new DesignModeService(); + let cls = createClass({ + template: htmlTemplate, + directives: [DesignModeTogglerComponent], + providers: [ + helpers.createProviderToValue('DesignModeService', designModeService) + ] + }); + helper = new ComponentTestHelper(cls, done); + }); + + it('changes css classes representing the switch is on or off', () => { + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeTruthy(); + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeFalsy(); + helper.component.inDesignMode = true; + helper.detectChanges(); + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeTruthy(); + expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeFalsy(); + }); + + it('emits event with value "true" when changing inDesignMode to On', (done) => { + designModeService.onToggle.subscribe((designModeOn: boolean) => { + expect(designModeOn).toBeTruthy(); + done(); + }); + helper.component.inDesignMode = true; + helper.detectChanges(); + }); + + it('emits events with value "false" when changing inDesignMode to Off', (done) => { + helper.component.inDesignMode = true; + helper.detectChanges(); + + designModeService.onToggle.subscribe((designModeOn: boolean) => { + expect(designModeOn).toBeFalsy(); + done(); + }); + + helper.component.inDesignMode = false; + helper.detectChanges(); + }); +}); \ No newline at end of file diff --git a/src/app/admin/designModeToggler.component.ts b/src/app/admin/designModeToggler.component.ts index bb9eee4..160564c 100644 --- a/src/app/admin/designModeToggler.component.ts +++ b/src/app/admin/designModeToggler.component.ts @@ -4,11 +4,12 @@ import {DesignModeService} from './designMode.service'; selector: 'noosfero-design-toggler', templateUrl: 'app/admin/designModeToggler.html' }) -@Inject(DesignModeService, '$scope') +@Inject(DesignModeService) export class DesignModeTogglerComponent { + icon: string = "  "; - constructor(private designModeService: DesignModeService, private $scope: ng.IScope) { + constructor(private designModeService: DesignModeService) { } private _inDesignMode: boolean = false; @@ -20,5 +21,4 @@ export class DesignModeTogglerComponent { set inDesignMode(value: boolean) { this.designModeService.setInDesignMode(value); }; - } \ No newline at end of file diff --git a/src/app/admin/designModeToggler.html b/src/app/admin/designModeToggler.html index b021c80..085482e 100644 --- a/src/app/admin/designModeToggler.html +++ b/src/app/admin/designModeToggler.html @@ -3,5 +3,6 @@ ng-model="ctrl.inDesignMode" on-label="{{'designMode.toggle.ON' | translate}}" off-label="{{'designMode.toggle.OFF' | translate}}" - knob-label="{{'designMode.label' | translate}}"> + class="switch-small" + knob-label="{{ ctrl.icon + ('designMode.label' | translate) }}"> \ No newline at end of file diff --git a/src/app/layout/scss/skins/_whbl.scss b/src/app/layout/scss/skins/_whbl.scss index 146307f..bd022c0 100644 --- a/src/app/layout/scss/skins/_whbl.scss +++ b/src/app/layout/scss/skins/_whbl.scss @@ -289,6 +289,31 @@ $whbl-font-color: #16191c; .pace .pace-progress { background-color: #fff; } + + noosfero-design-toggler .ats-switch .knob i { + color: #999999; + } + + .ats-switch .knob { + padding-right: 15px; + } + + .ats-switch .glyphicon { + top: 2px; + } + + .ats-switch .switch-left { + background-color: #41b941; + font-weight: bold; + color: white; + } + + .ats-switch .switch-right { + background-color: #ce3b3b; + font-weight: bold; + color: white; + } + } .rtl.skin-whbl #content-wrapper { border-left: 0; diff --git a/src/app/layout/services/body-state-classes.service.spec.ts b/src/app/layout/services/body-state-classes.service.spec.ts index 41176fd..ecd5343 100644 --- a/src/app/layout/services/body-state-classes.service.spec.ts +++ b/src/app/layout/services/body-state-classes.service.spec.ts @@ -4,7 +4,7 @@ import {AuthService} from "./../../login/auth.service"; import {AuthEvents} from "./../../login/auth-events"; import {EventEmitter} from 'ng-forward'; - +import {DesignModeService} from './../../admin/designMode.service'; describe("BodyStateClasses Service", () => { @@ -19,10 +19,13 @@ describe("BodyStateClasses Service", () => { }, authService: any = helpers.mocks.authService, bodyEl: { className: string }, - bodyElJq: any; + bodyElJq: any, + designModeService = new DesignModeService(); + + let getService = (): BodyStateClassesService => { - return new BodyStateClassesService($rootScope, $document, $state, authService); + return new BodyStateClassesService($rootScope, $document, $state, authService, designModeService); }; beforeEach(() => { @@ -168,4 +171,30 @@ describe("BodyStateClasses Service", () => { expect(contentWrapperMock.removeClass).toHaveBeenCalledWith(BodyStateClassesService.CONTENT_WRAPPER_FULL); }); + + it("should add the class noosfero-design-on when designMode is changed to true", () => { + let fnOnToggle: Function = null; + designModeService.onToggle = { + subscribe: (fn: Function) => { + fnOnToggle = fn; + }, + next: (value: boolean) => { + fnOnToggle.apply(designModeService, [value]); + } + }; + + let service = getService(); + + bodyElJq.addClass = jasmine.createSpy("addClass"); + bodyElJq.removeClass = jasmine.createSpy("removeClass"); + service["bodyElement"] = bodyElJq; + + service.start(); + + debugger; + designModeService.setInDesignMode(true); + + + expect(bodyElJq.addClass).toHaveBeenCalledWith(BodyStateClassesService.DESIGN_MODE_ON_CLASSNAME); + }); }); diff --git a/src/app/shared/components/bootstrap-switcher/bootstrap-switcher.component.ts b/src/app/shared/components/bootstrap-switcher/bootstrap-switcher.component.ts new file mode 100644 index 0000000..73a2c22 --- /dev/null +++ b/src/app/shared/components/bootstrap-switcher/bootstrap-switcher.component.ts @@ -0,0 +1,51 @@ +import {Component, Input, Output, EventEmitter} from 'ng-forward'; + + +export interface BootstrapSwitcherItem { + value: any; + label: string; +} +@Component({ + selector: 'noosfero-bootstrap-switcher', + template: ` + +
+ +
+ `, + inputs: ['label', 'options', 'defaultOption'], + outputs: ['onSwitch'] +}) +export class BootstrapSwitcherComponent { + @Input('activeClass') activeClass: string = 'active btn-danger'; + @Input('defaultClass') defaultClass: string = 'btn-default'; + @Input('label') label: string; + @Input('options') options: BootstrapSwitcherItem[]; + @Input('defaultOption') defaultOption: BootstrapSwitcherItem; + @Output('onSwitch') onSwitch: EventEmitter = new EventEmitter(); + + selectedOption: BootstrapSwitcherItem = null; + + constructor() { } + + ngOnInit() { + this.selectedOption = this.defaultOption; + } + + isSelectedOption(value: BootstrapSwitcherItem): boolean { + return this.selectedOption === value; + } + + getCssClassForItem(value: BootstrapSwitcherItem): string { + return this.isSelectedOption(value) ? this.activeClass : this.defaultClass; + } + + switcherClick(value: BootstrapSwitcherItem) { + this.selectedOption = value; + this.onSwitch.next(value); + } +} \ No newline at end of file diff --git a/themes/angular-participa-consulta/app/participa-consulta.scss b/themes/angular-participa-consulta/app/participa-consulta.scss index 4cd0e12..953dcd9 100644 --- a/themes/angular-participa-consulta/app/participa-consulta.scss +++ b/themes/angular-participa-consulta/app/participa-consulta.scss @@ -33,3 +33,8 @@ background-color: #7E7E7E; } } + +.ats-switch { + border: 0px; + border-color: transparent; +} -- libgit2 0.21.2