Commit 9b3a27c9804db1b9a5d72e43ca85b6579815de3f

Authored by Leandro Santos
1 parent da32e022

refactoring recent documents block

src/app/layout/blocks/recent-documents/index.ts
1 1 /* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./recent-documents.component";
  2 +export * from "./recent-documents-block.component";
... ...
src/app/layout/blocks/recent-documents/recent-documents-block.component.spec.ts 0 → 100644
... ... @@ -0,0 +1,80 @@
  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 {RecentDocumentsBlockComponent} from './recent-documents-block.component';
  5 +
  6 +const htmlTemplate: string = '<noosfero-recent-documents-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-recent-documents-block>';
  7 +
  8 +const tcb = new TestComponentBuilder();
  9 +
  10 +describe("Components", () => {
  11 + describe("Recent Documents Block Component", () => {
  12 +
  13 + let settingsObj = {};
  14 + let mockedArticleService = {
  15 + getByProfile: (profile: noosfero.Profile, filters: any): any => {
  16 + return Promise.resolve({ data: [{ name: "article1" }], headers: (name: string) => { return name; } });
  17 + }
  18 + };
  19 + let profile = { name: 'profile-name' };
  20 + beforeEach(angular.mock.module("templates"));
  21 +
  22 + let state = jasmine.createSpyObj("state", ["go"]);
  23 +
  24 +
  25 + function getProviders() {
  26 + return [
  27 + new Provider('$state', { useValue: state }),
  28 + new Provider('ArticleService', {
  29 + useValue: mockedArticleService
  30 + }),
  31 + ].concat(provideFilters("truncateFilter", "stripTagsFilter"));
  32 + }
  33 + let componentClass: any = null;
  34 +
  35 + function getComponent() {
  36 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [RecentDocumentsBlockComponent], providers: getProviders() })
  37 + class BlockContainerComponent {
  38 + block = { type: 'Block', settings: settingsObj };
  39 + owner = profile;
  40 + constructor() {
  41 + }
  42 + }
  43 + return BlockContainerComponent;
  44 + }
  45 +
  46 +
  47 + it("get recent documents from the article service", done => {
  48 + tcb.createAsync(getComponent()).then(fixture => {
  49 + let recentDocumentsBlock: RecentDocumentsBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  50 + expect(recentDocumentsBlock.documents).toEqual([{ name: "article1" }]);
  51 + done();
  52 + });
  53 + });
  54 +
  55 + it("go to article page when open a document", done => {
  56 + tcb.createAsync(getComponent()).then(fixture => {
  57 + let recentDocumentsBlock: RecentDocumentsBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  58 + recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } });
  59 + expect(state.go).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "identifier" });
  60 + done();
  61 + });
  62 + });
  63 +
  64 + it("it uses default limit 5 if not defined on block", done => {
  65 + settingsObj = null;
  66 + mockedArticleService = jasmine.createSpyObj("mockedArticleService", ["getByProfile"]);
  67 + (<any>mockedArticleService).mocked = true;
  68 + let thenMocked = jasmine.createSpy("then");
  69 + mockedArticleService.getByProfile = jasmine.createSpy("getByProfile").and.returnValue({then: thenMocked});
  70 + let getByProfileFunct = mockedArticleService.getByProfile;
  71 + tcb.createAsync(getComponent()).then(fixture => {
  72 + let recentDocumentsBlock: RecentDocumentsBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  73 + recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } });
  74 + expect(getByProfileFunct).toHaveBeenCalledWith(profile, { content_type: 'TinyMceArticle', per_page: 5 });
  75 + done();
  76 + });
  77 + });
  78 +
  79 + });
  80 +});
... ...
src/app/layout/blocks/recent-documents/recent-documents-block.component.ts 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +import {Component, Inject, Input} from "ng-forward";
  2 +import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service";
  3 +
  4 +@Component({
  5 + selector: "noosfero-recent-documents-block",
  6 + templateUrl: 'app/layout/blocks/recent-documents/recent-documents-block.html'
  7 +})
  8 +@Inject(ArticleService, "$state")
  9 +export class RecentDocumentsBlockComponent {
  10 +
  11 + @Input() block: any;
  12 + @Input() owner: any;
  13 +
  14 + profile: any;
  15 + documents: any;
  16 +
  17 + documentsLoaded: boolean = false;
  18 +
  19 + constructor(private articleService: ArticleService, private $state: any) {
  20 + }
  21 +
  22 + ngOnInit() {
  23 + this.profile = this.owner;
  24 + this.documents = [];
  25 +
  26 + let limit = ((this.block && this.block.settings) ? this.block.settings.limit : null) || 5;
  27 + // FIXME get all text articles
  28 + // FIXME make the getByProfile a generic method where we tell the type passing a class TinyMceArticle
  29 + // and the promise should be of type TinyMceArticle[], per example
  30 + this.articleService.getByProfile(this.profile, { content_type: 'TinyMceArticle', per_page: limit })
  31 + .then((result: noosfero.RestResult<noosfero.Article[]>) => {
  32 + this.documents = <noosfero.Article[]>result.data;
  33 + this.documentsLoaded = true;
  34 + });
  35 + }
  36 +
  37 + openDocument(article: any) {
  38 + this.$state.go("main.profile.page", { page: article.path, profile: article.profile.identifier });
  39 + }
  40 +
  41 +}
... ...
src/app/layout/blocks/recent-documents/recent-documents-block.html 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +<div deckgrid source="ctrl.documents" class="deckgrid">
  2 + <div class="a-card panel media" ng-click="mother.ctrl.openDocument(card);">
  3 + <div class="author media-left" ng-show="card.author.image">
  4 + <img ng-src="{{card.author.image.url}}" class="img-circle">
  5 + </div>
  6 + <div class="header media-body">
  7 + <h5 class="title media-heading" ng-bind="card.title"></h5>
  8 +
  9 + <div class="subheader">
  10 + <span class="time">
  11 + <i class="fa fa-clock-o"></i> <span am-time-ago="card.created_at | dateFormat"></span>
  12 + </span>
  13 + </div>
  14 + </div>
  15 + <img ng-show="card.image" ng-src="{{card.image.url}}" class="img-responsive article-image">
  16 + <div class="post-lead" ng-bind-html="card.body | stripTags | truncate: 100: '...': true"></div>
  17 + </div>
  18 +</div>
... ...
src/app/layout/blocks/recent-documents/recent-documents-block.scss 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +.block.recentdocumentsblock {
  2 + .deckgrid[deckgrid]::before {
  3 + font-size: 0; /* See https://github.com/akoenig/angular-deckgrid/issues/14#issuecomment-35728861 */
  4 + visibility: hidden;
  5 + }
  6 + .author {
  7 + img {
  8 + width: 30px;
  9 + height: 30px;
  10 + }
  11 + }
  12 + .header {
  13 + .subheader {
  14 + color: #C1C1C1;
  15 + font-size: 10px;
  16 + }
  17 + }
  18 + .post-lead {
  19 + color: #8E8E8E;
  20 + font-size: 14px;
  21 + }
  22 + .article-image {
  23 + margin: 10px 0;
  24 + }
  25 +}
  26 +
  27 +.col-md-2-5 {
  28 + .deckgrid[deckgrid]::before {
  29 + content: '1 .deck-column';
  30 + }
  31 +}
  32 +
  33 +.col-md-7 {
  34 + .block.recentdocumentsblock {
  35 + background-color: transparent;
  36 + border: 0;
  37 +
  38 + .deckgrid[deckgrid]::before {
  39 + content: '3 .deck-column';
  40 + }
  41 +
  42 + .panel-heading {
  43 + display: none;
  44 + }
  45 + .panel-body {
  46 + padding: 0;
  47 + }
  48 +
  49 + .deckgrid {
  50 + .column {
  51 + float: left;
  52 + }
  53 +
  54 + .deck-column {
  55 + @extend .col-md-4;
  56 + padding: 0;
  57 +
  58 + .a-card {
  59 + padding: 10px;
  60 + margin: 3px;
  61 + }
  62 + }
  63 + }
  64 + }
  65 +}
