Commit def8ed5487236d3f530d685039e5912a18c8622a
1 parent
4902da4d
Exists in
master
and in
26 other branches
Display blocks based on visibility rules
Showing
7 changed files
with
181 additions
and
42 deletions
Show diff stats
src/app/environment/environment.html
src/app/layout/boxes/box.html
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 | 3 | <div class="panel-heading" ng-show="block.title"> |
4 | 4 | <h3 class="panel-title">{{block.title}}</h3> |
5 | 5 | </div> | ... | ... |
src/app/layout/boxes/boxes.component.spec.ts
1 | 1 | import {Component} from 'ng-forward'; |
2 | - | |
3 | 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 | 6 | // this htmlTemplate will be re-used between the container components in this spec file |
14 | 7 | const htmlTemplate: string = '<noosfero-boxes [boxes]="ctrl.boxes" [owner]="ctrl.profile"></noosfero-blog>'; |
... | ... | @@ -16,49 +9,63 @@ const htmlTemplate: string = '<noosfero-boxes [boxes]="ctrl.boxes" [owner]="ctrl |
16 | 9 | |
17 | 10 | describe("Boxes Component", () => { |
18 | 11 | |
12 | + let helper: ComponentTestHelper<BoxesComponent>; | |
19 | 13 | beforeEach(() => { |
20 | 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 | 19 | { id: 1, position: 1 }, |
32 | 20 | { id: 2, position: 2 } |
33 | - ]; | |
34 | - | |
35 | - owner: noosfero.Profile = <noosfero.Profile> { | |
21 | + ], | |
22 | + owner: { | |
36 | 23 | id: 1, |
37 | 24 | identifier: 'profile-name', |
38 | 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 | 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 | 5 | @Component({ |
4 | 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 | 11 | export class BoxesComponent { |
8 | 12 | |
9 | 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 | 33 | boxesOrder(box: noosfero.Box) { |
13 | 34 | if (box.position === 2) return 0; |
14 | 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 | } | ... | ... |
... | ... | @@ -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 | +}); | ... | ... |
... | ... | @@ -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 | 1 | <div class="profile-container"> |
2 | 2 | <div class="profile-header" ng-bind-html="vm.profile.custom_header"></div> |
3 | 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 | 5 | </div> |
6 | 6 | <div class="profile-footer" ng-bind-html="vm.profile.custom_footer"></div> |
7 | 7 | </div> | ... | ... |