Commit d14121298f31300970fed97c1216414bbcdb5037

Authored by Victor Costa
2 parents f5a45d92 a3e051be
Exists in master and in 1 other branch dev-fixes

Merge branch 'ngforward' of softwarepublico.gov.br:noosfero-themes/angular-theme into ngforward

Showing 261 changed files with 3984 additions and 3345 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 261 files displayed.

.vscode/settings.json
... ... @@ -3,7 +3,9 @@
3 3 "files.exclude": {
4 4 "**/.git": true,
5 5 "**/.DS_Store": true,
6   - "src/app/*.js": false
  6 + "src/**/*.js": true,
  7 + "src/**/*.js.map": true,
  8 + "coverage": true
7 9 },
8 10 "editor.fontSize": 14,
9 11 "typescript.useCodeSnippetsOnMethodSuggest": true
... ...
dev-scripts/fix-jqlite.ts 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +let replace = require("replace");
  2 +
  3 +import * as path from "path";
  4 +
  5 +let wrong_jqlite_d_ts_file = path.join(__dirname, "../node_modules/ng-forward/cjs/util/jqlite-extensions.d.ts");
  6 +
  7 +replace({
  8 + regex: /import JQuery from \".\/\";/,
  9 + replacement: "",
  10 + paths: [wrong_jqlite_d_ts_file],
  11 + sillent: false
  12 +});
  13 +
... ...
package.json
... ... @@ -4,21 +4,23 @@
4 4 "dependencies": {
5 5 "angular": "^1.5.0",
6 6 "angular-mock": "^1.0.0",
7   - "moment": "^2.11.2"
  7 + "moment": "^2.11.2",
  8 + "ng-forward": "0.0.1-alpha.12"
8 9 },
9 10 "scripts": {
10 11 "build": "webpack; gulp build",
11 12 "webpack": "webpack",
  13 + "karma": "concurrently \"webpack -w\" \"karma start\"",
12 14 "docs": "gulp ngdocs; static-server docs",
13   - "karma": "karma",
14 15 "coverage": "karma start --single-run; npm run remap-coverage",
15 16 "remap-coverage": "ts-node --project ./dev-scripts ./dev-scripts/remapCoverage.ts",
16 17 "test-single": "karma start --single-run",
17 18 "test-and-coverage": "karma start & npm run remap-coverage",
18 19 "test": "webpack -w --test",
19   - "postinstall": "npm install -g bower && bower install && typings install && cd dev-scripts && typings install",
  20 + "postinstall": "npm install -g bower; bower install; typings install; npm run fix-jqlite; cd dev-scripts; typings install",
20 21 "start": "concurrently \"webpack -w\" \"gulp serve\"",
21   - "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts"
  22 + "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts",
  23 + "fix-jqlite": "ts-node --project ./dev-scripts dev-scripts/fix-jqlite.ts"
22 24 },
23 25 "devDependencies": {
24 26 "browser-sync": "~2.9.11",
... ... @@ -71,7 +73,6 @@
71 73 "karma-webpack": "^1.7.0",
72 74 "lodash": "~3.10.1",
73 75 "main-bower-files": "~2.9.0",
74   - "ng-forward": "0.0.1-alpha.12",
75 76 "on-build-webpack": "^0.1.0",
76 77 "phantomjs": "~1.9.18",
77 78 "phantomjs-polyfill": "0.0.2",
... ...
src/app/admin/index.ts 0 → 100644
... ... @@ -0,0 +1 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
... ...
src/app/article/article-default-view-component.spec.ts 0 → 100644
... ... @@ -0,0 +1,108 @@
  1 +
  2 +import {Input, provide, Component} from 'ng-forward';
  3 +import {ArticleViewComponent, ArticleDefaultViewComponent} from './article-default-view.component';
  4 +
  5 +import {createComponentFromClass, quickCreateComponent} from "../../spec/helpers";
  6 +
  7 +// this htmlTemplate will be re-used between the container components in this spec file
  8 +const htmlTemplate: string = '<noosfero-article [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-article>';
  9 +
  10 +
  11 +describe("Components", () => {
  12 +
  13 + describe("ArticleView Component", () => {
  14 +
  15 + // the karma preprocessor html2js transform the templates html into js files which put
  16 + // the templates to the templateCache into the module templates
  17 + // we need to load the module templates here as the template for the
  18 + // component Noosfero ArtileView will be load on our tests
  19 + beforeEach(angular.mock.module("templates"));
  20 +
  21 + it("renders the default component when no specific component is found", (done: Function) => {
  22 + // Creating a container component (ArticleContainerComponent) to include
  23 + // the component under test (ArticleView)
  24 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent] })
  25 + class ArticleContainerComponent {
  26 + article = { type: 'anyArticleType' };
  27 + profile = { name: 'profile-name' };
  28 + constructor() {
  29 + }
  30 + }
  31 +
  32 + createComponentFromClass(ArticleContainerComponent).then((fixture) => {
  33 + // and here we can inspect and run the test assertions
  34 +
  35 + // gets the children component of ArticleContainerComponent
  36 + let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  37 +
  38 + // and checks if the article View rendered was the Default Article View
  39 + expect(articleView.constructor.prototype).toEqual(ArticleDefaultViewComponent.prototype);
  40 +
  41 + // done needs to be called (it isn't really needed, as we can read in
  42 + // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)
  43 + // because createAsync in ng-forward is not really async, but as the intention
  44 + // here is write tests in angular 2 ways, this is recommended
  45 + done();
  46 + });
  47 +
  48 + });
  49 +
  50 + it("receives the article and profile as inputs", (done: Function) => {
  51 +
  52 + // Creating a container component (ArticleContainerComponent) to include
  53 + // the component under test (ArticleView)
  54 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent] })
  55 + class ArticleContainerComponent {
  56 + article = { type: 'anyArticleType' };
  57 + profile = { name: 'profile-name' };
  58 + constructor() {
  59 + }
  60 + }
  61 +
  62 + // uses the TestComponentBuilder instance to initialize the component
  63 + createComponentFromClass(ArticleContainerComponent).then((fixture) => {
  64 + // and here we can inspect and run the test assertions
  65 + let articleView: ArticleViewComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  66 +
  67 + // assure the article object inside the ArticleView matches
  68 + // the provided through the parent component
  69 + expect(articleView.article.type).toEqual("anyArticleType");
  70 + expect(articleView.profile.name).toEqual("profile-name");
  71 +
  72 + // done needs to be called (it isn't really needed, as we can read in
  73 + // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)
  74 + // because createAsync in ng-forward is not really async, but as the intention
  75 + // here is write tests in angular 2 ways, this is recommended
  76 + done();
  77 + });
  78 + });
  79 +
  80 +
  81 + it("renders a article view which matches to the article type", done => {
  82 + // NoosferoTinyMceArticle component created to check if it will be used
  83 + // when a article with type 'TinyMceArticle' is provided to the noosfero-article (ArticleView)
  84 + // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider
  85 + @Component({ selector: 'noosfero-tiny-mce-article', template: "<h1>TinyMceArticle</h1>" })
  86 + class TinyMceArticleView {
  87 + @Input() article: any;
  88 + @Input() profile: any;
  89 + }
  90 +
  91 + // Creating a container component (ArticleContainerComponent) to include our NoosferoTinyMceArticle
  92 + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleViewComponent, TinyMceArticleView] })
  93 + class CustomArticleType {
  94 + article = { type: 'TinyMceArticle' };
  95 + profile = { name: 'profile-name' };
  96 + constructor() {
  97 + }
  98 + }
  99 + createComponentFromClass(CustomArticleType).then(fixture => {
  100 + let myComponent: CustomArticleType = fixture.componentInstance;
  101 + expect(myComponent.article.type).toEqual("TinyMceArticle");
  102 + expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("TinyMceArticle");
  103 + done();
  104 + });
  105 + });
  106 +
  107 + });
  108 +});
0 109 \ No newline at end of file
... ...
src/app/article/article-default-view.component.ts 0 → 100644
... ... @@ -0,0 +1,57 @@
  1 +import { bundle, Input, Inject, Component, Directive } from 'ng-forward';
  2 +import {ArticleBlogComponent} from "./types/blog/blog.component";
  3 +
  4 +/**
  5 + * @ngdoc controller
  6 + * @name ArticleDefaultView
  7 + * @description
  8 + * A default view for Noosfero Articles. If the specific article view is
  9 + * not implemented, then this view is used.
  10 + */
  11 +@Component({
  12 + selector: 'noosfero-default-article',
  13 + templateUrl: 'app/article/article.html'
  14 +})
  15 +export class ArticleDefaultViewComponent {
  16 +
  17 + @Input() article: noosfero.Article;
  18 + @Input() profile: noosfero.Profile;
  19 +
  20 +}
  21 +
  22 +/**
  23 + * @ngdoc controller
  24 + * @name ArticleView
  25 + * @description
  26 + * A dynamic view for articles. It uses the article type to replace
  27 + * the default template with the custom article directive.
  28 + */
  29 +@Component({
  30 + selector: 'noosfero-article',
  31 + template: 'not-used',
  32 + directives: [ArticleDefaultViewComponent, ArticleBlogComponent]
  33 +})
  34 +@Inject("$element", "$scope", "$injector", "$compile")
  35 +export class ArticleViewComponent {
  36 +
  37 + @Input() article: noosfero.Article;
  38 + @Input() profile: noosfero.Profile;
  39 + directiveName: string;
  40 +
  41 + ngOnInit() {
  42 + let specificDirective = 'noosfero' + this.article.type;
  43 + this.directiveName = "noosfero-default-article";
  44 + if (this.$injector.has(specificDirective + 'Directive')) {
  45 + this.directiveName = specificDirective.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  46 + }
  47 + this.$element.replaceWith(this.$compile('<' + this.directiveName + ' [article]="ctrl.article" [profile]="ctrl.profile"></' + this.directiveName + '>')(this.$scope));
  48 + }
  49 +
  50 + constructor(
  51 + private $element: any,
  52 + private $scope: ng.IScope,
  53 + private $injector: ng.auto.IInjectorService,
  54 + private $compile: ng.ICompileService) {
  55 +
  56 + }
  57 +}
... ...
src/app/article/article.html 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +<div class="article">
  2 + <div class="page-header">
  3 + <h3 ng-bind="ctrl.article.title"></h3>
  4 + </div>
  5 +
  6 + <div class="sub-header clearfix">
  7 + <div class="page-info pull-right small text-muted">
  8 + <span class="time">
  9 + <i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.article.created_at | dateFormat"></span>
  10 + </span>
  11 + <span class="author" ng-if="ctrl.article.author">
  12 + <i class="fa fa-user"></i>
  13 + <a ui-sref="main.profile.home({profile: ctrl.article.author.identifier})">
  14 + <span class="author-name" ng-bind="ctrl.article.author.name"></span>
  15 + </a>
  16 + </span>
  17 + </div>
  18 + </div>
  19 +
  20 + <div class="page-body">
  21 + <div ng-bind-html="ctrl.article.body"></div>
  22 + </div>
  23 +</div>
... ...
src/app/article/article.scss 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +.article {
  2 + .page-info {
  3 + .author {
  4 + a {
  5 + color: #b4bcc2;
  6 + }
  7 + }
  8 + }
  9 +
  10 + .page-header {
  11 + margin-bottom: 5px;
  12 + }
  13 +
  14 + .sub-header {
  15 + margin-bottom: 20px;
  16 + }
  17 +}
... ...
src/app/article/basic-editor.component.spec.ts 0 → 100644
... ... @@ -0,0 +1,55 @@
  1 +import {quickCreateComponent} from "../../spec/helpers";
  2 +import {BasicEditorComponent} from "./basic-editor.component";
  3 +
  4 +
  5 +describe("Article BasicEditor", () => {
  6 +
  7 + let $rootScope: ng.IRootScopeService;
  8 + let $q: ng.IQService;
  9 + let articleServiceMock: any;
  10 + let profileServiceMock: any;
  11 + let $state: any;
  12 + let profile = { id: 1 };
  13 + let notification: any;
  14 +
  15 +
  16 + beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => {
  17 + $rootScope = _$rootScope_;
  18 + $q = _$q_;
  19 + }));
  20 +
  21 + beforeEach(() => {
  22 + $state = jasmine.createSpyObj("$state", ["transitionTo"]);
  23 + notification = jasmine.createSpyObj("notification", ["success"]);
  24 + profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["getCurrentProfile"]);
  25 + articleServiceMock = jasmine.createSpyObj("articleServiceMock", ["createInProfile"]);
  26 +
  27 + let getCurrentProfileResponse = $q.defer();
  28 + getCurrentProfileResponse.resolve(profile);
  29 +
  30 + let articleCreate = $q.defer();
  31 + articleCreate.resolve({ data: { path: "path", profile: { identifier: "profile" } } });
  32 +
  33 + profileServiceMock.getCurrentProfile = jasmine.createSpy("getCurrentProfile").and.returnValue(getCurrentProfileResponse.promise);
  34 + articleServiceMock.createInProfile = jasmine.createSpy("createInProfile").and.returnValue(articleCreate.promise);
  35 + });
  36 +
  37 + it("create an article in the current profile when save", done => {
  38 + let component: BasicEditorComponent = new BasicEditorComponent(articleServiceMock, profileServiceMock, $state, notification);
  39 + component.save();
  40 + $rootScope.$apply();
  41 + expect(profileServiceMock.getCurrentProfile).toHaveBeenCalled();
  42 + expect(articleServiceMock.createInProfile).toHaveBeenCalledWith(profile, component.article);
  43 + done();
  44 + });
  45 +
  46 + it("got to the new article page and display an alert when saving sucessfully", done => {
  47 + let component: BasicEditorComponent = new BasicEditorComponent(articleServiceMock, profileServiceMock, $state, notification);
  48 + component.save();
  49 + $rootScope.$apply();
  50 + expect($state.transitionTo).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "profile" });
  51 + expect(notification.success).toHaveBeenCalled();
  52 + done();
  53 + });
  54 +
  55 +});
