Compare View
Commits (6)
-
Fix edit mode state See merge request !46
Showing
16 changed files
Show diff stats
src/app/admin/layout-edit/designMode.service.spec.ts
| 1 | 1 | import {DesignModeService} from './designMode.service'; |
| 2 | +import {INoosferoLocalStorage} from "./../../shared/models/interfaces"; | |
| 2 | 3 | |
| 3 | 4 | describe('DesignMode Service', () => { |
| 4 | 5 | let service: DesignModeService; |
| 5 | 6 | |
| 7 | + let $localStorage = <INoosferoLocalStorage>{ currentUser: null, settings: { designMode: false } }; | |
| 6 | 8 | beforeEach(() => { |
| 7 | - service = new DesignModeService(); | |
| 9 | + service = new DesignModeService($localStorage); | |
| 8 | 10 | }); |
| 9 | 11 | |
| 10 | 12 | it('has the designModeOn equals false as default', () => { |
| ... | ... | @@ -18,12 +20,14 @@ describe('DesignMode Service', () => { |
| 18 | 20 | }); |
| 19 | 21 | |
| 20 | 22 | it('emits the onToggle event when changing the designModeOn property', () => { |
| 23 | + service.setInDesignMode(false); | |
| 21 | 24 | spyOn(service.onToggle, 'next').and.stub(); |
| 22 | 25 | service.setInDesignMode(true); |
| 23 | 26 | expect(service.onToggle.next).toHaveBeenCalled(); |
| 24 | 27 | }); |
| 25 | 28 | |
| 26 | 29 | it('does not emit onToggle event when there is no change on designModeOn property', () => { |
| 30 | + service.setInDesignMode(false); | |
| 27 | 31 | spyOn(service.onToggle, 'next').and.stub(); |
| 28 | 32 | service.setInDesignMode(false); |
| 29 | 33 | expect(service.onToggle.next).not.toHaveBeenCalled(); | ... | ... |
src/app/admin/layout-edit/designMode.service.ts
| 1 | -import {Injectable, Output, EventEmitter} from 'ng-forward'; | |
| 1 | +import {Injectable, Output, EventEmitter, Inject} from 'ng-forward'; | |
| 2 | +import {INoosferoLocalStorage} from "./../../shared/models/interfaces"; | |
| 2 | 3 | |
| 3 | 4 | @Injectable() |
| 5 | +@Inject("$localStorage") | |
| 4 | 6 | export class DesignModeService { |
| 5 | 7 | @Output() onToggle: EventEmitter<boolean> = new EventEmitter<boolean>(); |
| 6 | 8 | |
| 7 | - private designModeOn: boolean = false; | |
| 8 | - | |
| 9 | 9 | isInDesignMode(): boolean { |
| 10 | - return this.designModeOn; | |
| 10 | + return this.$localStorage.settings.designModeOn; | |
| 11 | + } | |
| 12 | + | |
| 13 | + destroy() { | |
| 14 | + delete this.$localStorage.settings; | |
| 15 | + this.$localStorage.settings = {}; | |
| 11 | 16 | } |
| 12 | 17 | |
| 13 | 18 | setInDesignMode(value: boolean) { |
| 14 | - if (this.designModeOn !== value) { | |
| 15 | - this.designModeOn = value; | |
| 16 | - this.onToggle.next(this.designModeOn); | |
| 19 | + if (this.$localStorage.settings.designModeOn !== value) { | |
| 20 | + this.$localStorage.settings.designModeOn = value; | |
| 21 | + this.onToggle.next(value); | |
| 17 | 22 | } |
| 18 | 23 | } |
| 19 | 24 | |
| 20 | - constructor() { | |
| 25 | + constructor(private $localStorage: INoosferoLocalStorage) { | |
| 26 | + if (!this.$localStorage.settings) { | |
| 27 | + this.$localStorage.settings = {}; | |
| 28 | + } | |
| 21 | 29 | } |
| 22 | 30 | } | ... | ... |
src/app/admin/layout-edit/designModeToggler.component.spec.ts
| ... | ... | @@ -2,6 +2,7 @@ import {ComponentTestHelper, createClass} from '../../../spec/component-test-hel |
| 2 | 2 | import * as helpers from '../../../spec/helpers'; |
| 3 | 3 | import {DesignModeTogglerComponent} from './designModeToggler.component'; |
| 4 | 4 | import {DesignModeService} from './designMode.service'; |
| 5 | +import {INoosferoLocalStorage} from "./../../shared/models/interfaces"; | |
| 5 | 6 | |
| 6 | 7 | describe('DesignModeToggler Component', () => { |
| 7 | 8 | const htmlTemplate: string = '<noosfero-design-toggler></noosfero-design-toggler>'; |
| ... | ... | @@ -14,13 +15,15 @@ describe('DesignModeToggler Component', () => { |
| 14 | 15 | }); |
| 15 | 16 | |
| 16 | 17 | let designModeService: DesignModeService; |
| 18 | + let $localStorage = <INoosferoLocalStorage>{ currentUser: null, settings: { designMode: false } }; | |
| 17 | 19 | beforeEach((done) => { |
| 18 | - designModeService = new DesignModeService(); | |
| 20 | + designModeService = new DesignModeService($localStorage); | |
| 19 | 21 | let cls = createClass({ |
| 20 | 22 | template: htmlTemplate, |
| 21 | 23 | directives: [DesignModeTogglerComponent], |
| 22 | 24 | providers: [ |
| 23 | - helpers.createProviderToValue('DesignModeService', designModeService) | |
| 25 | + helpers.createProviderToValue('DesignModeService', designModeService), | |
| 26 | + helpers.createProviderToValue('AuthService', helpers.mocks.authService), | |
| 24 | 27 | ] |
| 25 | 28 | }); |
| 26 | 29 | helper = new ComponentTestHelper<DesignModeTogglerComponent>(cls, done); |
| ... | ... | @@ -36,6 +39,7 @@ describe('DesignModeToggler Component', () => { |
| 36 | 39 | }); |
| 37 | 40 | |
| 38 | 41 | it('emits event with value "true" when changing inDesignMode to On', (done) => { |
| 42 | + designModeService.setInDesignMode(false); | |
| 39 | 43 | designModeService.onToggle.subscribe((designModeOn: boolean) => { |
| 40 | 44 | expect(designModeOn).toBeTruthy(); |
| 41 | 45 | done(); | ... | ... |
src/app/admin/layout-edit/designModeToggler.component.ts
| 1 | 1 | import {Component, Inject} from 'ng-forward'; |
| 2 | 2 | import {DesignModeService} from './designMode.service'; |
| 3 | +import {AuthService, AuthEvents} from '../../login' | |
| 4 | + | |
| 3 | 5 | @Component({ |
| 4 | 6 | selector: 'noosfero-design-toggler', |
| 5 | 7 | templateUrl: 'app/admin/layout-edit/designModeToggler.html' |
| 6 | 8 | }) |
| 7 | -@Inject(DesignModeService) | |
| 9 | +@Inject(DesignModeService, AuthService) | |
| 8 | 10 | export class DesignModeTogglerComponent { |
| 9 | 11 | |
| 10 | 12 | icon: string = " <i class='glyphicon glyphicon-wrench'></i> "; |
| 11 | 13 | |
| 12 | - constructor(private designModeService: DesignModeService) { | |
| 14 | + constructor(private designModeService: DesignModeService, private authService: AuthService) { | |
| 15 | + this.authService.subscribe(AuthEvents[AuthEvents.logoutSuccess], () => { | |
| 16 | + this.designModeService.destroy(); | |
| 17 | + }); | |
| 13 | 18 | } |
| 14 | 19 | |
| 15 | 20 | private _inDesignMode: boolean = false; | ... | ... |
src/app/layout/blocks/block.component.spec.ts
| ... | ... | @@ -2,6 +2,7 @@ import {Component} from 'ng-forward'; |
| 2 | 2 | import {BlockComponent} from './block.component'; |
| 3 | 3 | import * as helpers from "../../../spec/helpers"; |
| 4 | 4 | import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; |
| 5 | +import {DesignModeService} from '../../admin/layout-edit/designMode.service'; | |
| 5 | 6 | |
| 6 | 7 | const htmlTemplate: string = '<noosfero-block [block]="ctrl.block" [owner]="ctrl.profile"></noosfero-block>'; |
| 7 | 8 | |
| ... | ... | @@ -32,16 +33,17 @@ describe("Boxes Component", () => { |
| 32 | 33 | helpers.createProviderToValue('TranslatorService', translatorService), |
| 33 | 34 | helpers.createProviderToValue('$uibModal', helpers.mocks.$modal), |
| 34 | 35 | helpers.createProviderToValue('BlockService', blockService), |
| 35 | - helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService) | |
| 36 | + helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), | |
| 37 | + helpers.createProviderToValue('DesignModeService', helpers.mocks.designModeService) | |
| 36 | 38 | ] |
| 37 | 39 | }); |
| 38 | 40 | helper = new ComponentTestHelper<BlockComponent>(cls, done); |
| 39 | 41 | }); |
| 40 | - | |
| 41 | 42 | let translatorService = jasmine.createSpyObj("translatorService", ["currentLanguage"]); |
| 42 | 43 | let blockService = jasmine.createSpyObj("blockService", ["update"]); |
| 43 | 44 | let state = jasmine.createSpyObj("state", ["current"]); |
| 44 | 45 | state.current = { name: "" }; |
| 46 | + | |
| 45 | 47 | |
| 46 | 48 | it("set isHomepage as false by default", () => { |
| 47 | 49 | expect(helper.component.isHomepage).toBeFalsy(); | ... | ... |
src/app/layout/blocks/block.component.ts
| ... | ... | @@ -11,7 +11,8 @@ import { DesignModeService } from "../../admin/layout-edit/designMode.service"; |
| 11 | 11 | templateUrl: 'app/layout/blocks/block.html', |
| 12 | 12 | directives: [BlockEditionComponent] |
| 13 | 13 | }) |
| 14 | -@Inject("$uibModal", "$scope", "$state", "$rootScope", BlockService, NotificationService, AuthService, SessionService, TranslatorService, DesignModeService) | |
| 14 | +@Inject("$uibModal", "$scope", "$state", "$rootScope", BlockService, NotificationService, | |
| 15 | +AuthService, SessionService, TranslatorService, DesignModeService) | |
| 15 | 16 | export class BlockComponent { |
| 16 | 17 | |
| 17 | 18 | @Input() block: noosfero.Block; | ... | ... |
src/app/layout/blocks/block.html
| 1 | -<div ng-show="ctrl.canDisplay() || ctrl.editionMode || ctrl.designMode" ng-class="{'invisible-block': !ctrl.canDisplay()}" class="noosfero-block" ng-mouseover="displayActions = true" ng-mouseleave="displayActions = false"> | |
| 1 | +<div ng-show="ctrl.canDisplay() || ctrl.inEditMode() || ctrl.designMode" ng-class="{'invisible-block': !ctrl.canDisplay()}" class="noosfero-block" ng-mouseover="displayActions = true" ng-mouseleave="displayActions = false"> | |
| 2 | 2 | <div ng-show="displayActions" class="actions block-actions" permission="ctrl.block.permissions" permission-action="allow_edit"> |
| 3 | 3 | <button type="submit" class="btn btn-xs btn-default" ng-click="ctrl.openEdit()"><i class="fa fa-edit fa-fw"></i></button> |
| 4 | 4 | </div> | ... | ... |
src/app/layout/navbar/navbar.spec.ts
| ... | ... | @@ -9,6 +9,8 @@ import {SessionService, AuthService, AuthController, AuthEvents} from "./../../l |
| 9 | 9 | |
| 10 | 10 | import events from 'ng-forward/cjs/events/events'; |
| 11 | 11 | |
| 12 | +import {DesignModeService} from '../../admin/layout-edit/designMode.service'; | |
| 13 | + | |
| 12 | 14 | describe("Components", () => { |
| 13 | 15 | |
| 14 | 16 | describe("Navbar Component", () => { |
| ... | ... | @@ -22,6 +24,7 @@ describe("Components", () => { |
| 22 | 24 | let authService: any; |
| 23 | 25 | let stateService: any; |
| 24 | 26 | let sessionService: SessionService; |
| 27 | + let designModeService: DesignModeService; | |
| 25 | 28 | |
| 26 | 29 | let provideFunc = provide; |
| 27 | 30 | |
| ... | ... | @@ -37,6 +40,7 @@ describe("Components", () => { |
| 37 | 40 | authService = helpers.mocks.authService; |
| 38 | 41 | stateService = jasmine.createSpyObj("$state", ["go"]); |
| 39 | 42 | sessionService = <any>helpers.mocks.sessionWithCurrentUser(user); |
| 43 | + designModeService = helpers.mocks.designModeService; | |
| 40 | 44 | }); |
| 41 | 45 | |
| 42 | 46 | |
| ... | ... | @@ -76,6 +80,9 @@ describe("Components", () => { |
| 76 | 80 | }), |
| 77 | 81 | provide('TranslatorService', { |
| 78 | 82 | useValue: helpers.mocks.translatorService |
| 83 | + }), | |
| 84 | + provide('DesignModeService', { | |
| 85 | + useValue: helpers.mocks.designModeService | |
| 79 | 86 | }) |
| 80 | 87 | ].concat(helpers.provideFilters("translateFilter")), |
| 81 | 88 | directives: [Navbar], | ... | ... |
src/app/layout/services/body-state-classes.service.spec.ts
| ... | ... | @@ -5,11 +5,13 @@ import {AuthEvents} from "./../../login/auth-events"; |
| 5 | 5 | |
| 6 | 6 | import {EventEmitter} from 'ng-forward'; |
| 7 | 7 | import {DesignModeService} from './../../admin/layout-edit/designMode.service'; |
| 8 | +import {INoosferoLocalStorage} from "./../../shared/models/interfaces"; | |
| 8 | 9 | |
| 9 | 10 | describe("BodyStateClasses Service", () => { |
| 10 | 11 | |
| 11 | 12 | let currentStateName = "main"; |
| 12 | 13 | let bodyStateClasseService: BodyStateClassesService; |
| 14 | + let $localStorage = <INoosferoLocalStorage>{ currentUser: null, settings: { designMode: false } }; | |
| 13 | 15 | let $rootScope: ng.IRootScopeService = <any>{}, |
| 14 | 16 | $document: ng.IDocumentService = <any>{}, |
| 15 | 17 | $state: ng.ui.IStateService = <any>{ |
| ... | ... | @@ -20,7 +22,8 @@ describe("BodyStateClasses Service", () => { |
| 20 | 22 | authService: any = helpers.mocks.authService, |
| 21 | 23 | bodyEl: { className: string }, |
| 22 | 24 | bodyElJq: any, |
| 23 | - designModeService = new DesignModeService(); | |
| 25 | + | |
| 26 | + designModeService = new DesignModeService($localStorage); | |
| 24 | 27 | |
| 25 | 28 | |
| 26 | 29 | ... | ... |
src/app/login/session.service.spec.ts
| ... | ... | @@ -13,7 +13,7 @@ describe("Services", () => { |
| 13 | 13 | let $log: any; |
| 14 | 14 | |
| 15 | 15 | beforeEach(() => { |
| 16 | - $localStorage = <INoosferoLocalStorage>{ currentUser: null }; | |
| 16 | + $localStorage = <INoosferoLocalStorage>{ currentUser: null, settings: null }; | |
| 17 | 17 | $log = jasmine.createSpyObj('$log', ['debug']); |
| 18 | 18 | }); |
| 19 | 19 | ... | ... |
src/app/login/session.service.ts
src/app/profile/custom-content/custom-content.component.spec.ts
| 1 | 1 | import {CustomContentComponent} from './custom-content.component'; |
| 2 | 2 | import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; |
| 3 | 3 | import * as helpers from "../../../spec/helpers"; |
| 4 | +import {DesignModeService} from '../../admin/layout-edit/designMode.service'; | |
| 4 | 5 | |
| 5 | 6 | const htmlTemplate: string = '<custom-content [attribute]="\'custom_footer\'" [profile]="ctrl.profile"></custom-content>'; |
| 6 | 7 | |
| ... | ... | @@ -14,6 +15,7 @@ describe("Components", () => { |
| 14 | 15 | beforeEach((done) => { |
| 15 | 16 | let profileService = jasmine.createSpyObj("profileService", ["update"]); |
| 16 | 17 | let notificationService = jasmine.createSpyObj("notificationService", ["success"]); |
| 18 | + let designModeService = { isInDesignMode: () => { return true; }}; | |
| 17 | 19 | let properties = { profile: { custom_footer: "footer" } }; |
| 18 | 20 | let cls = createClass({ |
| 19 | 21 | template: htmlTemplate, |
| ... | ... | @@ -22,7 +24,8 @@ describe("Components", () => { |
| 22 | 24 | providers: [ |
| 23 | 25 | helpers.createProviderToValue("$uibModal", helpers.mocks.$modal), |
| 24 | 26 | helpers.createProviderToValue("ProfileService", profileService), |
| 25 | - helpers.createProviderToValue("NotificationService", notificationService) | |
| 27 | + helpers.createProviderToValue("NotificationService", notificationService), | |
| 28 | + helpers.createProviderToValue("DesignModeService", designModeService) | |
| 26 | 29 | ] |
| 27 | 30 | }); |
| 28 | 31 | helper = new ComponentTestHelper<CustomContentComponent>(cls, done); | ... | ... |
src/app/profile/custom-content/custom-content.component.ts
| ... | ... | @@ -20,7 +20,6 @@ export class CustomContentComponent { |
| 20 | 20 | |
| 21 | 21 | content: string; |
| 22 | 22 | originalContent: string; |
| 23 | - editionMode = false; | |
| 24 | 23 | private modalInstance: any = null; |
| 25 | 24 | |
| 26 | 25 | constructor(private $uibModal: any, |
| ... | ... | @@ -35,9 +34,10 @@ export class CustomContentComponent { |
| 35 | 34 | }, () => { |
| 36 | 35 | if (this.profile) this.content = (<any>this.profile)[this.attribute]; |
| 37 | 36 | }); |
| 38 | - this.designModeService.onToggle.subscribe((designModeOn: boolean) => { | |
| 39 | - this.editionMode = designModeOn; | |
| 40 | - }); | |
| 37 | + } | |
| 38 | + | |
| 39 | + inEditMode() { | |
| 40 | + return this.designModeService.isInDesignMode(); | |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | openEdit() { | ... | ... |
src/app/profile/custom-content/custom-content.html
| 1 | 1 | <div class="custom-content"> |
| 2 | - <div class="actions" permission="ctrl.profile.permissions" permission-action="allow_edit" ng-show="ctrl.editionMode"> | |
| 2 | + <div class="actions" permission="ctrl.profile.permissions" permission-action="allow_edit" ng-show="ctrl.inEditMode()"> | |
| 3 | 3 | <button type="submit" class="btn btn-xs btn-default" ng-click="ctrl.openEdit()"><i class="fa fa-edit fa-fw"></i> {{ctrl.label | translate}}</button> |
| 4 | 4 | </div> |
| 5 | 5 | <div class="content" ng-bind-html="ctrl.content"></div> | ... | ... |
src/app/shared/models/interfaces.ts
src/spec/mocks.ts
| ... | ... | @@ -193,6 +193,17 @@ export var mocks: any = { |
| 193 | 193 | currentUser: () => { return user; } |
| 194 | 194 | }; |
| 195 | 195 | }, |
| 196 | + designModeService: { | |
| 197 | + modeFn: null, | |
| 198 | + onToggle: { | |
| 199 | + subscribe: (fn: Function) => { | |
| 200 | + mocks.designModeService.modeFn = fn; | |
| 201 | + }, | |
| 202 | + next: (param: any) => { | |
| 203 | + mocks.designModeService.modeFn(param); | |
| 204 | + } | |
| 205 | + } | |
| 206 | + }, | |
| 196 | 207 | $translate: { |
| 197 | 208 | use: (lang?: string) => { |
| 198 | 209 | return lang ? Promise.resolve(lang) : "en"; | ... | ... |