Commit 399dd21d5c05c9a1a570c3fa7f0c9c914f62aeef

Authored by Leandro Santos
2 parents a2b0d2b1 8784fe3c
Exists in staging

Merge branch 'master' into staging

Showing 43 changed files with 728 additions and 116 deletions   Show diff stats
@@ -38,8 +38,8 @@ @@ -38,8 +38,8 @@
38 "angular-bind-html-compile": "^1.2.1", 38 "angular-bind-html-compile": "^1.2.1",
39 "angular-click-outside": "^2.7.1", 39 "angular-click-outside": "^2.7.1",
40 "ng-ckeditor": "^0.2.1", 40 "ng-ckeditor": "^0.2.1",
41 - "angular-bootstrap-toggle-switch": "^0.5.6",  
42 - "angular-tag-cloud": "^0.3.0" 41 + "angular-tag-cloud": "^0.3.0",
  42 + "angular-ui-switch": "^0.1.1"
43 }, 43 },
44 "devDependencies": { 44 "devDependencies": {
45 "angular-mocks": "~1.5.0" 45 "angular-mocks": "~1.5.0"
@@ -55,12 +55,7 @@ exports.themeExists = function (path) { @@ -55,12 +55,7 @@ exports.themeExists = function (path) {
55 * @param skin The skin name passed by arg to gulp task 55 * @param skin The skin name passed by arg to gulp task
56 */ 56 */
57 exports.skinExists = function (skin) { 57 exports.skinExists = function (skin) {
58 -  
59 - //Skip skin verification on 'build' task  
60 - // if(exports.isBuild()){  
61 - // return;  
62 - // }  
63 - 58 +
64 var skinPath, prefixPath = ''; 59 var skinPath, prefixPath = '';
65 var skinFile = skin+'.scss'; 60 var skinFile = skin+'.scss';
66 if (/skin-/.test(skin)) { 61 if (/skin-/.test(skin)) {
src/app/admin/layout-edit/designModeToggler.component.spec.ts
1 import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper'; 1 import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper';
  2 +import {INgForwardJQuery} from 'ng-forward/cjs/util/jqlite-extensions';
2 import * as helpers from '../../../spec/helpers'; 3 import * as helpers from '../../../spec/helpers';
3 import {DesignModeTogglerComponent} from './designModeToggler.component'; 4 import {DesignModeTogglerComponent} from './designModeToggler.component';
4 import {DesignModeService} from './designMode.service'; 5 import {DesignModeService} from './designMode.service';
5 import {INoosferoLocalStorage} from "./../../shared/models/interfaces"; 6 import {INoosferoLocalStorage} from "./../../shared/models/interfaces";
6 7
7 describe('DesignModeToggler Component', () => { 8 describe('DesignModeToggler Component', () => {
8 - const htmlTemplate: string = '<noosfero-design-toggler></noosfero-design-toggler>'; 9 + const htmlTemplate: string = '<design-toggler></design-toggler>';
9 10
10 let helper: ComponentTestHelper<DesignModeTogglerComponent>; 11 let helper: ComponentTestHelper<DesignModeTogglerComponent>;
11 beforeEach(() => { 12 beforeEach(() => {
12 angular.mock.module('templates'); 13 angular.mock.module('templates');
13 angular.mock.module('ngSanitize'); 14 angular.mock.module('ngSanitize');
14 - angular.mock.module('toggle-switch'); 15 + angular.mock.module('uiSwitch');
15 }); 16 });
16 17
17 let designModeService: DesignModeService; 18 let designModeService: DesignModeService;
@@ -30,12 +31,12 @@ describe(&#39;DesignModeToggler Component&#39;, () =&gt; { @@ -30,12 +31,12 @@ describe(&#39;DesignModeToggler Component&#39;, () =&gt; {
30 }); 31 });
31 32
32 it('changes css classes representing the switch is on or off', () => { 33 it('changes css classes representing the switch is on or off', () => {
33 - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeTruthy();  
34 - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeFalsy(); 34 + let switchEl: INgForwardJQuery = helper.debugElement.query('span.switch');
  35 +
  36 + expect(switchEl.hasClass('checked')).toBeFalsy();
35 helper.component.inDesignMode = true; 37 helper.component.inDesignMode = true;
36 helper.detectChanges(); 38 helper.detectChanges();
37 - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-on')).toBeTruthy();  
38 - expect(helper.debugElement.query('div.switch-animate').hasClass('switch-off')).toBeFalsy(); 39 + expect(switchEl.hasClass('checked')).toBeTruthy();
39 }); 40 });
40 41
41 it('emits event with value "true" when changing inDesignMode to On', (done) => { 42 it('emits event with value "true" when changing inDesignMode to On', (done) => {
@@ -60,4 +61,4 @@ describe(&#39;DesignModeToggler Component&#39;, () =&gt; { @@ -60,4 +61,4 @@ describe(&#39;DesignModeToggler Component&#39;, () =&gt; {
60 helper.component.inDesignMode = false; 61 helper.component.inDesignMode = false;
61 helper.detectChanges(); 62 helper.detectChanges();
62 }); 63 });
63 -});  
64 \ No newline at end of file 64 \ No newline at end of file
  65 +});
src/app/admin/layout-edit/designModeToggler.component.ts
1 -import {Component, Inject} from 'ng-forward'; 1 +import {Component, Inject, Input} from 'ng-forward';
2 import {DesignModeService} from './designMode.service'; 2 import {DesignModeService} from './designMode.service';
3 import {AuthService, AuthEvents} from '../../login'; 3 import {AuthService, AuthEvents} from '../../login';
4 4
5 @Component({ 5 @Component({
6 - selector: 'noosfero-design-toggler', 6 + selector: 'design-toggler',
7 templateUrl: 'app/admin/layout-edit/designModeToggler.html' 7 templateUrl: 'app/admin/layout-edit/designModeToggler.html'
8 }) 8 })
9 -@Inject(DesignModeService, AuthService) 9 +@Inject(DesignModeService, AuthService, '$sce')
10 export class DesignModeTogglerComponent { 10 export class DesignModeTogglerComponent {
11 11
12 - icon: string = "&nbsp;<i class='glyphicon glyphicon-wrench'></i>&nbsp;"; 12 + private _inDesignMode: boolean = false;
13 13
14 - constructor(private designModeService: DesignModeService, private authService: AuthService) { 14 + constructor(private designModeService: DesignModeService, private authService: AuthService, private $sce: ng.ISCEService) {
15 this.authService.subscribe(AuthEvents[AuthEvents.logoutSuccess], () => { 15 this.authService.subscribe(AuthEvents[AuthEvents.logoutSuccess], () => {
16 this.designModeService.destroy(); 16 this.designModeService.destroy();
17 }); 17 });
18 } 18 }
19 19
20 - private _inDesignMode: boolean = false;  
21 -  
22 get inDesignMode(): boolean { 20 get inDesignMode(): boolean {
23 return this.designModeService.isInDesignMode(); 21 return this.designModeService.isInDesignMode();
24 }; 22 };
src/app/admin/layout-edit/designModeToggler.html
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>  
9 \ No newline at end of file 1 \ No newline at end of file
  2 +<switch id="enabled" name="enabled" ng-model="ctrl.inDesignMode" on="ON" off="OFF" class="green"></switch>
src/app/admin/layout-edit/designModeToggler.scss 0 → 100644
@@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
  1 +$off-text: #949494;
  2 +$off-color: #EFEFEF;
  3 +$blue-color: #36B4F6;
  4 +$red-color: #DF3B3A;
  5 +
  6 +body.noosfero-design-on {
  7 +
  8 + div.content-wrapper {
  9 + opacity: 0.5;
  10 + }
  11 +}
  12 +
  13 +.switch {
  14 + @include not-select();
  15 + background-color: $off-color;
  16 +
  17 + &[on][off] {
  18 + width: 60px;
  19 + }
  20 +
  21 + &:focus {
  22 + outline: none;
  23 + }
  24 +
  25 + &.checked small {
  26 + left: initial;
  27 + right: 0px;
  28 + }
  29 +
  30 + &.blue.checked {
  31 + background: $blue-color;
  32 + border-color: $blue-color;
  33 + }
  34 +
  35 + &.red.checked {
  36 + background: $red-color;
  37 + border-color: $red-color;
  38 + }
  39 +
  40 + %switch-label {
  41 + font-weight: bold;
  42 + }
  43 +
  44 + .on {
  45 + @extend %switch-label;
  46 + }
  47 +
  48 + .off {
  49 + @extend %switch-label;
  50 + right: 2px;
  51 + top: 25%;
  52 + color: $off-text;
  53 + text-align: center;
  54 + }
  55 +}
src/app/environment/environment.html
1 <div class="environment-container"> 1 <div class="environment-container">
2 <div class="row"> 2 <div class="row">
3 - <noosfero-boxes ng-if="vm.boxes" [boxes]="vm.boxes" [owner]="vm.environment"></noosfero-boxes> 3 + <noosfero-boxes ng-if="vm.boxes"
  4 + [layout]="vm.environment.layout_template"
  5 + [boxes]="vm.boxes"
  6 + [owner]="vm.environment">
  7 + </noosfero-boxes>
4 </div> 8 </div>
5 </div> 9 </div>
src/app/layout/blocks/recent-activities-plugin-activities/activities/add_member_in_community.html 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +{{'joined the community' | translate}}
src/app/layout/blocks/recent-activities-plugin-activities/activities/create_article.html 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +{{'published an article:' | translate}} <a ng-href="{{ctrl.urlFor(activity.params.url)}}">{{activity.params.name}}</a>
src/app/layout/blocks/recent-activities-plugin-activities/activities/event.html 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<img ng-src="{{activity.params.first_image}}" ng-attr-alt="{{activity.params.name}}" class="event-image" />
  2 +<p class="event-description"><b>{{activity.params.name}}</b><br />{{activity.params.lead | stripTags}}</p>
  3 +<br style="clear: both;" />
src/app/layout/blocks/recent-activities-plugin-activities/activities/favorite_enterprise.html 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +{{'favorited an enterprise:' | translate}} <a ng-href="{{ctrl.urlFor(activity.params.enterprise_url)}}">{{activity.params.enterprise_name}}</a>
src/app/layout/blocks/recent-activities-plugin-activities/activities/new_friendship.html 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +{{'has made new friends:' | translate}}<br />
  2 +<span ng-repeat="name in activity.params.friend_name">
  3 + <a ng-href="{{ctrl.urlFor(activity.params.friend_url[$index])}}" ng-attr-title="{{name}}">
  4 + <img ng-src="{{activity.params.friend_profile_custom_icon[$index]}}" ng-attr-alt="{{name}}" />
  5 + </a>
  6 +</span>
src/app/layout/blocks/recent-activities-plugin-activities/activities/upload_image.html 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +{{'uploaded images:' | translate}}<br />
  2 +<span ng-repeat="path in activity.params.thumbnail_path">
  3 + <a class="upimg" ng-href="{{ctrl.urlFor(activity.params.view_url[$index])}}" ng-style="{'background-image':'url({{path}})'}">
  4 + <span>{{path}}</span>
  5 + </a>
  6 +</span>
src/app/layout/blocks/recent-activities-plugin-activities/index.ts 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./recent-activities-plugin-activities-block.component";
src/app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.component.spec.ts 0 → 100644
@@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
  1 +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
  2 +import {Provider, Input, provide, Component} from 'ng-forward';
  3 +import {provideFilters} from '../../../../spec/helpers';
  4 +import {RecentActivitiesPluginActivitiesBlockComponent} from './recent-activities-plugin-activities-block.component';
  5 +import * as helpers from "./../../../../spec/helpers";
  6 +
  7 +const htmlTemplate: string = '<noosfero-recent-activities-plugin-activities-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-recent-activities-plugin-activities-block>';
  8 +
  9 +const tcb = new TestComponentBuilder();
  10 +
  11 +describe("Components", () => {
  12 + describe("Recent Activities Block Component", () => {
  13 +
  14 + let settingsObj = {};
  15 + let person = <noosfero.Person>{ name: "Person" };
  16 + let mockedService = {
  17 + getApiContent: (block: noosfero.Block): any => {
  18 + return Promise.resolve({ activities: [{ verb: 'new_friendship' }], headers: (name: string) => { return name; } });
  19 + }
  20 + };
  21 + beforeEach(angular.mock.module("templates"));
  22 +
  23 + let state = jasmine.createSpyObj("state", ["go"]);
  24 +
  25 +
  26 + function getProviders() {
  27 + return [
  28 + new Provider('$state', { useValue: state }),
  29 + new Provider('BlockService', {
  30 + useValue: mockedService
  31 + })
  32 + ].concat(provideFilters("truncateFilter", "stripTagsFilter"));
  33 + }
  34 + let componentClass: any = null;
  35 +
  36 + function getComponent() {
  37 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [RecentActivitiesPluginActivitiesBlockComponent], providers: getProviders() })
  38 + class BlockContainerComponent {
  39 + block = { type: 'Block', settings: settingsObj };
  40 + owner = person;
  41 + constructor() {
  42 + }
  43 + }
  44 + return BlockContainerComponent;
  45 + }
  46 +
  47 + it("get activities from block service", done => {
  48 + tcb.createAsync(getComponent()).then(fixture => {
  49 + let RecentActivitiesPluginActivitiesBlock: RecentActivitiesPluginActivitiesBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  50 + expect(RecentActivitiesPluginActivitiesBlock.activities[0]['verb']).toEqual('new_friendship');
  51 + done();
  52 + });
  53 + });
  54 +
  55 + });
  56 +});
src/app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.component.ts 0 → 100644
@@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
  1 +import {Component, Inject, Input} from "ng-forward";
  2 +import {BlockService} from "../../../../lib/ng-noosfero-api/http/block.service";
  3 +import {Arrays} from "./../../../../lib/util/arrays";
  4 +
  5 +@Component({
  6 + selector: "noosfero-recent-activities-plugin-activities-block",
  7 + templateUrl: 'app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.html'
  8 +})
  9 +@Inject(BlockService, "$state")
  10 +export class RecentActivitiesPluginActivitiesBlockComponent {
  11 +
  12 + @Input() block: any;
  13 + @Input() owner: any;
  14 +
  15 + profile: any;
  16 + activities: any;
  17 +
  18 + constructor(private blockService: BlockService, private $state: any) { }
  19 +
  20 + getActivityTemplate(activity: any) {
  21 + if (activity.label === 'events') {
  22 + return 'app/layout/blocks/recent-activities-plugin-activities/activities/event.html';
  23 + }
  24 + else {
  25 + return 'app/layout/blocks/recent-activities-plugin-activities/activities/' + activity.verb + '.html';
  26 + }
  27 + }
  28 +
  29 + urlFor(params: any) {
  30 + let url = '//' + params.host;
  31 + if (params.port) {
  32 + url += ':' + params.port;
  33 + }
  34 + url += '/' + params.profile + '/';
  35 + if (params.page) {
  36 + url += params.page.join('/');
  37 + }
  38 + return url;
  39 + }
  40 +
  41 + ngOnInit() {
  42 + this.profile = this.owner;
  43 + this.activities = [];
  44 + this.blockService.getApiContent(this.block).then((content: any) => {
  45 + this.activities = content.activities;
  46 + });
  47 + }
  48 +}
src/app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.html 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +<div class="deckgrid recent-activities-block">
  2 + <div ng-repeat="activity in ctrl.activities" class="a-card panel media">
  3 +
  4 + <div class="subheader">
  5 + <p ng-if="activity.label === 'events'">
  6 + {{ 'activities.event.description' | translate }} <b>{{ activity.start_date | date:longDate }}</b> {{ 'time.at' | translate }} {{ activity.start_date | date:'HH:mm' }} - <a ng-href="/{{activity.user.identifier}}">{{activity.user.name}}</a> <span class="activity-label">{{activity.label}}</span>
  7 + </p>
  8 +
  9 + <p ng-if="activity.label !== 'events'">
  10 + {{ 'date.on' | translate }} <b>{{ activity.created_at | date:longDate }}</b> {{ 'time.at' | translate }} {{ activity.created_at | date:'HH:mm' }} - <a ng-href="/{{activity.user.identifier}}">{{activity.user.name}}</a> <span class="activity-label">{{activity.label}}</span>
  11 + </p>
  12 + </div>
  13 +
  14 + <div class="header media-body">
  15 + <h5 class="title media-heading">
  16 + <ng-include src="ctrl.getActivityTemplate(activity)"></ng-include>
  17 + </h5>
  18 + </div>
  19 +
  20 + <hr />
  21 + </div>
  22 +</div>
src/app/layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.scss 0 → 100644
@@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
  1 +.col-md-2-5 .deckgrid[deckgrid]::before {
  2 + visibility: hidden;
  3 +}
  4 +
  5 +.recent-activities-block {
  6 + img, .upimg {
  7 + padding: 1px;
  8 + border: 1px solid #ccc;
  9 + margin-right: 2px;
  10 + margin-top: 2px;
  11 + }
  12 +
  13 + .upimg {
  14 + display: inline-block;
  15 + width: 20px;
  16 + height: 20px;
  17 + background-size: cover;
  18 +
  19 + span {
  20 + display: none;
  21 + }
  22 + }
  23 +
  24 + .panel {
  25 + margin-bottom: 15px;
  26 + box-shadow: none;
  27 + border-radius: 0;
  28 + }
  29 +
  30 + h5 {
  31 + text-transform: capitalize;
  32 + }
  33 +
  34 + .subheader {
  35 + p {
  36 + margin: 2px 0;
  37 + font-size: 11px;
  38 + }
  39 + }
  40 +
  41 + hr {
  42 + border: 0;
  43 + height: 1px;
  44 + background: #ccc;
  45 + margin: 0;
  46 + margin-top: 15px;
  47 + }
  48 +
  49 + .activity-label {
  50 + @include border-radius(2px);
  51 + font-size: 11px;
  52 + text-transform: capitalize;
  53 + background: #333;
  54 + color: #fff;
  55 + padding: 2px;
  56 + margin-left: 5px;
  57 + display: inline-block;
  58 + }
  59 +
  60 + .event-image {
  61 + width: 15%;
  62 + height: auto;
  63 + float: left;
  64 + }
  65 +
  66 + .event-description {
  67 + width: 83%;
  68 + margin: 2px 0 0 2px;
  69 + float: left;
  70 + display: block;
  71 + }
  72 +}
src/app/layout/boxes/box.html
1 -<div ng-class="{'col-md-2-5': box.position!=1, 'col-md-7': box.position==1}">  
2 - <noosfero-block ng-repeat="block in box.blocks | orderBy: 'position'" [block]="block" [owner]="ctrl.owner"></noosfero-block> 1 +<div ng-class="box.position | setBoxLayout:ctrl.layout">
  2 + <noosfero-block
  3 + ng-repeat="block in box.blocks | orderBy: 'position'"
  4 + [block]="block" [owner]="ctrl.owner">
  5 + </noosfero-block>
3 </div> 6 </div>
src/app/layout/boxes/boxes.component.spec.ts
@@ -45,12 +45,7 @@ describe(&quot;Boxes Component&quot;, () =&gt; { @@ -45,12 +45,7 @@ describe(&quot;Boxes Component&quot;, () =&gt; {
45 state.current = { name: "" }; 45 state.current = { name: "" };
46 46
47 it("renders boxes into a container", () => { 47 it("renders boxes into a container", () => {
48 - expect(helper.find('div.col-md-7').length).toEqual(1);  
49 - expect(helper.find('div.col-md-2-5').length).toEqual(1);  
50 - });  
51 -  
52 - it("check the boxes order", () => {  
53 - expect(helper.component.boxesOrder(properties['boxes'][0])).toEqual(1);  
54 - expect(helper.component.boxesOrder(properties['boxes'][1])).toEqual(0); 48 + expect(helper.find('div.col-md-6').length).toEqual(1);
  49 + expect(helper.find('div.col-md-3').length).toEqual(1);
55 }); 50 });
56 }); 51 });
src/app/layout/boxes/boxes.component.ts
1 import {Input, Component} from 'ng-forward'; 1 import {Input, Component} from 'ng-forward';
  2 +import {DisplayBoxes} from "./display-boxes.filter";
  3 +import {SetBoxLayout} from "./set-box-layout.filter";
2 4
3 @Component({ 5 @Component({
4 selector: "noosfero-boxes", 6 selector: "noosfero-boxes",
5 - templateUrl: "app/layout/boxes/boxes.html" 7 + templateUrl: "app/layout/boxes/boxes.html",
  8 + directives: [DisplayBoxes, SetBoxLayout]
6 }) 9 })
7 export class BoxesComponent { 10 export class BoxesComponent {
8 11
9 @Input() boxes: noosfero.Box[]; 12 @Input() boxes: noosfero.Box[];
10 @Input() owner: noosfero.Profile | noosfero.Environment; 13 @Input() owner: noosfero.Profile | noosfero.Environment;
  14 + @Input() layout: string;
11 15
12 - boxesOrder(box: noosfero.Box) {  
13 - if (box.position === 2) return 0;  
14 - return box.position;  
15 - }  
16 } 16 }
src/app/layout/boxes/boxes.html
1 -<ng-include ng-repeat="box in ctrl.boxes | orderBy: ctrl.boxesOrder" src="'app/layout/boxes/box.html'"></ng-include> 1 +<ng-include ng-repeat="box in ctrl.boxes | displayBoxes:ctrl.layout" src="'app/layout/boxes/box.html'"></ng-include>
src/app/layout/boxes/display-boxes.filter.spec.ts 0 → 100644
@@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
  1 +import {DisplayBoxes} from './display-boxes.filter';
  2 +
  3 +describe("Boxes Filters", () => {
  4 + describe("Display Boxes Filter", () => {
  5 +
  6 + let boxes: noosfero.Box[] = [
  7 + {id: 1, position: 1 },
  8 + {id: 2, position: 2 },
  9 + {id: 3, position: 3 },
  10 + {id: 4, position: 4 }
  11 + ];
  12 +
  13 + let expected_on_default: noosfero.Box[] = [
  14 + {id: 1, position: 1 },
  15 + {id: 2, position: 2 },
  16 + {id: 3, position: 3 },
  17 + ];
  18 +
  19 + let expected_on_rightbar: noosfero.Box[] = [
  20 + {id: 1, position: 1 },
  21 + {id: 3, position: 3 },
  22 + ];
  23 +
  24 + it("filter boxes when layout is set to default", done => {
  25 + let filter = new DisplayBoxes();
  26 +
  27 + let filtered_boxes: noosfero.Box[] = filter.transform(boxes, "default");
  28 + expect(filtered_boxes.length).toEqual(3);
  29 + expect(filtered_boxes).toEqual(expected_on_default);
  30 + done();
  31 + });
  32 +
  33 + it("filter boxes when layout is set to rightbar", done => {
  34 + let filter = new DisplayBoxes();
  35 +
  36 + let filtered_boxes: noosfero.Box[] = filter.transform(boxes, "rightbar");
  37 + expect(filtered_boxes.length).toEqual(2);
  38 + expect(filtered_boxes).toEqual(expected_on_rightbar);
  39 + done();
  40 + });
  41 +
  42 + it("filter boxes with default layout when invalid layout is given", done => {
  43 + let filter = new DisplayBoxes();
  44 +
  45 + let filtered_boxes: noosfero.Box[] = filter.transform(boxes, "");
  46 + expect(filtered_boxes.length).toEqual(3);
  47 + expect(filtered_boxes).toEqual(expected_on_default);
  48 + done();
  49 + });
  50 + });
  51 +});
src/app/layout/boxes/display-boxes.filter.ts 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +import {Pipe, Inject} from "ng-forward";
  2 +
  3 +@Pipe("displayBoxes")
  4 +export class DisplayBoxes {
  5 +
  6 + transform(boxes: noosfero.Box[], layout: string) {
  7 + let function_str: string = "visible_on" + layout;
  8 + let valid_boxes: number[] = [];
  9 + let selected: noosfero.Box[] = [];
  10 + boxes = boxes || [];
  11 +
  12 + if (layout === "rightbar") {
  13 + valid_boxes = this.visible_on_right_bar();
  14 + }else {
  15 + valid_boxes = this.visible_on_default();
  16 + }
  17 +
  18 + for (let box of boxes) {
  19 + if (valid_boxes.indexOf(box.position) !== -1) {
  20 + selected.push(box);
  21 + }
  22 + }
  23 + return selected;
  24 + }
  25 +
  26 + private visible_on_default() {
  27 + return [1, 2, 3];
  28 + }
  29 +
  30 + private visible_on_right_bar() {
  31 + return [1, 3];
  32 + }
  33 +
  34 +}
  35 +
src/app/layout/boxes/set-box-layout.filter.spec.ts 0 → 100644
@@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
  1 +import {SetBoxLayout} from './set-box-layout.filter';
  2 +
  3 +describe("Boxes Filters", () => {
  4 + describe("Set Box Layout Filter", () => {
  5 + let box_layout_filter = new SetBoxLayout();
  6 + describe("When layout is set to default", () => {
  7 + it("return style when box position is 1 ", done => {
  8 + expect(box_layout_filter.transform(1, "default")).toEqual("col-md-6 col-md-push-3");
  9 + done();
  10 + });
  11 + it("return style when box position is 2", done => {
  12 + expect(box_layout_filter.transform(2, "default")).toEqual("col-md-3 col-md-pull-6");
  13 + done();
  14 + });
  15 + it("return style when any other position is given", done => {
  16 + expect(box_layout_filter.transform(null, "default")).toEqual("col-md-3");
  17 + expect(box_layout_filter.transform(3, "default")).toEqual("col-md-3");
  18 + expect(box_layout_filter.transform(99, "default")).toEqual("col-md-3");
  19 + done();
  20 + });
  21 + });
  22 +
  23 + describe("When layout is set to right_bar", () => {
  24 + it("return style when box position is 1 ", done => {
  25 + expect(box_layout_filter.transform(1, "rightbar")).toEqual("col-sm-12 col-md-8");
  26 + done();
  27 + });
  28 + it("return style when box other position is given", done => {
  29 + expect(box_layout_filter.transform(2, "rightbar")).toEqual("col-sm-12 col-md-4");
  30 + done();
  31 + });
  32 + });
  33 + });
  34 +});
src/app/layout/boxes/set-box-layout.filter.ts 0 → 100644
@@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
  1 +import {Pipe, Inject} from "ng-forward";
  2 +
  3 +@Pipe("setBoxLayout")
  4 +export class SetBoxLayout {
  5 +
  6 + transform(pos: number, layout: string) {
  7 + if (layout === "rightbar") {
  8 + return this.right_bar(pos);
  9 + }else {
  10 + return this.default(pos);
  11 + }
  12 + }
  13 +
  14 + private default(position: number) {
  15 + if (position === 1) {
  16 + return "col-md-6 col-md-push-3";
  17 + }else if (position === 2) {
  18 + return "col-md-3 col-md-pull-6";
  19 + }else {
  20 + return "col-md-3";
  21 + }
  22 + }
  23 +
  24 + private right_bar(position: number) {
  25 + if (position === 1) {
  26 + return "col-sm-12 col-md-8";
  27 + }else {
  28 + return "col-sm-12 col-md-4";
  29 + }
  30 + }
  31 +
  32 +}
src/app/layout/scss/_layout.scss
@@ -34,17 +34,4 @@ @@ -34,17 +34,4 @@
34 .main-box-body { 34 .main-box-body {
35 padding: 0 20px 20px 20px; 35 padding: 0 20px 20px 20px;
36 } 36 }
37 -}  
38 -  
39 -ul.nav > li.toggler-container {  
40 - position: relative;  
41 - padding-top: 12px;  
42 -}  
43 -  
44 -.noosfero-main-toolbar {  
45 - padding: 5px;  
46 - @include make-row();  
47 - margin-left: 0px;  
48 - margin-right: 0px;  
49 - background-color: #edecec;  
50 -} 37 +}
51 \ No newline at end of file 38 \ No newline at end of file
src/app/layout/scss/_mixins.scss
@@ -4,6 +4,12 @@ @@ -4,6 +4,12 @@
4 background-clip: padding-box; /* stops bg color from leaking outside the border: */ 4 background-clip: padding-box; /* stops bg color from leaking outside the border: */
5 } 5 }
6 6
  7 +@mixin box-shadow($args...) {
  8 + -webkit-box-shadow: $args;
  9 + -moz-box-shadow: $args;
  10 + box-shadow: $args;
  11 +}
  12 +
7 @mixin checkbox-mark($width, $height, $top, $left, $bg, $border, $content: "", $cursor: pointer, $position: absolute) { 13 @mixin checkbox-mark($width, $height, $top, $left, $bg, $border, $content: "", $cursor: pointer, $position: absolute) {
8 width: $width; 14 width: $width;
9 height: $height; 15 height: $height;
@@ -48,3 +54,31 @@ @@ -48,3 +54,31 @@
48 outline-width: $width; 54 outline-width: $width;
49 } 55 }
50 } 56 }
  57 +
  58 +@mixin not-select() {
  59 + -webkit-touch-callout: none; /* iOS Safari */
  60 + -webkit-user-select: none; /* Chrome/Safari/Opera */
  61 + -khtml-user-select: none; /* Konqueror */
  62 + -moz-user-select: none; /* Firefox */
  63 + -ms-user-select: none; /* Internet Explorer/Edge */
  64 + user-select: none; /* Non-prefixed version, currently
  65 + not supported by any browser */
  66 +}
  67 +
  68 +@mixin keyframes($animation-name) {
  69 + @-webkit-keyframes #{$animation-name} {
  70 + @content;
  71 + }
  72 + @-moz-keyframes #{$animation-name} {
  73 + @content;
  74 + }
  75 + @-ms-keyframes #{$animation-name} {
  76 + @content;
  77 + }
  78 + @-o-keyframes #{$animation-name} {
  79 + @content;
  80 + }
  81 + @keyframes #{$animation-name} {
  82 + @content;
  83 + }
  84 +}