... ...
src/app/article/basic-editor.component.ts 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +import {StateConfig, Component, Inject, provide} from 'ng-forward';
  2 +import {ArticleService} from "../../lib/ng-noosfero-api/http/article.service";
  3 +import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service";
  4 +import {NotificationService} from "../shared/services/notification.service.ts";
  5 +
  6 +@Component({
  7 + selector: 'article-basic-editor',
  8 + templateUrl: "app/article/basic-editor.html",
  9 + providers: [
  10 + provide('articleService', { useClass: ArticleService }),
  11 + provide('profileService', { useClass: ProfileService }),
  12 + provide('notification', { useClass: NotificationService })
  13 + ]
  14 +})
  15 +@Inject(ArticleService, ProfileService, "$state", NotificationService)
  16 +export class BasicEditorComponent {
  17 +
  18 + article: noosfero.Article = <noosfero.Article>{};
  19 +
  20 + constructor(private articleService: ArticleService,
  21 + private profileService: ProfileService,
  22 + private $state: ng.ui.IStateService,
  23 + private notification: NotificationService) { }
  24 +
  25 + save() {
  26 + this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => {
  27 + return this.articleService.createInProfile(profile, this.article);
  28 + }).then((response: noosfero.RestResult<noosfero.Article>) => {
  29 + let article = (<noosfero.Article>response.data);
  30 + this.$state.transitionTo('main.profile.page', { page: article.path, profile: article.profile.identifier });
  31 + this.notification.success("Good job!", "Article saved!");
  32 + });
  33 + }
  34 +
  35 +}
... ...
src/app/article/basic-editor.html 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +<form>
  2 + <div class="form-group">
  3 + <label for="titleInput">Title</label>
  4 + <input type="text" class="form-control" id="titleInput" placeholder="title" ng-model="vm.article.name">
  5 + </div>
  6 + <div class="form-group">
  7 + <label for="bodyInput">Text</label>
  8 + <textarea class="form-control" id="bodyInput" rows="10" ng-model="vm.article.body"></textarea>
  9 + </div>
  10 + <button type="submit" class="btn btn-default" ng-click="vm.save()">Save</button>
  11 +</form>
... ...
src/app/article/content-viewer/content-viewer-actions.component.spec.ts 0 → 100644
... ... @@ -0,0 +1,67 @@
  1 +import {providers} from 'ng-forward/cjs/testing/providers';
  2 +
  3 +import {Input, Component, provide} from 'ng-forward';
  4 +
  5 +import * as helpers from "../../../spec/helpers";
  6 +
  7 +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
  8 +import {ContentViewerActions} from './content-viewer-actions.component';
  9 +
  10 +// this htmlTemplate will be re-used between the container components in this spec file
  11 +const htmlTemplate: string = '<content-viewer-actions [article]="ctrl.article" [profile]="ctrl.profile"></content-viewer-actions>';
  12 +
  13 +describe('Content Viewer Actions Component', () => {
  14 +
  15 + beforeEach(() => {
  16 +
  17 + angular.mock.module("templates");
  18 +
  19 + providers((provide: any) => {
  20 + return <any>[
  21 + provide('ProfileService', {
  22 + useValue: helpers.mocks.profileService
  23 + })
  24 + ];
  25 + });
  26 + });
  27 +
  28 + let buildComponent = (): Promise<ComponentFixture> => {
  29 + return helpers.quickCreateComponent({
  30 + providers: [
  31 + helpers.provideEmptyObjects('Restangular'),
  32 + helpers.provideFilters('translateFilter')
  33 + ],
  34 + directives: [ContentViewerActions],
  35 + template: htmlTemplate
  36 + });
  37 + };
  38 +
  39 + it('renders content viewer actions directive', (done: Function) => {
  40 + buildComponent().then((fixture: ComponentFixture) => {
  41 + expect(fixture.debugElement.query('content-viewer-actions').length).toEqual(1);
  42 +
  43 + done();
  44 + });
  45 + });
  46 +
  47 + it('check if profile was loaded', (done: Function) => {
  48 + let profile: any = {
  49 + id: 1,
  50 + identifier: 'the-profile-test',
  51 + type: 'Person'
  52 + };
  53 +
  54 + helpers.mocks.profileService.getCurrentProfile = () => {
  55 + return helpers.mocks.promiseResultTemplate(profile);
  56 + };
  57 +
  58 + buildComponent().then((fixture: ComponentFixture) => {
  59 + let contentViewerComp: ContentViewerActions = fixture.debugElement.componentViewChildren[0].componentInstance;
  60 +
  61 + expect(contentViewerComp.profile).toEqual(jasmine.objectContaining(profile));
  62 +
  63 + done();
  64 + });
  65 + });
  66 +
  67 +});
... ...
src/app/article/content-viewer/content-viewer-actions.component.ts 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +import {Component, Inject, provide} from "ng-forward";
  2 +import {ProfileService} from "../../../lib/ng-noosfero-api/http/profile.service";
  3 +
  4 +@Component({
  5 + selector: "content-viewer-actions",
  6 + templateUrl: "app/article/content-viewer/navbar-actions.html",
  7 + providers: [provide('profileService', { useClass: ProfileService })]
  8 +})
  9 +@Inject(ProfileService)
  10 +export class ContentViewerActions {
  11 +
  12 + article: noosfero.Article;
  13 + profile: noosfero.Profile;
  14 +
  15 + constructor(profileService: ProfileService) {
  16 + profileService.getCurrentProfile().then((profile: noosfero.Profile) => {
  17 + this.profile = profile;
  18 + });
  19 + }
  20 +}
... ...
src/app/article/content-viewer/content-viewer.component.spec.ts 0 → 100644
... ... @@ -0,0 +1,88 @@
  1 +import {providers} from 'ng-forward/cjs/testing/providers';
  2 +
  3 +import {Input, Component, provide} from 'ng-forward';
  4 +
  5 +import * as helpers from "../../../spec/helpers";
  6 +
  7 +import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
  8 +import {ContentViewerComponent} from './content-viewer.component';
  9 +
  10 +// this htmlTemplate will be re-used between the container components in this spec file
  11 +const htmlTemplate: string = '<content-viewer [article]="ctrl.article" [profile]="ctrl.profile"></content-viewer>';
  12 +
  13 +describe('Content Viewer Component', () => {
  14 +
  15 + let stateParamsService: any;
  16 +
  17 + // loading the templates
  18 + beforeEach(() => {
  19 + angular.mock.module("templates");
  20 +
  21 + stateParamsService = { page: 1 };
  22 +
  23 + providers((provide: any) => {
  24 + return <any>[
  25 + provide('ArticleService', {
  26 + useValue: helpers.mocks.articleService
  27 + }),
  28 + provide('ProfileService', {
  29 + useValue: helpers.mocks.profileService
  30 + }),
  31 + // TODO: Como criar um mock do atributo "page" de stateParams
  32 + provide('$stateParams', {
  33 + useValue: stateParamsService
  34 + })
  35 + ];
  36 + });
  37 + });
  38 +
  39 + let buildComponent = (): Promise<ComponentFixture> => {
  40 + return helpers.quickCreateComponent({
  41 + providers: [
  42 + helpers.provideEmptyObjects('Restangular')
  43 + ],
  44 + directives: [ContentViewerComponent],
  45 + template: htmlTemplate
  46 + });
  47 + };
  48 +
  49 + it('renders content viewer directive', (done: Function) => {
  50 + buildComponent().then((fixture: ComponentFixture) => {
  51 + expect(fixture.debugElement.query('content-viewer').length).toEqual(1);
  52 +
  53 + done();
  54 + });
  55 + });
  56 +
  57 + it('check if article was loaded', (done: Function) => {
  58 + let article: any = {
  59 + id: 1,
  60 + title: 'The article test'
  61 + };
  62 + let profile: any = {
  63 + id: 1,
  64 + identifier: 'the-profile-test',
  65 + type: 'Person'
  66 + };
  67 +
  68 + helpers.mocks.profileService.getCurrentProfile = () => {
  69 + return helpers.mocks.promiseResultTemplate(profile);
  70 + };
  71 +
  72 + helpers.mocks.articleService.getArticleByProfileAndPath = (profile: noosfero.Profile, path: string) => {
  73 + return helpers.mocks.promiseResultTemplate({
  74 + data: article
  75 + });
  76 + };
  77 +
  78 +
  79 + buildComponent().then((fixture: ComponentFixture) => {
  80 + let contentViewerComp: ContentViewerComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  81 +
  82 + expect(contentViewerComp.profile).toEqual(profile);
  83 + expect(contentViewerComp.article).toEqual(article);
  84 +
  85 + done();
  86 + });
  87 + });
  88 +});
... ...
src/app/article/content-viewer/content-viewer.component.ts 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +import {ArticleViewComponent} from "./../article-default-view.component";
  2 +import {Input, Component, StateConfig, Inject, provide} from "ng-forward";
  3 +
  4 +import {ArticleBlogComponent} from "./../types/blog/blog.component";
  5 +import {ArticleService} from "../../../lib/ng-noosfero-api/http/article.service";
  6 +import {ProfileService} from "../../../lib/ng-noosfero-api/http/profile.service";
  7 +
  8 +@Component({
  9 + selector: "content-viewer",
  10 + templateUrl: "app/article/content-viewer/page.html",
  11 + directives: [ArticleBlogComponent, ArticleViewComponent],
  12 + providers: [
  13 + provide('articleService', { useClass: ArticleService }),
  14 + provide('profileService', { useClass: ProfileService })
  15 + ]
  16 +})
  17 +@Inject(ArticleService, ProfileService, "$log", "$stateParams")
  18 +export class ContentViewerComponent {
  19 +
  20 + @Input()
  21 + article: noosfero.Article = null;
  22 +
  23 + @Input()
  24 + profile: noosfero.Profile = null;
  25 +
  26 + constructor(private articleService: ArticleService, private profileService: ProfileService, private $log: ng.ILogService, private $stateParams: angular.ui.IStateParamsService) {
  27 + this.activate();
  28 + }
  29 +
  30 + activate() {
  31 + this.profileService.getCurrentProfile().then((profile: noosfero.Profile) => {
  32 + this.profile = profile;
  33 + return this.articleService.getArticleByProfileAndPath(this.profile, this.$stateParams["page"]);
  34 + }).then((result: noosfero.RestResult<any>) => {
  35 + this.article = <noosfero.Article>result.data;
  36 + });
  37 + }
  38 +}
... ...
src/app/article/content-viewer/index.ts 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./content-viewer-actions.component";
  3 +export * from "./content-viewer.component";
... ...
src/app/article/content-viewer/navbar-actions.html 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +<ul class="nav navbar-nav">
  2 + <li ng-show="vm.profile">
  3 + <a href="#" role="button" ui-sref="main.profile.cms({profile: vm.profile.identifier})">
  4 + <i class="fa fa-file fa-fw fa-lg"></i> {{"navbar.content_viewer_actions.new_post" | translate}}
  5 + </a>
  6 + </li>
  7 +</ul>
... ...
src/app/article/content-viewer/page.html 0 → 100644
... ... @@ -0,0 +1 @@
  1 +<noosfero-article ng-if="vm.article" [article]="vm.article" [profile]="vm.profile"></noosfero-article>
... ...
src/app/article/index.ts 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./article-default-view.component";
  3 +export * from "./basic-editor.component";
... ...
src/app/article/types/blog/blog.component.spec.ts 0 → 100644
... ... @@ -0,0 +1,129 @@
  1 +import {
  2 +providers
  3 +} from 'ng-forward/cjs/testing/providers';
  4 +
  5 +import {
  6 +Input,
  7 +Component
  8 +} from 'ng-forward';
  9 +import {
  10 +ArticleBlogComponent
  11 +} from './blog.component';
  12 +
  13 +import {
  14 +createComponentFromClass,
  15 +quickCreateComponent,
  16 +provideEmptyObjects,
  17 +createProviderToValue,
  18 +provideFilters
  19 +} from "../../../../spec/helpers.ts";
  20 +
  21 +// this htmlTemplate will be re-used between the container components in this spec file
  22 +const htmlTemplate: string = '<noosfero-blog [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-blog>';
  23 +
  24 +describe("Blog Component", () => {
  25 +
  26 + function promiseResultTemplate(response?: {}) {
  27 + let thenFuncEmpty = (func: Function) => {
  28 + // does nothing
  29 + };
  30 + if (response) {
  31 + return {
  32 + then: (func: (response: any) => void) => {
  33 + func(response);
  34 + }
  35 + };
  36 + } else {
  37 + return {
  38 + then: (func: (response: any) => void) => {
  39 + // does nothing
  40 + }
  41 + };
  42 + }
  43 + }
  44 +
  45 + let articleService = {
  46 + getChildren: (article_id: number, filters: {}) => {
  47 + return promiseResultTemplate(null);
  48 + }
  49 + };
  50 +
  51 + @Component({
  52 + selector: 'test-container-component',
  53 + template: htmlTemplate,
  54 + directives: [ArticleBlogComponent],
  55 + providers: [
  56 + provideEmptyObjects('Restangular'),
  57 + createProviderToValue('ArticleService', articleService),
  58 + provideFilters('truncateFilter')
  59 + ]
  60 + })
  61 + class BlogContainerComponent {
  62 + article = {
  63 + type: 'anyArticleType'
  64 + };
  65 + profile = {
  66 + name: 'profile-name'
  67 + };
  68 + }
  69 +
  70 + beforeEach(() => {
  71 +
  72 + // the karma preprocessor html2js transform the templates html into js files which put
  73 + // the templates to the templateCache into the module templates
  74 + // we need to load the module templates here as the template for the
  75 + // component Noosfero ArtileView will be load on our tests
  76 + angular.mock.module("templates");
  77 +
  78 + providers((provide: any) => {
  79 + return <any>[
  80 + provide('ArticleService', {
  81 + useValue: articleService
  82 + })
  83 + ];
  84 + });
  85 + });
  86 +
  87 + it("renders the blog content", (done: Function) => {
  88 +
  89 + createComponentFromClass(BlogContainerComponent).then((fixture) => {
  90 +
  91 + expect(fixture.debugElement.query('div.blog').length).toEqual(1);
  92 +
  93 + done();
  94 + });
  95 + });
  96 +
  97 + it("verify the blog data", (done: Function) => {
  98 +
  99 + let articles = [{
  100 + id: 1,
  101 + title: 'The article test'
  102 + }];
  103 +
  104 + let result = { data: articles, headers: (name: string) => { return 1; } };
  105 +
  106 + // defining a mock result to articleService.getChildren method
  107 + articleService.getChildren = (article_id: number, filters: {}) => {
  108 + return promiseResultTemplate(result);
  109 + };
  110 +
  111 + createComponentFromClass(BlogContainerComponent).then((fixture) => {
  112 +
  113 + // gets the children component of BlogContainerComponent
  114 + let articleBlog: BlogContainerComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  115 +
  116 + // check if the component property are the provided by the mocked articleService
  117 + let post = {
  118 + id: 1,
  119 + title: 'The article test'
  120 + };
  121 + expect((<any>articleBlog)["posts"][0]).toEqual(jasmine.objectContaining(post));
  122 + expect((<any>articleBlog)["totalPosts"]).toEqual(1);
  123 +
  124 + done();
  125 + });
  126 +
  127 + });
  128 +
  129 +});
