Commit def8ed5487236d3f530d685039e5912a18c8622a

Authored by Victor Costa
1 parent 4902da4d

Display blocks based on visibility rules

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 [boxes]="vm.boxes" [owner]="vm.environment"></noosfero-boxes> 3 + <noosfero-boxes ng-if="vm.boxes" [boxes]="vm.boxes" [owner]="vm.environment"></noosfero-boxes>
4 </div> 4 </div>
5 </div> 5 </div>
src/app/layout/boxes/box.html
1 <div ng-class="{'col-md-2-5': box.position!=1, 'col-md-7': box.position==1}"> 1 <div ng-class="{'col-md-2-5': box.position!=1, 'col-md-7': box.position==1}">
2 - <div ng-repeat="block in box.blocks | orderBy: 'position'" class="panel panel-default block {{block.type | lowercase}}" > 2 + <div ng-repeat="block in box.blocks | displayBlocks:ctrl.isHomepage:ctrl.currentUser | orderBy: 'position'" class="panel panel-default block {{block.type | lowercase}}" >
3 <div class="panel-heading" ng-show="block.title"> 3 <div class="panel-heading" ng-show="block.title">
4 <h3 class="panel-title">{{block.title}}</h3> 4 <h3 class="panel-title">{{block.title}}</h3>
5 </div> 5 </div>
src/app/layout/boxes/boxes.component.spec.ts
1 import {Component} from 'ng-forward'; 1 import {Component} from 'ng-forward';
2 -  
3 import {BoxesComponent} from './boxes.component'; 2 import {BoxesComponent} from './boxes.component';
4 -  
5 -import {  
6 - createComponentFromClass,  
7 - quickCreateComponent,  
8 - provideEmptyObjects,  
9 - createProviderToValue,  
10 - provideFilters  
11 -} from "../../../spec/helpers"; 3 +import * as helpers from "../../../spec/helpers";
  4 +import {ComponentTestHelper, createClass} from '../../../spec/component-test-helper';
12 5
13 // this htmlTemplate will be re-used between the container components in this spec file 6 // this htmlTemplate will be re-used between the container components in this spec file
14 const htmlTemplate: string = '<noosfero-boxes [boxes]="ctrl.boxes" [owner]="ctrl.profile"></noosfero-blog>'; 7 const htmlTemplate: string = '<noosfero-boxes [boxes]="ctrl.boxes" [owner]="ctrl.profile"></noosfero-blog>';
@@ -16,49 +9,63 @@ const htmlTemplate: string = &#39;&lt;noosfero-boxes [boxes]=&quot;ctrl.boxes&quot; [owner]=&quot;ctrl @@ -16,49 +9,63 @@ const htmlTemplate: string = &#39;&lt;noosfero-boxes [boxes]=&quot;ctrl.boxes&quot; [owner]=&quot;ctrl
16 9
17 describe("Boxes Component", () => { 10 describe("Boxes Component", () => {
18 11
  12 + let helper: ComponentTestHelper<BoxesComponent>;
19 beforeEach(() => { 13 beforeEach(() => {
20 angular.mock.module("templates"); 14 angular.mock.module("templates");
21 }); 15 });
22 16
23 - @Component({  
24 - selector: 'test-container-component',  
25 - template: htmlTemplate,  
26 - directives: [BoxesComponent],  
27 - providers: []  
28 - })  
29 - class BoxesContainerComponent {  
30 - boxes: noosfero.Box[] = [ 17 + let properties = {
  18 + boxes: [
31 { id: 1, position: 1 }, 19 { id: 1, position: 1 },
32 { id: 2, position: 2 } 20 { id: 2, position: 2 }
33 - ];  
34 -  
35 - owner: noosfero.Profile = <noosfero.Profile> { 21 + ],
  22 + owner: {
36 id: 1, 23 id: 1,
37 identifier: 'profile-name', 24 identifier: 'profile-name',
38 type: 'Person' 25 type: 'Person'
39 - };  
40 - } 26 + }
  27 + };
  28 + beforeEach((done) => {
  29 + let cls = createClass({
  30 + template: htmlTemplate,
  31 + directives: [BoxesComponent],
  32 + properties: properties,
  33 + providers: [
  34 + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})),
  35 + helpers.createProviderToValue('AuthService', helpers.mocks.authService),
  36 + helpers.createProviderToValue('$state', state)
  37 + ]
  38 + });
  39 + helper = new ComponentTestHelper<BoxesComponent>(cls, done);
  40 + });
41 41
42 - it("renders boxes into a container", (done: Function) => {  
43 - createComponentFromClass(BoxesContainerComponent).then((fixture) => {  
44 - let boxesHtml = fixture.debugElement;  
45 - expect(boxesHtml.query('div.col-md-7').length).toEqual(1);  
46 - expect(boxesHtml.query('div.col-md-2-5').length).toEqual(1); 42 + let state = jasmine.createSpyObj("state", ["current"]);
  43 + state.current = { name: "" };
47 44
48 - done();  
49 - }); 45 + it("renders boxes into a container", () => {
  46 + expect(helper.find('div.col-md-7').length).toEqual(1);
  47 + expect(helper.find('div.col-md-2-5').length).toEqual(1);
50 }); 48 });
51 49
52 - it("check the boxes order", (done: Function) => {  
53 - createComponentFromClass(BoxesContainerComponent).then((fixture) => { 50 + it("check the boxes order", () => {
  51 + expect(helper.component.boxesOrder(properties['boxes'][0])).toEqual(1);
  52 + expect(helper.component.boxesOrder(properties['boxes'][1])).toEqual(0);
  53 + });
54 54
55 - let boxesComponent: BoxesComponent = fixture.debugElement.componentViewChildren[0].componentInstance;  
56 - let boxesContainer: BoxesContainerComponent = fixture.componentInstance; 55 + it("set isHomepage as false by default", () => {
  56 + expect(helper.component.isHomepage).toBeFalsy();
  57 + });
57 58
58 - expect(boxesComponent.boxesOrder(boxesContainer.boxes[0])).toEqual(1);  
59 - expect(boxesComponent.boxesOrder(boxesContainer.boxes[1])).toEqual(0); 59 + it("set isHomepage as true when in profile home page", () => {
  60 + state.current = { name: "main.profile.home" };
  61 + helper.component.ngOnInit();
  62 + expect(helper.component.isHomepage).toBeTruthy();
  63 + });
60 64
61 - done();  
62 - }); 65 + it("set isHomepage as true when in environment home page", () => {
  66 + state.current = { name: "main.environment.home" };
  67 + helper.component.owner = <noosfero.Environment>{};
  68 + helper.component.ngOnInit();
  69 + expect(helper.component.isHomepage).toBeTruthy();
63 }); 70 });
64 }); 71 });
src/app/layout/boxes/boxes.component.ts
1 import {Input, Inject, Component} from 'ng-forward'; 1 import {Input, Inject, Component} from 'ng-forward';
  2 +import {SessionService, AuthService, AuthEvents} from "../../login";
  3 +import {DisplayBlocks} from "./display-blocks.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: [DisplayBlocks]