... ...
src/app/layout/blocks/recent-documents/recent-documents.component.spec.ts
... ... @@ -1,80 +0,0 @@
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 {RecentDocumentsBlockComponent} from './recent-documents.component';
5   -
6   -const htmlTemplate: string = '<noosfero-recent-documents-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-recent-documents-block>';
7   -
8   -const tcb = new TestComponentBuilder();
9   -
10   -describe("Components", () => {
11   - describe("Recent Documents Block Component", () => {
12   -
13   - let settingsObj = {};
14   - let mockedArticleService = {
15   - getByProfile: (profile: noosfero.Profile, filters: any): any => {
16   - return Promise.resolve({ data: [{ name: "article1" }], headers: (name: string) => { return name; } });
17   - }
18   - };
19   - let profile = { name: 'profile-name' };
20   - beforeEach(angular.mock.module("templates"));
21   -
22   - let state = jasmine.createSpyObj("state", ["go"]);
23   -
24   -
25   - function getProviders() {
26   - return [
27   - new Provider('$state', { useValue: state }),
28   - new Provider('ArticleService', {
29   - useValue: mockedArticleService
30   - }),
31   - ].concat(provideFilters("truncateFilter", "stripTagsFilter"));
32   - }
33   - let componentClass: any = null;
34   -
35   - function getComponent() {
36   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [RecentDocumentsBlockComponent], providers: getProviders() })
37   - class BlockContainerComponent {
38   - block = { type: 'Block', settings: settingsObj };
39   - owner = profile;
40   - constructor() {
41   - }
42   - }
43   - return BlockContainerComponent;
44   - }
45   -
46   -
47   - it("get recent documents from the article service", done => {
48   - tcb.createAsync(getComponent()).then(fixture => {
49   - let recentDocumentsBlock: RecentDocumentsBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
50   - expect(recentDocumentsBlock.documents).toEqual([{ name: "article1" }]);
51   - done();
52   - });
53   - });
54   -
55   - it("go to article page when open a document", done => {
56   - tcb.createAsync(getComponent()).then(fixture => {
57   - let recentDocumentsBlock: RecentDocumentsBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
58   - recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } });
59   - expect(state.go).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "identifier" });
60   - done();
61   - });
62   - });
63   -
64   - it("it uses default limit 5 if not defined on block", done => {
65   - settingsObj = null;
66   - mockedArticleService = jasmine.createSpyObj("mockedArticleService", ["getByProfile"]);
67   - (<any>mockedArticleService).mocked = true;
68   - let thenMocked = jasmine.createSpy("then");
69   - mockedArticleService.getByProfile = jasmine.createSpy("getByProfile").and.returnValue({then: thenMocked});
70   - let getByProfileFunct = mockedArticleService.getByProfile;
71   - tcb.createAsync(getComponent()).then(fixture => {
72   - let recentDocumentsBlock: RecentDocumentsBlockComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
73   - recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } });
74   - expect(getByProfileFunct).toHaveBeenCalledWith(profile, { content_type: 'TinyMceArticle', per_page: 5 });
75   - done();
76   - });
77   - });
78   -
79   - });
80   -});
81 0 \ No newline at end of file
src/app/layout/blocks/recent-documents/recent-documents.component.ts
... ... @@ -1,41 +0,0 @@
1   -import {Component, Inject, Input} from "ng-forward";
2   -import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service";
3   -
4   -@Component({
5   - selector: "noosfero-recent-documents-block",
6   - templateUrl: 'app/layout/blocks/recent-documents/recent-documents.html'
7   -})
8   -@Inject(ArticleService, "$state")
9   -export class RecentDocumentsBlockComponent {
10   -
11   - @Input() block: any;
12   - @Input() owner: any;
13   -
14   - profile: any;
15   - documents: any;
16   -
17   - documentsLoaded: boolean = false;
18   -
19   - constructor(private articleService: ArticleService, private $state: any) {
20   - }
21   -
22   - ngOnInit() {
23   - this.profile = this.owner;
24   - this.documents = [];
25   -
26   - let limit = ((this.block && this.block.settings) ? this.block.settings.limit : null) || 5;
27   - // FIXME get all text articles
28   - // FIXME make the getByProfile a generic method where we tell the type passing a class TinyMceArticle
29   - // and the promise should be of type TinyMceArticle[], per example
30   - this.articleService.getByProfile(this.profile, { content_type: 'TinyMceArticle', per_page: limit })
31   - .then((result: noosfero.RestResult<noosfero.Article[]>) => {
32   - this.documents = <noosfero.Article[]>result.data;
33   - this.documentsLoaded = true;
34   - });
35   - }
36   -
37   - openDocument(article: any) {
38   - this.$state.go("main.profile.page", { page: article.path, profile: article.profile.identifier });
39   - }
40   -
41   -}
src/app/layout/blocks/recent-documents/recent-documents.html
... ... @@ -1,18 +0,0 @@
1   -<div deckgrid source="ctrl.documents" class="deckgrid">
2   - <div class="a-card panel media" ng-click="mother.ctrl.openDocument(card);">
3   - <div class="author media-left" ng-show="card.author.image">
4   - <img ng-src="{{card.author.image.url}}" class="img-circle">
5   - </div>
6   - <div class="header media-body">
7   - <h5 class="title media-heading" ng-bind="card.title"></h5>
8   -
9   - <div class="subheader">
10   - <span class="time">
11   - <i class="fa fa-clock-o"></i> <span am-time-ago="card.created_at | dateFormat"></span>
12   - </span>
13   - </div>
14   - </div>
15   - <img ng-show="card.image" ng-src="{{card.image.url}}" class="img-responsive article-image">
16   - <div class="post-lead" ng-bind-html="card.body | stripTags | truncate: 100: '...': true"></div>
17   - </div>
18   -</div>
src/app/layout/blocks/recent-documents/recent-documents.scss
... ... @@ -1,65 +0,0 @@
1   -.block.recentdocumentsblock {
2   - .deckgrid[deckgrid]::before {
3   - font-size: 0; /* See https://github.com/akoenig/angular-deckgrid/issues/14#issuecomment-35728861 */
4   - visibility: hidden;
5   - }
6   - .author {
7   - img {
8   - width: 30px;
9   - height: 30px;
10   - }
11   - }
12   - .header {
13   - .subheader {
14   - color: #C1C1C1;
15   - font-size: 10px;
16   - }
17   - }
18   - .post-lead {
19   - color: #8E8E8E;
20   - font-size: 14px;
21   - }
22   - .article-image {
23   - margin: 10px 0;
24   - }
25   -}
26   -
27   -.col-md-2-5 {
28   - .deckgrid[deckgrid]::before {
29   - content: '1 .deck-column';
30   - }
31   -}
32   -
33   -.col-md-7 {
34   - .block.recentdocumentsblock {
35   - background-color: transparent;
36   - border: 0;
37   -
38   - .deckgrid[deckgrid]::before {
39   - content: '3 .deck-column';
40   - }
41   -
42   - .panel-heading {
43   - display: none;
44   - }
45   - .panel-body {
46   - padding: 0;
47   - }
48   -
49   - .deckgrid {
50   - .column {
51   - float: left;
52   - }
53   -
54   - .deck-column {
55   - @extend .col-md-4;
56   - padding: 0;
57   -
58   - .a-card {
59   - padding: 10px;
60   - margin: 3px;
61   - }
62   - }
63   - }
64   - }
65   -}
src/app/main/main.component.ts
... ... @@ -11,7 +11,7 @@ import {EnvironmentComponent} from &quot;../environment/environment.component&quot;;
11 11 import {EnvironmentHomeComponent} from "../environment/environment-home.component";
12 12 import {PeopleBlockComponent} from "../layout/blocks/people/people-block.component";
13 13 import {LinkListBlockComponent} from "./../layout/blocks/link-list/link-list-block.component";
14   -import {RecentDocumentsBlockComponent} from "../layout/blocks/recent-documents/recent-documents.component";
  14 +import {RecentDocumentsBlockComponent} from "../layout/blocks/recent-documents/recent-documents-block.component";
15 15 import {ProfileImageBlockComponent} from "../layout/blocks/profile-image/profile-image-block.component";
16 16 import {RawHTMLBlockComponent} from "../layout/blocks/raw-html/raw-html-block.component";
17 17  
... ...