src/app/layout/scss/skins/_whbl.scss
@@ -291,11 +291,7 @@ $whbl-font-color: #16191c; @@ -291,11 +291,7 @@ $whbl-font-color: #16191c;
291 background-color: #fff; 291 background-color: #fff;
292 } 292 }
293 293
294 - noosfero-design-toggler .ats-switch .knob i {  
295 - color: #999999;  
296 - }  
297 -  
298 - .ats-switch .knob { 294 + .ats-switch .knob {
299 padding-right: 15px; 295 padding-right: 15px;
300 } 296 }
301 297
src/app/layout/services/body-state-classes.service.spec.ts
@@ -193,7 +193,6 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; { @@ -193,7 +193,6 @@ describe(&quot;BodyStateClasses Service&quot;, () =&gt; {
193 193
194 service.start(); 194 service.start();
195 195
196 - debugger;  
197 designModeService.setInDesignMode(true); 196 designModeService.setInDesignMode(true);
198 197
199 198
src/app/main/main.component.ts
@@ -20,6 +20,7 @@ import {StatisticsBlockComponent} from &quot;../layout/blocks/statistics/statistics-b @@ -20,6 +20,7 @@ import {StatisticsBlockComponent} from &quot;../layout/blocks/statistics/statistics-b
20 import {PersonTagsPluginInterestsBlockComponent} from "../layout/blocks/person-tags-plugin-interests/person-tags-plugin-interests-block.component"; 20 import {PersonTagsPluginInterestsBlockComponent} from "../layout/blocks/person-tags-plugin-interests/person-tags-plugin-interests-block.component";
21 import {TagsBlockComponent} from "../layout/blocks/tags/tags-block.component"; 21 import {TagsBlockComponent} from "../layout/blocks/tags/tags-block.component";
22 import {CustomContentComponent} from "../profile/custom-content/custom-content.component"; 22 import {CustomContentComponent} from "../profile/custom-content/custom-content.component";
  23 +import {RecentActivitiesPluginActivitiesBlockComponent} from "../layout/blocks/recent-activities-plugin-activities/recent-activities-plugin-activities-block.component";
23 24
24 import {MembersBlockComponent} from "../layout/blocks/members/members-block.component"; 25 import {MembersBlockComponent} from "../layout/blocks/members/members-block.component";
25 import {CommunitiesBlockComponent} from "../layout/blocks/communities/communities-block.component"; 26 import {CommunitiesBlockComponent} from "../layout/blocks/communities/communities-block.component";
@@ -87,7 +88,7 @@ export class EnvironmentContent { @@ -87,7 +88,7 @@ export class EnvironmentContent {
87 * @name main.Main 88 * @name main.Main
88 * @requires AuthService, Session, Notification, ArticleBlog, ArticleView, Boxes, Block, LinkListBlock, 89 * @requires AuthService, Session, Notification, ArticleBlog, ArticleView, Boxes, Block, LinkListBlock,
89 * MainBlock, RecentDocumentsBlock, Navbar, ProfileImageBlock, MembersBlock, 90 * MainBlock, RecentDocumentsBlock, Navbar, ProfileImageBlock, MembersBlock,
90 - * NoosferoTemplate, DateFormat, RawHTMLBlock, PersonTagsPluginInterestsBlock 91 + * NoosferoTemplate, DateFormat, RawHTMLBlock, PersonTagsPluginInterestsBlock, RecentActivitiesPluginActivitiesBlock,
91 * @description 92 * @description
92 * The Main controller for the Noosfero Angular Theme application. 93 * The Main controller for the Noosfero Angular Theme application.
93 * 94 *
@@ -106,7 +107,7 @@ export class EnvironmentContent { @@ -106,7 +107,7 @@ export class EnvironmentContent {
106 MainBlockComponent, RecentDocumentsBlockComponent, Navbar, SidebarComponent, ProfileImageBlockComponent, 107 MainBlockComponent, RecentDocumentsBlockComponent, Navbar, SidebarComponent, ProfileImageBlockComponent,
107 MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent, StatisticsBlockComponent, 108 MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent, StatisticsBlockComponent,
108 LoginBlockComponent, CustomContentComponent, PermissionDirective, SearchFormComponent, SearchComponent, 109 LoginBlockComponent, CustomContentComponent, PermissionDirective, SearchFormComponent, SearchComponent,
109 - PersonTagsPluginInterestsBlockComponent, TagsBlockComponent, BlockComponent 110 + PersonTagsPluginInterestsBlockComponent, TagsBlockComponent, RecentActivitiesPluginActivitiesBlockComponent, BlockComponent
110 ].concat(plugins.mainComponents).concat(plugins.hotspots), 111 ].concat(plugins.mainComponents).concat(plugins.hotspots),
111 providers: [AuthService, SessionService, NotificationService, BodyStateClassesService, 112 providers: [AuthService, SessionService, NotificationService, BodyStateClassesService,
112 "ngAnimate", "ngCookies", "ngStorage", "ngTouch", 113 "ngAnimate", "ngCookies", "ngStorage", "ngTouch",
@@ -115,7 +116,7 @@ export class EnvironmentContent { @@ -115,7 +116,7 @@ export class EnvironmentContent {
115 "angular-bind-html-compile", "angularMoment", "angular.filter", "akoenig.deckgrid", 116 "angular-bind-html-compile", "angularMoment", "angular.filter", "akoenig.deckgrid",
116 "angular-timeline", "duScroll", "oitozero.ngSweetAlert", 117 "angular-timeline", "duScroll", "oitozero.ngSweetAlert",
117 "pascalprecht.translate", "tmh.dynamicLocale", "angularLoad", 118 "pascalprecht.translate", "tmh.dynamicLocale", "angularLoad",
118 - "angular-click-outside", "toggle-switch", "ngTagCloud", "noosfero.init"] 119 + "angular-click-outside", "ngTagCloud", "noosfero.init", "uiSwitch"]
119 }) 120 })
120 @StateConfig([ 121 @StateConfig([
121 { 122 {
src/app/profile/config-bar.component.ts 0 → 100644
@@ -0,0 +1,21 @@ @@ -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: "configbar",
  6 + templateUrl: "app/profile/configbar.html",
  7 + providers: [
  8 + provide('profileService', { useClass: ProfileService })
  9 + ]
  10 +})
  11 +@Inject(ProfileService)
  12 +export class ConfigBarComponent {
  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/configbar.html 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +<div id="config-tool" ng-class="{'closed': !showConfig}">
  2 + <a id="config-tool-cog" ng-click="showConfig = !showConfig">
  3 + <i class="fa fa-cog" ng-class="{'anim-icon': showConfig}"></i>
  4 + </a>
  5 +
  6 + <div id="config-tool-options">
  7 + <h4>{{ 'configbar.label' | translate }}</h4>
  8 + <div class="section-title">{{ 'configbar.section.layout' | translate }}</div>
  9 + <ul>
  10 + <li>
  11 + <label class="pull-left">
  12 + <i class="fa fa-th-large"></i>
  13 + <span class="item-label">{{ 'designMode.label' | translate }}</span>
  14 + </label>
  15 + <label class="pull-right">
  16 + <design-toggler></design-toggler>
  17 + </label>
  18 + </li>
  19 + </ul>
  20 + </div>
  21 +</div>
src/app/profile/configbar.scss 0 → 100644
@@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
  1 +@import "../layout/scss/mixins";
  2 +
  3 +@include keyframes(rotating) {
  4 + from {
  5 + transform: rotate(0deg);
  6 + }
  7 + to {
  8 + transform: rotate(360deg);
  9 + }
  10 +}
  11 +
  12 +/* CONFIG TOOLS */
  13 +#config-tool {
  14 + @include transition(all 0.2s ease-in-out 0s);
  15 + @include box-shadow(0px 1px 4px rgba(0, 0, 0, 0.3));
  16 + position: fixed;
  17 + right: 0;
  18 + top: 120px;
  19 + min-width: 200px;
  20 + z-index: 1000;
  21 +
  22 + #config-tool-cog {
  23 + @include border-radius($border-radius-base 0 0 $border-radius-base);
  24 + @include transition(all 0.1s ease-in-out 0s);
  25 + @include box-shadow(-3px 3px 3px -2px rgba(0, 0, 0, 0.1));
  26 + background: #fff;
  27 + cursor: pointer;
  28 + left: -50px;
  29 + padding: 10px;
  30 + position: absolute;
  31 + text-align: center;
  32 + width: 50px;
  33 + top: 0;
  34 +
  35 + i {
  36 + font-size: 2.2em;
  37 + }
  38 +
  39 + .anim-icon {
  40 + @include animation(rotating 0.7s ease-in-out 0s);
  41 + }
  42 + }
  43 +
  44 + &.closed {
  45 + right: -280px;
  46 + box-shadow: none;
  47 +
  48 + #config-tool-cog {
  49 + &:hover {
  50 + background-color: $primary-color;
  51 + color: #fff;
  52 + }
  53 + }
  54 + }
  55 +
  56 + &.opened {
  57 + right: 0;
  58 + }
  59 +
  60 + .section-title {
  61 + margin: 30px 0 5px;
  62 + font: {
  63 + size: 15px;
  64 + weight: bold;
  65 + }
  66 +
  67 + }
  68 +
  69 + #config-tool-options {
  70 + @include box-shadow(-3px 3px 3px -2px rgba(0, 0, 0, 0.1));
  71 + background: #fff;
  72 + padding: 15px;
  73 +
  74 + h4 {
  75 + margin: 0;
  76 + font-size: 1.3em;
  77 + }
  78 +
  79 + ul {
  80 + list-style: none;
  81 + border-radius: 2px;
  82 + padding: 0;
  83 +
  84 + background: {
  85 + clip: padding-box;
  86 + color: #f1f3f2;
  87 + }
  88 +
  89 + li {
  90 + padding: 10px;
  91 + width: 250px;
  92 + min-height: 50px;
  93 + font: {
  94 + size: 13px;
  95 + weight: 300;
  96 + }
  97 +
  98 + .checkbox {
  99 + margin: 0;
  100 + }
  101 +
  102 + .pull-left {
  103 + margin-top: 8px;
  104 + font-weight: normal;
  105 + }
  106 +
  107 + }
  108 + }
  109 + }
  110 +}
src/app/profile/profile-toolbar.component.ts
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
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,7 +10,7 @@ import {ProfileService} from &quot;../../lib/ng-noosfero-api/http/profile.service&quot;;
10 import {NotificationService} from "../shared/services/notification.service"; 10 import {NotificationService} from "../shared/services/notification.service";
11 import {MyProfileComponent} from "./myprofile.component"; 11 import {MyProfileComponent} from "./myprofile.component";
12 import {ProfileActionsComponent} from "./profile-actions.component"; 12 import {ProfileActionsComponent} from "./profile-actions.component";
13 -import {ProfileToolbarComponent} from "./profile-toolbar.component"; 13 +import {ConfigBarComponent} from "./config-bar.component";
14 /** 14 /**
15 * @ngdoc controller 15 * @ngdoc controller
16 * @name profile.Profile 16 * @name profile.Profile
@@ -44,8 +44,8 @@ import {ProfileToolbarComponent} from &quot;./profile-toolbar.component&quot;; @@ -44,8 +44,8 @@ import {ProfileToolbarComponent} from &quot;./profile-toolbar.component&quot;;
44 controllerAs: "vm" 44 controllerAs: "vm"
45 }, 45 },
46 "toolbar@main": { 46 "toolbar@main": {
47 - templateUrl: "app/profile/toolbar.html",  
48 - controller: ProfileToolbarComponent, 47 + templateUrl: "app/profile/configbar.html",
  48 + controller: ConfigBarComponent,
49 controllerAs: "vm" 49 controllerAs: "vm"
50 } 50 }
51 } 51 }
@@ -61,8 +61,8 @@ import {ProfileToolbarComponent} from &quot;./profile-toolbar.component&quot;; @@ -61,8 +61,8 @@ import {ProfileToolbarComponent} from &quot;./profile-toolbar.component&quot;;
61 controllerAs: "vm" 61 controllerAs: "vm"
62 }, 62 },
63 "toolbar@main": { 63 "toolbar@main": {
64 - templateUrl: "app/profile/toolbar.html",  
65 - controller: ProfileToolbarComponent, 64 + templateUrl: "app/profile/configbar.html",
  65 + controller: ConfigBarComponent,
66 controllerAs: "vm" 66 controllerAs: "vm"
67 } 67 }
68 } 68 }
@@ -118,8 +118,8 @@ import {ProfileToolbarComponent} from &quot;./profile-toolbar.component&quot;; @@ -118,8 +118,8 @@ import {ProfileToolbarComponent} from &quot;./profile-toolbar.component&quot;;
118 controllerAs: "vm" 118 controllerAs: "vm"
119 }, 119 },
120 "toolbar@main": { 120 "toolbar@main": {
121 - templateUrl: "app/profile/toolbar.html",  
122 - controller: ProfileToolbarComponent, 121 + templateUrl: "app/profile/configbar.html",
  122 + controller: ConfigBarComponent,
123 controllerAs: "vm" 123 controllerAs: "vm"
124 } 124 }
125 } 125 }
src/app/profile/profile.html
1 <div class="profile-container"> 1 <div class="profile-container">
2 - <custom-content class="profile-header" [label]="'profile.custom_header.label'" [attribute]="'custom_header'" [profile]="vm.profile"></custom-content>  
3 - <div class="row">  
4 - <noosfero-boxes ng-if="vm.boxes" [boxes]="vm.boxes" [owner]="vm.profile"></noosfero-boxes>  
5 - </div> 2 + <custom-content class="profile-header"
  3 + [label]="'profile.custom_header.label'"
  4 + [attribute]="'custom_header'"
  5 + [profile]="vm.profile">
  6 + </custom-content>
  7 + <noosfero-boxes ng-if="vm.boxes"
  8 + [layout]="vm.profile.layout_template"
  9 + [boxes]="vm.boxes"
  10 + [owner]="vm.profile" class="row">
  11 + </noosfero-boxes>
6 <custom-content class="profile-footer" [label]="'profile.custom_footer.label'" [attribute]="'custom_footer'" [profile]="vm.profile"></custom-content> 12 <custom-content class="profile-footer" [label]="'profile.custom_footer.label'" [attribute]="'custom_footer'" [profile]="vm.profile"></custom-content>
7 </div> 13 </div>
src/app/profile/toolbar.html
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
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>  
5 \ No newline at end of file 0 \ No newline at end of file
src/languages/en.json
@@ -6,6 +6,8 @@ @@ -6,6 +6,8 @@
6 "navbar.logout": "Log Out", 6 "navbar.logout": "Log Out",
7 "navbar.login": "Login", 7 "navbar.login": "Login",
8 "navbar.toggle_menu": "Toggle navigation", 8 "navbar.toggle_menu": "Toggle navigation",
  9 + "configbar.label": "Configuration",
  10 + "configbar.section.layout": "Layout",
9 "language.all": "All languages", 11 "language.all": "All languages",
10 "language.en": "English", 12 "language.en": "English",
11 "language.pt": "Portuguese", 13 "language.pt": "Portuguese",
@@ -77,9 +79,7 @@ @@ -77,9 +79,7 @@
77 "custom_content.title": "Edit content", 79 "custom_content.title": "Edit content",
78 "profile.custom_header.label": "Header", 80 "profile.custom_header.label": "Header",
79 "profile.custom_footer.label": "Footer", 81 "profile.custom_footer.label": "Footer",
80 - "designMode.label": "In Design",  
81 - "designMode.toggle.ON": "ON",  
82 - "designMode.toggle.OFF": "OFF", 82 + "designMode.label": "Design mode",
83 "search.results.summary": "{results, plural, one{result} other{# results}}", 83 "search.results.summary": "{results, plural, one{result} other{# results}}",
84 "search.results.query.label": "Search therm:", 84 "search.results.query.label": "Search therm:",
85 "search.label": "Search", 85 "search.label": "Search",
@@ -97,5 +97,8 @@ @@ -97,5 +97,8 @@
97 "block.edition.display_user.all": "All users", 97 "block.edition.display_user.all": "All users",
98 "block.edition.display_user.logged": "Logged", 98 "block.edition.display_user.logged": "Logged",
99 "block.edition.display_user.not_logged": "Not logged", 99 "block.edition.display_user.not_logged": "Not logged",
100 - "block.edition.language.label": "Show for:" 100 + "block.edition.language.label": "Show for:",
  101 + "activities.event.description": "Event on",
  102 + "time.at": "at",
  103 + "date.on": "On"
101 } 104 }
src/languages/pt.json
@@ -6,6 +6,8 @@ @@ -6,6 +6,8 @@
6 "navbar.logout": "Sair", 6 "navbar.logout": "Sair",
7 "navbar.login": "Login", 7 "navbar.login": "Login",
8 "navbar.toggle_menu": "Abrir Menu", 8 "navbar.toggle_menu": "Abrir Menu",
  9 + "configbar.label": "Configurações",
  10 + "configbar.section.layout": "Visual",
9 "language.all": "Todos os idiomas", 11 "language.all": "Todos os idiomas",
10 "language.en": "Inglês", 12 "language.en": "Inglês",
11 "language.pt": "Português", 13 "language.pt": "Português",
@@ -29,7 +31,7 @@ @@ -29,7 +31,7 @@
29 "navbar.content_viewer_actions.new_item": "Novo Item", 31 "navbar.content_viewer_actions.new_item": "Novo Item",
30 "navbar.profile_actions.new_item": "Novo Item", 32 "navbar.profile_actions.new_item": "Novo Item",
31 "navbar.content_viewer_actions.new_post": "Novo Artigo", 33 "navbar.content_viewer_actions.new_post": "Novo Artigo",
32 - "navbar.content_viewer_actions.new_discussion": "Nova Discussão", 34 + "navbar.content_viewer_actions.new_discussion": "Nova Consulta",
33 "navbar.profile_actions.new_discussion": "Nova Discussão", 35 "navbar.profile_actions.new_discussion": "Nova Discussão",
34 "notification.error.default.message": "Algo deu errado!", 36 "notification.error.default.message": "Algo deu errado!",
35 "notification.error.default.title": "Oops...", 37 "notification.error.default.title": "Oops...",
@@ -77,9 +79,7 @@ @@ -77,9 +79,7 @@
77 "custom_content.title": "Editar conteúdo", 79 "custom_content.title": "Editar conteúdo",
78 "profile.custom_header.label": "Cabeçalho", 80 "profile.custom_header.label": "Cabeçalho",
79 "profile.custom_footer.label": "Rodapé", 81 "profile.custom_footer.label": "Rodapé",
80 - "designMode.label": "Modo de Edição",  
81 - "designMode.toggle.ON": "Ligado",  
82 - "designMode.toggle.OFF": "Desligado", 82 + "designMode.label": "Alterar design",
83 "search.results.summary": "{results, plural, one{# resultado} other{# resultados}}", 83 "search.results.summary": "{results, plural, one{# resultado} other{# resultados}}",
84 "search.results.query.label": "Termo da busca:", 84 "search.results.query.label": "Termo da busca:",
85 "search.label": "Pesquisar", 85 "search.label": "Pesquisar",
@@ -97,5 +97,8 @@ @@ -97,5 +97,8 @@
97 "block.edition.display_user.all": "Todos os usuários", 97 "block.edition.display_user.all": "Todos os usuários",
98 "block.edition.display_user.logged": "Logados", 98 "block.edition.display_user.logged": "Logados",
99 "block.edition.display_user.not_logged": "Não logados", 99 "block.edition.display_user.not_logged": "Não logados",
100 - "block.edition.language.label": "Exibir para:" 100 + "block.edition.language.label": "Exibir para:",
  101 + "activities.event.description": "Evento em",
  102 + "time.at": "às",
  103 + "date.on": "Em"
101 } 104 }
src/lib/ng-noosfero-api/interfaces/environment.ts
@@ -15,5 +15,14 @@ namespace noosfero { @@ -15,5 +15,14 @@ namespace noosfero {
15 */ 15 */
16 id: number; 16 id: number;
17 settings: any 17 settings: any
  18 +
  19 + /**
  20 + * @ngdoc property
  21 + * @name layout_template
  22 + * @propertyOf noofero.Environment
  23 + * @returns {string} The Environment layout (e.g. default, rightbar)
  24 + */
  25 + layout_template: string;
18 } 26 }
19 -}  
20 \ No newline at end of file 27 \ No newline at end of file
  28 +}
  29 +