0 130 \ No newline at end of file
... ...
src/app/article/types/blog/blog.component.ts 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +import {Component, Input, Inject} from "ng-forward";
  2 +
  3 +import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service";
  4 +
  5 +/**
  6 + * @ngdoc controller
  7 + * @name ArticleBlog
  8 + * @description
  9 + * An specific {@link ArticleView} for Blog articles.
  10 + */
  11 +@Component({
  12 + selector: "noosfero-blog",
  13 + templateUrl: "app/article/types/blog/blog.html"
  14 +})
  15 +@Inject(ArticleService)
  16 +export class ArticleBlogComponent {
  17 +
  18 + @Input() article: noosfero.Article;
  19 + @Input() profile: noosfero.Profile;
  20 +
  21 + private posts: noosfero.Article[];
  22 + private perPage: number = 3;
  23 + private currentPage: number;
  24 + private totalPosts: number = 0;
  25 +
  26 + constructor(private articleService: ArticleService) { }
  27 +
  28 + ngOnInit() {
  29 + this.loadPage();
  30 + }
  31 +
  32 + loadPage() {
  33 + let filters = {
  34 + content_type: "TinyMceArticle",
  35 + per_page: this.perPage,
  36 + page: this.currentPage
  37 + };
  38 +
  39 + this.articleService
  40 + .getChildren(this.article, filters)
  41 + .then((result: noosfero.RestResult<noosfero.Article[]>) => {
  42 + this.totalPosts = <number>result.headers("total");
  43 + this.posts = result.data;
  44 + });
  45 + }
  46 +
  47 +}
... ...
src/app/article/types/blog/blog.html 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +<div class="blog">
  2 + <div class="blog-cover" ng-show="ctrl.article.image">
  3 + <img ng-src="{{ctrl.article.image.url}}" class="img-responsive">
  4 + <h3 ng-bind="ctrl.article.title"></h3>
  5 + </div>
  6 +
  7 + <div class="page-header" ng-show="!ctrl.article.image">
  8 + <h3 ng-bind="ctrl.article.title"></h3>
  9 + </div>
  10 +
  11 + <div>
  12 + <div ng-repeat="child in ctrl.posts | orderBy: 'created_at':true">
  13 + <div class="page-header">
  14 + <a class="title" ui-sref="main.profile.page({profile: ctrl.profile.identifier, page: child.path})"><h4 ng-bind="child.title"></h4></a>
  15 + <div class="post-lead" ng-bind-html="child.body | truncate: 500: '...': true"></div>
  16 + </div>
  17 + </div>
  18 + </div>
  19 +
  20 + <pagination ng-model="ctrl.currentPage" total-items="ctrl.totalPosts" class="pagination-sm center-block"
  21 + boundary-links="true" items-per-page="ctrl.perPage" ng-change="ctrl.loadPage()"
  22 + first-text="«" last-text="»" previous-text="‹" next-text="›">
  23 + </pagination>
  24 +</div>
... ...
src/app/article/types/blog/blog.scss 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +.blog {
  2 + .blog-cover {
  3 + margin: -15px;
  4 + position: relative;
  5 + h3 {
  6 + position: absolute;
  7 + bottom: 0;
  8 + background-color: rgba(0, 0, 0, 0.4);
  9 + color: white;
  10 + padding: 10px 15px;
  11 + margin: 0;
  12 + width: 100%;
  13 + }
  14 + }
  15 +}
... ...
src/app/article/types/blog/index.ts 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
  2 +export * from "./blog.component";
... ...
src/app/article/types/index.ts 0 → 100644
... ... @@ -0,0 +1 @@
  1 +/* Module Index Entry - generated using the script npm run generate-index */
