Commit 451be0ef9e2d26647c0b5c8af6a3b2cf0771ae52
Committed by
Michel Felipe
1 parent
29d769ad
Exists in
master
and in
26 other branches
Display content block initial version
Showing
12 changed files
with
235 additions
and
13 deletions
Show diff stats
src/app/layout/blocks/display-content/display-content-block.component.spec.ts
0 → 100644
| @@ -0,0 +1,75 @@ | @@ -0,0 +1,75 @@ | ||
| 1 | +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; | ||
| 2 | +import {Provider, provide} from 'ng-forward'; | ||
| 3 | +import {ComponentTestHelper, createClass} from './../../../../spec/component-test-helper'; | ||
| 4 | +import {providers} from 'ng-forward/cjs/testing/providers'; | ||
| 5 | +import {DisplayContentBlockComponent} from './display-content-block.component'; | ||
| 6 | +import * as helpers from './../../../../spec/helpers'; | ||
| 7 | + | ||
| 8 | +const htmlTemplate: string = '<noosfero-display-content-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-display-content-block>'; | ||
| 9 | + | ||
| 10 | +describe("Components", () => { | ||
| 11 | + | ||
| 12 | + describe("Display Content Block Component", () => { | ||
| 13 | + let state = jasmine.createSpyObj("state", ["go"]); | ||
| 14 | + let providers = [ | ||
| 15 | + provide('ArticleService', { | ||
| 16 | + useValue: helpers.mocks.articleService | ||
| 17 | + }), | ||
| 18 | + provide('$state', { useValue: state }) | ||
| 19 | + ].concat(helpers.provideFilters("translateFilter")); | ||
| 20 | + | ||
| 21 | + let sections: noosfero.Section[] = [ | ||
| 22 | + { value: 'abstract', checked: 'abstract'}, | ||
| 23 | + { value: 'title', checked: 'title' } | ||
| 24 | + ]; | ||
| 25 | + let settings: noosfero.Settings = { | ||
| 26 | + limit: 6, | ||
| 27 | + sections: sections | ||
| 28 | + }; | ||
| 29 | + | ||
| 30 | + let helper: ComponentTestHelper<DisplayContentBlockComponent>; | ||
| 31 | + | ||
| 32 | + beforeEach(angular.mock.module("templates")); | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * The beforeEach procedure will initialize the helper and parse | ||
| 36 | + * the component according to the given providers. Unfortunetly, in | ||
| 37 | + * this mode, the providers and properties given to the construtor | ||
| 38 | + * can't be overriden. | ||
| 39 | + */ | ||
| 40 | + beforeEach((done) => { | ||
| 41 | + // Create the component bed for the test. Optionally, this could be done | ||
| 42 | + // in each test if one needs customization of these parameters per test | ||
| 43 | + let cls = createClass({ | ||
| 44 | + template: htmlTemplate, | ||
| 45 | + directives: [DisplayContentBlockComponent], | ||
| 46 | + providers: providers, | ||
| 47 | + properties: { | ||
| 48 | + block: { | ||
| 49 | + settings: settings | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | + }); | ||
| 53 | + helper = new ComponentTestHelper<DisplayContentBlockComponent>(cls, done); | ||
| 54 | + }); | ||
| 55 | + | ||
| 56 | + it("verify settings is injected", () => { | ||
| 57 | + expect(helper.component.block).not.toBeNull; | ||
| 58 | + expect(helper.component.block.settings).not.toBeNull; | ||
| 59 | + expect(helper.component.block.settings.limit).toEqual(6); | ||
| 60 | + expect(helper.component.block.settings.sections.length).toEqual(3); | ||
| 61 | + }); | ||
| 62 | + | ||
| 63 | + it("verify abstract is displayed", () => { | ||
| 64 | + expect(helper.all("div[ng-bind-html|='article.abstract']")[0]).not.toBeNull; | ||
| 65 | + }); | ||
| 66 | + | ||
| 67 | + it("verify title is displayed", () => { | ||
| 68 | + expect(helper.all("div > h5")[0]).not.toBeNull; | ||
| 69 | + }); | ||
| 70 | + | ||
| 71 | + it("verify body is not displayed", () => { | ||
| 72 | + expect(helper.all("div[ng-bind-html|='article.body']")[0]).toBeNull; | ||
| 73 | + }); | ||
| 74 | + }); | ||
| 75 | +}); |
src/app/layout/blocks/display-content/display-content-block.component.ts
0 → 100644
| @@ -0,0 +1,55 @@ | @@ -0,0 +1,55 @@ | ||
| 1 | +import {Input, Inject, Component} from "ng-forward"; | ||
| 2 | +import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service"; | ||
| 3 | + | ||
| 4 | +@Component({ | ||
| 5 | + selector: "noosfero-display-content-block", | ||
| 6 | + templateUrl: 'app/layout/blocks/display-content/display-content-block.html', | ||
| 7 | +}) | ||
| 8 | +@Inject(ArticleService, "$state") | ||
| 9 | +export class DisplayContentBlockComponent { | ||
| 10 | + | ||
| 11 | + @Input() block: noosfero.Block; | ||
| 12 | + @Input() owner: noosfero.Profile; | ||
| 13 | + | ||
| 14 | + profile: noosfero.Profile; | ||
| 15 | + articles: noosfero.Article[]; | ||
| 16 | + sections: noosfero.Section[]; | ||
| 17 | + | ||
| 18 | + documentsLoaded: boolean = false; | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * This configuration doesn't exists on Noosfero. Statically typing here. | ||
| 22 | + */ | ||
| 23 | + private addDefaultSections() { | ||
| 24 | + let author: noosfero.Section = <noosfero.Section>{ value: 'author', checked: 'author' }; | ||
| 25 | + this.sections.push(author); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + constructor(private articleService: ArticleService, private $state: ng.ui.IStateService) { | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + ngOnInit() { | ||
| 32 | + this.profile = this.owner; | ||
| 33 | + let limit = ((this.block && this.block.settings) ? this.block.settings.limit : null) || 5; | ||
| 34 | + this.articleService.getByProfile(this.profile, { content_type: 'TinyMceArticle', per_page: limit }) | ||
| 35 | + .then((result: noosfero.RestResult<noosfero.Article[]>) => { | ||
| 36 | + this.articles = <noosfero.Article[]>result.data; | ||
| 37 | + this.sections = this.block.settings.sections; | ||
| 38 | + // Add sections not defined by Noosfero API | ||
| 39 | + this.addDefaultSections(); | ||
| 40 | + this.documentsLoaded = true; | ||
| 41 | + }); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Returns whether a settings section should be displayed. | ||
| 46 | + * | ||
| 47 | + */ | ||
| 48 | + private display(section_name: string): boolean { | ||
| 49 | + let section: noosfero.Section = this.sections.find( function(section: noosfero.Section) { | ||
| 50 | + return section.value === section_name; | ||
| 51 | + }); | ||
| 52 | + return section !== undefined && section.checked !== undefined; | ||
| 53 | + } | ||
| 54 | +} | ||
| 55 | + |
src/app/layout/blocks/display-content/display-content-block.html
0 → 100644
| @@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
| 1 | +<div class="{{ctrl.type}}-block"> | ||
| 2 | + <div ng-repeat="article in ctrl.articles" ui-sref="main.profile.page({profile: ctrl.profile.identifier, page: article.path})"" class="article"> | ||
| 3 | + <!-- Article Title --> | ||
| 4 | + <div class="page-header" ng-if="ctrl.display('title')"> | ||
| 5 | + <h5 class="title media-heading" ng-bind="article.title"></h3> | ||
| 6 | + </div> | ||
| 7 | + | ||
| 8 | + <div class="sub-header clearfix"> | ||
| 9 | + <!-- Article Abstract and Read More Link --> | ||
| 10 | + <div class="post-lead" ng-if="ctrl.display('abstract')"> | ||
| 11 | + <div ng-bind-html="article.abstract"></div> | ||
| 12 | + <a href="#" ui-sref="main.profile.page({profile: ctrl.profile.identifier, page: article.path})"> | ||
| 13 | + <i class="fa fa-pencil-square-o fa-fw fa-lg"></i> {{"article.actions.read_more" | translate}} | ||
| 14 | + </a> | ||
| 15 | + </div> | ||
| 16 | + <div class="page-info pull-right small text-muted" ng-if="ctrl.display('publish_date')"> | ||
| 17 | + <!-- Article Published Date --> | ||
| 18 | + <span class="time"> | ||
| 19 | + <i class="fa fa-clock-o"></i> <span am-time-ago="article.created_at | dateFormat"></span> | ||
| 20 | + </span> | ||
| 21 | + <!-- Article Author --> | ||
| 22 | + <span class="author" ng-if="ctrl.display('author')"> | ||
| 23 | + <i class="fa fa-user"></i> | ||
| 24 | + <a ui-sref="main.profile.home({profile: article.author.identifier})" ng-if="article.author"> | ||
| 25 | + <span class="author-name" ng-bind="article.author.name"></span> | ||
| 26 | + </a> | ||
| 27 | + </span> | ||
| 28 | + </div> | ||
| 29 | + </div> | ||
| 30 | + | ||
| 31 | + <div class="post-lead"> | ||
| 32 | + <!-- Article Image --> | ||
| 33 | + <img ng-show="ctrl.display('image')" ng-src="{{article.image.url}}" class="img-responsive article-image"> | ||
| 34 | + <!-- Article Body --> | ||
| 35 | + <div ng-bind-html="article.body" ng-show="ctrl.display('body')"></div> | ||
| 36 | + </div> | ||
| 37 | + | ||
| 38 | + <!-- Article Tags --> | ||
| 39 | + <div ng-if="ctrl.display('tags')" class="post-lead"> | ||
| 40 | + <div class="label" ng-repeat="tag in article.tag_list"> | ||
| 41 | + <span class="badge" ng-bind="tag"></span> | ||
| 42 | + </div> | ||
| 43 | + </div> | ||
| 44 | + | ||
| 45 | + </div> | ||
| 46 | +</div> |
src/app/layout/blocks/display-content/display-content-block.scss
0 → 100644
| @@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
| 1 | +.members-block { | ||
| 2 | + .member { | ||
| 3 | + img, i.profile-image { | ||
| 4 | + width: 60px; | ||
| 5 | + } | ||
| 6 | + img { | ||
| 7 | + display: inline-block; | ||
| 8 | + vertical-align: top; | ||
| 9 | + } | ||
| 10 | + i.profile-image { | ||
| 11 | + text-align: center; | ||
| 12 | + background-color: #889DB1; | ||
| 13 | + color: #F1F1F1; | ||
| 14 | + font-size: 4.5em; | ||
| 15 | + } | ||
| 16 | + } | ||
| 17 | +} |
src/app/main/main.component.ts
| @@ -9,18 +9,16 @@ import {BoxesComponent} from "../layout/boxes/boxes.component"; | @@ -9,18 +9,16 @@ import {BoxesComponent} from "../layout/boxes/boxes.component"; | ||
| 9 | import {BlockComponent} from "../layout/blocks/block.component"; | 9 | import {BlockComponent} from "../layout/blocks/block.component"; |
| 10 | import {EnvironmentComponent} from "../environment/environment.component"; | 10 | import {EnvironmentComponent} from "../environment/environment.component"; |
| 11 | import {EnvironmentHomeComponent} from "../environment/environment-home.component"; | 11 | import {EnvironmentHomeComponent} from "../environment/environment-home.component"; |
| 12 | -import {PeopleBlockComponent} from "../layout/blocks/people/people-block.component"; | ||
| 13 | -import {LinkListBlockComponent} from "./../layout/blocks/link-list/link-list-block.component"; | ||
| 14 | -import {RecentDocumentsBlockComponent} from "../layout/blocks/recent-documents/recent-documents-block.component"; | ||
| 15 | -import {ProfileImageBlockComponent} from "../layout/blocks/profile-image/profile-image-block.component"; | ||
| 16 | -import {RawHTMLBlockComponent} from "../layout/blocks/raw-html/raw-html-block.component"; | 12 | +import {PeopleBlockComponent} from "../layout/blocks/people-block/people-block.component"; |
| 13 | +import {DisplayContentBlockComponent} from "../layout/blocks/display-content/display-content-block.component"; | ||
| 14 | +import {LinkListBlockComponent} from "./../layout/blocks/link-list/link-list.component"; | ||
| 15 | +import {RecentDocumentsBlockComponent} from "../layout/blocks/recent-documents/recent-documents.component"; | ||
| 16 | +import {ProfileImageBlockComponent} from "../layout/blocks/profile-image-block/profile-image-block.component"; | ||
| 17 | +import {RawHTMLBlockComponent} from "../layout/blocks/raw-html/raw-html.component"; | ||
| 17 | import {StatisticsBlockComponent} from "../layout/blocks/statistics/statistics-block.component"; | 18 | import {StatisticsBlockComponent} from "../layout/blocks/statistics/statistics-block.component"; |
| 18 | 19 | ||
| 19 | -import {MembersBlockComponent} from "./../layout/blocks/members/members-block.component"; | ||
| 20 | -import {CommunitiesBlockComponent} from "./../layout/blocks/communities/communities-block.component"; | ||
| 21 | - | ||
| 22 | -import {LoginBlockComponent} from "../layout/blocks/login-block/login-block.component"; | ||
| 23 | - | 20 | +import {MembersBlockComponent} from "./../layout/blocks/members-block/members-block.component"; |
| 21 | +import {CommunitiesBlockComponent} from "./../layout/blocks/communities-block/communities-block.component"; | ||
| 24 | import {NoosferoTemplate} from "../shared/pipes/noosfero-template.filter"; | 22 | import {NoosferoTemplate} from "../shared/pipes/noosfero-template.filter"; |
| 25 | import {DateFormat} from "../shared/pipes/date-format.filter"; | 23 | import {DateFormat} from "../shared/pipes/date-format.filter"; |
| 26 | 24 | ||
| @@ -83,7 +81,7 @@ export class EnvironmentContent { | @@ -83,7 +81,7 @@ export class EnvironmentContent { | ||
| 83 | * NoosferoTemplate, DateFormat, RawHTMLBlock | 81 | * NoosferoTemplate, DateFormat, RawHTMLBlock |
| 84 | * @description | 82 | * @description |
| 85 | * The Main controller for the Noosfero Angular Theme application. | 83 | * The Main controller for the Noosfero Angular Theme application. |
| 86 | - * | 84 | + * |
| 87 | * The main route '/' is defined as the URL for this controller, which routes | 85 | * The main route '/' is defined as the URL for this controller, which routes |
| 88 | * requests to the {@link main.MainContentComponent} controller and also, the '/profile' route, | 86 | * requests to the {@link main.MainContentComponent} controller and also, the '/profile' route, |
| 89 | * which routes requests to the {@link profile.Profile} controller. See {@link profile.Profile} | 87 | * which routes requests to the {@link profile.Profile} controller. See {@link profile.Profile} |
| @@ -94,7 +92,7 @@ export class EnvironmentContent { | @@ -94,7 +92,7 @@ export class EnvironmentContent { | ||
| 94 | template: '<div ng-view></div>', | 92 | template: '<div ng-view></div>', |
| 95 | directives: [ | 93 | directives: [ |
| 96 | ArticleBlogComponent, ArticleViewComponent, BoxesComponent, BlockComponent, | 94 | ArticleBlogComponent, ArticleViewComponent, BoxesComponent, BlockComponent, |
| 97 | - EnvironmentComponent, PeopleBlockComponent, | 95 | + EnvironmentComponent, PeopleBlockComponent, DisplayContentBlockComponent, |
| 98 | LinkListBlockComponent, CommunitiesBlockComponent, HtmlEditorComponent, | 96 | LinkListBlockComponent, CommunitiesBlockComponent, HtmlEditorComponent, |
| 99 | MainBlockComponent, RecentDocumentsBlockComponent, Navbar, SidebarComponent, ProfileImageBlockComponent, | 97 | MainBlockComponent, RecentDocumentsBlockComponent, Navbar, SidebarComponent, ProfileImageBlockComponent, |
| 100 | MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent, StatisticsBlockComponent, | 98 | MembersBlockComponent, NoosferoTemplate, DateFormat, RawHTMLBlockComponent, StatisticsBlockComponent, |
src/languages/en.json
| @@ -37,6 +37,7 @@ | @@ -37,6 +37,7 @@ | ||
| 37 | "comment.post.success.message": "Comment saved!", | 37 | "comment.post.success.message": "Comment saved!", |
| 38 | "comment.reply": "reply", | 38 | "comment.reply": "reply", |
| 39 | "article.actions.edit": "Edit", | 39 | "article.actions.edit": "Edit", |
| 40 | + "article.actions.read_more": "Read More", | ||
| 40 | "article.basic_editor.title": "Title", | 41 | "article.basic_editor.title": "Title", |
| 41 | "article.basic_editor.body": "Body", | 42 | "article.basic_editor.body": "Body", |
| 42 | "article.basic_editor.save": "Save", | 43 | "article.basic_editor.save": "Save", |
src/languages/pt.json
| @@ -37,6 +37,7 @@ | @@ -37,6 +37,7 @@ | ||
| 37 | "comment.post.success.message": "Comentário salvo com sucesso!", | 37 | "comment.post.success.message": "Comentário salvo com sucesso!", |
| 38 | "comment.reply": "responder", | 38 | "comment.reply": "responder", |
| 39 | "article.actions.edit": "Editar", | 39 | "article.actions.edit": "Editar", |
| 40 | + "article.actions.read_more": "Ler mais", | ||
| 40 | "article.basic_editor.title": "Título", | 41 | "article.basic_editor.title": "Título", |
| 41 | "article.basic_editor.body": "Corpo", | 42 | "article.basic_editor.body": "Corpo", |
| 42 | "article.basic_editor.save": "Salvar", | 43 | "article.basic_editor.save": "Salvar", |
src/lib/ng-noosfero-api/interfaces/article.ts
src/lib/ng-noosfero-api/interfaces/block.ts
| @@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
| 1 | +namespace noosfero { | ||
| 2 | + /** | ||
| 3 | + * @ngdoc interface | ||
| 4 | + * @name noosfero.Section | ||
| 5 | + * @description | ||
| 6 | + * Represents a block settings section. A Section has a value property, | ||
| 7 | + * which represents the Section name, and an optinally checked property which | ||
| 8 | + * has the same value as the value property indicating that this property is | ||
| 9 | + * selected in the block configuration. | ||
| 10 | + */ | ||
| 11 | + export interface Section { | ||
| 12 | + | ||
| 13 | + value: string; | ||
| 14 | + checked: string; | ||
| 15 | + } | ||
| 16 | +} | ||
| 0 | \ No newline at end of file | 17 | \ No newline at end of file |