Commit d2590816220ba082c9eb8fecbedc192f4e7ef712
Exists in
master
and in
35 other branches
added coverage task
Showing
34 changed files
with
526 additions
and
187 deletions
Show diff stats
.vscode/tasks.json
@@ -23,6 +23,10 @@ | @@ -23,6 +23,10 @@ | ||
23 | { | 23 | { |
24 | "taskName": "test", | 24 | "taskName": "test", |
25 | "isTestCommand": true | 25 | "isTestCommand": true |
26 | + }, | ||
27 | + { | ||
28 | + "taskName": "generate-indexes", | ||
29 | + "args": [] | ||
26 | } | 30 | } |
27 | ] | 31 | ] |
28 | } | 32 | } |
29 | \ No newline at end of file | 33 | \ No newline at end of file |
gulp/server.js
@@ -36,6 +36,7 @@ function browserSyncInit(baseDir, browser) { | @@ -36,6 +36,7 @@ function browserSyncInit(baseDir, browser) { | ||
36 | browserSync.instance = browserSync.init({ | 36 | browserSync.instance = browserSync.init({ |
37 | startPath: '/', | 37 | startPath: '/', |
38 | server: server, | 38 | server: server, |
39 | + port: 3001, | ||
39 | browser: browser | 40 | browser: browser |
40 | }); | 41 | }); |
41 | } | 42 | } |
karma.conf.js
@@ -112,7 +112,6 @@ module.exports = function (config) { | @@ -112,7 +112,6 @@ module.exports = function (config) { | ||
112 | 112 | ||
113 | browsers: ['PhantomJS'], | 113 | browsers: ['PhantomJS'], |
114 | 114 | ||
115 | - | ||
116 | plugins: karmaPlugins, | 115 | plugins: karmaPlugins, |
117 | 116 | ||
118 | 117 | ||
@@ -124,6 +123,7 @@ module.exports = function (config) { | @@ -124,6 +123,7 @@ module.exports = function (config) { | ||
124 | } | 123 | } |
125 | }; | 124 | }; |
126 | 125 | ||
126 | + | ||
127 | if (argv.coverage) { | 127 | if (argv.coverage) { |
128 | 128 | ||
129 | /*configuration.webpack = { | 129 | /*configuration.webpack = { |
@@ -177,9 +177,6 @@ module.exports = function (config) { | @@ -177,9 +177,6 @@ module.exports = function (config) { | ||
177 | }; | 177 | }; |
178 | } | 178 | } |
179 | 179 | ||
180 | - // 'src/**/*.js': ['sourcemap'], | ||
181 | - // 'src/**/*.[sS]pec.ts': ['sourcemap'] | ||
182 | - // }; | ||
183 | 180 | ||
184 | pathSrcHtml.forEach(function (path) { | 181 | pathSrcHtml.forEach(function (path) { |
185 | configuration.preprocessors[path] = ['ng-html2js']; | 182 | configuration.preprocessors[path] = ['ng-html2js']; |
package.json
@@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
11 | "remap-coverage": "ts-node --project ./dev-scripts ./dev-scripts/remapCoverage.ts", | 11 | "remap-coverage": "ts-node --project ./dev-scripts ./dev-scripts/remapCoverage.ts", |
12 | "test-single": "webpack && karma start --single-run", | 12 | "test-single": "webpack && karma start --single-run", |
13 | "test": "concurrently \"webpack -w\" \"karma start\"", | 13 | "test": "concurrently \"webpack -w\" \"karma start\"", |
14 | - "postinstall": "npm install -g bower && bower install", | 14 | + "postinstall": "npm install -g bower && bower install && typings install", |
15 | "start": "concurrently \"webpack -w\" \"gulp serve\"", | 15 | "start": "concurrently \"webpack -w\" \"gulp serve\"", |
16 | "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts" | 16 | "generate-indexes": "ts-node --project ./dev-scripts ./dev-scripts/generate-index-modules.ts" |
17 | }, | 17 | }, |
src/app/components/auth/index.ts
1 | -/* Module Index Entry - generated using the script npm run generate-indexes */ | 1 | +/* Module Index Entry - generated using the script npm run generate-index */ |
2 | export * from "./auth_controller"; | 2 | export * from "./auth_controller"; |
3 | export * from "./auth_events"; | 3 | export * from "./auth_events"; |
4 | export * from "./auth_service"; | 4 | export * from "./auth_service"; |
src/app/components/navbar/index.ts
src/app/components/navbar/navbar.directive.js
@@ -1,58 +0,0 @@ | @@ -1,58 +0,0 @@ | ||
1 | -(function() { | ||
2 | - 'use strict'; | ||
3 | - | ||
4 | - angular | ||
5 | - .module('noosferoApp') | ||
6 | - .directive('acmeNavbar', acmeNavbar); | ||
7 | - | ||
8 | - /** @ngInject */ | ||
9 | - function acmeNavbar() { | ||
10 | - var directive = { | ||
11 | - restrict: 'E', | ||
12 | - templateUrl: 'app/components/navbar/navbar.html', | ||
13 | - scope: {}, | ||
14 | - controller: NavbarController, | ||
15 | - controllerAs: 'vm', | ||
16 | - bindToController: true | ||
17 | - }; | ||
18 | - | ||
19 | - return directive; | ||
20 | - | ||
21 | - /** @ngInject */ | ||
22 | - function NavbarController(moment, $modal, AuthService, Session, $scope, $state, AUTH_EVENTS) { | ||
23 | - var vm = this; | ||
24 | - | ||
25 | - vm.currentUser = Session.getCurrentUser(); | ||
26 | - vm.modalInstance = null; | ||
27 | - | ||
28 | - vm.openLogin = function() { | ||
29 | - vm.modalInstance = $modal.open({ | ||
30 | - templateUrl: 'app/components/auth/login.html', | ||
31 | - controller: 'AuthController', | ||
32 | - controllerAs: 'vm', | ||
33 | - bindToController: true | ||
34 | - }); | ||
35 | - }; | ||
36 | - vm.logout = function() { | ||
37 | - AuthService.logout(); | ||
38 | - $state.go($state.current, {}, {reload: true}); //TODO move to auth | ||
39 | - }; | ||
40 | - $scope.$on(AUTH_EVENTS.loginSuccess, function() { | ||
41 | - if(vm.modalInstance) { | ||
42 | - vm.modalInstance.close(); | ||
43 | - vm.modalInstance = null; | ||
44 | - } | ||
45 | - $state.go($state.current, {}, {reload: true}); //TODO move to auth | ||
46 | - }); | ||
47 | - $scope.$on(AUTH_EVENTS.logoutSuccess, function() { | ||
48 | - vm.currentUser = Session.getCurrentUser(); | ||
49 | - }); | ||
50 | - | ||
51 | - vm.activate = function() { | ||
52 | - if(!vm.currentUser) vm.openLogin(); | ||
53 | - } | ||
54 | - vm.activate(); | ||
55 | - } | ||
56 | - } | ||
57 | - | ||
58 | -})(); |
src/app/components/navbar/navbar.html
@@ -17,25 +17,25 @@ | @@ -17,25 +17,25 @@ | ||
17 | </ul> | 17 | </ul> |
18 | 18 | ||
19 | <ul class="nav navbar-nav navbar-right"> | 19 | <ul class="nav navbar-nav navbar-right"> |
20 | - <li ng-show="!vm.currentUser"> | ||
21 | - <a ng-href="#" ng-click="vm.openLogin()">Login</a> | 20 | + <li ng-show="!ctrl.currentUser"> |
21 | + <a ng-href="#" ng-click="ctrl.openLogin()">Login</a> | ||
22 | </li> | 22 | </li> |
23 | 23 | ||
24 | - <li class="dropdown profile-menu" ng-show="vm.currentUser" dropdown> | 24 | + <li class="dropdown profile-menu" ng-show="ctrl.currentUser" dropdown> |
25 | <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle> | 25 | <a href="#" class="dropdown-toggle" aria-expanded="false" dropdown-toggle> |
26 | - <noosfero-profile-image profile="vm.currentUser.person" class="profile-image"></noosfero-profile-image> | ||
27 | - <span ng-bind="vm.currentUser.person.name"></span> <b class="caret"></b> | 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> | 28 | </a> |
29 | <ul class="dropdown-menu" dropdown-menu> | 29 | <ul class="dropdown-menu" dropdown-menu> |
30 | <li> | 30 | <li> |
31 | - <a ui-sref="main.profile.info({profile: vm.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> Profile</a> | 31 | + <a ui-sref="main.profile.info({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-user"></i> Profile</a> |
32 | </li> | 32 | </li> |
33 | <li> | 33 | <li> |
34 | - <a target="_self" ui-sref="main.profile.settings({profile: vm.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> Settings</a> | 34 | + <a target="_self" ui-sref="main.profile.settings({profile: ctrl.currentUser.person.identifier})"><i class="fa fa-fw fa-gear"></i> Settings</a> |
35 | </li> | 35 | </li> |
36 | <li class="divider"></li> | 36 | <li class="divider"></li> |
37 | <li> | 37 | <li> |
38 | - <a href="#" ng-click="vm.logout()"><i class="fa fa-fw fa-power-off"></i> Log Out</a> | 38 | + <a href="#" ng-click="ctrl.logout()"><i class="fa fa-fw fa-power-off"></i> Log Out</a> |
39 | </li> | 39 | </li> |
40 | </ul> | 40 | </ul> |
41 | </li> | 41 | </li> |
@@ -0,0 +1,56 @@ | @@ -0,0 +1,56 @@ | ||
1 | +import {createComponentFromClass, quickCreateComponent} from "./../../../spec/helpers"; | ||
2 | +import {Navbar} from "./"; | ||
3 | +import {AUTH_EVENTS} from "./../auth"; | ||
4 | +import {User} from "./../../models/interfaces"; | ||
5 | +import {Injectable, Provider, provide} from "ng-forward"; | ||
6 | + | ||
7 | + | ||
8 | + | ||
9 | +describe("Navbar Component", () => { | ||
10 | + | ||
11 | + let $rootScope: ng.IRootScopeService; | ||
12 | + let user = <User>{ | ||
13 | + id: 1, | ||
14 | + login: "user" | ||
15 | + }; | ||
16 | + | ||
17 | + beforeEach(angular.mock.module("templates")); | ||
18 | + | ||
19 | + // beforeEach(inject((_$rootScope_: ng.IRootScopeService) => { | ||
20 | + // $rootScope = _$rootScope_; | ||
21 | + // })); | ||
22 | + | ||
23 | + it('should get the loggedIn user', (done: Function) => { | ||
24 | + | ||
25 | + | ||
26 | + let scope = jasmine.createSpyObj("scope", ["$on"]); | ||
27 | + | ||
28 | + let providers = [ | ||
29 | + | ||
30 | + | ||
31 | + new Provider('moment', { useValue: {} }), | ||
32 | + new Provider('$modal', { useValue: {} }), | ||
33 | + new Provider('AuthService', { useValue: {} }), | ||
34 | + new Provider('Session', { useValue: { | ||
35 | + getCurrentUser: () => { return user} | ||
36 | + } }), | ||
37 | + new Provider('$scope', { useValue: scope }), | ||
38 | + new Provider('$state', { useValue: {} }), | ||
39 | + new Provider('AUTH_EVENTS', { useValue: {AUTH_EVENTS} }) | ||
40 | + ]; | ||
41 | + | ||
42 | + | ||
43 | + | ||
44 | + quickCreateComponent({ | ||
45 | + providers: providers, | ||
46 | + template: "<acme-navbar></acme-navbar>", | ||
47 | + directives: [Navbar] | ||
48 | + }).then(fixture => { | ||
49 | + let navbarInstance: Navbar = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
50 | + expect(navbarInstance).toBeDefined(); | ||
51 | + expect(navbarInstance["currentUser"]).toEqual(user) | ||
52 | + done(); | ||
53 | + }) | ||
54 | + }); | ||
55 | + | ||
56 | +}); | ||
0 | \ No newline at end of file | 57 | \ No newline at end of file |
@@ -0,0 +1,68 @@ | @@ -0,0 +1,68 @@ | ||
1 | +import {Component, Inject} from "ng-forward"; | ||
2 | + | ||
3 | + | ||
4 | +import {Session, AuthService, IAuthEvents} from "./../auth"; | ||
5 | +import {User} from "./../../models/interfaces"; | ||
6 | + | ||
7 | +@Component({ | ||
8 | + selector: "acme-navbar", | ||
9 | + templateUrl: "app/components/navbar/navbar.html" | ||
10 | +}) | ||
11 | +@Inject("moment", "$modal", "AuthService", "Session", "$scope", "$state", "AUTH_EVENTS") | ||
12 | +export class Navbar { | ||
13 | + | ||
14 | + private currentUser: User; | ||
15 | + private modalInstance: any = null; | ||
16 | + /** | ||
17 | + * | ||
18 | + */ | ||
19 | + constructor( | ||
20 | + private moment: moment.MomentStatic, | ||
21 | + private $modal: any, | ||
22 | + private authService: AuthService, | ||
23 | + private session: Session, | ||
24 | + private $scope: ng.IScope, | ||
25 | + private $state: ng.ui.IStateService, | ||
26 | + private AUTH_EVENTS: IAuthEvents | ||
27 | + ) { | ||
28 | + | ||
29 | + this.currentUser = session.getCurrentUser(); | ||
30 | + | ||
31 | + $scope.$on(AUTH_EVENTS.loginSuccess, function() { | ||
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 | + $scope.$on(AUTH_EVENTS.logoutSuccess, () => { | ||
41 | + this.currentUser = this.session.getCurrentUser(); | ||
42 | + }); | ||
43 | + | ||
44 | + } | ||
45 | + | ||
46 | + openLogin() { | ||
47 | + this.modalInstance = this.$modal.open({ | ||
48 | + templateUrl: 'app/components/auth/login.html', | ||
49 | + controller: 'AuthController', | ||
50 | + controllerAs: 'vm', | ||
51 | + bindToController: true | ||
52 | + }); | ||
53 | + }; | ||
54 | + | ||
55 | + logout() { | ||
56 | + this.authService.logout(); | ||
57 | + this.$state.go(this.$state.current, {}, { reload: true }); //TODO move to auth | ||
58 | + }; | ||
59 | + | ||
60 | + | ||
61 | + | ||
62 | + activate() { | ||
63 | + if (!this.currentUser) { | ||
64 | + this.openLogin(); | ||
65 | + } | ||
66 | + } | ||
67 | + | ||
68 | +} | ||
0 | \ No newline at end of file | 69 | \ No newline at end of file |
src/app/components/noosfero-blocks/block.component.ts
@@ -11,7 +11,7 @@ export class Block { | @@ -11,7 +11,7 @@ export class Block { | ||
11 | @Input() owner: any; | 11 | @Input() owner: any; |
12 | 12 | ||
13 | ngOnInit() { | 13 | ngOnInit() { |
14 | - let blockName = this.block.type ? this.block.type.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() : "default-block"; | 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)); | 15 | this.$element.replaceWith(this.$compile('<noosfero-' + blockName + ' [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-' + blockName + '>')(this.$scope)); |
16 | } | 16 | } |
17 | 17 |
src/app/components/noosfero-blocks/link-list/index.ts
src/app/components/noosfero-blocks/link-list/link-list.component.spec.ts
0 → 100644
@@ -0,0 +1,64 @@ | @@ -0,0 +1,64 @@ | ||
1 | +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; | ||
2 | +import {Pipe, Input, provide, Component} from 'ng-forward'; | ||
3 | + | ||
4 | +import {LinkListBlock} from './link-list.component'; | ||
5 | + | ||
6 | +const tcb = new TestComponentBuilder(); | ||
7 | + | ||
8 | +const htmlTemplate: string = '<noosfero-link-list-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-link-list-block>'; | ||
9 | + | ||
10 | + | ||
11 | +describe("Link List Block Component", () => { | ||
12 | + | ||
13 | + beforeEach(angular.mock.module("templates")); | ||
14 | + | ||
15 | + it("receives the block and the owner as inputs", done => { | ||
16 | + | ||
17 | + // Creating a container component (BlockContainerComponent) to include | ||
18 | + // the component under test (Block) | ||
19 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [LinkListBlock] }) | ||
20 | + class BlockContainerComponent { | ||
21 | + block = { type: 'Block' }; | ||
22 | + owner = { name: 'profile-name' }; | ||
23 | + constructor() { | ||
24 | + } | ||
25 | + } | ||
26 | + | ||
27 | + // uses the TestComponentBuilder instance to initialize the component | ||
28 | + //.overrideView(LinkListBlock, { template: 'asdasdasd', pipes: [NoosferoTemplate] }) | ||
29 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
30 | + // and here we can inspect and run the test assertions | ||
31 | + let myComponent: LinkListBlock = fixture.componentInstance; | ||
32 | + | ||
33 | + // assure the block object inside the Block matches | ||
34 | + // the provided through the parent component | ||
35 | + expect(myComponent.block.type).toEqual("Block"); | ||
36 | + expect(myComponent.owner.name).toEqual("profile-name"); | ||
37 | + done(); | ||
38 | + }); | ||
39 | + }); | ||
40 | + | ||
41 | + | ||
42 | + it("display links stored in block settings", done => { | ||
43 | + | ||
44 | + @Pipe('noosferoTemplateFilter') | ||
45 | + class NoosferoTemplateFilter { | ||
46 | + transform(input: any, changeTo: any) { | ||
47 | + return input; | ||
48 | + } | ||
49 | + } | ||
50 | + | ||
51 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [LinkListBlock] }) | ||
52 | + class CustomBlockType { | ||
53 | + block: any = { settings: { links: [{ name: 'link1', address: 'address1' }, { name: 'link2', address: 'address2' }] } }; | ||
54 | + owner: any = { name: 'profile-name' }; | ||
55 | + constructor() { | ||
56 | + } | ||
57 | + } | ||
58 | + tcb.overrideView(LinkListBlock, { templateUrl: "app/components/noosfero-blocks/link-list/link-list.html", pipes: [NoosferoTemplateFilter] }).createAsync(CustomBlockType).then(fixture => { | ||
59 | + expect(fixture.debugElement.queryAll(".link-list-block a").length).toEqual(2); | ||
60 | + done(); | ||
61 | + }); | ||
62 | + }); | ||
63 | + | ||
64 | +}); |
src/app/components/noosfero-blocks/link-list/link-list.component.ts
@@ -12,7 +12,9 @@ export class LinkListBlock { | @@ -12,7 +12,9 @@ export class LinkListBlock { | ||
12 | links: any; | 12 | links: any; |
13 | 13 | ||
14 | ngOnInit() { | 14 | ngOnInit() { |
15 | - this.links = this.block.settings.links; | 15 | + if (this.block && this.block.settings) { |
16 | + this.links = this.block.settings.links; | ||
17 | + } | ||
16 | } | 18 | } |
17 | 19 | ||
18 | } | 20 | } |
src/app/components/noosfero-blocks/main-block/main-block.component.js
@@ -1,20 +0,0 @@ | @@ -1,20 +0,0 @@ | ||
1 | -(function() { | ||
2 | - 'use strict'; | ||
3 | - | ||
4 | - angular | ||
5 | - .module('noosferoApp') | ||
6 | - .component('noosferoMainBlock', { | ||
7 | - restrict: 'E', | ||
8 | - templateUrl: 'app/components/noosfero-blocks/main-block/main-block.html', | ||
9 | - bindings: { | ||
10 | - block: '<', | ||
11 | - owner: '<' | ||
12 | - }, | ||
13 | - controller: MainBlockController | ||
14 | - }); | ||
15 | - | ||
16 | - /** @ngInject */ | ||
17 | - function MainBlockController() { | ||
18 | - } | ||
19 | - | ||
20 | -})(); |
src/app/components/noosfero-blocks/main-block/main-block.component.spec.ts
0 → 100644
@@ -0,0 +1,40 @@ | @@ -0,0 +1,40 @@ | ||
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 | + | ||
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 | +}); |
src/app/components/noosfero-blocks/main-block/main-block.component.ts
0 → 100644
@@ -0,0 +1,10 @@ | @@ -0,0 +1,10 @@ | ||
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/members-block/members-block.component.js
@@ -1,26 +0,0 @@ | @@ -1,26 +0,0 @@ | ||
1 | -(function() { | ||
2 | - 'use strict'; | ||
3 | - | ||
4 | - angular | ||
5 | - .module('noosferoApp') | ||
6 | - .component('noosferoMembersBlock', { | ||
7 | - restrict: 'E', | ||
8 | - templateUrl: 'app/components/noosfero-blocks/members-block/members-block.html', | ||
9 | - bindings: { | ||
10 | - block: '<', | ||
11 | - owner: '<' | ||
12 | - }, | ||
13 | - controller: MembersBlockController | ||
14 | - }); | ||
15 | - | ||
16 | - /** @ngInject */ | ||
17 | - function MembersBlockController(noosfero) { | ||
18 | - var vm = this; | ||
19 | - vm.members = []; | ||
20 | - | ||
21 | - noosfero.members(noosfero.profiles.one(vm.owner.id)).one().get({per_page: 6}).then(function(response) { | ||
22 | - vm.members = response.data.people; | ||
23 | - }); | ||
24 | - } | ||
25 | - | ||
26 | -})(); |
src/app/components/noosfero-blocks/members-block/members-block.component.spec.ts
0 → 100644
@@ -0,0 +1,52 @@ | @@ -0,0 +1,52 @@ | ||
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("Members Block Component", () => { | ||
11 | + | ||
12 | + beforeEach(angular.mock.module("templates")); | ||
13 | + | ||
14 | + let state = jasmine.createSpyObj("state", ["go"]); | ||
15 | + let providers = [ | ||
16 | + new Provider('truncateFilter', { useValue: () => { } }), | ||
17 | + new Provider('stripTagsFilter', { useValue: () => { } }), | ||
18 | + new Provider('$state', { useValue: state }), | ||
19 | + new Provider('ProfileService', { | ||
20 | + useValue: { | ||
21 | + getProfileMembers: (profileId: number, filters: any): any => { | ||
22 | + return Promise.resolve({ data: { people: [{ identifier: "person1" }] } }); | ||
23 | + } | ||
24 | + } | ||
25 | + }), | ||
26 | + ]; | ||
27 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [MembersBlock], providers: providers }) | ||
28 | + class BlockContainerComponent { | ||
29 | + block = { type: 'Block', settings: {} }; | ||
30 | + owner = { name: 'profile-name' }; | ||
31 | + constructor() { | ||
32 | + } | ||
33 | + } | ||
34 | + | ||
35 | + it("get members of the block owner", done => { | ||
36 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
37 | + let recentDocumentsBlock: MembersBlock = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
38 | + expect(recentDocumentsBlock.members).toEqual([{ identifier: "person1" }]); | ||
39 | + done(); | ||
40 | + }); | ||
41 | + }); | ||
42 | + | ||
43 | + it("render the profile image for each member", done => { | ||
44 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
45 | + let recentDocumentsBlock: MembersBlock = fixture.debugElement.componentViewChildren[0].componentInstance; | ||
46 | + fixture.debugElement.getLocal("$rootScope").$apply(); | ||
47 | + expect(fixture.debugElement.queryAll("noosfero-profile-image").length).toEqual(1); | ||
48 | + done(); | ||
49 | + }); | ||
50 | + }); | ||
51 | + | ||
52 | +}); |
src/app/components/noosfero-blocks/members-block/members-block.component.ts
0 → 100644
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
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 | <div class="members-block"> | 1 | <div class="members-block"> |
2 | - <a ng-repeat="member in $ctrl.members" ui-sref="main.profile({profile: member.identifier})" class="member"> | 2 | + <a ng-repeat="member in ctrl.members" ui-sref="main.profile({profile: member.identifier})" class="member"> |
3 | <noosfero-profile-image profile="member"></noosfero-profile-image> | 3 | <noosfero-profile-image profile="member"></noosfero-profile-image> |
4 | </a> | 4 | </a> |
5 | </div> | 5 | </div> |
src/app/components/noosfero-blocks/profile-image/profile-image.component.js
@@ -1,22 +0,0 @@ | @@ -1,22 +0,0 @@ | ||
1 | -(function() { | ||
2 | - 'use strict'; | ||
3 | - | ||
4 | - angular | ||
5 | - .module('noosferoApp') | ||
6 | - .component('noosferoProfileImageBlock', { | ||
7 | - restrict: 'E', | ||
8 | - templateUrl: 'app/components/noosfero-blocks/profile-image/profile-image.html', | ||
9 | - bindings: { | ||
10 | - block: '<', | ||
11 | - owner: '<' | ||
12 | - }, | ||
13 | - controller: ProfileImageBlockController | ||
14 | - }); | ||
15 | - | ||
16 | - /** @ngInject */ | ||
17 | - function ProfileImageBlockController() { | ||
18 | - var vm = this; | ||
19 | - vm.profile = vm.owner; | ||
20 | - } | ||
21 | - | ||
22 | -})(); |
src/app/components/noosfero-blocks/profile-image/profile-image.component.spec.ts
0 → 100644
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
1 | +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; | ||
2 | +import {Pipe, Input, provide, Component} from 'ng-forward'; | ||
3 | + | ||
4 | +import {ProfileImageBlock} from './profile-image.component'; | ||
5 | + | ||
6 | +const tcb = new TestComponentBuilder(); | ||
7 | + | ||
8 | +const htmlTemplate: string = '<noosfero-profile-image-block [block]="ctrl.block" [owner]="ctrl.owner"></noosfero-profile-image-block>'; | ||
9 | + | ||
10 | + | ||
11 | +describe("Profile Image Block Component", () => { | ||
12 | + | ||
13 | + beforeEach(angular.mock.module("templates")); | ||
14 | + | ||
15 | + @Component({ selector: 'test-container-component', template: htmlTemplate, directives: [ProfileImageBlock] }) | ||
16 | + class BlockContainerComponent { | ||
17 | + block = { type: 'Block' }; | ||
18 | + owner = { name: 'profile-name' }; | ||
19 | + constructor() { | ||
20 | + } | ||
21 | + } | ||
22 | + | ||
23 | + it("render the profile image", done => { | ||
24 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
25 | + expect(fixture.debugElement.queryAll("noosfero-profile-image").length).toEqual(1); | ||
26 | + done(); | ||
27 | + }); | ||
28 | + }); | ||
29 | + | ||
30 | + it("render the settings link", done => { | ||
31 | + tcb.createAsync(BlockContainerComponent).then(fixture => { | ||
32 | + expect(fixture.debugElement.queryAll(".settings-link").length).toEqual(1); | ||
33 | + done(); | ||
34 | + }); | ||
35 | + }); | ||
36 | + | ||
37 | +}); |
src/app/components/noosfero-blocks/profile-image/profile-image.component.ts
0 → 100644
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +import {Input, Component} from "ng-forward"; | ||
2 | + | ||
3 | +@Component({ | ||
4 | + selector: "noosfero-profile-image-block", | ||
5 | + templateUrl: 'app/components/noosfero-blocks/profile-image/profile-image.html', | ||
6 | +}) | ||
7 | +export class ProfileImageBlock { | ||
8 | + | ||
9 | + @Input() block: any; | ||
10 | + @Input() owner: any; | ||
11 | + | ||
12 | +} |
src/app/components/noosfero-blocks/profile-image/profile-image.html
1 | <div class="center-block text-center profile-image-block"> | 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> | 2 | + <a ui-sref="main.profile.info({profile: ctrl.owner.identifier})"> |
3 | + <noosfero-profile-image profile="ctrl.owner"></noosfero-profile-image> | ||
4 | </a> | 4 | </a> |
5 | - <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: $ctrl.owner.identifier})">Control panel</a> | 5 | + <a class="settings-link" target="_self" ui-sref="main.profile.settings({profile: ctrl.owner.identifier})">Control panel</a> |
6 | </div> | 6 | </div> |
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.js
@@ -1,33 +0,0 @@ | @@ -1,33 +0,0 @@ | ||
1 | -(function() { | ||
2 | - 'use strict'; | ||
3 | - | ||
4 | - angular | ||
5 | - .module('noosferoApp') | ||
6 | - .component('noosferoRecentDocumentsBlock', { | ||
7 | - restrict: 'E', | ||
8 | - templateUrl: 'app/components/noosfero-blocks/recent-documents/recent-documents.html', | ||
9 | - bindings: { | ||
10 | - block: '<', | ||
11 | - owner: '<' | ||
12 | - }, | ||
13 | - controller: RecentDocumentsController | ||
14 | - }); | ||
15 | - | ||
16 | - /** @ngInject */ | ||
17 | - function RecentDocumentsController(noosfero, $state) { | ||
18 | - var vm = this; | ||
19 | - vm.profile = vm.owner; | ||
20 | - vm.documents = []; | ||
21 | - | ||
22 | - vm.openDocument = function(article) { | ||
23 | - $state.go("main.profile.page", {page: article.path, profile: article.profile.identifier}); | ||
24 | - } | ||
25 | - | ||
26 | - var limit = vm.block.settings.limit || 5; | ||
27 | - //FIXME get all text articles | ||
28 | - noosfero.profiles.one(vm.profile.id).one('articles').get({content_type: 'TinyMceArticle', per_page: limit}).then(function(response) { | ||
29 | - vm.documents = response.data.articles; | ||
30 | - }); | ||
31 | - } | ||
32 | - | ||
33 | -})(); |
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.spec.ts
0 → 100644
@@ -0,0 +1,52 @@ | @@ -0,0 +1,52 @@ | ||
1 | +import {TestComponentBuilder} from 'ng-forward/cjs/testing/test-component-builder'; | ||
2 | +import {Provider, Input, provide, Component} from 'ng-forward'; | ||
3 | + | ||
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("Recent Documents Block Component", () => { | ||
11 | + | ||
12 | + beforeEach(angular.mock.module("templates")); | ||
13 | + | ||
14 | + let state = jasmine.createSpyObj("state", ["go"]); | ||
15 | + let providers = [ | ||
16 | + new Provider('truncateFilter', { useValue: () => { } }), | ||
17 | + new Provider('stripTagsFilter', { useValue: () => { } }), | ||
18 | + new Provider('$state', { useValue: state }), | ||
19 | + new Provider('ArticleService', { | ||
20 | + useValue: { | ||
21 | + getByProfile: (profileId: number, filters: any): any => { | ||
22 | + return Promise.resolve({ data: { articles: [{ name: "article1" }] } }); | ||
23 | + } | ||
24 | + } | ||
25 | + }), | ||
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 | +}); |
src/app/components/noosfero-blocks/recent-documents/recent-documents.component.ts
0 → 100644
@@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
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 | + constructor(private ArticleService: ArticleService, private $state: any) { | ||
18 | + } | ||
19 | + | ||
20 | + ngOnInit() { | ||
21 | + this.profile = this.owner; | ||
22 | + this.documents = []; | ||
23 | + | ||
24 | + var limit = (this.block && this.block.settings) ? this.block.settings.limit : null || 5; | ||
25 | + //FIXME get all text articles | ||
26 | + this.ArticleService.getByProfile(this.profile.id, { content_type: 'TinyMceArticle', per_page: limit }).then((response: any) => { | ||
27 | + this.documents = response.data.articles; | ||
28 | + }); | ||
29 | + } | ||
30 | + | ||
31 | + openDocument(article: any) { | ||
32 | + this.$state.go("main.profile.page", { page: article.path, profile: article.profile.identifier }); | ||
33 | + } | ||
34 | + | ||
35 | +} |
src/app/components/noosfero-blocks/recent-documents/recent-documents.html
1 | -<div deckgrid source="$ctrl.documents" class="deckgrid"> | ||
2 | - <div class="a-card panel media" ng-click="mother.$ctrl.openDocument(card);"> | 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"> | 3 | <div class="author media-left" ng-show="card.author.image"> |
4 | <img ng-src="{{card.author.image.url}}" class="img-circle"> | 4 | <img ng-src="{{card.author.image.url}}" class="img-circle"> |
5 | </div> | 5 | </div> |
src/app/index.ts
@@ -19,6 +19,8 @@ import {bootstrap, bundle} from "ng-forward"; | @@ -19,6 +19,8 @@ import {bootstrap, bundle} from "ng-forward"; | ||
19 | import {AUTH_EVENTS} from "./components/auth/auth_events"; | 19 | import {AUTH_EVENTS} from "./components/auth/auth_events"; |
20 | import {AuthController} from "./components/auth/auth_controller"; | 20 | import {AuthController} from "./components/auth/auth_controller"; |
21 | 21 | ||
22 | +import {Navbar} from "./components/navbar"; | ||
23 | + | ||
22 | declare var moment: any; | 24 | declare var moment: any; |
23 | 25 | ||
24 | let noosferoApp: any = bundle("noosferoApp", Main, ["ngAnimate", "ngCookies", "ngStorage", "ngTouch", | 26 | let noosferoApp: any = bundle("noosferoApp", Main, ["ngAnimate", "ngCookies", "ngStorage", "ngTouch", |
@@ -41,13 +43,8 @@ NoosferoApp.run(noosferoAngularRunBlock); | @@ -41,13 +43,8 @@ NoosferoApp.run(noosferoAngularRunBlock); | ||
41 | NoosferoApp.addController("AuthController", AuthController); | 43 | NoosferoApp.addController("AuthController", AuthController); |
42 | 44 | ||
43 | 45 | ||
44 | -require("./components/navbar/navbar.directive.js"); | ||
45 | require("./components/noosfero-activities/activities.component.js"); | 46 | require("./components/noosfero-activities/activities.component.js"); |
46 | require("./components/noosfero-activities/activity/activity.component.js"); | 47 | require("./components/noosfero-activities/activity/activity.component.js"); |
47 | -require("./components/noosfero-blocks/main-block/main-block.component.js"); | ||
48 | -require("./components/noosfero-blocks/members-block/members-block.component.js"); | ||
49 | -require("./components/noosfero-blocks/profile-image/profile-image.component.js"); | ||
50 | -require("./components/noosfero-blocks/recent-documents/recent-documents.component.js"); | ||
51 | require("./components/noosfero/noosfero-template.filter.js"); | 48 | require("./components/noosfero/noosfero-template.filter.js"); |
52 | require("./components/noosfero/noosfero.service.js"); | 49 | require("./components/noosfero/noosfero.service.js"); |
53 | require("./components/noosfero/profile-image/profile-image.component.js"); | 50 | require("./components/noosfero/profile-image/profile-image.component.js"); |
src/app/main/main.component.ts
@@ -7,11 +7,20 @@ import {Profile} from "../profile/profile.component"; | @@ -7,11 +7,20 @@ import {Profile} from "../profile/profile.component"; | ||
7 | import {Boxes} from "../components/noosfero-boxes/boxes.component"; | 7 | import {Boxes} from "../components/noosfero-boxes/boxes.component"; |
8 | import {Block} from "../components/noosfero-blocks/block.component"; | 8 | import {Block} from "../components/noosfero-blocks/block.component"; |
9 | import {LinkListBlock} from "../components/noosfero-blocks/link-list/link-list.component"; | 9 | import {LinkListBlock} from "../components/noosfero-blocks/link-list/link-list.component"; |
10 | +import {RecentDocumentsBlock} from "../components/noosfero-blocks/recent-documents/recent-documents.component"; | ||
11 | +import {ProfileImageBlock} from "../components/noosfero-blocks/profile-image/profile-image.component"; | ||
12 | +import {MembersBlock} from "../components/noosfero-blocks/members-block/members-block.component"; | ||
10 | 13 | ||
11 | 14 | ||
12 | import {AuthService} from "./../components/auth/auth_service"; | 15 | import {AuthService} from "./../components/auth/auth_service"; |
13 | import {Session} from "./../components/auth/session"; | 16 | import {Session} from "./../components/auth/session"; |
14 | 17 | ||
18 | + | ||
19 | +import {Navbar} from "../components/navbar"; | ||
20 | + | ||
21 | +import {MainBlock} from "../components/noosfero-blocks/main-block/main-block.component"; | ||
22 | + | ||
23 | + | ||
15 | @Component({ | 24 | @Component({ |
16 | selector: 'main-content', | 25 | selector: 'main-content', |
17 | templateUrl: "app/main/main.html", | 26 | templateUrl: "app/main/main.html", |
@@ -24,7 +33,10 @@ export class MainContent { | @@ -24,7 +33,10 @@ export class MainContent { | ||
24 | @Component({ | 33 | @Component({ |
25 | selector: 'main', | 34 | selector: 'main', |
26 | template: '<div ng-view></div>', | 35 | template: '<div ng-view></div>', |
27 | - directives: [NoosferoArticleBlog, ArticleView, Boxes, Block, LinkListBlock], | 36 | + directives: [ |
37 | + NoosferoArticleBlog, ArticleView, Boxes, Block, LinkListBlock, | ||
38 | + MainBlock, RecentDocumentsBlock, Navbar, ProfileImageBlock, MembersBlock | ||
39 | + ], | ||
28 | providers: [AuthService, Session] | 40 | providers: [AuthService, Session] |
29 | }) | 41 | }) |
30 | @StateConfig([ | 42 | @StateConfig([ |
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +import { Injectable, Inject } from "ng-forward"; | ||
2 | + | ||
3 | +@Injectable() | ||
4 | +@Inject("Restangular") | ||
5 | +export class ArticleService { | ||
6 | + | ||
7 | + constructor(private Restangular: any) { | ||
8 | + | ||
9 | + } | ||
10 | + | ||
11 | + getByProfile(profileId: number, filters: any) { | ||
12 | + return this.Restangular.service('profiles').one(profileId).one('articles').get(filters); | ||
13 | + } | ||
14 | + | ||
15 | +} |
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +import { Injectable, Inject } from "ng-forward"; | ||
2 | + | ||
3 | +@Injectable() | ||
4 | +@Inject("Restangular") | ||
5 | +export class ProfileService { | ||
6 | + | ||
7 | + constructor(private Restangular: any) { | ||
8 | + | ||
9 | + } | ||
10 | + | ||
11 | + getProfileMembers(profileId: number, filters: any) { | ||
12 | + return this.Restangular.service('profiles').one(profileId).customGET("members", filters); | ||
13 | + } | ||
14 | + | ||
15 | +} |
typings.json
@@ -9,6 +9,8 @@ | @@ -9,6 +9,8 @@ | ||
9 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", | 9 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", |
10 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dd638012d63e069f2c99d06ef4dcc9616a943ee4", | 10 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dd638012d63e069f2c99d06ef4dcc9616a943ee4", |
11 | "jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#470954c4f427e0805a2d633636a7c6aa7170def8", | 11 | "jquery": "github:DefinitelyTyped/DefinitelyTyped/jquery/jquery.d.ts#470954c4f427e0805a2d633636a7c6aa7170def8", |
12 | + "moment": "github:DefinitelyTyped/DefinitelyTyped/moment/moment.d.ts#b090bcf9ba9f756ec8ff53e7707269729172a325", | ||
13 | + "moment-node": "github:DefinitelyTyped/DefinitelyTyped/moment/moment-node.d.ts#b090bcf9ba9f756ec8ff53e7707269729172a325", | ||
12 | "ngstorage": "github:DefinitelyTyped/DefinitelyTyped/ngstorage/ngstorage.d.ts#f59279e1f7535149b4e14d2ccf537b2c81cfff75", | 14 | "ngstorage": "github:DefinitelyTyped/DefinitelyTyped/ngstorage/ngstorage.d.ts#f59279e1f7535149b4e14d2ccf537b2c81cfff75", |
13 | "restangular": "github:DefinitelyTyped/DefinitelyTyped/restangular/restangular.d.ts#f2ae460e1751bb6668d291d4eb9255f047dd0ac5" | 15 | "restangular": "github:DefinitelyTyped/DefinitelyTyped/restangular/restangular.d.ts#f2ae460e1751bb6668d291d4eb9255f047dd0ac5" |
14 | } | 16 | } |