... ...
src/app/cms/cms.component.spec.ts
... ... @@ -1,54 +0,0 @@
1   -import {quickCreateComponent} from "../../spec/helpers";
2   -import {Cms} from "./cms.component";
3   -
4   -describe("Components", () => {
5   - describe("Cms Component", () => {
6   -
7   - let $rootScope: ng.IRootScopeService;
8   - let $q: ng.IQService;
9   - let articleServiceMock: any;
10   - let profileServiceMock: any;
11   - let $state: any;
12   - let notification: any;
13   -
14   - beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => {
15   - $rootScope = _$rootScope_;
16   - $q = _$q_;
17   - }));
18   -
19   - beforeEach(() => {
20   - $state = jasmine.createSpyObj("$state", ["transitionTo"]);
21   - notification = jasmine.createSpyObj("notification", ["success"]);
22   - profileServiceMock = jasmine.createSpyObj("profileServiceMock", ["getCurrentProfile"]);
23   - articleServiceMock = jasmine.createSpyObj("articleServiceMock", ["create"]);
24   -
25   - let getCurrentProfileResponse = $q.defer();
26   - getCurrentProfileResponse.resolve({ id: 1 });
27   -
28   - let articleCreate = $q.defer();
29   - articleCreate.resolve({ data: { article: { path: "path", profile: { identifier: "profile" } } } });
30   -
31   - profileServiceMock.getCurrentProfile = jasmine.createSpy("getCurrentProfile").and.returnValue(getCurrentProfileResponse.promise);
32   - articleServiceMock.create = jasmine.createSpy("create").and.returnValue(articleCreate.promise);
33   - });
34   -
35   - it("create an article in the current profile when save", done => {
36   - let component: Cms = new Cms(articleServiceMock, profileServiceMock, $state, notification);
37   - component.save();
38   - $rootScope.$apply();
39   - expect(profileServiceMock.getCurrentProfile).toHaveBeenCalled();
40   - expect(articleServiceMock.create).toHaveBeenCalledWith(1, component.article);
41   - done();
42   - });
43   -
44   - it("got to the new article page and display an alert when saving sucessfully", done => {
45   - let component: Cms = new Cms(articleServiceMock, profileServiceMock, $state, notification);
46   - component.save();
47   - $rootScope.$apply();
48   - expect($state.transitionTo).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "profile" });
49   - expect(notification.success).toHaveBeenCalled();
50   - done();
51   - });
52   -
53   - });
54   -});
src/app/cms/cms.component.ts
... ... @@ -1,35 +0,0 @@
1   -import {StateConfig, Component, Inject, provide} from 'ng-forward';
2   -import {Profile} from "./../models/interfaces";
3   -import {ArticleService} from "../../lib/ng-noosfero-api/http/article.service";
4   -import {ProfileService} from "../../lib/ng-noosfero-api/http/profile.service";
5   -import {Notification} from "../components/notification/notification.component";
6   -
7   -@Component({
8   - selector: 'cms',
9   - templateUrl: "app/cms/cms.html",
10   - providers: [
11   - provide('articleService', { useClass: ArticleService }),
12   - provide('profileService', { useClass: ProfileService }),
13   - provide('notification', { useClass: Notification })
14   - ]
15   -})
16   -@Inject(ArticleService, ProfileService, "$state", Notification)
17   -export class Cms {
18   -
19   - article: any = {};
20   -
21   - constructor(private articleService: ArticleService,
22   - private profileService: ProfileService,
23   - private $state: ng.ui.IStateService,
24   - private notification: Notification) { }
25   -
26   - save() {
27   - this.profileService.getCurrentProfile().then((profile: Profile) => {
28   - return this.articleService.create(profile.id, this.article);
29   - }).then((response: restangular.IResponse) => {
30   - this.$state.transitionTo('main.profile.page', { page: response.data.article.path, profile: response.data.article.profile.identifier });
31   - this.notification.success("Good job!", "Article saved!");
32   - });
33   - }
34   -
35   -}
src/app/cms/cms.html
... ... @@ -1,11 +0,0 @@
1   -<form>
2   - <div class="form-group">
3   - <label for="titleInput">Title</label>
4   - <input type="text" class="form-control" id="titleInput" placeholder="title" ng-model="vm.article.name">
5   - </div>
6   - <div class="form-group">
7   - <label for="bodyInput">Text</label>
8   - <textarea class="form-control" id="bodyInput" rows="10" ng-model="vm.article.body"></textarea>
9   - </div>
10   - <button type="submit" class="btn btn-default" ng-click="vm.save()">Save</button>
11   -</form>
src/app/cms/index.ts
... ... @@ -1,2 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./cms.component";
src/app/components/auth/auth_controller.spec.ts
... ... @@ -1,33 +0,0 @@
1   -import {AuthController} from "./auth_controller";
2   -import {AuthService} from "./auth_service";
3   -
4   -describe("Controllers", () => {
5   -
6   -
7   - describe("AuthController", () => {
8   -
9   - it("calls authenticate on AuthService when login called", () => {
10   -
11   - // creating a Mock AuthService
12   - let AuthServiceMock: AuthService = jasmine.createSpyObj("AuthService", ["login"]);
13   -
14   - // pass AuthServiceMock into the constructor
15   - let authController = new AuthController(null, null, AuthServiceMock);
16   -
17   - // setup of authController -> set the credentials instance property
18   - let credentials = { username: "username", password: "password" };
19   -
20   - authController.credentials = credentials;
21   -
22   - // calls the authController login method
23   - authController.login();
24   -
25   - // checks if the method login of the injected AuthService has been called
26   - expect(AuthServiceMock.login).toHaveBeenCalledWith(credentials);
27   -
28   - });
29   -
30   -
31   -
32   - });
33   -});
src/app/components/auth/auth_controller.ts
... ... @@ -1,21 +0,0 @@
1   -import {Credentials} from "./../../models/interfaces";
2   -import {AuthService} from "./auth_service";
3   -
4   -export class AuthController {
5   -
6   - static $inject = ["$log", "$stateParams", "AuthService"];
7   -
8   - constructor(
9   - private $log: ng.ILogService,
10   - private $stateParams: any,
11   - private AuthService: AuthService
12   - ) {
13   -
14   - }
15   -
16   - credentials: Credentials;
17   -
18   - login() {
19   - this.AuthService.login(this.credentials);
20   - }
21   -}
src/app/components/auth/auth_events.ts
... ... @@ -1,11 +0,0 @@
1   -export interface IAuthEvents {
2   - loginSuccess: string;
3   - loginFailed: string;
4   - logoutSuccess: string;
5   -}
6   -
7   -export const AUTH_EVENTS: IAuthEvents = {
8   - loginSuccess: "auth-login-success",
9   - loginFailed: "auth-login-failed",
10   - logoutSuccess: "auth-logout-success"
11   -};
12 0 \ No newline at end of file
src/app/components/auth/auth_service.spec.ts
... ... @@ -1,82 +0,0 @@
1   -
2   -
3   -import {AuthService, AUTH_EVENTS} from "./";
4   -import {User, Credentials} from "./../../models/interfaces";
5   -
6   -describe("Services", () => {
7   -
8   -
9   - describe("Auth Service", () => {
10   -
11   - let $httpBackend: ng.IHttpBackendService;
12   - let authService: AuthService;
13   - let credentials: Credentials;
14   - let $rootScope: ng.IRootScopeService;
15   - let user: User;
16   -
17   - beforeEach(angular.mock.module("noosferoApp", ($translateProvider: angular.translate.ITranslateProvider) => {
18   - $translateProvider.translations('en', {});
19   - }));
20   -
21   - beforeEach(inject((_$httpBackend_: ng.IHttpBackendService, _$rootScope_: ng.IRootScopeService, _AuthService_: AuthService) => {
22   - $httpBackend = _$httpBackend_;
23   - authService = _AuthService_;
24   - $rootScope = _$rootScope_;
25   -
26   - user = <User>{
27   - id: 1,
28   - login: "user"
29   - };
30   - }));
31   -
32   -
33   - describe("Succesffull login", () => {
34   -
35   - beforeEach(() => {
36   - credentials = { username: "user", password: "password" };
37   -
38   - $httpBackend.expectPOST("/api/v1/login", "login=user&password=password").respond(200, { user: user });
39   - });
40   -
41   - it("should return loggedUser", (done) => {
42   - authService.login(credentials).then((loggedUser) => {
43   - expect(loggedUser).toBeDefined();
44   - done();
45   - });
46   - $httpBackend.flush();
47   - expect($httpBackend.verifyNoOutstandingRequest());
48   - });
49   -
50   -
51   - it("should emit event loggin successful with user logged data", () => {
52   -
53   - authService.login(credentials);
54   -
55   - let eventEmmited: boolean = false;
56   - $rootScope.$on(AUTH_EVENTS.loginSuccess, (event: ng.IAngularEvent, userThroughEvent: User) => {
57   - eventEmmited = true;
58   - expect(userThroughEvent).toEqual(user)
59   - });
60   -
61   - $httpBackend.flush();
62   -
63   - expect(eventEmmited).toBeTruthy(AUTH_EVENTS.loginSuccess + " was not emmited!");
64   - });
65   -
66   - it("should return the current logged in user", () => {
67   - authService.login(credentials);
68   - $httpBackend.flush();
69   - let actual: User = authService.currentUser();
70   - expect(actual).toEqual(user, "The returned user must be present");
71   - });
72   -
73   - it("should not return the current user after logout", () => {
74   - authService.logout();
75   - let actual: any = authService.currentUser();
76   - expect(actual).toEqual(undefined, "The returned user must not be defined");
77   - });
78   - });
79   -
80   -
81   - });
82   -});
src/app/components/auth/auth_service.ts
... ... @@ -1,69 +0,0 @@
1   -import {Injectable, Inject} from "ng-forward";
2   -
3   -import {Credentials, NoosferoRootScope, User, UserResponse} from "./../../models/interfaces";
4   -import {Session} from "./session";
5   -
6   -import {AUTH_EVENTS, IAuthEvents} from "./auth_events";
7   -
8   -@Injectable()
9   -@Inject("$q", "$http", "$rootScope", "Session", "$log", "AUTH_EVENTS")
10   -export class AuthService {
11   -
12   - constructor(private $q: ng.IQService,
13   - private $http: ng.IHttpService,
14   - private $rootScope: NoosferoRootScope,
15   - private session: Session,
16   - private $log: ng.ILogService,
17   - private auth_events: IAuthEvents) {
18   -
19   - }
20   -
21   - loginFromCookie() {
22   - let url: string = '/api/v1/login_from_cookie';
23   - return this.$http.post(url, null).then(this.loginSuccessCallback.bind(this), this.loginFailedCallback.bind(this));
24   - }
25   -
26   -
27   - private loginSuccessCallback(response: ng.IHttpPromiseCallbackArg<UserResponse>) {
28   - this.$log.debug('AuthService.login [SUCCESS] response', response);
29   - let currentUser: User = this.session.create(response.data);
30   - this.$rootScope.currentUser = currentUser;
31   - this.$rootScope.$broadcast(this.auth_events.loginSuccess, currentUser);
32   - return currentUser;
33   - }
34   -
35   - login(credentials: Credentials): ng.IPromise<User> {
36   - let url = '/api/v1/login';
37   - let encodedData = 'login=' + credentials.username + '&password=' + credentials.password;
38   - return this.$http.post(url, encodedData).then(this.loginSuccessCallback.bind(this), this.loginFailedCallback.bind(this));
39   - }
40   -
41   - private loginFailedCallback(response: ng.IHttpPromiseCallbackArg<any>): any {
42   - this.$log.debug('AuthService.login [FAIL] response', response);
43   - this.$rootScope.$broadcast(this.auth_events.loginFailed);
44   - // return $q.reject(response);
45   - return null;
46   - }
47   -
48   - public logout() {
49   - this.session.destroy();
50   - this.$rootScope.currentUser = undefined;
51   - this.$rootScope.$broadcast(this.auth_events.logoutSuccess);
52   - this.$http.jsonp('/account/logout'); // FIXME logout from noosfero to sync login state
53   - }
54   -
55   - public isAuthenticated() {
56   - return !!this.session.currentUser();
57   - }
58   -
59   - public currentUser(): User {
60   - return this.session.currentUser();
61   - }
62   -
63   - public isAuthorized(authorizedRoles: string | string[]) {
64   - if (!angular.isArray(authorizedRoles)) {
65   - authorizedRoles = [<string>authorizedRoles];
66   - }
67   - return (this.isAuthenticated() && authorizedRoles.indexOf(this.session.currentUser().userRole) !== -1);
68   - }
69   -}
70 0 \ No newline at end of file
src/app/components/auth/index.ts
... ... @@ -1,5 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./auth_controller";
3   -export * from "./auth_events";
4   -export * from "./auth_service";
5   -export * from "./session";
src/app/components/auth/login.html
... ... @@ -1,16 +0,0 @@
1   -<div class="modal-header">
2   - <h3 class="modal-title">{{"auth.title" | translate}}</h3>
3   -</div>
4   -<div class="modal-body">
5   - <form>
6   - <div class="form-group">
7   - <label for="exampleInputEmail1">{{"auth.form.login" | translate}}</label>
8   - <input type="text" class="form-control" id="exampleInputEmail1" placeholder="Login / Email" ng-model="vm.credentials.username">
9   - </div>
10   - <div class="form-group">
11   - <label for="exampleInputPassword1">{{"auth.form.password" | translate}}</label>
12   - <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password" ng-model="vm.credentials.password">
13   - </div>
14   - <button type="submit" class="btn btn-default" ng-click="vm.login()">{{"auth.form.login_button" | translate}}</button>
15   - </form>
16   -</div>
src/app/components/auth/session.ts
... ... @@ -1,27 +0,0 @@
1   -import {Injectable, Inject} from "ng-forward";
2   -import {UserResponse, User, INoosferoLocalStorage} from "./../../models/interfaces";
3   -
4   -@Injectable()
5   -@Inject("$localStorage", "$log")
6   -export class Session {
7   -
8   - constructor(private $localStorage: INoosferoLocalStorage, private $log: ng.ILogService) {
9   -
10   - }
11   -
12   - create(data: UserResponse): User {
13   - this.$localStorage.currentUser = data.user;
14   - this.$log.debug('User session created.', this.$localStorage.currentUser);
15   - return this.$localStorage.currentUser;
16   - };
17   -
18   - destroy() {
19   - delete this.$localStorage.currentUser;
20   - this.$log.debug('User session destroyed.');
21   - };
22   -
23   - currentUser(): User {
24   - return this.$localStorage.currentUser;
25   - };
26   -
27   -}
28 0 \ No newline at end of file
src/app/components/auth/session_spec.ts
... ... @@ -1,49 +0,0 @@
1   -import {Component} from "ng-forward";
2   -import {Session} from "./";
3   -import {fixtures, createComponentFromClass, createProviderToValue} from "./../../../spec/helpers";
4   -import {UserResponse, User, INoosferoLocalStorage} from "./../../models/interfaces";
5   -
6   -
7   -describe("Services", () => {
8   -
9   -
10   - describe("Session Service", () => {
11   -
12   - let $localStorage: INoosferoLocalStorage = null;
13   - let $log: any;
14   -
15   - beforeEach(() => {
16   - $localStorage = <INoosferoLocalStorage>{ currentUser: null };
17   - $log = jasmine.createSpyObj('$log', ['debug']);
18   - });
19   -
20   - it("method 'create()' saves the current user on $localstorage service", () => {
21   - let session = new Session($localStorage, $log);
22   - let userResponse = <UserResponse>{
23   - user: fixtures.user
24   - };
25   - session.create(userResponse);
26   - expect($localStorage.currentUser).toEqual(userResponse.user);
27   - });
28   -
29   - it("method 'destroy()' clean the currentUser on $localstorage", () => {
30   - let session = new Session($localStorage, $log);
31   - let userResponse = <UserResponse>{
32   - user: fixtures.user
33   - };
34   - $localStorage.currentUser = fixtures.user;
35   - session.destroy();
36   - expect($localStorage.currentUser).toBeUndefined();
37   - });
38   -
39   - it("method 'currentUser()' returns the user recorded on $localstorage service", () => {
40   - let session = new Session($localStorage, $log);
41   - let userResponse = <UserResponse>{
42   - user: fixtures.user
43   - };
44   - $localStorage.currentUser = fixtures.user;
45   - expect(session.currentUser()).toEqual($localStorage.currentUser);
46   - });
47   - });
48   -
49   -});
50 0 \ No newline at end of file
src/app/components/index.ts
... ... @@ -1 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
src/app/components/language-selector/language-selector.component.spec.ts
... ... @@ -1,46 +0,0 @@
1   -import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {provide} from 'ng-forward';
3   -
4   -import {LanguageSelector} from './language-selector.component';
5   -
6   -import * as helpers from "../../../spec/helpers";
7   -
8   -describe("Components", () => {
9   -
10   - describe("Language Selector Component", () => {
11   -
12   - beforeEach(angular.mock.module("templates"));
13   -
14   - let translatorService: any;
15   -
16   - let buildComponent = (): Promise<ComponentFixture> => {
17   - translatorService = jasmine.createSpyObj("translatorService", ["availableLanguages", "currentLanguage"])
18   - return helpers.quickCreateComponent({
19   - template: "<language-selector></language-selector>",
20   - directives: [LanguageSelector],
21   - providers: [
22   - provide('TranslatorService', {
23   - useValue: translatorService
24   - })
25   - ].concat(helpers.provideFilters("translateFilter"))
26   - });
27   - }
28   -
29   - it("display language options", (done) => {
30   - buildComponent().then(fixture => {
31   - fixture.debugElement.getLocal("$rootScope").$apply();
32   - expect(fixture.debugElement.queryAll('li.language').length).toEqual(2);
33   - done();
34   - });
35   - });
36   -
37   - it("call the translator service when change the language", (done) => {
38   - let translatorService = jasmine.createSpyObj("translatorService", ["changeLanguage"]);
39   - let languageSelector = new LanguageSelector(<any>translatorService);
40   - languageSelector.changeLanguage("en");
41   - expect(translatorService.changeLanguage).toHaveBeenCalledWith("en");
42   - done();
43   - });
44   -
45   - });
46   -});
src/app/components/language-selector/language-selector.component.ts
... ... @@ -1,24 +0,0 @@
1   -import {Component, Inject} from "ng-forward";
2   -import {TranslatorService} from "../translator/translator.service";
3   -
4   -@Component({
5   - selector: "language-selector",
6   - templateUrl: "app/components/language-selector/language-selector.html"
7   -})
8   -@Inject(TranslatorService)
9   -export class LanguageSelector {
10   -
11   - constructor(private translatorService: TranslatorService) { }
12   -
13   - currentLanguage() {
14   - return this.translatorService.currentLanguage();
15   - }
16   -
17   - changeLanguage(language: string) {
18   - this.translatorService.changeLanguage(language);
19   - }
20   -
21   - availableLanguages() {
22   - return this.translatorService.availableLanguages;
23   - }
24   -}
src/app/components/language-selector/language-selector.html
... ... @@ -1,13 +0,0 @@
1   -<li class="dropdown profile-menu" dropdown>
2   - <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle>
3   - <span>{{"language.selector" | translate}}</span> <b class="caret"></b>
4   - </a>
5   - <ul class="dropdown-menu" dropdown-menu>
6   - <li ng-repeat="(language, description) in ctrl.availableLanguages()"
7   - class="language language-{{language}}" ng-class="{'active': language==ctrl.currentLanguage()}">
8   - <a href="#" ng-click="ctrl.changeLanguage(language)">
9   - {{description}}
10   - </a>
11   - </li>
12   - </ul>
13   -</li>
src/app/components/navbar/index.ts
... ... @@ -1,2 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./navbar";
src/app/components/navbar/navbar.directive.spec.js
... ... @@ -1,45 +0,0 @@
1   -(function() {
2   - 'use strict';
3   -
4   - describe('directive navbar', function() {
5   - var vm;
6   - var el;
7   - var AUTH_EVENTS;
8   - var $state;
9   -
10   - beforeEach(module('angular'));
11   - beforeEach(inject(function($compile, $rootScope, $httpBackend, _AUTH_EVENTS_, _$state_) {
12   - $state = _$state_;
13   - AUTH_EVENTS = _AUTH_EVENTS_;
14   - $httpBackend.when('POST','/api/v1/login_from_cookie').respond({});
15   -
16   - el = angular.element('<acme-navbar></acme-navbar>');
17   -
18   - $compile(el)($rootScope.$new());
19   - $rootScope.$digest();
20   - vm = el.isolateScope().vm;
21   - }));
22   -
23   - it('should be compiled', function() {
24   - expect(el.html()).not.toEqual(null);
25   - });
26   -
27   - it('should have isolate scope object with instanciate members', function() {
28   - expect(vm).toEqual(jasmine.any(Object));
29   - expect(vm.currentUser).toEqual(undefined);
30   - });
31   -
32   - it('should reload current state after login', function() {
33   - spyOn($state, 'go');
34   - el.isolateScope().$broadcast(AUTH_EVENTS.loginSuccess, {});
35   - expect($state.go).toHaveBeenCalled();
36   - });
37   -
38   - it('should open login when not logged in', function() {
39   - spyOn(vm, 'openLogin');
40   - vm.activate();
41   - expect(vm.openLogin).toHaveBeenCalled();
42   - });
43   -
44   - });
45   -})();
src/app/components/navbar/navbar.html
... ... @@ -1,49 +0,0 @@
1   -<nav class="navbar navbar-static-top navbar-inverse">
2   - <div class="container-fluid">
3   - <div class="navbar-header">
4   - <button type="button" class="navbar-toggle collapsed" ng-click="isCollapsed = !isCollapsed">
5   - <span class="sr-only">{{"navbar.toggle_menu" | translate}}</span>
6   - <span class="icon-bar"></span>
7   - <span class="icon-bar"></span>
8   - <span class="icon-bar"></span>
9   - </button>
10   - <a class="navbar-brand" ui-sref="main">
11   - <span class="noosfero-logo"><img src="assets/images/logo-noosfero.png"></span> {{"noosfero.name" | translate}}
12   - </a>
13   - </div>
14   -
15   - <div class="collapse navbar-collapse" id="navbar-collapse" collapse="isCollapsed">
16   - <ul class="nav navbar-nav">
17   - </ul>
18   -
19   - <ul class="nav navbar-nav navbar-right">
20   - <li ng-show="!ctrl.currentUser">
21   - <a ng-href="#" ng-click="ctrl.openLogin()">{{"navbar.login" | translate}}</a>
22   - </li>
23   -
24   - <li class="dropdown profile-menu" ng-show="ctrl.currentUser" dropdown>
25   - <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle>
26   - <noosfero-profile-image [profile]="ctrl.currentUser.person" class="profile-image"></noosfero-profile-image>
27   - <span ng-bind="ctrl.currentUser.person.name"></span> <b class="caret"></b>
28   - </a>
29   - <ul class="dropdown-menu" dropdown-menu>
30   - <li>
31   - <a ui-sref="main.profile.info({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> {{"navbar.profile" | translate}}</a>
32   - </li>
33   - <li>
34   - <a target="_self" ui-sref="main.profile.settings({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> {{"navbar.settings" | translate}}</a>
35   - </li>
36   - <li class="divider"></li>
37   - <li>
38   - <a href="#" ng-click="ctrl.logout()"><i class="fa fa-fw fa-power-off"></i> {{"navbar.logout" | translate}}</a>
39   - </li>
40   - </ul>
41   - </li>
42   - </ul>
43   - <ul class="nav navbar-nav navbar-right">
44   - <language-selector class="nav navbar-nav navbar-right"></language-selector>
45   - </ul>
46   - <div ui-view="actions"></div>
47   - </div>
48   - </div>
49   -</nav>
src/app/components/navbar/navbar.scss
... ... @@ -1,31 +0,0 @@
1   -.navbar {
2   -
3   - .container-fluid {
4   - padding-right: 12%;
5   - padding-left: 12%;
6   - @media (max-width: 978px) {
7   - padding-right: 2%;
8   - padding-left: 2%;
9   - }
10   -
11   - .navbar-brand {
12   - .noosfero-logo img {
13   - height: 35px;
14   - }
15   - }
16   -
17   - .navbar-nav {
18   - .profile-menu .profile-image {
19   - img {
20   - height: 30px;
21   - width: 30px;
22   - display: inline-block;
23   - @extend .img-circle;
24   - }
25   - i {
26   - font-size: 1.7em;
27   - }
28   - }
29   - }
30   - }
31   -}
src/app/components/navbar/navbar.spec.ts
... ... @@ -1,188 +0,0 @@
1   -import * as helpers from "./../../../spec/helpers";
2   -import {Navbar} from "./navbar";
3   -import {AUTH_EVENTS} from "./../auth";
4   -import {User} from "./../../models/interfaces";
5   -import {Injectable, Provider, provide} from "ng-forward";
6   -
7   -import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
8   -
9   -import {Session, AuthService, AuthController, IAuthEvents} from "./../auth";
10   -
11   -
12   -describe("Components", () => {
13   -
14   - describe("Navbar Component", () => {
15   -
16   - let user: User = null;
17   - let scope: any;
18   - let $rootScope: ng.IRootScopeService;
19   -
20   - let modalInstance: any;
21   - let $modal: any;
22   - let authService: any;
23   - let stateService: any;
24   - let sessionService: Session;
25   -
26   - let provideFunc = provide;
27   -
28   - // before Each -> loading mocks on locals variables
29   - beforeEach(() => {
30   - user = <User>{
31   - id: 1,
32   - login: "user"
33   - };
34   - scope = helpers.mocks.scopeWithEvents;
35   - modalInstance = helpers.mocks.modalInstance;
36   - $modal = helpers.mocks.$modal;
37   - authService = helpers.mocks.authService;
38   - stateService = jasmine.createSpyObj("$state", ["go"]);
39   - sessionService = <any>helpers.mocks.sessionWithCurrentUser(user);
40   - });
41   -
42   -
43   - // loading the templates
44   - beforeEach(angular.mock.module("templates"));
45   -
46   -
47   - // this function allow build the fixture of the container component
48   - // and is reused in each test
49   - // The main idea behing not prebuild it on a general beforeEach block is
50   - // to allow tests configure the mock services accordilly their own needs
51   - let buildComponent = (): Promise<ComponentFixture> => {
52   - return helpers.quickCreateComponent({
53   - providers: [
54   - provide('$modal', {
55   - useValue: $modal
56   - }),
57   - provide('AuthService', {
58   - useValue: authService
59   - }),
60   - helpers.provideEmptyObjects('moment'),
61   - provide('$state', {
62   - useValue: stateService
63   - }),
64   - provide("$scope", {
65   - useValue: scope
66   - }),
67   - provide('Session', {
68   - useValue: sessionService
69   - }),
70   - provide('AUTH_EVENTS', {
71   - useValue: {
72   - AUTH_EVENTS
73   - }
74   - }),
75   - provide('TranslatorService', {
76   - useValue: helpers.mocks.translatorService
77   - })
78   - ].concat(helpers.provideFilters("translateFilter")),
79   - directives: [Navbar],
80   - template: '<acme-navbar></acme-navbar>'
81   - });
82   - }
83   -
84   -
85   - it('should get the loggedIn user', (done: Function) => {
86   - buildComponent().then((fixture: ComponentFixture) => {
87   - let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance;
88   - expect(navbarInstance).toBeDefined();
89   - expect(navbarInstance["currentUser"]).toEqual(user);
90   - done();
91   - });
92   - });
93   -
94   - it('should open on click', (done: Function) => {
95   - spyOn($modal, "open");
96   - buildComponent().then((fixture: ComponentFixture) => {
97   - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
98   - navbarComp.openLogin();
99   - expect($modal.open).toHaveBeenCalled();
100   - expect($modal.open).toHaveBeenCalledWith({
101   - templateUrl: 'app/components/auth/login.html',
102   - controller: AuthController,
103   - controllerAs: 'vm',
104   - bindToController: true
105   - });
106   - done();
107   - });
108   - });
109   -
110   - it('should logout', (done: Function) => {
111   - buildComponent().then((fixture: ComponentFixture) => {
112   - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
113   - spyOn(authService, "logout");
114   - try {
115   - navbarComp.logout();
116   - expect(authService.logout).toHaveBeenCalled();
117   - done();
118   - } catch (e) {
119   - console.error(e);
120   - fail(e.message);
121   - done();
122   - }
123   - });
124   - });
125   -
126   -
127   - it('should not activate user when logged in', (done: Function) => {
128   - buildComponent().then((fixture: ComponentFixture) => {
129   - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
130   - spyOn(navbarComp, "openLogin");
131   - navbarComp.activate();
132   - expect((<any>navbarComp.openLogin).calls.count()).toBe(0);
133   - done();
134   - });
135   - });
136   -
137   - it('should activate when user not logged in', (done: Function) => {
138   - spyOn(sessionService, 'currentUser').and.returnValue(null);
139   - buildComponent().then((fixture: ComponentFixture) => {
140   - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
141   - spyOn(navbarComp, "openLogin");
142   - navbarComp.activate();
143   - expect(navbarComp.openLogin).toHaveBeenCalled();
144   - done();
145   - });
146   - });
147   -
148   -
149   - it('closes the modal after login', (done: Function) => {
150   - modalInstance = jasmine.createSpyObj("modalInstance", ["close"]);
151   - modalInstance.close = jasmine.createSpy("close");
152   -
153   - $modal.open = () => {
154   - return modalInstance;
155   - };
156   -
157   - buildComponent().then((fixture: ComponentFixture) => {
158   - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
159   - let localScope: ng.IScope = navbarComp["$scope"];
160   -
161   - navbarComp.openLogin();
162   - localScope.$emit(AUTH_EVENTS.loginSuccess);
163   - expect(modalInstance.close).toHaveBeenCalled();
164   - done();
165   - });
166   - });
167   -
168   - it('updates current user on logout', (done: Function) => {
169   - buildComponent().then((fixture: ComponentFixture) => {
170   - let navbarComp: Navbar = <Navbar>fixture.debugElement.componentViewChildren[0].componentInstance;
171   - let localScope: ng.IScope = navbarComp["$scope"];
172   -
173   - // init navbar currentUser with some user
174   - navbarComp["currentUser"] = user;
175   -
176   - // changes the current User to return null,
177   - // and emmit the 'logoutSuccess' event
178   - // just what happens when user logsout
179   - sessionService.currentUser = () => { return null; };
180   - localScope.$emit(AUTH_EVENTS.logoutSuccess);
181   - expect(navbarComp["currentUser"]).toBeNull();
182   - done();
183   - });
184   - });
185   -
186   -
187   - });
188   -});
src/app/components/navbar/navbar.ts
... ... @@ -1,67 +0,0 @@
1   -import {Component, Inject} from "ng-forward";
2   -import {LanguageSelector} from "../language-selector/language-selector.component";
3   -
4   -
5   -import {Session, AuthService, AuthController, IAuthEvents, AUTH_EVENTS} from "./../auth";
6   -import {User} from "./../../models/interfaces";
7   -
8   -@Component({
9   - selector: "acme-navbar",
10   - templateUrl: "app/components/navbar/navbar.html",
11   - directives: [LanguageSelector],
12   - providers: [AuthService, Session]
13   -})
14   -@Inject("$modal", AuthService, "Session", "$scope", "$state")
15   -export class Navbar {
16   -
17   - private currentUser: User;
18   - private modalInstance: any = null;
19   - /**
20   - *
21   - */
22   - constructor(
23   - private $modal: any,
24   - private authService: AuthService,
25   - private session: Session,
26   - private $scope: ng.IScope,
27   - private $state: ng.ui.IStateService
28   - ) {
29   - this.currentUser = this.session.currentUser();
30   -
31   - this.$scope.$on(AUTH_EVENTS.loginSuccess, () => {
32   - if (this.modalInstance) {
33   - this.modalInstance.close();
34   - this.modalInstance = null;
35   - }
36   -
37   - this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth
38   - });
39   -
40   - this.$scope.$on(AUTH_EVENTS.logoutSuccess, () => {
41   - this.currentUser = this.session.currentUser();
42   - });
43   - }
44   -
45   - openLogin() {
46   - this.modalInstance = this.$modal.open({
47   - templateUrl: 'app/components/auth/login.html',
48   - controller: AuthController,
49   - controllerAs: 'vm',
50   - bindToController: true
51   - });
52   - };
53   -
54   - logout() {
55   - this.authService.logout();
56   - this.$state.go(this.$state.current, {}, { reload: true }); // TODO move to auth
57   - };
58   -
59   -
60   -
61   - activate() {
62   - if (!this.currentUser) {
63   - this.openLogin();
64   - }
65   - }
66   -
67   -}
src/app/components/noosfero-activities/activities.component.spec.ts
... ... @@ -1,36 +0,0 @@
1   -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Pipe, Input, provide, Component} from 'ng-forward';
3   -import {provideFilters} from '../../../spec/helpers';
4   -
5   -import {NoosferoActivities} from './activities.component';
6   -
7   -const tcb = new TestComponentBuilder();
8   -
9   -const htmlTemplate: string = '<noosfero-activities [activities]="ctrl.activities"></noosfero-activities>';
10   -
11   -
12   -describe("Components", () => {
13   -
14   - describe("Noosfero Activities", () => {
15   -
16   - beforeEach(angular.mock.module("templates"));
17   -
18   - @Component({
19   - selector: 'test-container-component',
20   - template: htmlTemplate,
21   - directives: [NoosferoActivities],
22   - providers: provideFilters("truncateFilter", "stripTagsFilter", "translateFilter")
23   - })
24   - class BlockContainerComponent {
25   - activities = [{ name: "activity1", verb: "create_article" }, { name: "activity2", verb: "create_article" }];
26   - }
27   -
28   - it("render a noosfero activity tag for each activity", done => {
29   - tcb.createAsync(BlockContainerComponent).then(fixture => {
30   - expect(fixture.debugElement.queryAll("noosfero-activity").length).toEqual(2);
31   - done();
32   - });
33   - });
34   - });
35   -
36   -});
src/app/components/noosfero-activities/activities.component.ts
... ... @@ -1,27 +0,0 @@
1   -import {Component, Input} from "ng-forward";
2   -import {NoosferoActivity} from "./activity/activity.component";
3   -import {Activity} from "../../models/interfaces";
4   -
5   -/**
6   - * @ngdoc controller
7   - * @name NoosferoActivities
8   - * @description
9   - * The controller responsible to retreive profile activities.
10   - */
11   -
12   -@Component({
13   - selector: "noosfero-activities",
14   - templateUrl: 'app/components/noosfero-activities/activities.html',
15   - directives: [NoosferoActivity]
16   -})
17   -export class NoosferoActivities {
18   -
19   - /**
20   - * @ngdoc property
21   - * @propertyOf NoosferoActivities
22   - * @name activities
23   - * @returns {Activity[]} An array of {@link Activity}.
24   - */
25   - @Input() activities: Activity[];
26   -
27   -}
src/app/components/noosfero-activities/activities.html
... ... @@ -1,5 +0,0 @@
1   -<timeline>
2   - <timeline-event ng-repeat="activity in ctrl.activities | orderBy: 'created_at':true">
3   - <noosfero-activity [activity]="activity"></noosfero-activity>
4   - </timeline-event>
5   -</timeline>
src/app/components/noosfero-activities/activities.scss
... ... @@ -1,11 +0,0 @@
1   -.comma-separated {
2   - .separated-item {
3   - &:after {
4   - content: ", ";
5   - margin-left: -3px;
6   - }
7   - &:last-child:after {
8   - content: "";
9   - }
10   - }
11   -}
src/app/components/noosfero-activities/activity/activity.component.spec.ts
... ... @@ -1,38 +0,0 @@
1   -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Pipe, Input, provide, Component} from 'ng-forward';
3   -import {provideFilters} from '../../../../spec/helpers';
4   -
5   -import {NoosferoActivity} from './activity.component';
6   -
7   -const tcb = new TestComponentBuilder();
8   -
9   -const htmlTemplate: string = '<noosfero-activity [activity]="ctrl.activity"></noosfero-activity>';
10   -
11   -
12   -describe("Components", () => {
13   -
14   - describe("Noosfero Activity", () => {
15   -
16   - beforeEach(angular.mock.module("templates"));
17   -
18   - @Component({
19   - selector: 'test-container-component',
20   - template: htmlTemplate,
21   - directives: [NoosferoActivity],
22   - providers: provideFilters("truncateFilter", "stripTagsFilter", "translateFilter")
23   - })
24   - class BlockContainerComponent {
25   - activity = { name: "activity1", verb: "create_article" };
26   - }
27   -
28   - it("render the specific template for an activity verb", done => {
29   - tcb.createAsync(BlockContainerComponent).then(fixture => {
30   - let component: NoosferoActivity = fixture.debugElement.componentViewChildren[0].componentInstance;
31   - expect(component.getActivityTemplate()).toEqual('app/components/noosfero-activities/activity/create_article.html');
32   - expect(fixture.debugElement.queryAll(".activity.create_article").length).toEqual(1);
33   - done();
34   - });
35   - });
36   - });
37   -
38   -});
src/app/components/noosfero-activities/activity/activity.component.ts
... ... @@ -1,16 +0,0 @@
1   -import {Component, Input} from "ng-forward";
2   -import {Activity} from "../../../models/interfaces";
3   -
4   -@Component({
5   - selector: "noosfero-activity",
6   - templateUrl: 'app/components/noosfero-activities/activity/activity.html'
7   -})
8   -export class NoosferoActivity {
9   -
10   - @Input() activity: Activity;
11   -
12   - getActivityTemplate() {
13   - return 'app/components/noosfero-activities/activity/' + this.activity.verb + '.html';
14   - }
15   -
16   -}
src/app/components/noosfero-activities/activity/activity.html
... ... @@ -1,3 +0,0 @@
1   -<div class="activity {{ctrl.activity.verb}}">
2   - <ng-include src="ctrl.getActivityTemplate()"></ng-include>
3   -</div>
src/app/components/noosfero-activities/activity/add_member_in_community.html
... ... @@ -1,13 +0,0 @@
1   -<timeline-badge class="info">
2   - <i class="fa fa-user-plus"></i>
3   -</timeline-badge>
4   -<timeline-panel>
5   - <timeline-heading>
6   - <h4 class="timeline-title">
7   - <a ui-sref="main.profile.info({profile: ctrl.activity.user.identifier})"><strong ng-bind="ctrl.activity.user.name"></strong></a>
8   - <span> {{"activities.add_member_in_community.description" | translate}}</span>
9   - </h4>
10   - <p><small class="text-muted"><i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.activity.created_at | dateFormat"></span></small></p>
11   - </timeline-heading>
12   - <div class="timeline-body"></div>
13   -</timeline-panel>
src/app/components/noosfero-activities/activity/create_article.html
... ... @@ -1,26 +0,0 @@
1   -<timeline-badge class="success">
2   - <i class="fa fa-file-text"></i>
3   -</timeline-badge>
4   -<timeline-panel>
5   - <timeline-heading>
6   - <h4 class="timeline-title">
7   - <a ui-sref="main.profile.info({profile: ctrl.activity.user.identifier})"><strong ng-bind="ctrl.activity.user.name"></strong></a>
8   - <span> {{"activities.create_article.description" | translate}} </span>
9   - <a ui-sref="main.profile.info({profile: ctrl.activity.target.article.profile.identifier})">
10   - <strong ng-bind="ctrl.activity.target.article.profile.name"></strong></span>
11   - </a>
12   - </h4>
13   - <p><small class="text-muted"><i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.activity.created_at | dateFormat"></span></small></p>
14   - </timeline-heading>
15   - <div class="timeline-body">
16   - <div class="article">
17   - <div class="title">
18   - <a ui-sref="main.profile.page({profile: ctrl.activity.target.article.profile.identifier, page: ctrl.activity.target.article.path})"
19   - ng-bind="ctrl.activity.target.article.title"></a>
20   - </div>
21   - <div class="lead small">
22   - <div ng-bind-html="ctrl.activity.target.article.body | stripTags | truncate: 100 : '...': true"></div>
23   - </div>
24   - </div>
25   - </div>
26   -</timeline-panel>
src/app/components/noosfero-activities/activity/index.ts
... ... @@ -1 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
src/app/components/noosfero-activities/activity/new_friendship.html
... ... @@ -1,18 +0,0 @@
1   -<timeline-badge class="info">
2   - <i class="fa fa-user-plus"></i>
3   -</timeline-badge>
4   -<timeline-panel>
5   - <timeline-heading>
6   - <h4 class="timeline-title">
7   - <a ui-sref="main.profile.info({profile: ctrl.activity.user.identifier})"><strong ng-bind="ctrl.activity.user.name"></strong></a>
8   - <span> {{"activities.new_friendship.description" | translate:{friends: ctrl.activity.params.friend_name.length}:"messageformat" }} </span>
9   - <span class="comma-separated">
10   - <a class="separated-item" ui-sref="main.profile.info({profile: ctrl.activity.params.friend_url[$index].profile})" ng-repeat="friend in ctrl.activity.params.friend_name">
11   - <strong ng-bind="friend"></strong>
12   - </a>
13   - </span>
14   - </h4>
15   - <p><small class="text-muted"><i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.activity.created_at | dateFormat"></span></small></p>
16   - </timeline-heading>
17   - <div class="timeline-body"></div>
18   -</timeline-panel>
src/app/components/noosfero-activities/index.ts
... ... @@ -1 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
src/app/components/noosfero-articles/article/article.html
... ... @@ -1,23 +0,0 @@
1   -<div class="article">
2   - <div class="page-header">
3   - <h3 ng-bind="ctrl.article.title"></h3>
4   - </div>
5   -
6   - <div class="sub-header clearfix">
7   - <div class="page-info pull-right small text-muted">
8   - <span class="time">
9   - <i class="fa fa-clock-o"></i> <span am-time-ago="ctrl.article.created_at | dateFormat"></span>
10   - </span>
11   - <span class="author" ng-if="ctrl.article.author">
12   - <i class="fa fa-user"></i>
13   - <a ui-sref="main.profile.home({profile: ctrl.article.author.identifier})">
14   - <span class="author-name" ng-bind="ctrl.article.author.name"></span>
15   - </a>
16   - </span>
17   - </div>
18   - </div>
19   -
20   - <div class="page-body">
21   - <div ng-bind-html="ctrl.article.body"></div>
22   - </div>
23   -</div>
src/app/components/noosfero-articles/article/article.scss
... ... @@ -1,17 +0,0 @@
1   -.article {
2   - .page-info {
3   - .author {
4   - a {
5   - color: #b4bcc2;
6   - }
7   - }
8   - }
9   -
10   - .page-header {
11   - margin-bottom: 5px;
12   - }
13   -
14   - .sub-header {
15   - margin-bottom: 20px;
16   - }
17   -}
src/app/components/noosfero-articles/article/article_view.spec.ts
... ... @@ -1,108 +0,0 @@
1   -
2   -import {Input, provide, Component} from 'ng-forward';
3   -import {ArticleView, ArticleDefaultView} from './article_view';
4   -
5   -import {createComponentFromClass, quickCreateComponent} from "../../../../spec/helpers";
6   -
7   -// this htmlTemplate will be re-used between the container components in this spec file
8   -const htmlTemplate: string = '<noosfero-article [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-article>';
9   -
10   -
11   -describe("Components", () => {
12   -
13   - describe("ArticleView Component", () => {
14   -
15   - // the karma preprocessor html2js transform the templates html into js files which put
16   - // the templates to the templateCache into the module templates
17   - // we need to load the module templates here as the template for the
18   - // component Noosfero ArtileView will be load on our tests
19   - beforeEach(angular.mock.module("templates"));
20   -
21   - it("renders the default component when no specific component is found", (done: Function) => {
22   - // Creating a container component (ArticleContainerComponent) to include
23   - // the component under test (ArticleView)
24   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleView] })
25   - class ArticleContainerComponent {
26   - article = { type: 'anyArticleType' };
27   - profile = { name: 'profile-name' };
28   - constructor() {
29   - }
30   - }
31   -
32   - createComponentFromClass(ArticleContainerComponent).then((fixture) => {
33   - // and here we can inspect and run the test assertions
34   -
35   - // gets the children component of ArticleContainerComponent
36   - let articleView: ArticleView = fixture.debugElement.componentViewChildren[0].componentInstance;
37   -
38   - // and checks if the article View rendered was the Default Article View
39   - expect(articleView.constructor.prototype).toEqual(ArticleDefaultView.prototype);
40   -
41   - // done needs to be called (it isn't really needed, as we can read in
42   - // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)
43   - // because createAsync in ng-forward is not really async, but as the intention
44   - // here is write tests in angular 2 ways, this is recommended
45   - done();
46   - });
47   -
48   - });
49   -
50   - it("receives the article and profile as inputs", (done: Function) => {
51   -
52   - // Creating a container component (ArticleContainerComponent) to include
53   - // the component under test (ArticleView)
54   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleView] })
55   - class ArticleContainerComponent {
56   - article = { type: 'anyArticleType' };
57   - profile = { name: 'profile-name' };
58   - constructor() {
59   - }
60   - }
61   -
62   - // uses the TestComponentBuilder instance to initialize the component
63   - createComponentFromClass(ArticleContainerComponent).then((fixture) => {
64   - // and here we can inspect and run the test assertions
65   - let articleView: ArticleView = fixture.debugElement.componentViewChildren[0].componentInstance;
66   -
67   - // assure the article object inside the ArticleView matches
68   - // the provided through the parent component
69   - expect(articleView.article.type).toEqual("anyArticleType");
70   - expect(articleView.profile.name).toEqual("profile-name");
71   -
72   - // done needs to be called (it isn't really needed, as we can read in
73   - // here (https://github.com/ngUpgraders/ng-forward/blob/master/API.md#createasync)
74   - // because createAsync in ng-forward is not really async, but as the intention
75   - // here is write tests in angular 2 ways, this is recommended
76   - done();
77   - });
78   - });
79   -
80   -
81   - it("renders a article view which matches to the article type", done => {
82   - // NoosferoTinyMceArticle component created to check if it will be used
83   - // when a article with type 'TinyMceArticle' is provided to the noosfero-article (ArticleView)
84   - // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider
85   - @Component({ selector: 'noosfero-tiny-mce-article', template: "<h1>TinyMceArticle</h1>" })
86   - class TinyMceArticleView {
87   - @Input() article: any;
88   - @Input() profile: any;
89   - }
90   -
91   - // Creating a container component (ArticleContainerComponent) to include our NoosferoTinyMceArticle
92   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ArticleView, TinyMceArticleView] })
93   - class CustomArticleType {
94   - article = { type: 'TinyMceArticle' };
95   - profile = { name: 'profile-name' };
96   - constructor() {
97   - }
98   - }
99   - createComponentFromClass(CustomArticleType).then(fixture => {
100   - let myComponent: CustomArticleType = fixture.componentInstance;
101   - expect(myComponent.article.type).toEqual("TinyMceArticle");
102   - expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("TinyMceArticle");
103   - done();
104   - });
105   - });
106   -
107   - });
108   -});
109 0 \ No newline at end of file
src/app/components/noosfero-articles/article/article_view.ts
... ... @@ -1,57 +0,0 @@
1   -import { bundle, Input, Inject, Component, Directive } from 'ng-forward';
2   -import {ArticleBlog} from "../blog/blog.component";
3   -
4   -/**
5   - * @ngdoc controller
6   - * @name ArticleDefaultView
7   - * @description
8   - * A default view for Noosfero Articles. If the specific article view is
9   - * not implemented, then this view is used.
10   - */
11   -@Component({
12   - selector: 'noosfero-default-article',
13   - templateUrl: 'app/components/noosfero-articles/article/article.html'
14   -})
15   -export class ArticleDefaultView {
16   -
17   - @Input() article: any;
18   - @Input() profile: any;
19   -
20   -}
21   -
22   -/**
23   - * @ngdoc controller
24   - * @name ArticleView
25   - * @description
26   - * A dynamic view for articles. It uses the article type to replace
27   - * the default template with the custom article directive.
28   - */
29   -@Component({
30   - selector: 'noosfero-article',
31   - template: 'not-used',
32   - directives: [ArticleDefaultView, ArticleBlog]
33   -})
34   -@Inject("$element", "$scope", "$injector", "$compile")
35   -export class ArticleView {
36   -
37   - @Input() article: any;
38   - @Input() profile: any;
39   - directiveName: string;
40   -
41   - ngOnInit() {
42   - let specificDirective = 'noosfero' + this.article.type;
43   - this.directiveName = "noosfero-default-article";
44   - if (this.$injector.has(specificDirective + 'Directive')) {
45   - this.directiveName = specificDirective.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
46   - }
47   - this.$element.replaceWith(this.$compile('<' + this.directiveName + ' [article]="ctrl.article" [profile]="ctrl.profile"></' + this.directiveName + '>')(this.$scope));
48   - }
49   -
50   - constructor(
51   - private $element: any,
52   - private $scope: ng.IScope,
53   - private $injector: ng.auto.IInjectorService,
54   - private $compile: ng.ICompileService) {
55   -
56   - }
57   -}
src/app/components/noosfero-articles/article/index.ts
... ... @@ -1,2 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./article_view";
src/app/components/noosfero-articles/blog/blog.component.spec.ts
... ... @@ -1,132 +0,0 @@
1   -import {
2   - providers
3   -} from 'ng-forward/cjs/testing/providers';
4   -
5   -import {
6   - Input,
7   - Component
8   -} from 'ng-forward';
9   -import {
10   - ArticleBlog
11   -} from './blog.component';
12   -
13   -import {
14   - createComponentFromClass,
15   - quickCreateComponent,
16   - provideEmptyObjects,
17   - createProviderToValue,
18   - provideFilters
19   -} from "../../../../spec/helpers.ts";
20   -
21   -// this htmlTemplate will be re-used between the container components in this spec file
22   -const htmlTemplate: string = '<noosfero-blog [article]="ctrl.article" [profile]="ctrl.profile"></noosfero-blog>';
23   -
24   -describe("Blog Component", () => {
25   -
26   - function promiseResultTemplate(response ? : {}) {
27   - let thenFuncEmpty = (func: Function) => {
28   - // does nothing
29   - };
30   - if (response) {
31   - return {
32   - then: (func: (response: any) => void) => {
33   - func(response);
34   - }
35   - };
36   - } else {
37   - return {
38   - then: (func: (response: any) => void) => {
39   - // does nothing
40   - }
41   - };
42   - }
43   - }
44   -
45   - let articleService = {
46   - getChildren: (article_id: number, filters: {}) => {
47   - return promiseResultTemplate(null);
48   - }
49   - };
50   -
51   - @Component({
52   - selector: 'test-container-component',
53   - template: htmlTemplate,
54   - directives: [ArticleBlog],
55   - providers: [
56   - provideEmptyObjects('Restangular'),
57   - createProviderToValue('ArticleService', articleService),
58   - provideFilters('truncateFilter')
59   - ]
60   - })
61   - class BlogContainerComponent {
62   - article = {
63   - type: 'anyArticleType'
64   - };
65   - profile = {
66   - name: 'profile-name'
67   - };
68   - }
69   -
70   - beforeEach(() => {
71   -
72   - // the karma preprocessor html2js transform the templates html into js files which put
73   - // the templates to the templateCache into the module templates
74   - // we need to load the module templates here as the template for the
75   - // component Noosfero ArtileView will be load on our tests
76   - angular.mock.module("templates")
77   -
78   - providers((provide: any) => {
79   - return <any > [
80   - provide('ArticleService', {
81   - useValue: articleService
82   - })
83   - ]
84   - });
85   - });
86   -
87   - it("renders the blog content", (done: Function) => {
88   -
89   - createComponentFromClass(BlogContainerComponent).then((fixture) => {
90   -
91   - expect(fixture.debugElement.query('div.blog').length).toEqual(1);
92   -
93   - done();
94   - });
95   - });
96   -
97   - it("verify the blog data", (done: Function) => {
98   -
99   - // defining a mock result to articleService.getChildren method
100   - articleService.getChildren = (article_id: number, filters: {}) => {
101   - return promiseResultTemplate({
102   - headers: (headerName: string) => {
103   - return 1;
104   - },
105   - data: < any > {
106   - articles: [{
107   - id: 1,
108   - title: 'The article test'
109   - }]
110   - }
111   - });
112   - };
113   -
114   - createComponentFromClass(BlogContainerComponent).then((fixture) => {
115   -
116   - // gets the children component of BlogContainerComponent
117   - let articleBlog: BlogContainerComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
118   -
119   - // check if the component property are the provided by the mocked articleService
120   - let post = {
121   - id: 1,
122   - title: 'The article test'
123   - };
124   - expect(( < any > articleBlog)["posts"][0]).toEqual(jasmine.objectContaining(post));
125   - expect(( < any > articleBlog)["totalPosts"]).toEqual(1);
126   -
127   - done();
128   - });
129   -
130   - });
131   -
132   -});
133 0 \ No newline at end of file
src/app/components/noosfero-articles/blog/blog.component.ts
... ... @@ -1,48 +0,0 @@
1   -import {Component, Input, Inject} from "ng-forward";
2   -
3   -import {Article, Profile} from "./../../../models/interfaces";
4   -import {ArticleService} from "../../../../lib/ng-noosfero-api/http/article.service";
5   -
6   -/**
7   - * @ngdoc controller
8   - * @name ArticleBlog
9   - * @description
10   - * An specific {@link ArticleView} for Blog articles.
11   - */
12   -@Component({
13   - selector: "noosfero-blog",
14   - templateUrl: "app/components/noosfero-articles/blog/blog.html"
15   -})
16   -@Inject(ArticleService)
17   -export class ArticleBlog {
18   -
19   - @Input() article: Article;
20   - @Input() profile: Profile;
21   -
22   - private posts: any[];
23   - private perPage: number = 3;
24   - private currentPage: number;
25   - private totalPosts: number = 0;
26   -
27   - constructor(private articleService: ArticleService) { }
28   -
29   - ngOnInit() {
30   - this.loadPage();
31   - }
32   -
33   - loadPage() {
34   - let filters = {
35   - content_type: "TinyMceArticle",
36   - per_page: this.perPage,
37   - page: this.currentPage
38   - };
39   -
40   - this.articleService
41   - .getChildren(this.article.id, filters)
42   - .then((response: restangular.IResponse) => {
43   - this.totalPosts = <number>(<any>response.headers("total"));
44   - this.posts = response.data.articles;
45   - });
46   - }
47   -
48   -}
src/app/components/noosfero-articles/blog/blog.html
... ... @@ -1,24 +0,0 @@
1   -<div class="blog">
2   - <div class="blog-cover" ng-show="ctrl.article.image">
3   - <img ng-src="{{ctrl.article.image.url}}" class="img-responsive">
4   - <h3 ng-bind="ctrl.article.title"></h3>
5   - </div>
6   -
7   - <div class="page-header" ng-show="!ctrl.article.image">
8   - <h3 ng-bind="ctrl.article.title"></h3>
9   - </div>
10   -
11   - <div>
12   - <div ng-repeat="child in ctrl.posts | orderBy: 'created_at':true">
13   - <div class="page-header">
14   - <a class="title" ui-sref="main.profile.page({profile: ctrl.profile.identifier, page: child.path})"><h4 ng-bind="child.title"></h4></a>
15   - <div class="post-lead" ng-bind-html="child.body | truncate: 500: '...': true"></div>
16   - </div>
17   - </div>
18   - </div>
19   -
20   - <pagination ng-model="ctrl.currentPage" total-items="ctrl.totalPosts" class="pagination-sm center-block"
21   - boundary-links="true" items-per-page="ctrl.perPage" ng-change="ctrl.loadPage()"
22   - first-text="«" last-text="»" previous-text="‹" next-text="›">
23   - </pagination>
24   -</div>
src/app/components/noosfero-articles/blog/blog.scss
... ... @@ -1,15 +0,0 @@
1   -.blog {
2   - .blog-cover {
3   - margin: -15px;
4   - position: relative;
5   - h3 {
6   - position: absolute;
7   - bottom: 0;
8   - background-color: rgba(0, 0, 0, 0.4);
9   - color: white;
10   - padding: 10px 15px;
11   - margin: 0;
12   - width: 100%;
13   - }
14   - }
15   -}
src/app/components/noosfero-articles/blog/index.ts
... ... @@ -1,2 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./blog.component";
src/app/components/noosfero-articles/index.ts
... ... @@ -1 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
src/app/components/noosfero-blocks/block.component.spec.ts
... ... @@ -1,91 +0,0 @@
1   -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Input, provide, Component} from 'ng-forward';
3   -
4   -import {Block} from './block.component';
5   -
6   -const tcb = new TestComponentBuilder();
7   -
8   -const htmlTemplate: string = '<noosfero-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-block>';
9   -
10   -describe("Components", () => {
11   - describe("Block Component", () => {
12   -
13   - // the karma preprocessor html2js transform the templates html into js files which put
14   - // the templates to the templateCache into the module templates
15   - // we need to load the module templates here as the template for the
16   - // component Block will be load on our tests
17   - beforeEach(angular.mock.module("templates"));
18   -
19   - it("receives the block and the owner as inputs", done => {
20   -
21   - // Creating a container component (BlockContainerComponent) to include
22   - // the component under test (Block)
23   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [Block] })
24   - class BlockContainerComponent {
25   - block = { type: 'Block' };
26   - owner = { name: 'profile-name' };
27   - constructor() {
28   - }
29   - }
30   -
31   - // uses the TestComponentBuilder instance to initialize the component
32   - tcb
33   - .createAsync(BlockContainerComponent).then(fixture => {
34   - // and here we can inspect and run the test assertions
35   - let myComponent: Block = fixture.componentInstance;
36   -
37   - // assure the block object inside the Block matches
38   - // the provided through the parent component
39   - expect(myComponent.block.type).toEqual("Block");
40   - expect(myComponent.owner.name).toEqual("profile-name");
41   - done();
42   - });
43   - });
44   -
45   -
46   - it("renders a component which matches to the block type", done => {
47   - // CustomBlock component created to check if it will be used
48   - // when a block with type 'CustomBlock' is provided to the noosfero-block (Block)
49   - // *** Important *** - the selector is what ng-forward uses to define the name of the directive provider
50   - @Component({ selector: 'noosfero-custom-block', template: "<h1>My Custom Block</h1>" })
51   - class CustomBlock {
52   - @Input() block: any;
53   - @Input() owner: any;
54   - }
55   -
56   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [Block, CustomBlock] })
57   - class CustomBlockType {
58   - block = { type: 'CustomBlock' };
59   - owner = { name: 'profile-name' };
60   - constructor() {
61   - }
62   - }
63   - tcb
64   - .createAsync(CustomBlockType).then(fixture => {
65   - let myComponent: CustomBlockType = fixture.componentInstance;
66   - expect(myComponent.block.type).toEqual("CustomBlock");
67   - expect(fixture.debugElement.componentViewChildren[0].text()).toEqual("My Custom Block");
68   - done();
69   - });
70   - });
71   -
72   -
73   - it("renders the default block when hasn't defined a block type", done => {
74   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [Block] })
75   - class CustomBlockType {
76   - block: any = { type: null };
77   - owner: any = { name: 'profile-name' };
78   - constructor() {
79   - }
80   - }
81   - tcb
82   - .createAsync(CustomBlockType).then(fixture => {
83   - let myComponent: CustomBlockType = fixture.componentInstance;
84   - expect(myComponent.block.type).toBeNull();
85   - expect(!!fixture.debugElement.nativeElement.querySelector("noosfero-default-block")).toBeTruthy();
86   - done();
87   - });
88   - });
89   -
90   - });
91   -});
92 0 \ No newline at end of file
src/app/components/noosfero-blocks/block.component.ts
... ... @@ -1,20 +0,0 @@
1   -import { Input, Inject, Component } from 'ng-forward';
2   -
3   -@Component({
4   - selector: 'noosfero-block',
5   - template: '<div></div>'
6   -})
7   -@Inject("$element", "$scope", "$injector", "$compile")
8   -export class Block {
9   -
10   - @Input() block: any;
11   - @Input() owner: any;
12   -
13   - ngOnInit() {
14   - let blockName = (this.block && this.block.type) ? this.block.type.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() : "default-block";
15   - this.$element.replaceWith(this.$compile('<noosfero-' + blockName + ' [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-' + blockName + '>')(this.$scope));
16   - }
17   -
18   - constructor(private $element: any, private $scope: ng.IScope, private $injector: ng.auto.IInjectorService, private $compile: ng.ICompileService) {
19   - }
20   -}
src/app/components/noosfero-blocks/block.scss
... ... @@ -1,10 +0,0 @@
1   -.block {
2   - .panel-title {
3   - font-size: 15px;
4   - font-weight: bold;
5   - }
6   - .panel-heading {
7   - background-color: transparent;
8   - border: 0;
9   - }
10   -}
src/app/components/noosfero-blocks/index.ts
... ... @@ -1,2 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./block.component";
src/app/components/noosfero-blocks/link-list/index.ts
... ... @@ -1,2 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
2   -export * from "./link-list.component";
src/app/components/noosfero-blocks/link-list/link-list.component.spec.ts
... ... @@ -1,65 +0,0 @@
1   -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Pipe, Input, provide, Component} from 'ng-forward';
3   -import {provideFilters} from '../../../../spec/helpers';
4   -
5   -import {LinkListBlock} from './link-list.component';
6   -
7   -const tcb = new TestComponentBuilder();
8   -
9   -const htmlTemplate: string = '<noosfero-link-list-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-link-list-block>';
10   -
11   -
12   -describe("Components", () => {
13   -
14   - describe("Link List Block Component", () => {
15   -
16   - beforeEach(angular.mock.module("templates"));
17   -
18   - it("receives the block and the owner as inputs", done => {
19   -
20   - // Creating a container component (BlockContainerComponent) to include
21   - // the component under test (Block)
22   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [LinkListBlock] })
23   - class BlockContainerComponent {
24   - block = { type: 'Block' };
25   - owner = { name: 'profile-name' };
26   - constructor() {
27   - }
28   - }
29   -
30   - // uses the TestComponentBuilder instance to initialize the component
31   - //.overrideView(LinkListBlock, { template: 'asdasdasd', pipes: [NoosferoTemplate] })
32   - tcb.createAsync(BlockContainerComponent).then(fixture => {
33   - // and here we can inspect and run the test assertions
34   - let myComponent: LinkListBlock = fixture.componentInstance;
35   -
36   - // assure the block object inside the Block matches
37   - // the provided through the parent component
38   - expect(myComponent.block.type).toEqual("Block");
39   - expect(myComponent.owner.name).toEqual("profile-name");
40   - done();
41   - });
42   - });
43   -
44   -
45   - it("display links stored in block settings", done => {
46   -
47   - @Component({
48   - selector: 'test-container-component',
49   - template: htmlTemplate,
50   - directives: [LinkListBlock],
51   - providers: provideFilters("noosferoTemplateFilter")
52   - })
53   - class CustomBlockType {
54   - block: any = { settings: { links: [{ name: 'link1', address: 'address1' }, { name: 'link2', address: 'address2' }] } };
55   - owner: any = { name: 'profile-name' };
56   - }
57   - tcb.createAsync(CustomBlockType).then(fixture => {
58   - expect(fixture.debugElement.queryAll(".link-list-block a").length).toEqual(2);
59   - done();
60   - });
61   - });
62   -
63   - });
64   -
65   -});
66 0 \ No newline at end of file
src/app/components/noosfero-blocks/link-list/link-list.component.ts
... ... @@ -1,20 +0,0 @@
1   -import {Component, Input} from "ng-forward";
2   -
3   -@Component({
4   - selector: "noosfero-link-list-block",
5   - templateUrl: "app/components/noosfero-blocks/link-list/link-list.html"
6   -})
7   -export class LinkListBlock {
8   -
9   - @Input() block: any;
10   - @Input() owner: any;
11   -
12   - links: any;
13   -
14   - ngOnInit() {
15   - if (this.block && this.block.settings) {
16   - this.links = this.block.settings.links;
17   - }
18   - }
19   -
20   -}
src/app/components/noosfero-blocks/link-list/link-list.html
... ... @@ -1,7 +0,0 @@
1   -<div class="link-list-block">
2   - <div ng-repeat="link in ctrl.links">
3   - <a ng-href="{{link.address | noosferoTemplate:{profile: ctrl.owner.identifier} }}">
4   - <i class="fa fa-fw icon-{{link.icon}}"></i> <span>{{link.name}}</span>
5   - </a>
6   - </div>
7   -</div>
src/app/components/noosfero-blocks/link-list/link-list.scss
... ... @@ -1,34 +0,0 @@
1   -.icon-event {
2   - @extend .fa-calendar;
3   -}
4   -.icon-photos {
5   - @extend .fa-photo;
6   -}
7   -.icon-edit {
8   - @extend .fa-edit;
9   -}
10   -.icon-ok {
11   - @extend .fa-check;
12   -}
13   -.icon-send {
14   - @extend .fa-send-o;
15   -}
16   -.icon-menu-people {
17   - @extend .fa-user;
18   -}
19   -.icon-forum {
20   - @extend .fa-users;
21   -}
22   -.icon-new {
23   - @extend .fa-file-o;
24   -}
25   -.icon-save {
26   - @extend .fa-save;
27   -}
28   -
29   -.link-list-block {
30   - a i {
31   - line-height: 25px;
32   - color: #949494;
33   - }
34   -}
src/app/components/noosfero-blocks/main-block/index.ts
... ... @@ -1 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
src/app/components/noosfero-blocks/main-block/main-block.component.spec.ts
... ... @@ -1,41 +0,0 @@
1   -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Input, provide, Component, StateConfig} from 'ng-forward';
3   -
4   -import {MainBlock} from './main-block.component';
5   -import {NoosferoApp} from '../../../index.module';
6   -
7   -const tcb = new TestComponentBuilder();
8   -
9   -const htmlTemplate: string = '<noosfero-main-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-main-block>';
10   -
11   -describe("Components", () => {
12   - describe("Main Block Component", () => {
13   -
14   - // the karma preprocessor html2js transform the templates html into js files which put
15   - // the templates to the templateCache into the module templates
16   - // we need to load the module templates here as the template for the
17   - // component Block will be load on our tests
18   - beforeEach(angular.mock.module("templates"));
19   -
20   - it("check if the main block has a tag with ui-view attribute", done => {
21   -
22   - // Creating a container component (BlockContainerComponent) to include
23   - // the component under test (Block)
24   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [MainBlock] })
25   - class BlockContainerComponent {
26   - }
27   -
28   - // uses the TestComponentBuilder instance to initialize the component
29   - tcb.createAsync(BlockContainerComponent).then(fixture => {
30   - // and here we can inspect and run the test assertions
31   - //let myComponent: MainBlock = fixture.componentInstance;
32   -
33   - // assure the block object inside the Block matches
34   - // the provided through the parent component
35   - expect(fixture.debugElement.queryAll('[ui-view="mainBlockContent"]').length).toEqual(1)
36   - done();
37   - });
38   - });
39   -
40   - });
41   -});
42 0 \ No newline at end of file
src/app/components/noosfero-blocks/main-block/main-block.component.ts
... ... @@ -1,10 +0,0 @@
1   -import {Component, Input} from 'ng-forward'
2   -import {Block} from '../block.component';
3   -
4   -@Component({
5   - selector: 'noosfero-main-block',
6   - templateUrl: 'app/components/noosfero-blocks/main-block/main-block.html'
7   -})
8   -export class MainBlock {
9   -
10   -}
src/app/components/noosfero-blocks/main-block/main-block.html
... ... @@ -1 +0,0 @@
1   -<div ui-view="mainBlockContent" autoscroll></div>
src/app/components/noosfero-blocks/members-block/index.ts
... ... @@ -1 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
src/app/components/noosfero-blocks/members-block/members-block.component.spec.ts
... ... @@ -1,53 +0,0 @@
1   -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Provider, Input, provide, Component} from 'ng-forward';
3   -
4   -import {MembersBlock} from './members-block.component';
5   -
6   -const htmlTemplate: string = '<noosfero-members-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-members-block>';
7   -
8   -const tcb = new TestComponentBuilder();
9   -
10   -describe("Components", () => {
11   - describe("Members Block Component", () => {
12   -
13   - beforeEach(angular.mock.module("templates"));
14   -
15   - let state = jasmine.createSpyObj("state", ["go"]);
16   - let providers = [
17   - new Provider('truncateFilter', { useValue: () => { } }),
18   - new Provider('stripTagsFilter', { useValue: () => { } }),
19   - new Provider('$state', { useValue: state }),
20   - new Provider('ProfileService', {
21   - useValue: {
22   - getProfileMembers: (profileId: number, filters: any): any => {
23   - return Promise.resolve({ data: { people: [{ identifier: "person1" }] } });
24   - }
25   - }
26   - }),
27   - ];
28   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [MembersBlock], providers: providers })
29   - class BlockContainerComponent {
30   - block = { type: 'Block', settings: {} };
31   - owner = { name: 'profile-name' };
32   - constructor() {
33   - }
34   - }
35   -
36   - it("get members of the block owner", done => {
37   - tcb.createAsync(BlockContainerComponent).then(fixture => {
38   - let block: MembersBlock = fixture.debugElement.componentViewChildren[0].componentInstance;
39   - expect(block.members).toEqual([{ identifier: "person1" }]);
40   - done();
41   - });
42   - });
43   -
44   - it("render the profile image for each member", done => {
45   - tcb.createAsync(BlockContainerComponent).then(fixture => {
46   - fixture.debugElement.getLocal("$rootScope").$apply();
47   - expect(fixture.debugElement.queryAll("noosfero-profile-image").length).toEqual(1);
48   - done();
49   - });
50   - });
51   -
52   - });
53   -});
54 0 \ No newline at end of file
src/app/components/noosfero-blocks/members-block/members-block.component.ts
... ... @@ -1,25 +0,0 @@
1   -import {Input, Inject, Component} from "ng-forward";
2   -import {ProfileService} from "../../../../lib/ng-noosfero-api/http/profile.service";
3   -
4   -@Component({
5   - selector: "noosfero-members-block",
6   - templateUrl: 'app/components/noosfero-blocks/members-block/members-block.html',
7   -})
8   -@Inject(ProfileService)
9   -export class MembersBlock {
10   -
11   - @Input() block: any;
12   - @Input() owner: any;
13   -
14   - members: any = [];
15   -
16   - constructor(private profileService: ProfileService) {
17   -
18   - }
19   -
20   - ngOnInit() {
21   - this.profileService.getProfileMembers(this.owner.id, { per_page: 6 }).then((response: any) => {
22   - this.members = response.data.people;
23   - });
24   - }
25   -}
src/app/components/noosfero-blocks/members-block/members-block.html
... ... @@ -1,5 +0,0 @@
1   -<div class="members-block">
2   - <a ng-repeat="member in ctrl.members" ui-sref="main.profile.home({profile: member.identifier})" class="member">
3   - <noosfero-profile-image [profile]="member"></noosfero-profile-image>
4   - </a>
5   -</div>
src/app/components/noosfero-blocks/members-block/members-block.scss
... ... @@ -1,17 +0,0 @@
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/components/noosfero-blocks/profile-image-block/profile-image-block.component.spec.ts
... ... @@ -1,46 +0,0 @@
1   -import {TestComponentBuilder, ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Pipe, Input, provide, Component} from 'ng-forward';
3   -
4   -import {ProfileImageBlock} from './profile-image-block.component';
5   -
6   -import * as helpers from "./../../../../spec/helpers";
7   -
8   -const tcb = new TestComponentBuilder();
9   -
10   -const htmlTemplate: string = '<noosfero-profile-image-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-profile-image-block>';
11   -
12   -describe("Components", () => {
13   -
14   - describe("Profile Image Block Component", () => {
15   -
16   - beforeEach(angular.mock.module("templates"));
17   -
18   - @Component({
19   - selector: 'test-container-component',
20   - template: htmlTemplate,
21   - directives: [ProfileImageBlock],
22   - providers: helpers.provideFilters("translateFilter")
23   - })
24   - class BlockContainerComponent {
25   - block = { type: 'Block' };
26   - owner = { name: 'profile-name' };
27   - constructor() {
28   - }
29   - }
30   -
31   - it("show image if present", () => {
32   - helpers.tcb.createAsync(BlockContainerComponent).then(fixture => {
33   - var elProfile = fixture.debugElement.componentViewChildren[0];
34   - expect(elProfile.query('div.profile-image-block').length).toEqual(1);
35   - });
36   - });
37   -
38   - it("has link to the profile", () => {
39   - helpers.tcb.createAsync(BlockContainerComponent).then(fixture => {
40   - var elProfile = fixture.debugElement.componentViewChildren[0];
41   - expect(elProfile.query('a.settings-link').length).toEqual(1);
42   - });
43   - });
44   -
45   - });
46   -});
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.component.ts
... ... @@ -1,14 +0,0 @@
1   -import {Inject, Input, Component} from "ng-forward";
2   -import {ProfileImage} from "./../../../components/noosfero/profile-image/profile-image.component";
3   -
4   -@Component({
5   - selector: "noosfero-profile-image-block",
6   - templateUrl: 'app/components/noosfero-blocks/profile-image-block/profile-image-block.html',
7   - directives: [ProfileImage]
8   -})
9   -export class ProfileImageBlock {
10   -
11   - @Input() block: any;
12   - @Input() owner: any;
13   -
14   -}
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.html
... ... @@ -1,6 +0,0 @@
1   -<div class="center-block text-center profile-image-block">
2   - <a ui-sref="main.profile.info({profile: ctrl.owner.identifier})">
3   - <noosfero-profile-image [profile]="ctrl.owner"></noosfero-profile-image>
4   - </a>
5   - <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: ctrl.owner.identifier})">{{"blocks.profile_image.control_panel" | translate}}</a>
6   -</div>
src/app/components/noosfero-blocks/profile-image-block/profile-image-block.scss
... ... @@ -1,5 +0,0 @@
1   -.profile-image-block {
2   - .settings-link {
3   - display: block;
4   - }
5   -}
src/app/components/noosfero-blocks/raw-html/raw-html.component.spec.ts
... ... @@ -1,36 +0,0 @@
1   -import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder';
2   -import {Component} from 'ng-forward';
3   -
4   -import {RawHTMLBlock} from './raw-html.component';
5   -
6   -const tcb = new TestComponentBuilder();
7   -
8   -const htmlTemplate: string = '<noosfero-raw-htmlblock [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-raw-htmlblock>';
9   -
10   -describe("Components", () => {
11   -
12   - describe("Raw Html Block Component", () => {
13   -
14   - beforeEach(angular.mock.module("templates"));
15   - beforeEach(angular.mock.module("ngSanitize"));
16   -
17   - it("display html stored in block settings", done => {
18   -
19   - @Component({
20   - selector: 'test-container-component',
21   - template: htmlTemplate,
22   - directives: [RawHTMLBlock],
23   - })
24   - class CustomBlockType {
25   - block: any = { settings: { html: '<em>block content</em>' } };
26   - owner: any = { name: 'profile-name' };
27   - }
28   - tcb.createAsync(CustomBlockType).then(fixture => {
29   - expect(fixture.debugElement.query(".raw-html-block em").text().trim()).toEqual('block content');
30   - done();
31   - });
32   - });
33   -
34   - });
35   -
36   -});
src/app/components/noosfero-blocks/raw-html/raw-html.component.ts
... ... @@ -1,18 +0,0 @@
1   -import {Component, Input} from "ng-forward";
2   -
3   -@Component({
4   - selector: "noosfero-raw-htmlblock",
5   - templateUrl: 'app/components/noosfero-blocks/raw-html/raw-html.html'
6   -})
7   -
8   -export class RawHTMLBlock {
9   -
10   - @Input() block: any;
11   - @Input() owner: any;
12   -
13   - html: string;
14   -
15   - ngOnInit() {
16   - this.html = this.block.settings.html;
17   - }
18   -}
src/app/components/noosfero-blocks/raw-html/raw-html.html
... ... @@ -1,2 +0,0 @@
1   -<div class="raw-html-block" ng-bind-html="ctrl.html">
2   -</div>
src/app/components/noosfero-blocks/recent-documents/index.ts
... ... @@ -1 +0,0 @@
1   -/* Module Index Entry - generated using the script npm run generate-index */
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.spec.ts
... ... @@ -1,53 +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 {RecentDocumentsBlock} 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   - beforeEach(angular.mock.module("templates"));
14   -
15   - let state = jasmine.createSpyObj("state", ["go"]);
16   - let providers = [
17   - new Provider('$state', { useValue: state }),
18   - new Provider('ArticleService', {
19   - useValue: {
20   - getByProfile: (profileId: number, filters: any): any => {
21   - return Promise.resolve({ data: { articles: [{ name: "article1" }] } });
22   - }
23   - }
24   - }),
25   - ].concat(provideFilters("truncateFilter", "stripTagsFilter"));
26   -
27   - @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [RecentDocumentsBlock], providers: providers })
28   - class BlockContainerComponent {
29   - block = { type: 'Block', settings: {} };
30   - owner = { name: 'profile-name' };
31   - constructor() {
32   - }
33   - }
34   -
35   - it("get recent documents from the article service", done => {
36   - tcb.createAsync(BlockContainerComponent).then(fixture => {
37   - let recentDocumentsBlock: RecentDocumentsBlock = fixture.debugElement.componentViewChildren[0].componentInstance;
38   - expect(recentDocumentsBlock.documents).toEqual([{ name: "article1" }]);
39   - done();
40   - });
41   - });
42   -
43   - it("go to article page when open a document", done => {
44   - tcb.createAsync(BlockContainerComponent).then(fixture => {
45   - let recentDocumentsBlock: RecentDocumentsBlock = fixture.debugElement.componentViewChildren[0].componentInstance;
46   - recentDocumentsBlock.openDocument({ path: "path", profile: { identifier: "identifier" } });
47   - expect(state.go).toHaveBeenCalledWith("main.profile.page", { page: "path", profile: "identifier" });
48   - done();
49   - });
50   - });
51   -
52   - });
53   -});
54 0 \ No newline at end of file
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.ts
... ... @@ -1,38 +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/components/noosfero-blocks/recent-documents/recent-documents.html'
7   -})
8   -@Inject(ArticleService, "$state")
9   -export class RecentDocumentsBlock {
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   - var limit = (this.block && this.block.settings) ? this.block.settings.limit : null || 5;
27   - //FIXME get all text articles
28   - this.articleService.getByProfile(this.profile.id, { content_type: 'TinyMceArticle', per_page: limit }).then((response: any) => {
29   - this.documents = response.data.articles;
30   - this.documentsLoaded = true;
31   - });
32   - }
33   -
34   - openDocument(article: any) {
35   - this.$state.go("main.profile.page", { page: article.path, profile: article.profile.identifier });
36   - }
37   -
38   -}
src/app/components/noosfero-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>