6 }) 9 })
  10 +@Inject("SessionService", 'AuthService', "$state")
7 export class BoxesComponent { 11 export class BoxesComponent {
8 12
9 @Input() boxes: noosfero.Box[]; 13 @Input() boxes: noosfero.Box[];
10 - @Input() owner: noosfero.Profile; 14 + @Input() owner: noosfero.Profile | noosfero.Environment;
  15 +
  16 + currentUser: noosfero.User;
  17 + isHomepage = true;
  18 +
  19 + constructor(private session: SessionService, private authService: AuthService, private $state: ng.ui.IStateService) {
  20 + this.currentUser = this.session.currentUser();
  21 + this.authService.subscribe(AuthEvents[AuthEvents.loginSuccess], () => {
  22 + this.currentUser = this.session.currentUser();
  23 + });
  24 + this.authService.subscribe(AuthEvents[AuthEvents.logoutSuccess], () => {
  25 + this.currentUser = this.session.currentUser();
  26 + });
  27 + }
  28 +
  29 + ngOnInit() {
  30 + this.verifyHomepage();
  31 + }
11 32
12 boxesOrder(box: noosfero.Box) { 33 boxesOrder(box: noosfero.Box) {
13 if (box.position === 2) return 0; 34 if (box.position === 2) return 0;
14 return box.position; 35 return box.position;
15 } 36 }
  37 +
  38 + private verifyHomepage() {
  39 + if (this.owner && ["Profile", "Community", "Person"].indexOf((<any>this.owner)['type']) >= 0) {
  40 + this.isHomepage = this.$state.current.name === "main.profile.home";
  41 + } else {
  42 + this.isHomepage = this.$state.current.name === "main.environment.home";
  43 + }
  44 + }
16 } 45 }
src/app/layout/boxes/display-blocks.filter.spec.ts 0 → 100644
@@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
  1 +import {quickCreateComponent} from "../../../spec/helpers";
  2 +import {DisplayBlocks} from './display-blocks.filter';
  3 +
  4 +describe("Filters", () => {
  5 + describe("Display Blocks Filter", () => {
  6 +
  7 + it("not fail when blocks is null", done => {
  8 + let filter = new DisplayBlocks();
  9 + expect(filter.transform(null, true, <noosfero.User>{})).toEqual([]);
  10 + done();
  11 + });
  12 +
  13 + it("return blocks when no setting is passed", done => {
  14 + let blocks = [{}];
  15 + let filter = new DisplayBlocks();
  16 + expect(filter.transform(<any>blocks, true, <noosfero.User>{})).toEqual(blocks);
  17 + done();
  18 + });
  19 +
  20 + it("return blocks when no display is passed", done => {
  21 + let blocks = [{ setting: {} }];
  22 + let filter = new DisplayBlocks();
  23 + expect(filter.transform(<any>blocks, true, <noosfero.User>{})).toEqual(blocks);
  24 + done();
  25 + });
  26 +
  27 + it("filter invisible blocks", done => {
  28 + let blocks = [{ settings: { display: "never" } }];
  29 + let filter = new DisplayBlocks();
  30 + expect(filter.transform(<any>blocks, true, <noosfero.User>{})).toEqual([]);
  31 + done();
  32 + });
  33 +
  34 + it("filter blocks with except_home_page in homepage", done => {
  35 + let blocks = [{ settings: { display: "except_home_page" } }];
  36 + let filter = new DisplayBlocks();
  37 + expect(filter.transform(<any>blocks, true, <noosfero.User>{})).toEqual([]);
  38 + done();
  39 + });
  40 +
  41 + it("filter blocks with home_page_only outside homepage", done => {
  42 + let blocks = [{ settings: { display: "home_page_only" } }];
  43 + let filter = new DisplayBlocks();
  44 + expect(filter.transform(<any>blocks, false, <noosfero.User>{})).toEqual([]);
  45 + done();
  46 + });
  47 +
  48 + it("show all blocks when display_user is all for logged user", done => {
  49 + let blocks = [{ settings: { display_user: "all" } }];
  50 + let filter = new DisplayBlocks();
  51 + expect(filter.transform(<any>blocks, true, <noosfero.User>{})).toEqual(blocks);
  52 + done();
  53 + });
  54 +
  55 + it("show all blocks when display_user is all for not logged user", done => {
  56 + let blocks = [{ settings: { display_user: "all" } }];
  57 + let filter = new DisplayBlocks();
  58 + expect(filter.transform(<any>blocks, true, null)).toEqual(blocks);
  59 + done();
  60 + });
  61 +
  62 + it("filter blocks when display_user is logged for not logged user", done => {
  63 + let blocks = [{ settings: { display_user: "logged" } }];
  64 + let filter = new DisplayBlocks();
  65 + expect(filter.transform(<any>blocks, true, null)).toEqual([]);
  66 + done();
  67 + });
  68 +
  69 + it("filter blocks when display_user is not_logged for logged user", done => {
  70 + let blocks = [{ settings: { display_user: "not_logged" } }];
  71 + let filter = new DisplayBlocks();
  72 + expect(filter.transform(<any>blocks, true, <noosfero.User>{})).toEqual([]);
  73 + done();
  74 + });
  75 + });
  76 +});
