Compare View

switch
from
...
to
 
Commits (8)
bower.json
... ... @@ -35,9 +35,10 @@
35 35 "angular-i18n": "^1.5.0",
36 36 "angular-load": "^0.4.1",
37 37 "angular-translate-interpolation-messageformat": "^2.10.0",
38   - "angular-bind-html-compile": "^1.2.1",
39   - "angular-click-outside": "^2.7.1",
40   - "ng-ckeditor": "^0.2.1"
  38 + "angular-bind-html-compile": "^1.2.1",
  39 + "angular-click-outside": "^2.7.1",
  40 + "ng-ckeditor": "^0.2.1",
  41 + "angular-bootstrap-toggle-switch": "^0.5.6"
41 42 },
42 43 "devDependencies": {
43 44 "angular-mocks": "~1.5.0"
... ...
src/app/admin/layout-edit/designMode.service.spec.ts 0 → 100644
... ... @@ -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 32 \ No newline at end of file
... ...
src/app/admin/layout-edit/designMode.service.ts 0 → 100644
... ... @@ -0,0 +1,23 @@
  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 + isInDesignMode(): boolean {
  11 + return this.designModeOn;
  12 + }
  13 +
  14 + setInDesignMode(value: boolean) {
  15 + if (this.designModeOn !== value) {
  16 + this.designModeOn = value;
  17 + this.onToggle.next(this.designModeOn);
  18 + }
  19 + }
  20 +
  21 + constructor() {
  22 + }
  23 +}
0 24 \ No newline at end of file
... ...
src/app/admin/layout-edit/designModeToggler.component.spec.ts 0 → 100644
... ... @@ -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 60 \ No newline at end of file
... ...
src/app/admin/layout-edit/designModeToggler.component.ts 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +import {Component, Inject} from 'ng-forward';
  2 +import {DesignModeService} from './designMode.service';
  3 +@Component({
  4 + selector: 'noosfero-design-toggler',
  5 + templateUrl: 'app/admin/layout-edit/designModeToggler.html'
  6 +})
  7 +@Inject(DesignModeService)
  8 +export class DesignModeTogglerComponent {
  9 +
  10 + icon: string = "&nbsp;<i class='glyphicon glyphicon-wrench'></i>&nbsp;";
  11 +
  12 + constructor(private designModeService: DesignModeService) {
  13 + }
  14 +
  15 + private _inDesignMode: boolean = false;
  16 +
  17 + get inDesignMode(): boolean {
  18 + return this.designModeService.isInDesignMode();
  19 + };
  20 +
  21 + set inDesignMode(value: boolean) {
  22 + this.designModeService.setInDesignMode(value);
  23 + };
  24 +}
0 25 \ No newline at end of file
... ...
src/app/admin/layout-edit/designModeToggler.html 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<toggle-switch
  2 + html="true"
  3 + ng-model="ctrl.inDesignMode"
  4 + on-label="{{'designMode.toggle.ON' | translate}}"
  5 + off-label="{{'designMode.toggle.OFF' | translate}}"
  6 + class="switch-small"
  7 + knob-label="{{ ctrl.icon + ('designMode.label' | translate) }}">
  8 +</toggle-switch>
0 9 \ No newline at end of file
... ...
src/app/article/content-viewer/content-viewer.component.ts
... ... @@ -14,7 +14,7 @@ import {ProfileService} from &quot;../../../lib/ng-noosfero-api/http/profile.service&quot;
14 14 provide('profileService', { useClass: ProfileService })
15 15 ]
16 16 })
17   -@Inject(ArticleService, ProfileService, "$log", "$stateParams")
  17 +@Inject(ArticleService, ProfileService, "$stateParams")