src/lib/ng-noosfero-api/interfaces/profile.ts
@@ -80,5 +80,13 @@ namespace noosfero { @@ -80,5 +80,13 @@ namespace noosfero {
80 custom_footer: string; 80 custom_footer: string;
81 81
82 permissions: string[]; 82 permissions: string[];
  83 +
  84 + /**
  85 + * @ngdoc property
  86 + * @name layout_template
  87 + * @propertyOf noofero.Profile
  88 + * @returns {string} The Profile layout template (e.g.: "rightbar", "default")
  89 + */
  90 + layout_template: string;
83 } 91 }
84 } 92 }
themes/angular-participa-consulta/app/layout/scss/skins/_yellow.scss
  1 +$yellow-hover: #f5b025;
  2 +$yellow-base: #f9c404;
  3 +
1 .skin-yellow { 4 .skin-yellow {
2 @extend %skin-base; 5 @extend %skin-base;
3 6
@@ -49,7 +52,7 @@ @@ -49,7 +52,7 @@
49 52
50 .container-fluid .navbar-header .navbar-toggle { 53 .container-fluid .navbar-header .navbar-toggle {
51 &:hover, &:focus { 54 &:hover, &:focus {
52 - background-color: #f5b025; 55 + background-color: $yellow-hover;
53 } 56 }
54 } 57 }
55 58
@@ -61,4 +64,26 @@ @@ -61,4 +64,26 @@
61 } 64 }
62 } 65 }
63 66
  67 + #config-tool {
  68 +
  69 + #config-tool-cog {
  70 + color: $yellow-hover;
  71 + }
  72 +
  73 + #config-tool-options {
  74 + h4 {
  75 + color: #2c3e50;
  76 + font-weight: bold;
  77 + }
  78 + }
  79 +
  80 + &.closed {
  81 + #config-tool-cog {
  82 + &:hover {
  83 + background-color: $yellow-hover;
  84 + }
  85 + }
  86 + }
  87 + }
  88 +
64 } 89 }