src/app/layout/boxes/display-blocks.filter.ts 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +import {Pipe, Inject} from "ng-forward";
  2 +
  3 +@Pipe("displayBlocks")
  4 +export class DisplayBlocks {
  5 +
  6 + transform(blocks: noosfero.Block[], isHomepage: boolean, currentUser: noosfero.User) {
  7 + let selected: noosfero.Block[] = [];
  8 + blocks = blocks || [];
  9 + for (let block of blocks) {
  10 + if (this.visible(block, isHomepage) && this.displayToUser(block, currentUser)) {
  11 + selected.push(block);
  12 + }
  13 + }
  14 + return selected;
  15 + }
  16 +
  17 + private visible(block: noosfero.Block, isHomepage: boolean) {
  18 + let display = block.settings ? (<any>block.settings)['display'] : null;
  19 + return !display || ((isHomepage ? display !== "except_home_page" : display !== "home_page_only") && display !== "never");
  20 + }
  21 +
  22 + private displayToUser(block: noosfero.Block, currentUser: noosfero.User) {
  23 + let displayUser = block.settings ? (<any>block.settings)['display_user'] : null;
  24 + return !displayUser || displayUser === "all" ||
  25 + (currentUser ? displayUser === "logged" : displayUser === "not_logged");
  26 + }
  27 +}
src/app/profile/profile.html
1 <div class="profile-container"> 1 <div class="profile-container">
2 <div class="profile-header" ng-bind-html="vm.profile.custom_header"></div> 2 <div class="profile-header" ng-bind-html="vm.profile.custom_header"></div>
3 <div class="row"> 3 <div class="row">
4 - <noosfero-boxes [boxes]="vm.boxes" [owner]="vm.profile"></noosfero-boxes> 4 + <noosfero-boxes ng-if="vm.boxes" [boxes]="vm.boxes" [owner]="vm.profile"></noosfero-boxes>
5 </div> 5 </div>
6 <div class="profile-footer" ng-bind-html="vm.profile.custom_footer"></div> 6 <div class="profile-footer" ng-bind-html="vm.profile.custom_footer"></div>
7 </div> 7 </div>