18 18 export class ContentViewerComponent {
19 19  
20 20 @Input()
... ... @@ -23,7 +23,10 @@ export class ContentViewerComponent {
23 23 @Input()
24 24 profile: noosfero.Profile = null;
25 25  
26   - constructor(private articleService: ArticleService, private profileService: ProfileService, private $log: ng.ILogService, private $stateParams: angular.ui.IStateParamsService) {
  26 + constructor(
  27 + private articleService: ArticleService,
  28 + private profileService: ProfileService,
  29 + private $stateParams: angular.ui.IStateParamsService) {
27 30 this.activate();
28 31 }
29 32  
... ...
src/app/layout/navbar/navbar.html
... ... @@ -26,19 +26,20 @@
26 26 <span ng-bind="ctrl.currentUser.person.name"></span> <b class="caret"></b>
27 27 </a>
28 28 <ul class="dropdown-menu" uib-dropdown-menu>
29   - <li>
30   - <a ui-sref="main.profile.info({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> {{"navbar.profile" | translate}}</a>
31   - </li>
32   - <li>
33   - <a target="_self" ui-sref="main.profile.settings({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> {{"navbar.settings" | translate}}</a>
34   - </li>
35   - <li class="divider"></li>
36   - <li>
37   - <a href="#" ng-click="ctrl.logout()"><i class="fa fa-fw fa-power-off"></i> {{"navbar.logout" | translate}}</a>
38   - </li>
  29 + <li>
  30 + <a ui-sref="main.profile.info({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> {{"navbar.profile" | translate}}</a>
  31 + </li>
  32 + <li>
  33 + <a target="_self" ui-sref="main.profile.settings({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> {{"navbar.settings" | translate}}</a>
  34 + </li>
  35 + <li class="divider"></li>
  36 + <li>
  37 + <a href="#" ng-click="ctrl.logout()"><i class="fa fa-fw fa-power-off"></i> {{"navbar.logout" | translate}}</a>
  38 + </li>
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>
... ... @@ -49,3 +50,5 @@
49 50 </div>
50 51 </div>
51 52 </nav>
  53 +<div ui-view="toolbar">
  54 +</div>
52 55 \ No newline at end of file
... ...
src/app/layout/navbar/navbar.ts
... ... @@ -4,11 +4,13 @@ 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/layout-edit/designModeToggler.component';
  8 +import {BootstrapSwitcherComponent, BootstrapSwitcherItem} from './../../shared/components/bootstrap-switcher/bootstrap-switcher.component';
7 9  
8 10 @Component({
9 11 selector: "acme-navbar",
10 12 templateUrl: "app/layout/navbar/navbar.html",
11   - directives: [LanguageSelectorComponent],
  13 + directives: [LanguageSelectorComponent, DesignModeTogglerComponent, BootstrapSwitcherComponent],
12 14 providers: [AuthService, SessionService, SidebarNotificationService, EnvironmentService]
13 15 })
14 16 @Inject("$uibModal", AuthService, "SessionService", "$state", SidebarNotificationService, BodyStateClassesService, EnvironmentService)
... ... @@ -18,7 +20,6 @@ export class Navbar {
18 20 private modalInstance: any = null;
19 21 public showHamburger: boolean = false;
20 22 public currentEnvironment: noosfero.Environment = <any>{ name: '' };
21   -
22 23 /**
23 24 *
24 25 */
... ...
src/app/layout/scss/_layout.scss
... ... @@ -35,3 +35,24 @@
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 +}
  51 +
  52 +.noosfero-main-toolbar {
  53 + padding: 5px;
  54 + @include make-row();
  55 + margin-left: 0px;
  56 + margin-right: 0px;
  57 + background-color: #edecec;
  58 +}
38 59 \ No newline at end of file
... ...
src/app/layout/scss/skins/_whbl.scss
... ... @@ -281,6 +281,31 @@ $whbl-font-color: #16191c;
281 281 .pace .pace-progress {
282 282 background-color: #fff;
283 283 }
  284 +
  285 + noosfero-design-toggler .ats-switch .knob i {
  286 + color: #999999;
  287 + }
  288 +
  289 + .ats-switch .knob {
  290 + padding-right: 15px;
  291 + }
  292 +
  293 + .ats-switch .glyphicon {
  294 + top: 2px;
  295 + }
  296 +
  297 + .ats-switch .switch-left {
  298 + background-color: #41b941;
  299 + font-weight: bold;
  300 + color: white;
  301 + }
  302 +
  303 + .ats-switch .switch-right {
  304 + background-color: #ce3b3b;
  305 + font-weight: bold;
  306 + color: white;
  307 + }
  308 +
284 309 }
285 310 .rtl.skin-whbl #content-wrapper {
286 311 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 4 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 8  
9 9 describe("BodyStateClasses Service", () => {
10 10  
... ... @@ -19,10 +19,13 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; {
19 19 },
20 20 authService: any = helpers.mocks.authService,
21 21 bodyEl: { className: string },
22   - bodyElJq: any;
  22 + bodyElJq: any,
  23 + designModeService = new DesignModeService();
  24 +
  25 +
23 26  
24 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 31 beforeEach(() => {
... ... @@ -168,4 +171,30 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; {
168 171  
169 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/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/layout-edit/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/app/main/main.component.ts
... ... @@ -111,7 +111,7 @@ export class EnvironmentContent {
111 111 "angular-bind-html-compile", "angularMoment", "angular.filter", "akoenig.deckgrid",
112 112 "angular-timeline", "duScroll", "oitozero.ngSweetAlert",
113 113 "pascalprecht.translate", "tmh.dynamicLocale", "angularLoad",
114   - "angular-click-outside", "noosfero.init"]
  114 + "angular-click-outside", "toggle-switch", "noosfero.init"]
115 115 })
116 116 @StateConfig([
117 117 {
... ...
src/app/profile/profile-toolbar.component.ts 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +import {Component, Inject, provide} from "ng-forward";
  2 +import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service";
  3 +
  4 +@Component({
  5 + selector: "profile-toolbar",
  6 + templateUrl: "app/profile/toolbar.html",
  7 + providers: [
  8 + provide('profileService', { useClass: ProfileService })
  9 + ]
  10 +})
  11 +@Inject(ProfileService)
  12 +export class ProfileToolbarComponent {
  13 + profile: noosfero.Profile;
  14 + parentId: number;
  15 +
  16 + constructor(profileService: ProfileService) {
  17 + profileService.getCurrentProfile().then((profile: noosfero.Profile) => {
  18 + this.profile = profile;
  19 + });
  20 + }
  21 +}
... ...
src/app/profile/profile.component.ts
... ... @@ -10,7 +10,7 @@ import {ProfileService} from &quot;../../lib/ng-noosfero-api/http/profile.service&quot;;
10 10 import {NotificationService} from "../shared/services/notification.service";
11 11 import {MyProfileComponent} from "./myprofile.component";
12 12 import {ProfileActionsComponent} from "./profile-actions.component";
13   -
  13 +import {ProfileToolbarComponent} from "./profile-toolbar.component";
14 14 /**
15 15 * @ngdoc controller
16 16 * @name profile.Profile
... ... @@ -42,6 +42,11 @@ import {ProfileActionsComponent} from &quot;./profile-actions.component&quot;;
42 42 templateUrl: "app/profile/navbar-actions.html",
43 43 controller: ProfileActionsComponent,
44 44 controllerAs: "vm"
  45 + },
  46 + "toolbar@main": {
  47 + templateUrl: "app/profile/toolbar.html",
  48 + controller: ProfileToolbarComponent,
  49 + controllerAs: "vm"
45 50 }
46 51 }
47 52 },
... ... @@ -54,6 +59,11 @@ import {ProfileActionsComponent} from &quot;./profile-actions.component&quot;;
54 59 templateUrl: "app/profile/navbar-actions.html",
55 60 controller: ProfileActionsComponent,
56 61 controllerAs: "vm"
  62 + },
  63 + "toolbar@main": {
  64 + templateUrl: "app/profile/toolbar.html",
  65 + controller: ProfileToolbarComponent,
  66 + controllerAs: "vm"
57 67 }
58 68 }
59 69 },
... ... @@ -106,6 +116,11 @@ import {ProfileActionsComponent} from &quot;./profile-actions.component&quot;;
106 116 templateUrl: "app/article/content-viewer/navbar-actions.html",
107 117 controller: ContentViewerActionsComponent,
108 118 controllerAs: "vm"
  119 + },
  120 + "toolbar@main": {
  121 + templateUrl: "app/profile/toolbar.html",
  122 + controller: ProfileToolbarComponent,
  123 + controllerAs: "vm"
109 124 }
110 125 }
111 126 }
... ...
src/app/profile/toolbar.html 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +<div class="noosfero-main-toolbar" permission="vm.profile.permissions" permission-action="allow_edit">
  2 + <noosfero-design-toggler class="pull-right"></noosfero-design-toggler>
  3 +
  4 +</div>
0 5 \ No newline at end of file
... ...
src/app/shared/components/bootstrap-switcher/bootstrap-switcher.component.ts 0 → 100644
... ... @@ -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: ['activeClass', 'defaultClass', 'label', 'options', 'defaultOption'],
  21 + outputs: ['onSwitch']
  22 +})
  23 +export class BootstrapSwitcherComponent {
  24 + @Input() activeClass: string = 'active btn-danger';
  25 + @Input() defaultClass: string = 'btn-default';
  26 + @Input() label: string;
  27 + @Input() options: BootstrapSwitcherItem[];
  28 + @Input() defaultOption: BootstrapSwitcherItem;
  29 + @Output() 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 52 \ No newline at end of file
... ...
src/app/shared/components/interfaces.ts 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +
  2 +
  3 +export interface IComponentWithPermissions {
  4 + permissions: () => string[];
  5 +}
0 6 \ No newline at end of file
... ...
src/app/shared/components/permission/permission.directive.ts
... ... @@ -6,7 +6,7 @@ import {Directive, Inject, Input} from &quot;ng-forward&quot;;
6 6 @Inject('$attrs', '$scope', '$element')
7 7 export class PermissionDirective {
8 8  
9   - constructor($attrs: ng.IAttributes, $scope: ng.IScope, $element: any) {
  9 + constructor($attrs: ng.IAttributes, $scope: ng.IScope, $element: ng.IAugmentedJQuery) {
10 10 $scope.$watch($attrs['permission'], () => {
11 11 let permissions = $scope.$eval($attrs['permission']);
12 12 let permissionAction = $attrs['permissionAction'];
... ...
src/languages/en.json
... ... @@ -75,6 +75,9 @@
75 75 "custom_content.title": "Edit content",
76 76 "profile.custom_header.label": "Header",
77 77 "profile.custom_footer.label": "Footer",
  78 + "designMode.label": "In Design",
  79 + "designMode.toggle.ON": "ON",
  80 + "designMode.toggle.OFF": "OFF",
78 81 "search.results.summary": "{results, plural, one{result} other{# results}}",
79 82 "search.results.query.label": "Search for:",
80 83 "search.results.query.placeholder": "Search"
... ...
src/languages/pt.json
... ... @@ -75,6 +75,9 @@
75 75 "custom_content.title": "Editar conteúdo",
76 76 "profile.custom_header.label": "Cabeçalho",
77 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 "search.results.summary": "{results, plural, one{# resultado} other{# resultados}}",
79 82 "search.results.query.label": "Buscar:",
80 83 "search.results.query.placeholder": "Informe aqui sua busca"
... ...
src/lib/ng-noosfero-api/http/profile.service.ts
... ... @@ -22,7 +22,7 @@ export class ProfileService {
22 22 this._currentProfilePromise.resolve(profile);
23 23 }
24 24  
25   - setCurrentProfileByIdentifier(identifier: string) {
  25 + setCurrentProfileByIdentifier(identifier: string): ng.IPromise<noosfero.Profile> {
26 26 this.resetCurrentProfile();
27 27 return this.getByIdentifier(identifier).then((profile: noosfero.Profile) => {
28 28 this.setCurrentProfile(profile);
... ...
src/lib/ng-noosfero-api/interfaces/article.ts
... ... @@ -14,5 +14,7 @@ namespace noosfero {
14 14 start_date: string;
15 15 end_date: string;
16 16 accept_comments: boolean;
  17 +
  18 + permissions: string[];
17 19 }
18 20 }
... ...
src/lib/ng-noosfero-api/interfaces/modelWithPermissions.ts 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +namespace noosfero {
  2 + export interface ModelWithPermissions {
  3 + permissions: string[];
  4 + }
  5 +}
0 6 \ No newline at end of file
... ...
src/lib/ng-noosfero-api/interfaces/profile.ts
... ... @@ -78,5 +78,7 @@ namespace noosfero {
78 78 * @returns {string} The Profile footer
79 79 */
80 80 custom_footer: string;
  81 +
  82 + permissions: string[];
81 83 }
82 84 }
... ...
themes/angular-participa-consulta/app/participa-consulta.scss
... ... @@ -77,3 +77,8 @@ $selected-color: #f6c445;
77 77 background-color: #7E7E7E;
78 78 }
79 79 }
  80 +
  81 +.ats-switch {
  82 + border: 0px;
  83 + border-color: transparent;
  84 +}
... ...