diff --git a/.travis.yml b/.travis.yml
index 3aca566204..d1a00422a2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,6 +25,7 @@ env:
- MODULE=ng2-activiti-diagrams
- MODULE=ng2-activiti-analytics
- MODULE=ng2-alfresco-userinfo
+ - MODULE=ng2-alfresco-social
before_script:
- if ([ "$MODULE" != "ng2-alfresco-core" ]); then
diff --git a/appveyor.yml b/appveyor.yml
index 1ff6eb8387..2e00efed22 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -24,6 +24,7 @@ environment:
- COMPONENT_NAME: ng2-activiti-diagrams
- COMPONENT_NAME: ng2-activiti-analytics
- COMPONENT_NAME: ng2-alfresco-userinfo
+ - COMPONENT_NAME: ng2-alfresco-social
# Install scripts. (runs after repo cloning)
install:
diff --git a/demo-shell-ng2/app/app.component.html b/demo-shell-ng2/app/app.component.html
index 131f0aeb30..d052ae1f88 100644
--- a/demo-shell-ng2/app/app.component.html
+++ b/demo-shell-ng2/app/app.component.html
@@ -58,6 +58,7 @@
Process Services
Webscript
Tag
+ Social
About
Settings
diff --git a/demo-shell-ng2/app/app.module.ts b/demo-shell-ng2/app/app.module.ts
index 0cc24ac864..e7d6029f49 100644
--- a/demo-shell-ng2/app/app.module.ts
+++ b/demo-shell-ng2/app/app.module.ts
@@ -25,6 +25,7 @@ import { DataTableModule } from 'ng2-alfresco-datatable';
import { DocumentListModule } from 'ng2-alfresco-documentlist';
import { UploadModule } from 'ng2-alfresco-upload';
import { TagModule } from 'ng2-alfresco-tag';
+import { SocialModule } from 'ng2-alfresco-social';
import { WebScriptModule } from 'ng2-alfresco-webscript';
import { ViewerModule } from 'ng2-alfresco-viewer';
import { ActivitiFormModule } from 'ng2-activiti-form';
@@ -50,6 +51,7 @@ import {
FormViewer,
WebscriptComponent,
TagComponent,
+ SocialComponent,
AboutComponent,
FilesComponent,
FormNodeViewer,
@@ -68,6 +70,7 @@ import {
DocumentListModule.forRoot(),
UploadModule.forRoot(),
TagModule.forRoot(),
+ SocialModule.forRoot(),
WebScriptModule.forRoot(),
ViewerModule.forRoot(),
ActivitiFormModule.forRoot(),
@@ -91,6 +94,7 @@ import {
FormViewer,
WebscriptComponent,
TagComponent,
+ SocialComponent,
AboutComponent,
FilesComponent,
FormNodeViewer,
diff --git a/demo-shell-ng2/app/app.routes.ts b/demo-shell-ng2/app/app.routes.ts
index 139c70467b..08ff178d0f 100644
--- a/demo-shell-ng2/app/app.routes.ts
+++ b/demo-shell-ng2/app/app.routes.ts
@@ -29,6 +29,7 @@ import {
ActivitiAppsView,
WebscriptComponent,
TagComponent,
+ SocialComponent,
AboutComponent,
FormViewer,
FormNodeViewer,
@@ -117,6 +118,11 @@ export const appRoutes: Routes = [
component: TagComponent,
canActivate: [AuthGuardEcm]
},
+ {
+ path: 'social',
+ component: SocialComponent,
+ canActivate: [AuthGuardEcm]
+ },
{ path: 'about', component: AboutComponent },
{ path: 'settings', component: SettingComponent }
];
diff --git a/demo-shell-ng2/app/components/index.ts b/demo-shell-ng2/app/components/index.ts
index fb66f819f6..95e9466cd1 100644
--- a/demo-shell-ng2/app/components/index.ts
+++ b/demo-shell-ng2/app/components/index.ts
@@ -24,6 +24,7 @@ export { ActivitiDemoComponent } from './activiti/activiti-demo.component';
export { FormViewer } from './activiti/form-viewer.component';
export { WebscriptComponent } from './webscript/webscript.component';
export { TagComponent } from './tag/tag.component';
+export { SocialComponent } from './social/social.component';
export { AboutComponent } from './about/about.component';
export { FilesComponent } from './files/files.component';
export { FormNodeViewer } from './activiti/form-node-viewer.component';
diff --git a/demo-shell-ng2/app/components/social/social.component.ts b/demo-shell-ng2/app/components/social/social.component.ts
new file mode 100644
index 0000000000..af40a06f6c
--- /dev/null
+++ b/demo-shell-ng2/app/components/social/social.component.ts
@@ -0,0 +1,39 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'alfresco-social-demo',
+ template: `
+
+
+
+ `
+})
+export class SocialComponent {
+
+ nodeId: string = '74cd8a96-8a21-47e5-9b3b-a1b3e296787d';
+}
diff --git a/demo-shell-ng2/app/vendor.ts b/demo-shell-ng2/app/vendor.ts
index 55f232dee5..91d7764380 100644
--- a/demo-shell-ng2/app/vendor.ts
+++ b/demo-shell-ng2/app/vendor.ts
@@ -25,6 +25,7 @@ import 'ng2-alfresco-documentlist';
import 'ng2-alfresco-login';
import 'ng2-alfresco-search';
import 'ng2-alfresco-tag';
+import 'ng2-alfresco-social';
import 'ng2-alfresco-upload';
import 'ng2-alfresco-viewer';
import 'ng2-alfresco-webscript';
diff --git a/demo-shell-ng2/package.json b/demo-shell-ng2/package.json
index a8655859dc..3bed7b0f9f 100644
--- a/demo-shell-ng2/package.json
+++ b/demo-shell-ng2/package.json
@@ -85,6 +85,7 @@
"ng2-alfresco-login": "1.3.0",
"ng2-alfresco-search": "1.3.0",
"ng2-alfresco-tag": "1.3.0",
+ "ng2-alfresco-social": "1.3.0",
"ng2-alfresco-upload": "1.3.0",
"ng2-alfresco-userinfo": "1.3.0",
"ng2-alfresco-viewer": "1.3.0",
diff --git a/ng2-components/ng2-alfresco-social/.editorconfig b/ng2-components/ng2-alfresco-social/.editorconfig
new file mode 100644
index 0000000000..75a2477db7
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/.editorconfig
@@ -0,0 +1,23 @@
+# http://editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[package.json]
+indent_style = space
+indent_size = 2
+
+[karma.conf.js]
+indent_style = space
+indent_size = 2
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/ng2-components/ng2-alfresco-social/.gitignore b/ng2-components/ng2-alfresco-social/.gitignore
new file mode 100644
index 0000000000..fb23a7fef5
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/.gitignore
@@ -0,0 +1,19 @@
+npm-debug.log
+node_modules
+.idea
+typings
+coverage
+dist
+src/**/*.js
+src/**/*.js.map
+src/**/*.d.ts
+demo/**/*.js
+demo/**/*.js.map
+demo/**/*.d.ts
+index.js
+index.js.map
+!systemjs.config.js
+*.tgz
+/package/
+/bundles/
+index.d.ts
diff --git a/ng2-components/ng2-alfresco-social/.npmignore b/ng2-components/ng2-alfresco-social/.npmignore
new file mode 100644
index 0000000000..8bb008aff4
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/.npmignore
@@ -0,0 +1,16 @@
+npm-debug.log
+.idea
+
+coverage/
+demo/
+node_modules
+typings/
+fonts/
+
+/.editorconfig
+/.travis.yml
+/*.json
+/karma-test-shim.js
+/karma.conf.js
+/gulpfile.ts
+/.npmignore
diff --git a/ng2-components/ng2-alfresco-social/LICENSE b/ng2-components/ng2-alfresco-social/LICENSE
new file mode 100644
index 0000000000..de3d8c60b8
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2016 Alfresco
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/ng2-components/ng2-alfresco-social/README.md b/ng2-components/ng2-alfresco-social/README.md
new file mode 100644
index 0000000000..4ded788814
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/README.md
@@ -0,0 +1,291 @@
+# Alfresco Social Component for Angular 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Prerequisites
+
+Before you start using this development framework, make sure you have installed all required software and done all the
+necessary configuration [prerequisites](https://github.com/Alfresco/alfresco-ng2-components/blob/master/PREREQUISITES.md).
+
+## Install
+
+Follow the 3 steps below:
+
+1. Npm
+
+ ```sh
+ npm install ng2-alfresco-social --save
+ ```
+
+2. Html
+
+ Include these dependencies in your index.html page:
+
+ ```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+3. SystemJs
+
+ Add the following components to your systemjs.config.js file:
+
+ - ng2-translate
+ - alfresco-js-api
+ - ng2-alfresco-core
+ - ng2-alfresco-social
+
+ Please refer to the following example file: [systemjs.config.js](demo/systemjs.config.js) .
+
+
+#### Basic usage
+
+In this component are present two different components :
+
+* adf-like
+* adf-rating
+
+
+
+## adf-like
+
+```html
+
+```
+
+```ts
+import { NgModule, Component } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
+import { SocialModule } from 'ng2-alfresco-social';
+
+@Component({
+ selector: 'alfresco-app-demo',
+ template: `
+ `
+})
+class LikeDemo {
+
+ constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService) {
+ settingsService.ecmHost = 'http://localhost:8080';
+
+ this.authService.login('admin', 'admin').subscribe(
+ ticket => {
+ console.log(ticket);
+ },
+ error => {
+ console.log(error);
+ });
+ }
+}
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ CoreModule.forRoot(),
+ SocialModule
+ ],
+ declarations: [ LikeDemo ],
+ bootstrap: [ LikeDemo ]
+})
+export class AppModule { }
+
+platformBrowserDynamic().bootstrapModule(AppModule);
+```
+
+### Options
+
+Attribute | Options | Default | Description | Mandatory
+--- | --- | --- | --- | ---
+`nodeId` | *string* | | The identifier of a node.|
+
+#### Events
+
+| Name | Description |
+| --- | --- |
+| `changeVote` | The event is emitted when vote change |
+
+
+
+
+## adf-rating
+
+```html
+
+```
+
+```ts
+import { NgModule, Component } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
+import { SocialModule } from 'ng2-alfresco-social';
+
+@Component({
+ selector: 'alfresco-app-demo',
+ template: ``
+})
+class RatingDemo {
+
+ constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService) {
+ settingsService.ecmHost = 'http://localhost:8080';
+
+ this.authService.login('admin', 'admin').subscribe(
+ ticket => {
+ console.log(ticket);
+ },
+ error => {
+ console.log(error);
+ });
+ }
+}
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ CoreModule.forRoot(),
+ SocialModule
+ ],
+ declarations: [ RatingDemo ],
+ bootstrap: [ RatingDemo ]
+})
+export class AppModule { }
+
+platformBrowserDynamic().bootstrapModule(AppModule);
+```
+
+### Options
+
+Attribute | Options | Default | Description | Mandatory
+--- | --- | --- | --- | ---
+`nodeId` | *string* | | The identifier of a node.|
+
+#### Events
+
+| Name | Description |
+| --- | --- |
+| `changeVote` | The event is emitted when vote change |
+
+
+
+
+## Build from sources
+
+Alternatively you can build component from sources with the following commands:
+
+
+```sh
+npm install
+npm run build
+```
+
+### Build the files and keep watching for changes
+
+```sh
+$ npm run build:w
+```
+
+## Running unit tests
+
+```sh
+npm test
+```
+
+### Running unit tests in browser
+
+```sh
+npm test-browser
+```
+
+This task rebuilds all the code, runs tslint, license checks and other quality check tools
+before performing unit testing.
+
+### Code coverage
+
+```sh
+npm run coverage
+```
+
+## Demo
+
+If you want have a demo of how the component works, please check the demo folder :
+
+```sh
+cd demo
+npm install
+npm start
+```
+
+## NPM scripts
+
+| Command | Description |
+| --- | --- |
+| npm run build | Build component |
+| npm run build:w | Build component and keep watching the changes |
+| npm run test | Run unit tests in the console |
+| npm run test-browser | Run unit tests in the browser
+| npm run coverage | Run unit tests and display code coverage report |
+
+## License
+
+[Apache Version 2.0](https://github.com/Alfresco/alfresco-ng2-components/blob/master/LICENSE)
diff --git a/ng2-components/ng2-alfresco-social/assets/license_header.txt b/ng2-components/ng2-alfresco-social/assets/license_header.txt
new file mode 100644
index 0000000000..83fd1531a3
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/assets/license_header.txt
@@ -0,0 +1,16 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
\ No newline at end of file
diff --git a/ng2-components/ng2-alfresco-social/demo/.editorconfig b/ng2-components/ng2-alfresco-social/demo/.editorconfig
new file mode 100644
index 0000000000..75a2477db7
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/.editorconfig
@@ -0,0 +1,23 @@
+# http://editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[package.json]
+indent_style = space
+indent_size = 2
+
+[karma.conf.js]
+indent_style = space
+indent_size = 2
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/ng2-components/ng2-alfresco-social/demo/.gitignore b/ng2-components/ng2-alfresco-social/demo/.gitignore
new file mode 100644
index 0000000000..6afdbb8367
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/.gitignore
@@ -0,0 +1,6 @@
+typings/
+node_modules/
+.idea
+dist/
+!systemjs.config.js
+!browser-sync-config.js
diff --git a/ng2-components/ng2-alfresco-social/demo/README.md b/ng2-components/ng2-alfresco-social/demo/README.md
new file mode 100644
index 0000000000..e2d5d6e690
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/README.md
@@ -0,0 +1,19 @@
+# ng2-alfresco-social - Demo
+
+* To install dependencies
+
+```sh
+$ npm install
+```
+
+* To provide a live demo
+
+```sh
+$ npm run start
+```
+
+* To clean npm_modules and typings folder
+
+```sh
+$ npm run clean
+```
diff --git a/ng2-components/ng2-alfresco-social/demo/index.html b/ng2-components/ng2-alfresco-social/demo/index.html
new file mode 100644
index 0000000000..73ffc4d31b
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/index.html
@@ -0,0 +1,47 @@
+
+
+
+
+ Alfresco Angular 2 Social - Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ng2-components/ng2-alfresco-social/demo/package.json b/ng2-components/ng2-alfresco-social/demo/package.json
new file mode 100644
index 0000000000..062a9cd6ba
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/package.json
@@ -0,0 +1,68 @@
+{
+ "name": "ng2-alfresco-social-demo",
+ "description": "Alfresco Angular2 Rating - Demo",
+ "version": "0.3.0",
+ "author": "Alfresco Software, Ltd.",
+ "main": "index.js",
+ "scripts": {
+ "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings dist",
+ "clean-build" : "rimraf 'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts'",
+ "postinstall": "npm run build",
+ "start": "npm run build && concurrently \"npm run tsc:w\" \"npm run server\" ",
+ "server": "wsrv -o -s -l",
+ "build": "npm run tslint && npm run clean-build && npm run tsc",
+ "build:w": "npm run tslint && rimraf dist && npm run tsc:w",
+ "travis": "npm link ng2-alfresco-core",
+ "tsc": "tsc",
+ "tsc:w": "tsc -w",
+ "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts -e '{,**/}**.d.ts'"
+ },
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@angular/common": "2.2.2",
+ "@angular/compiler": "2.2.2",
+ "@angular/compiler-cli": "2.2.2",
+ "@angular/core": "2.2.2",
+ "@angular/forms": "2.2.2",
+ "@angular/http": "2.2.2",
+ "@angular/platform-browser": "2.2.2",
+ "@angular/platform-browser-dynamic": "2.2.2",
+ "@angular/material": "2.0.0-beta.1",
+ "@angular/router": "3.2.2",
+ "@angular/upgrade": "2.2.2",
+ "core-js": "2.4.1",
+ "reflect-metadata": "0.1.10",
+ "rxjs": "5.0.0-beta.12",
+ "systemjs": "0.19.27",
+ "zone.js": "0.6.26",
+ "intl": "1.2.4",
+ "dialog-polyfill": "0.4.7",
+ "element.scrollintoviewifneeded-polyfill": "1.0.1",
+ "material-design-icons": "2.2.3",
+ "material-design-lite": "1.2.1",
+ "ng2-translate": "4.0.0",
+ "alfresco-js-api": "~1.3.0",
+ "ng2-alfresco-core": "1.3.0",
+ "ng2-alfresco-social": "1.3.0"
+ },
+ "devDependencies": {
+ "@types/jasmine": "^2.2.33",
+ "@types/node": "^6.0.42",
+ "concurrently": "^2.2.0",
+ "rimraf": "2.5.2",
+ "tslint": "3.15.1",
+ "typescript": "^2.0.3",
+ "wsrv": "^0.1.5"
+ },
+ "contributors": [
+ {
+ "name": "Eugenio Romano",
+ "email": "eugenio.romano@alfresco.com"
+ }
+ ],
+ "keywords": [
+ "angular2",
+ "typescript",
+ "alfresco"
+ ]
+}
diff --git a/ng2-components/ng2-alfresco-social/demo/src/main.ts b/ng2-components/ng2-alfresco-social/demo/src/main.ts
new file mode 100644
index 0000000000..2929533fb1
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/src/main.ts
@@ -0,0 +1,117 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { NgModule, Component, Input, OnInit } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService, LogService } from 'ng2-alfresco-core';
+import { SocialModule } from 'ng2-alfresco-social';
+
+@Component({
+ selector: 'alfresco-app-demo',
+ template: `
+
+
+
+
+
+ Authentication failed to ip {{ ecmHost }} with user: admin, admin, you can still try to add a valid ticket to perform
+ operations.
+
+
+
+
+
+ `
+})
+class SocialDemo implements OnInit {
+
+ @Input()
+ nodeId: string = '74cd8a96-8a21-47e5-9b3b-a1b3e296787d';
+
+ authenticated: boolean;
+ ecmHost: string = 'http://127.0.0.1:8080';
+ ticket: string;
+
+ constructor(private authService: AlfrescoAuthenticationService,
+ private settingsService: AlfrescoSettingsService,
+ private storage: StorageService,
+ private logService: LogService) {
+
+ settingsService.ecmHost = this.ecmHost;
+ settingsService.setProviders('ECM');
+
+ if (this.authService.getTicketEcm()) {
+ this.ticket = this.authService.getTicketEcm();
+ }
+ }
+
+ ngOnInit() {
+ this.login();
+ }
+
+ login() {
+ this.authService.login('admin', 'admin').subscribe(
+ ticket => {
+ this.logService.info(ticket);
+ this.ticket = this.authService.getTicketEcm();
+ this.authenticated = true;
+ },
+ error => {
+ this.logService.error(error);
+ this.authenticated = false;
+ });
+ }
+
+ public updateTicket(): void {
+ this.storage.setItem('ticket-ECM', this.ticket);
+ }
+
+ public updateHost(): void {
+ this.settingsService.ecmHost = this.ecmHost;
+ this.login();
+ }
+
+ logData(data) {
+ this.logService.info(data);
+ }
+}
+
+@NgModule({
+ imports: [
+ BrowserModule,
+ CoreModule.forRoot(),
+ SocialModule
+ ],
+ declarations: [SocialDemo],
+ bootstrap: [SocialDemo]
+})
+export class AppModule {
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/ng2-components/ng2-alfresco-social/demo/systemjs.config.js b/ng2-components/ng2-alfresco-social/demo/systemjs.config.js
new file mode 100644
index 0000000000..b449fbd000
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/systemjs.config.js
@@ -0,0 +1,48 @@
+/**
+ * System configuration for Angular 2 samples
+ * Adjust as necessary for your application needs.
+ */
+(function (global) {
+ System.config({
+ paths: {
+ // paths serve as alias
+ 'npm:': 'node_modules/'
+ },
+ // map tells the System loader where to look for things
+ map: {
+ // our app is within the app folder
+ app: 'src',
+ // angular bundles
+ '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
+ '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
+ '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
+ '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
+ '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
+ '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
+ '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
+ '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
+ '@angular/material': 'npm:@angular/material/bundles/material.umd.js',
+
+ // other libraries
+ 'rxjs': 'npm:rxjs',
+ 'ng2-translate': 'npm:ng2-translate',
+ 'alfresco-js-api': 'npm:alfresco-js-api/dist',
+ 'ng2-alfresco-core': 'npm:ng2-alfresco-core',
+ 'ng2-alfresco-social': 'npm:ng2-alfresco-social'
+ },
+ // packages tells the System loader how to load when no filename and/or no extension
+ packages: {
+ app: {
+ main: './main.js',
+ defaultExtension: 'js'
+ },
+ rxjs: {
+ defaultExtension: 'js'
+ },
+ 'ng2-translate': { defaultExtension: 'js' },
+ 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'},
+ 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'},
+ 'ng2-alfresco-social': { main: './index.js', defaultExtension: 'js'}
+ }
+ });
+})(this);
diff --git a/ng2-components/ng2-alfresco-social/demo/tsconfig.json b/ng2-components/ng2-alfresco-social/demo/tsconfig.json
new file mode 100644
index 0000000000..524fcfda8e
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/tsconfig.json
@@ -0,0 +1,32 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "sourceMap": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "skipLibCheck": true,
+ "noLib": false,
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
+ "noImplicitAny": false,
+ "noImplicitReturns": false,
+ "noImplicitUseStrict": false,
+ "noFallthroughCasesInSwitch": true,
+ "removeComments": true,
+ "declaration": true,
+ "lib": [
+ "es2015",
+ "dom"
+ ],
+ "suppressImplicitAnyIndexErrors": true
+ },
+ "exclude": [
+ "node_modules"
+ ],
+ "angularCompilerOptions": {
+ "strictMetadataEmit": false,
+ "skipTemplateCodegen": true
+ }
+}
diff --git a/ng2-components/ng2-alfresco-social/demo/tslint.json b/ng2-components/ng2-alfresco-social/demo/tslint.json
new file mode 100644
index 0000000000..8c9703b9de
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/tslint.json
@@ -0,0 +1,124 @@
+{
+ "rules": {
+ "align": [
+ true,
+ "parameters",
+ "arguments",
+ "statements"
+ ],
+ "ban": false,
+ "class-name": true,
+ "comment-format": [
+ true,
+ "check-space",
+ "check-lowercase"
+ ],
+ "curly": true,
+ "eofline": true,
+ "forin": true,
+ "indent": [
+ true,
+ "spaces"
+ ],
+ "interface-name": false,
+ "jsdoc-format": true,
+ "label-position": true,
+ "label-undefined": true,
+ "max-line-length": [
+ true,
+ 180
+ ],
+ "member-ordering": [
+ true,
+ "public-before-private",
+ "static-before-instance",
+ "variables-before-functions"
+ ],
+ "no-any": false,
+ "no-arg": true,
+ "no-bitwise": true,
+ "no-conditional-assignment": true,
+ "no-consecutive-blank-lines": true,
+ "no-console": [
+ true,
+ "debug",
+ "info",
+ "time",
+ "timeEnd",
+ "trace"
+ ],
+ "no-construct": true,
+ "no-constructor-vars": false,
+ "no-debugger": true,
+ "no-duplicate-key": true,
+ "no-duplicate-variable": true,
+ "no-empty": true,
+ "no-eval": true,
+ "no-inferrable-types": false,
+ "no-internal-module": true,
+ "no-require-imports": true,
+ "no-shadowed-variable": true,
+ "no-switch-case-fall-through": true,
+ "no-trailing-whitespace": true,
+ "no-unreachable": true,
+ "no-unused-expression": true,
+ "no-unused-variable": true,
+ "no-use-before-declare": true,
+ "no-var-keyword": true,
+ "no-var-requires": true,
+ "object-literal-sort-keys": false,
+ "one-line": [
+ true,
+ "check-open-brace",
+ "check-catch",
+ "check-else",
+ "check-whitespace"
+ ],
+ "quotemark": [
+ true,
+ "single",
+ "avoid-escape"
+ ],
+ "radix": true,
+ "semicolon": true,
+ "switch-default": true,
+ "trailing-comma": [
+ true,
+ {
+ "multiline": "never",
+ "singleline": "never"
+ }
+ ],
+ "triple-equals": [
+ true,
+ "allow-null-check"
+ ],
+ "typedef": false,
+ "typedef-whitespace": [
+ true,
+ {
+ "call-signature": "nospace",
+ "index-signature": "nospace",
+ "parameter": "nospace",
+ "property-declaration": "nospace",
+ "variable-declaration": "nospace"
+ }
+ ],
+ "use-strict": false,
+ "variable-name": [
+ true,
+ "check-format",
+ "allow-leading-underscore",
+ "ban-keywords"
+ ],
+ "whitespace": [
+ true,
+ "check-branch",
+ "check-operator",
+ "check-separator",
+ "check-type",
+ "check-module",
+ "check-decl"
+ ]
+ }
+}
diff --git a/ng2-components/ng2-alfresco-social/demo/wsrv-config.json b/ng2-components/ng2-alfresco-social/demo/wsrv-config.json
new file mode 100644
index 0000000000..1ad5de60f0
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/demo/wsrv-config.json
@@ -0,0 +1,5 @@
+{
+ "watch": [
+ "node_modules/ng2-alfresco-social/dist/**/*.{html,htm,css,js}"
+ ]
+}
diff --git a/ng2-components/ng2-alfresco-social/docs/assets/social1.png b/ng2-components/ng2-alfresco-social/docs/assets/social1.png
new file mode 100644
index 0000000000..55984b8db0
Binary files /dev/null and b/ng2-components/ng2-alfresco-social/docs/assets/social1.png differ
diff --git a/ng2-components/ng2-alfresco-social/docs/assets/social2.png b/ng2-components/ng2-alfresco-social/docs/assets/social2.png
new file mode 100644
index 0000000000..94cb875c2f
Binary files /dev/null and b/ng2-components/ng2-alfresco-social/docs/assets/social2.png differ
diff --git a/ng2-components/ng2-alfresco-social/gulpfile.ts b/ng2-components/ng2-alfresco-social/gulpfile.ts
new file mode 100755
index 0000000000..7f7285181b
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/gulpfile.ts
@@ -0,0 +1,307 @@
+import * as gulp from 'gulp';
+import * as util from 'gulp-util';
+import * as runSequence from 'run-sequence';
+import * as gulpLoadPlugins from 'gulp-load-plugins';
+import * as merge from 'merge-stream';
+import * as rimraf from 'rimraf';
+import { join } from 'path';
+import * as Builder from 'systemjs-builder';
+var autoprefixer = require('autoprefixer');
+import * as cssnano from 'cssnano';
+import * as filter from 'gulp-filter';
+import * as sourcemaps from 'gulp-sourcemaps';
+
+var APP_SRC = `.`;
+var CSS_PROD_BUNDLE = 'main.css';
+var JS_PROD_SHIMS_BUNDLE = 'shims.js';
+var NG_FACTORY_FILE = 'main-prod';
+
+const BUILD_TYPES = {
+ DEVELOPMENT: 'dev',
+ PRODUCTION: 'prod'
+};
+
+function normalizeDependencies(deps) {
+ deps
+ .filter((d) => !/\*/.test(d.src)) // Skip globs
+ .forEach((d) => d.src = require.resolve(d.src));
+ return deps;
+}
+
+function filterDependency(type: string, d): boolean {
+ const t = d.buildType || d.env;
+ d.buildType = t;
+ if (!t) {
+ d.buildType = Object.keys(BUILD_TYPES).map(k => BUILD_TYPES[k]);
+ }
+ if (!(d.buildType instanceof Array)) {
+ (d).env = [d.buildType];
+ }
+ return d.buildType.indexOf(type) >= 0;
+}
+
+function getInjectableDependency() {
+ var APP_ASSETS = [
+ {src: `src/css/main.css`, inject: true, vendor: false},
+ ];
+
+ var NPM_DEPENDENCIES = [
+ {src: 'zone.js/dist/zone.js', inject: 'libs'},
+ {src: 'core-js/client/shim.min.js', inject: 'shims'},
+ {src: 'systemjs/dist/system.src.js', inject: 'shims', buildType:'dev'}
+ ];
+
+ return normalizeDependencies(NPM_DEPENDENCIES.filter(filterDependency.bind(null, 'dev')))
+ .concat(APP_ASSETS.filter(filterDependency.bind(null, 'dev')));
+}
+
+const plugins = gulpLoadPlugins();
+
+let tsProjects: any = {};
+
+function makeTsProject(options: Object = {}) {
+ let optionsHash = JSON.stringify(options);
+ if (!tsProjects[optionsHash]) {
+ let config = Object.assign({
+ typescript: require('typescript')
+ }, options);
+ tsProjects[optionsHash] =
+ plugins.typescript.createProject('tsconfig.json', config);
+ }
+ return tsProjects[optionsHash];
+}
+
+gulp.task('build.html_css', () => {
+ const gulpConcatCssConfig = {
+ targetFile: CSS_PROD_BUNDLE,
+ options: {
+ rebaseUrls: false
+ }
+ };
+
+ const processors = [
+ autoprefixer({
+ browsers: [
+ 'ie >= 10',
+ 'ie_mob >= 10',
+ 'ff >= 30',
+ 'chrome >= 34',
+ 'safari >= 7',
+ 'opera >= 23',
+ 'ios >= 7',
+ 'android >= 4.4',
+ 'bb >= 10'
+ ]
+ })
+ ];
+
+ const reportPostCssError = (e: any) => util.log(util.colors.red(e.message));
+
+ processors.push(
+ cssnano({
+ discardComments: {removeAll: true},
+ discardUnused: false, // unsafe, see http://goo.gl/RtrzwF
+ zindex: false, // unsafe, see http://goo.gl/vZ4gbQ
+ reduceIdents: false // unsafe, see http://goo.gl/tNOPv0
+ })
+ );
+
+ /**
+ * Processes the CSS files within `src/client` excluding those in `src/client/assets` using `postcss` with the
+ * configured processors
+ * Execute the appropriate component-stylesheet processing method based on user stylesheet preference.
+ */
+ function processComponentStylesheets() {
+ return gulp.src(join('src/**', '*.css'))
+ .pipe(plugins.cached('process-component-css'))
+ .pipe(plugins.postcss(processors))
+ .on('error', reportPostCssError);
+ }
+
+
+ /**
+ * Get a stream of external css files for subsequent processing.
+ */
+ function getExternalCssStream() {
+ return gulp.src(getExternalCss())
+ .pipe(plugins.cached('process-external-css'));
+ }
+
+ /**
+ * Get an array of filenames referring to all external css stylesheets.
+ */
+ function getExternalCss() {
+ return getInjectableDependency().filter(dep => /\.css$/.test(dep.src)).map(dep => dep.src);
+ }
+
+ /**
+ * Processes the external CSS files using `postcss` with the configured processors.
+ */
+ function processExternalCss() {
+ return getExternalCssStream()
+ .pipe(plugins.postcss(processors))
+ .pipe(plugins.concatCss(gulpConcatCssConfig.targetFile, gulpConcatCssConfig.options))
+ .on('error', reportPostCssError);
+ }
+
+ return merge(processComponentStylesheets(), processExternalCss());
+
+});
+
+gulp.task('build.bundles.app', (done) => {
+ var BUNDLER_OPTIONS = {
+ format: 'umd',
+ minify: false,
+ mangle: false,
+ sourceMaps: true
+ };
+ var CONFIG_TYPESCRIPT = {
+ baseURL: '.',
+ transpiler: 'typescript',
+ typescriptOptions: {
+ module: 'cjs'
+ },
+ map: {
+ typescript: 'node_modules/typescript/lib/typescript.js',
+ '@angular': 'node_modules/@angular',
+ rxjs: 'node_modules/rxjs',
+ 'ng2-translate': 'node_modules/ng2-translate',
+ 'alfresco-js-api': 'node_modules/alfresco-js-api/dist/alfresco-js-api',
+ 'ng2-alfresco-core': 'node_modules/ng2-alfresco-core/',
+ 'ng2-activiti-diagrams': 'node_modules/ng2-activiti-diagrams/',
+ 'ng2-activiti-analytics': 'node_modules/ng2-activiti-analytics/',
+ 'ng2-alfresco-datatable': 'node_modules/ng2-alfresco-datatable/',
+ 'ng2-alfresco-documentlist': 'node_modules/ng2-alfresco-documentlist/',
+ 'ng2-activiti-form': 'node_modules/ng2-activiti-form/',
+ 'ng2-alfresco-login': 'node_modules/ng2-alfresco-login/',
+ 'ng2-activiti-processlist': 'node_modules/ng2-activiti-processlist/',
+ 'ng2-alfresco-search': 'node_modules/ng2-alfresco-search/',
+ 'ng2-activiti-tasklist': 'node_modules/ng2-activiti-tasklist/',
+ 'ng2-alfresco-social': 'node_modules/ng2-alfresco-social/',
+ 'ng2-alfresco-upload': 'node_modules/ng2-alfresco-upload/',
+ 'ng2-alfresco-userinfo': 'node_modules/ng2-alfresco-userinfo/',
+ 'ng2-alfresco-viewer': 'node_modules/ng2-alfresco-viewer/',
+ 'ng2-alfresco-webscript': 'node_modules/ng2-alfresco-webscript/'
+ },
+ paths: {
+ '*': '*.js'
+ },
+ meta: {
+ 'node_modules/@angular/*': {build: false},
+ 'node_modules/rxjs/*': {build: false},
+ 'node_modules/ng2-translate/*': {build: false},
+ 'node_modules/ng2-alfresco-core/*': {build: false},
+ 'node_modules/ng2-activiti-diagrams/*': {build: false},
+ 'node_modules/ng2-activiti-analytics/*': {build: false},
+ 'node_modules/ng2-alfresco-datatable/*': {build: false},
+ 'node_modules/ng2-alfresco-documentlist/*': {build: false},
+ 'node_modules/ng2-activiti-form/*': {build: false},
+ 'node_modules/ng2-alfresco-login/*': {build: false},
+ 'node_modules/ng2-activiti-processlist/*': {build: false},
+ 'node_modules/ng2-alfresco-search/*': {build: false},
+ 'node_modules/ng2-activiti-tasklist/*': {build: false},
+ 'node_modules/ng2-alfresco-social/*': {build: false},
+ 'node_modules/ng2-alfresco-upload/*': {build: false},
+ 'node_modules/ng2-alfresco-userinfo/*': {build: false},
+ 'node_modules/ng2-alfresco-viewer/*': {build: false},
+ 'node_modules/ng2-alfresco-webscript/*': {build: false}
+ }
+ };
+
+ var pkg = require('./package.json');
+ var namePkg = pkg.name;
+
+ var builder = new Builder(CONFIG_TYPESCRIPT);
+ builder
+ .buildStatic(APP_SRC + "/index", 'bundles/' + namePkg + '.js', BUNDLER_OPTIONS)
+ .then(function () {
+ return done();
+ })
+ .catch(function (err) {
+ return done(err);
+ });
+});
+
+gulp.task('build.assets.prod', () => {
+ return gulp.src([
+ join('src/**', '*.ts'),
+ 'index.ts',
+ join('src/**', '*.css'),
+ join('src/**', '*.html'),
+ '!'+join('*/**', '*.d.ts'),
+ '!'+join('*/**', '*.spec.ts'),
+ '!gulpfile.ts'])
+
+});
+
+gulp.task('build.bundles', () => {
+ merge(bundleShims());
+
+ /**
+ * Returns the shim files to be injected.
+ */
+ function getShims() {
+ let libs = getInjectableDependency()
+ .filter(d => /\.js$/.test(d.src));
+
+ return libs.filter(l => l.inject === 'shims')
+ .concat(libs.filter(l => l.inject === 'libs'))
+ .concat(libs.filter(l => l.inject === true))
+ .map(l => l.src);
+ }
+
+ /**
+ * Bundles the shim files.
+ */
+ function bundleShims() {
+ return gulp.src(getShims())
+ .pipe(plugins.concat(JS_PROD_SHIMS_BUNDLE))
+ // Strip the first (global) 'use strict' added by reflect-metadata, but don't strip any others to avoid unintended scope leaks.
+ .pipe(plugins.replace(/('|")use strict\1;var Reflect;/, 'var Reflect;'))
+ .pipe(gulp.dest('bundles'));
+ }
+
+});
+
+gulp.task('build.js.prod', () => {
+ const INLINE_OPTIONS = {
+ base: APP_SRC,
+ target: 'es5',
+ useRelativePaths: true,
+ removeLineBreaks: true
+ };
+
+ let tsProject = makeTsProject();
+ let src = [
+ join('src/**/*.ts'),
+ join('!src/**/*.d.ts'),
+ join('!src/**/*.spec.ts'),
+ `!src/**/${NG_FACTORY_FILE}.ts`
+ ];
+
+ let result = gulp.src(src)
+ .pipe(plugins.plumber())
+ .pipe(plugins.inlineNg2Template(INLINE_OPTIONS))
+ .pipe(sourcemaps.init())
+ .pipe(tsProject())
+ .once('error', function (e: any) {
+ this.once('finish', () => process.exit(1));
+ });
+
+ return result.js
+ .pipe(plugins.template())
+ .pipe(sourcemaps.write())
+ .pipe(gulp.dest('src'))
+ .on('error', (e: any) => {
+ console.log(e);
+ });
+});
+
+gulp.task('build.prod', (done: any) =>
+ runSequence(
+ 'build.assets.prod',
+ 'build.html_css',
+ 'build.js.prod',
+ 'build.bundles',
+ 'build.bundles.app',
+ done));
diff --git a/ng2-components/ng2-alfresco-social/index.ts b/ng2-components/ng2-alfresco-social/index.ts
new file mode 100644
index 0000000000..3716ab32fa
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/index.ts
@@ -0,0 +1,61 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { NgModule, ModuleWithProviders } from '@angular/core';
+import { CoreModule } from 'ng2-alfresco-core';
+
+import { RatingComponent } from './src/components/rating.component';
+import { LikeComponent } from './src/components/like.component';
+import { RatingService } from './src/services/rating.service';
+
+export * from './src/components/rating.component';
+export * from './src/components/like.component';
+export * from './src/services/rating.service';
+
+export const RATING_DIRECTIVES: any[] = [
+ RatingComponent,
+ LikeComponent
+];
+
+export const RATING_PROVIDERS: any[] = [
+ RatingService
+];
+
+@NgModule({
+ imports: [
+ CoreModule
+ ],
+ declarations: [
+ ...RATING_DIRECTIVES
+ ],
+ providers: [
+ ...RATING_PROVIDERS
+ ],
+ exports: [
+ ...RATING_DIRECTIVES
+ ]
+})
+export class SocialModule {
+ static forRoot(): ModuleWithProviders {
+ return {
+ ngModule: SocialModule,
+ providers: [
+ ...RATING_DIRECTIVES
+ ]
+ };
+ }
+}
diff --git a/ng2-components/ng2-alfresco-social/karma-test-shim.js b/ng2-components/ng2-alfresco-social/karma-test-shim.js
new file mode 100644
index 0000000000..8696dd2b16
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/karma-test-shim.js
@@ -0,0 +1,115 @@
+// Tun on full stack traces in errors to help debugging
+Error.stackTraceLimit = Infinity;
+
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
+
+window.componentHandler = {
+ upgradeAllRegistered: function () {
+ },
+ upgradeElement: function () {
+ }
+};
+
+__karma__.loaded = function() {};
+
+var builtPath = '/base/src/';
+
+function isJsFile(path) {
+ return path.slice(-3) == '.js';
+}
+
+function isSpecFile(path) {
+ return /\.spec\.(.*\.)?js$/.test(path);
+}
+
+function isBuiltFile(path) {
+ return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
+}
+
+var allSpecFiles = Object.keys(window.__karma__.files)
+ .filter(isSpecFile)
+ .filter(isBuiltFile);
+
+var paths = {
+ // paths serve as alias
+ 'npm:': 'base/node_modules/'
+};
+
+var map = {
+ 'app': 'base/src',
+ // angular bundles
+ '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
+ '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
+ '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
+ '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
+ '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
+ '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
+ '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
+ '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
+ '@angular/material': 'npm:@angular/material/bundles/material.umd.js',
+
+ // testing
+ '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
+ '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
+ '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
+ '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
+ '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
+ '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
+ '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
+ '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
+
+ // other libraries
+ 'rxjs': 'npm:rxjs',
+ 'ng2-translate': 'npm:ng2-translate',
+ 'hammerjs': 'npm:hammerjs',
+
+ 'alfresco-js-api': 'npm:alfresco-js-api/dist',
+ 'ng2-alfresco-core': 'npm:ng2-alfresco-core'
+};
+
+var packages = {
+ 'app': { main: 'main.js', defaultExtension: 'js' },
+ 'rxjs': { defaultExtension: 'js' },
+ 'ng2-translate': { defaultExtension: 'js' },
+ 'hammerjs': {main: './hammerjs.js', defaultExtension: 'js'},
+
+ 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'},
+ 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'}
+};
+
+var config = {
+ paths: paths,
+ map: map,
+ packages: packages
+};
+
+System.config(config);
+
+System.import('@angular/core/testing')
+ .then(initTestBed)
+ .then(initTesting);
+
+function initTestBed(){
+ return Promise.all([
+ System.import('@angular/core/testing'),
+ System.import('@angular/platform-browser-dynamic/testing')
+ ])
+ .then(function (providers) {
+ var coreTesting = providers[0];
+ var browserTesting = providers[1];
+
+ coreTesting.TestBed.initTestEnvironment(
+ browserTesting.BrowserDynamicTestingModule,
+ browserTesting.platformBrowserDynamicTesting());
+ })
+}
+
+// Import all spec files and start karma
+function initTesting () {
+ return Promise.all(
+ allSpecFiles.map(function (moduleName) {
+ return System.import(moduleName);
+ })
+ )
+ .then(__karma__.start, __karma__.error);
+}
diff --git a/ng2-components/ng2-alfresco-social/karma.conf.js b/ng2-components/ng2-alfresco-social/karma.conf.js
new file mode 100644
index 0000000000..b3920fc80c
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/karma.conf.js
@@ -0,0 +1,127 @@
+'use strict';
+
+module.exports = function (config) {
+ var configuration = {
+ basePath: '.',
+
+ frameworks: ['jasmine-ajax', 'jasmine'],
+
+ files: [
+ // System.js for module loading
+ 'node_modules/systemjs/dist/system.src.js',
+
+ // Polyfills
+ 'node_modules/core-js/client/shim.js',
+ 'node_modules/reflect-metadata/Reflect.js',
+
+ // zone.js
+ 'node_modules/zone.js/dist/zone.js',
+ 'node_modules/zone.js/dist/long-stack-trace-zone.js',
+ 'node_modules/zone.js/dist/proxy.js',
+ 'node_modules/zone.js/dist/sync-test.js',
+ 'node_modules/zone.js/dist/jasmine-patch.js',
+ 'node_modules/zone.js/dist/async-test.js',
+ 'node_modules/zone.js/dist/fake-async-test.js',
+ 'node_modules/hammerjs/hammer.js',
+
+ // RxJs
+ { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
+ { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
+
+ // Paths loaded via module imports:
+ // Angular itself
+ {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
+ {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false},
+
+ 'node_modules/alfresco-js-api/dist/alfresco-js-api.js',
+
+ {pattern: 'node_modules/ng2-translate/**/*.js', included: false, watched: false},
+
+ 'karma-test-shim.js',
+
+ // paths loaded via module imports
+ {pattern: 'src/**/*.js', included: false, watched: true},
+ {pattern: 'src/**/*.html', included: true, served: true, watched: true},
+ {pattern: 'src/**/*.css', included: true, served: true, watched: true},
+
+ // ng2-components
+ { pattern: 'node_modules/ng2-alfresco-core/src/**/*.js', included: false, served: true, watched: false },
+ { pattern: 'node_modules/ng2-alfresco-core/index.js', included: false, served: true, watched: false },
+
+ // paths to support debugging with source maps in dev tools
+ {pattern: 'src/**/*.ts', included: false, watched: false},
+ {pattern: 'src/**/*.js.map', included: false, watched: false}
+ ],
+
+ exclude: [
+ 'node_modules/**/*spec.js'
+ ],
+
+ // proxied base paths
+ proxies: {
+ // required for component assets fetched by Angular's compiler
+ '/src/': '/base/src/'
+ },
+
+ port: 9876,
+
+ // level of logging
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ logLevel: config.LOG_INFO,
+
+ colors: true,
+
+ autoWatch: true,
+
+ captureTimeout: 180000,
+ browserDisconnectTimeout: 180000,
+ browserDisconnectTolerance: 3,
+ browserNoActivityTimeout: 300000,
+
+ browsers: ['Chrome'],
+
+ customLaunchers: {
+ Chrome_travis_ci: {
+ base: 'Chrome',
+ flags: ['--no-sandbox']
+ }
+ },
+
+ // Karma plugins loaded
+ plugins: [
+ 'karma-jasmine',
+ 'karma-coverage',
+ 'karma-jasmine-ajax',
+ 'karma-chrome-launcher',
+ 'karma-mocha-reporter',
+ 'karma-jasmine-html-reporter'
+ ],
+
+ // Coverage reporter generates the coverage
+ reporters: ['mocha', 'coverage', 'kjhtml'],
+
+ // Source files that you wanna generate coverage for.
+ // Do not include tests or libraries (these files will be instrumented by Istanbul)
+ preprocessors: {
+ 'src/**/!(*spec|index|*mock|*model|*event).js': 'coverage'
+ },
+
+ coverageReporter: {
+ includeAllSources: true,
+ dir: 'coverage/',
+ subdir: 'report',
+ reporters: [
+ {type: 'text'},
+ {type: 'json', file: 'coverage-final.json'},
+ {type: 'html'},
+ {type: 'lcov'}
+ ]
+ }
+ };
+
+ if (process.env.TRAVIS) {
+ configuration.browsers = ['Chrome_travis_ci'];
+ }
+
+ config.set(configuration)
+};
diff --git a/ng2-components/ng2-alfresco-social/package.json b/ng2-components/ng2-alfresco-social/package.json
new file mode 100644
index 0000000000..a360ad0f6d
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/package.json
@@ -0,0 +1,114 @@
+{
+ "name": "ng2-alfresco-social",
+ "description": "Alfresco rating component",
+ "version": "1.3.0",
+ "author": "Alfresco Software, Ltd.",
+ "scripts": {
+ "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings",
+ "clean-build": "rimraf index.js index.js.map index.d.ts 'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles",
+ "build": "npm run clean-build && npm run tslint && tsc && license-check && npm run build.umd",
+ "build:w": "npm run clean-build && npm run tslint && npm run tsc:w && license-check && npm run build.umd",
+ "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'",
+ "tsc": "tsc",
+ "tsc:w": "tsc -w",
+ "pretest": "npm run build",
+ "test": "karma start karma.conf.js --reporters mocha,coverage --single-run",
+ "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"",
+ "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json",
+ "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report",
+ "publish:prod": "npm run test && npm publish",
+ "travis": "npm link ng2-alfresco-core",
+ "gulp": "gulp",
+ "build.umd": "gulp build.prod --color --env-config prod --build-type prod",
+ "reinstall": "npm cache clean && npm install"
+ },
+ "main": "./index.js",
+ "module": "./index.js",
+ "typings": "./index.d.ts",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Alfresco/alfresco-ng2-components.git"
+ },
+ "bugs": {
+ "url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
+ },
+ "dependencies": {
+ "@angular/common": "2.2.2",
+ "@angular/compiler": "2.2.2",
+ "@angular/core": "2.2.2",
+ "@angular/forms": "2.2.2",
+ "@angular/http": "2.2.2",
+ "@angular/material": "2.0.0-beta.1",
+ "@angular/platform-browser": "2.2.2",
+ "@angular/platform-browser-dynamic": "2.2.2",
+ "@angular/router": "3.2.2",
+ "alfresco-js-api": "~1.3.0",
+ "core-js": "2.4.1",
+ "hammerjs": "2.0.8",
+ "ng2-alfresco-core": "1.3.0",
+ "ng2-translate": "2.5.0",
+ "reflect-metadata": "0.1.10",
+ "rxjs": "5.0.0-beta.12",
+ "systemjs": "0.19.27",
+ "zone.js": "0.6.26"
+ },
+ "devDependencies": {
+ "@types/hammerjs": "^2.0.34",
+ "@types/jasmine": "2.5.35",
+ "@types/node": "6.0.45",
+ "autoprefixer": "^6.5.4",
+ "concurrently": "^2.2.0",
+ "cpx": "^1.3.1",
+ "cssnano": "^3.8.1",
+ "gulp": "^3.9.1",
+ "gulp-autoprefixer": "^3.1.1",
+ "gulp-cached": "^1.1.1",
+ "gulp-concat": "^2.6.1",
+ "gulp-concat-css": "^2.3.0",
+ "gulp-filter": "^4.0.0",
+ "gulp-inline-ng2-template": "^4.0.0",
+ "gulp-load-plugins": "^1.4.0",
+ "gulp-plumber": "^1.1.0",
+ "gulp-postcss": "^6.2.0",
+ "gulp-replace": "^0.5.4",
+ "gulp-sourcemaps": "^1.9.1",
+ "gulp-template": "^4.0.0",
+ "gulp-typescript": "^3.1.3",
+ "gulp-uglify": "^2.0.0",
+ "gulp-util": "^3.0.7",
+ "jasmine-ajax": "^3.2.0",
+ "jasmine-core": "2.4.1",
+ "karma": "~0.13.22",
+ "karma-chrome-launcher": "~1.0.1",
+ "karma-coverage": "^1.0.0",
+ "karma-jasmine": "~1.0.2",
+ "karma-jasmine-ajax": "^0.1.13",
+ "karma-jasmine-html-reporter": "^0.2.0",
+ "karma-mocha-reporter": "^2.0.3",
+ "license-check": "^1.0.4",
+ "merge-stream": "^1.0.1",
+ "remap-istanbul": "^0.6.3",
+ "rimraf": "2.5.2",
+ "run-sequence": "^1.2.2",
+ "systemjs-builder": "^0.15.34",
+ "traceur": "^0.0.91",
+ "ts-node": "^1.7.0",
+ "tslint": "^3.8.1",
+ "typescript": "^2.0.3",
+ "wsrv": "^0.1.5"
+ },
+ "keywords": [
+ "rating",
+ "alfresco-component"
+ ],
+ "license-check-config": {
+ "src": [
+ "./src/**/*.js"
+ ],
+ "path": "assets/license_header.txt",
+ "blocking": true,
+ "logInfo": false,
+ "logError": true
+ },
+ "license": "Apache-2.0"
+}
diff --git a/ng2-components/ng2-alfresco-social/src/components/like.component.css b/ng2-components/ng2-alfresco-social/src/components/like.component.css
new file mode 100644
index 0000000000..b6e3833506
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/like.component.css
@@ -0,0 +1,41 @@
+.adf-like-container {
+ overflow: hidden;
+ width: 100%;
+}
+
+.adf-like {
+ padding: 5px;
+ cursor: pointer;
+ float: left;
+ margin: 5px 0px 5px 5px;
+}
+
+.adf-like-select {
+ cursor: pointer;
+ color: #2196f3;
+}
+
+.adf-like-select:hover {
+ cursor: pointer;
+ color: #808080;
+}
+
+.adf-like-grey {
+ cursor: pointer;
+ color: #808080;
+}
+
+.adf-like-grey:hover {
+ cursor: pointer;
+ color: #2196f3;
+}
+
+.adf-like-counter {
+ float: left;
+ padding: 13px 0 0 0;
+}
+
+.adf-left{
+ float: left;
+ padding: 13px 0 0 4px;
+}
diff --git a/ng2-components/ng2-alfresco-social/src/components/like.component.html b/ng2-components/ng2-alfresco-social/src/components/like.component.html
new file mode 100644
index 0000000000..b9e462fcea
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/like.component.html
@@ -0,0 +1,11 @@
+
+
+
+ thumb_up
+
+
+
{{likesCounter}}
+
Like
+
1">Likes
+
diff --git a/ng2-components/ng2-alfresco-social/src/components/like.component.spec.ts b/ng2-components/ng2-alfresco-social/src/components/like.component.spec.ts
new file mode 100644
index 0000000000..4b2e201768
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/like.component.spec.ts
@@ -0,0 +1,208 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
+import { LikeComponent } from '../components/like.component';
+import { DebugElement } from '@angular/core';
+import { CoreModule } from 'ng2-alfresco-core';
+import { RatingService } from '../services/rating.service';
+
+declare let jasmine: any;
+
+describe('Like component', () => {
+
+ let component: any;
+ let fixture: ComponentFixture;
+ let debug: DebugElement;
+ let element: HTMLElement;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ CoreModule.forRoot()
+ ],
+ declarations: [
+ LikeComponent
+ ],
+ providers: [
+ RatingService
+ ]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LikeComponent);
+
+ debug = fixture.debugElement;
+ element = fixture.nativeElement;
+ component = fixture.componentInstance;
+ component.nodeId = 'test-id';
+
+ fixture.detectChanges();
+ });
+
+ describe('Rendering tests', () => {
+
+ beforeEach(() => {
+ jasmine.Ajax.install();
+ });
+
+ afterEach(() => {
+ jasmine.Ajax.uninstall();
+ });
+
+ it('should like component should be present', (done) => {
+ fixture.detectChanges();
+
+ component.ngOnChanges().subscribe(() => {
+ expect(element.querySelector('#adf-like-test-id')).not.toBe(null);
+ done();
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ entry: {
+ id: 'likes',
+ aggregate: {
+ numberOfRatings: 1
+ }
+ }
+ }
+ });
+
+ });
+
+ it('should like component show the number of likes', (done) => {
+ fixture.detectChanges();
+
+ component.ngOnChanges().subscribe(() => {
+ expect(element.querySelector('#adf-like-counter').innerHTML).not.toBe(1);
+ done();
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ entry: {
+ id: 'likes',
+ aggregate: {
+ numberOfRatings: 1
+ }
+ }
+ }
+ });
+ });
+
+ describe('User actions', () => {
+
+ it('should like component update the number of likes when clicked', (done) => {
+ fixture.detectChanges();
+
+ expect(element.querySelector('#adf-like-counter').innerHTML).toBe('0');
+
+ component.ngOnChanges().subscribe(() => {
+ component.changeVote.subscribe(() => {
+ fixture.detectChanges();
+ expect(element.querySelector('#adf-like-counter').innerHTML).toBe('1');
+ });
+
+ let likeButton: any = element.querySelector('#adf-like-test-id');
+ likeButton.click();
+
+ component.changeVote.subscribe(() => {
+ fixture.detectChanges();
+ expect(element.querySelector('#adf-like-counter').innerHTML).toBe('2');
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ 'entry': {
+ 'myRating': true,
+ 'ratedAt': '2017-04-06T15:25:50.305+0000',
+ 'id': 'likes',
+ 'aggregate': {'numberOfRatings': 2}
+ }
+ }
+ });
+
+ done();
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ entry: {
+ id: 'likes',
+ aggregate: {
+ numberOfRatings: 1
+ }
+ }
+ }
+ });
+ });
+
+ it('should like component decrease the number of likes when clicked and is already liked', (done) => {
+ fixture.detectChanges();
+
+ expect(element.querySelector('#adf-like-counter').innerHTML).toBe('0');
+
+ component.ngOnChanges().subscribe(() => {
+ fixture.detectChanges();
+
+ let likeButton: any = element.querySelector('#adf-like-test-id');
+ likeButton.click();
+
+ component.changeVote.subscribe(() => {
+ fixture.detectChanges();
+ expect(element.querySelector('#adf-like-counter').innerHTML).toBe('0');
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 204,
+ contentType: 'json'
+ });
+
+ done();
+ });
+
+ component.changeVote.subscribe(() => {
+ fixture.detectChanges();
+ expect(element.querySelector('#adf-like-counter').innerHTML).toBe('1');
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ 'entry': {
+ 'myRating': true,
+ 'ratedAt': '2017-04-06T15:41:01.851+0000',
+ 'id': 'likes',
+ 'aggregate': {'numberOfRatings': 1}
+ }
+ }
+ });
+ });
+ });
+ });
+});
diff --git a/ng2-components/ng2-alfresco-social/src/components/like.component.ts b/ng2-components/ng2-alfresco-social/src/components/like.component.ts
new file mode 100644
index 0000000000..514488c703
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/like.component.ts
@@ -0,0 +1,80 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { RatingService } from './../services/rating.service';
+
+@Component({
+ selector: 'adf-like',
+ styleUrls: ['./like.component.css'],
+ templateUrl: './like.component.html',
+ providers: [RatingService]
+})
+export class LikeComponent {
+
+ @Input()
+ nodeId: string;
+
+ likesCounter: number = 0;
+
+ ratingType: string = 'likes';
+
+ isLike: boolean = false;
+
+ @Output()
+ changeVote = new EventEmitter();
+
+ constructor(private ratingService: RatingService) {
+ }
+
+ ngOnChanges() {
+ let ratingObserver = this.ratingService.getRating(this.nodeId, this.ratingType);
+
+ ratingObserver.subscribe(
+ (data) => {
+ if (data.entry.aggregate) {
+ this.likesCounter = data.entry.aggregate.numberOfRatings;
+ if (data.entry.ratedAt) {
+ this.isLike = true;
+ }
+ }
+ }
+ );
+
+ return ratingObserver;
+ }
+
+ likeClick() {
+ if (this.isLike) {
+ this.ratingService.deleteRating(this.nodeId, this.ratingType).subscribe(
+ () => {
+ this.likesCounter -= 1;
+ this.isLike = false;
+ }
+ );
+ } else {
+ this.ratingService.postRating(this.nodeId, this.ratingType, true).subscribe(
+ (data) => {
+ this.likesCounter = data.entry.aggregate.numberOfRatings;
+ this.isLike = true;
+ }
+ );
+ }
+
+ this.changeVote.emit(this.likesCounter);
+ }
+}
diff --git a/ng2-components/ng2-alfresco-social/src/components/rating.component.css b/ng2-components/ng2-alfresco-social/src/components/rating.component.css
new file mode 100644
index 0000000000..a240c62f75
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/rating.component.css
@@ -0,0 +1,30 @@
+.adf-rating-container {
+ overflow: hidden;
+ width: 100%;
+}
+
+.adf-rating-star {
+ float: left;
+ transition: all .3s;
+ padding: 1px;
+ cursor: pointer;
+}
+
+.adf-colored-star {
+ color: #ffe944;
+}
+
+.adf-grey-star {
+ color: #808080;
+}
+
+.adf-stars-container {
+ padding: 0!important;
+ margin: 0!important;
+ display: inline-block;
+}
+
+.adf-rating-star:hover {
+ transform: rotate(13deg) scale(1.2);
+}
+
diff --git a/ng2-components/ng2-alfresco-social/src/components/rating.component.html b/ng2-components/ng2-alfresco-social/src/components/rating.component.html
new file mode 100644
index 0000000000..f4e9df056f
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/rating.component.html
@@ -0,0 +1,10 @@
+
+
+ -
+
+ star_rate
+ star_border
+
+
+
+
diff --git a/ng2-components/ng2-alfresco-social/src/components/rating.component.spec.ts b/ng2-components/ng2-alfresco-social/src/components/rating.component.spec.ts
new file mode 100644
index 0000000000..a8a5ecbb64
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/rating.component.spec.ts
@@ -0,0 +1,165 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
+import { RatingComponent } from '../components/rating.component';
+import { DebugElement } from '@angular/core';
+import { CoreModule } from 'ng2-alfresco-core';
+import { RatingService } from '../services/rating.service';
+
+declare let jasmine: any;
+
+describe('Rating component', () => {
+
+ let component: any;
+ let fixture: ComponentFixture;
+ let debug: DebugElement;
+ let element: HTMLElement;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ CoreModule.forRoot()
+ ],
+ declarations: [
+ RatingComponent
+ ],
+ providers: [
+ RatingService
+ ]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RatingComponent);
+
+ debug = fixture.debugElement;
+ element = fixture.nativeElement;
+ component = fixture.componentInstance;
+ component.nodeId = 'test-id';
+
+ fixture.detectChanges();
+ });
+
+ describe('Rendering tests', () => {
+
+ beforeEach(() => {
+ jasmine.Ajax.install();
+ });
+
+ afterEach(() => {
+ jasmine.Ajax.uninstall();
+ });
+
+ it('should rating component should be present', (done) => {
+ fixture.detectChanges();
+
+ component.ngOnChanges().subscribe(() => {
+ expect(element.querySelector('#adf-rating-container')).not.toBe(null);
+ done();
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ entry: {
+ id: 'fiveStar',
+ aggregate: {
+ numberOfRatings: 1,
+ average: 4
+ }
+ }
+ }
+ });
+ });
+
+ it('should the star rating filled with the right grey/colored star', (done) => {
+ fixture.detectChanges();
+
+ component.ngOnChanges().subscribe(() => {
+ fixture.detectChanges();
+
+ expect(element.querySelectorAll('.adf-colored-star').length).toBe(3);
+ expect(element.querySelectorAll('.adf-grey-star').length).toBe(2);
+ done();
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ entry: {
+ id: 'fiveStar',
+ aggregate: {
+ numberOfRatings: 4,
+ average: 3
+ }
+ }
+ }
+ });
+ });
+
+ it('should click on a star change your vote', (done) => {
+ fixture.detectChanges();
+
+ component.ngOnChanges().subscribe(() => {
+ fixture.detectChanges();
+
+ expect(element.querySelectorAll('.adf-colored-star').length).toBe(1);
+
+ component.changeVote.subscribe(() => {
+ fixture.detectChanges();
+
+ expect(element.querySelectorAll('.adf-colored-star').length).toBe(3);
+
+ done();
+ });
+
+ let starThree: any = element.querySelector('#adf-colored-star-3');
+ starThree.click();
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ 'entry': {
+ 'myRating': 3,
+ 'ratedAt': '2017-04-06T14:36:40.731+0000',
+ 'id': 'fiveStar',
+ 'aggregate': {'numberOfRatings': 1, 'average': 3.0}
+ }
+ }
+ });
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ 'entry': {
+ myRating: 1,
+ 'ratedAt': '2017-04-06T14:34:28.061+0000',
+ 'id': 'fiveStar',
+ 'aggregate': {'numberOfRatings': 1, 'average': 1.0}
+ }
+ }
+ });
+ });
+
+ });
+});
diff --git a/ng2-components/ng2-alfresco-social/src/components/rating.component.ts b/ng2-components/ng2-alfresco-social/src/components/rating.component.ts
new file mode 100644
index 0000000000..b1de0c7591
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/components/rating.component.ts
@@ -0,0 +1,85 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { RatingService } from './../services/rating.service';
+
+@Component({
+ selector: 'adf-rating',
+ styleUrls: ['./rating.component.css'],
+ templateUrl: './rating.component.html',
+ providers: [RatingService]
+})
+export class RatingComponent {
+
+ @Input()
+ nodeId: string;
+
+ average: number = 0;
+
+ ratingType: string = 'fiveStar';
+
+ @Output()
+ changeVote = new EventEmitter();
+
+ stars: Array = [];
+
+ constructor(private ratingService: RatingService) {
+ }
+
+ ngOnChanges() {
+ let ratingObserver = this.ratingService.getRating(this.nodeId, this.ratingType);
+
+ ratingObserver.subscribe(
+ (data) => {
+ if (data.entry.aggregate) {
+ this.average = data.entry.aggregate.average;
+ this.calculateStars();
+ }
+ }
+ );
+
+ return ratingObserver;
+ }
+
+ calculateStars() {
+ this.stars = [];
+
+ for (let i = 0; i < 5; i++) {
+ if (i < this.average) {
+ this.stars.push({fill: true});
+ } else {
+ this.stars.push({fill: false});
+ }
+ }
+
+ this.changeVote.emit(this.average);
+ }
+
+ updateVote(vote: number) {
+ this.ratingService.postRating(this.nodeId, this.ratingType, vote).subscribe(
+ (data) => {
+ if (data.entry.aggregate) {
+ if (this.average !== data.entry.aggregate.average) {
+ this.average = data.entry.aggregate.average;
+ this.calculateStars();
+ }
+ }
+ }
+ );
+ }
+}
diff --git a/ng2-components/ng2-alfresco-social/src/services/rating.service.spec.ts b/ng2-components/ng2-alfresco-social/src/services/rating.service.spec.ts
new file mode 100644
index 0000000000..474888cf6c
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/services/rating.service.spec.ts
@@ -0,0 +1,102 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ReflectiveInjector } from '@angular/core';
+import {
+ AlfrescoAuthenticationService,
+ AlfrescoSettingsService,
+ AlfrescoApiService,
+ StorageService,
+ LogService
+} from 'ng2-alfresco-core';
+import { RatingService } from '../services/rating.service';
+
+declare let jasmine: any;
+
+describe('Rating service', () => {
+
+ let service, injector;
+
+ beforeEach(() => {
+ injector = ReflectiveInjector.resolveAndCreate([
+ AlfrescoSettingsService,
+ AlfrescoApiService,
+ AlfrescoAuthenticationService,
+ RatingService,
+ StorageService,
+ LogService
+ ]);
+ });
+
+ beforeEach(() => {
+ service = injector.get(RatingService);
+ });
+
+ beforeEach(() => {
+ jasmine.Ajax.install();
+ });
+
+ afterEach(() => {
+ jasmine.Ajax.uninstall();
+ });
+
+ it('Should get rating return an Observable', (done) => {
+ let ratingType: string = 'fiveStar';
+ let nodeId: string = 'fake-node-id';
+
+ service.getRating(nodeId, ratingType).subscribe((data) => {
+ expect(data.entry.myRating).toBe('1');
+ done();
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ 'entry': {
+ myRating: 1,
+ 'ratedAt': '2017-04-06T14:34:28.061+0000',
+ 'id': 'fiveStar',
+ 'aggregate': {'numberOfRatings': 1, 'average': 1.0}
+ }
+ }
+ });
+ });
+
+ it('Should post rating return an Observable', (done) => {
+ let ratingType: string = 'fiveStar';
+ let nodeId: string = 'fake-node-id';
+
+ service.postRating(nodeId, ratingType, 3).subscribe((data) => {
+ expect(data.entry.myRating).toBe('3');
+ done();
+ });
+
+ jasmine.Ajax.requests.mostRecent().respondWith({
+ status: 200,
+ contentType: 'json',
+ responseText: {
+ 'entry': {
+ 'myRating': 3,
+ 'ratedAt': '2017-04-06T14:36:40.731+0000',
+ 'id': 'fiveStar',
+ 'aggregate': {'numberOfRatings': 1, 'average': 3.0}
+ }
+ }
+ });
+ });
+});
diff --git a/ng2-components/ng2-alfresco-social/src/services/rating.service.ts b/ng2-components/ng2-alfresco-social/src/services/rating.service.ts
new file mode 100644
index 0000000000..9fe4b015d8
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/src/services/rating.service.ts
@@ -0,0 +1,55 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Injectable } from '@angular/core';
+import { Response } from '@angular/http';
+import { Observable } from 'rxjs/Rx';
+import { AlfrescoApiService } from 'ng2-alfresco-core';
+
+@Injectable()
+export class RatingService {
+
+ constructor(private apiService: AlfrescoApiService) {
+ }
+
+ getRating(nodeId: string, ratingType: any): any {
+ return Observable.fromPromise(this.apiService.getInstance().core.ratingsApi.getRating(nodeId, ratingType))
+ .map(res => res)
+ .catch(this.handleError);
+ }
+
+ postRating(nodeId: string, ratingType: string, vote: any): any {
+ let ratingBody = {
+ 'id': ratingType,
+ 'myRating': vote
+ };
+ return Observable.fromPromise(this.apiService.getInstance().core.ratingsApi.rate(nodeId, ratingBody))
+ .map(res => res)
+ .catch(this.handleError);
+ }
+
+ deleteRating(nodeId: string, ratingId: string): any {
+ return Observable.fromPromise(this.apiService.getInstance().core.ratingsApi.removeRating(nodeId, ratingId))
+ .map(res => res)
+ .catch(this.handleError);
+ }
+
+ private handleError(error: Response): any {
+ console.error(error);
+ return Observable.throw(error || 'Server error');
+ }
+}
diff --git a/ng2-components/ng2-alfresco-social/tsconfig.json b/ng2-components/ng2-alfresco-social/tsconfig.json
new file mode 100644
index 0000000000..28919f9cc5
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/tsconfig.json
@@ -0,0 +1,40 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "sourceMap": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "skipLibCheck": true,
+ "noLib": false,
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
+ "noImplicitAny": false,
+ "noImplicitReturns": false,
+ "noImplicitUseStrict": false,
+ "noFallthroughCasesInSwitch": true,
+ "removeComments": true,
+ "declaration": true,
+ "lib": [
+ "es2015",
+ "dom"
+ ],
+ "typeRoots": [
+ "node_modules/@types"
+ ],
+ "suppressImplicitAnyIndexErrors": true
+ },
+ "exclude": [
+ "demo",
+ "node_modules",
+ "dist",
+ "tools",
+ "gulpfile.ts",
+ "gulpfile.d.ts"
+ ],
+ "angularCompilerOptions": {
+ "strictMetadataEmit": false,
+ "skipTemplateCodegen": true
+ }
+}
diff --git a/ng2-components/ng2-alfresco-social/tslint.json b/ng2-components/ng2-alfresco-social/tslint.json
new file mode 100644
index 0000000000..acc666937e
--- /dev/null
+++ b/ng2-components/ng2-alfresco-social/tslint.json
@@ -0,0 +1,121 @@
+{
+ "rules": {
+ "align": [
+ true,
+ "parameters",
+ "statements"
+ ],
+ "ban": false,
+ "class-name": true,
+ "comment-format": [
+ true,
+ "check-space"
+ ],
+ "curly": true,
+ "eofline": true,
+ "forin": true,
+ "indent": [
+ true,
+ "spaces"
+ ],
+ "interface-name": false,
+ "jsdoc-format": true,
+ "label-position": true,
+ "label-undefined": true,
+ "max-line-length": [
+ true,
+ 180
+ ],
+ "member-ordering": [
+ true,
+ "static-before-instance",
+ "variables-before-functions"
+ ],
+ "no-any": false,
+ "no-arg": true,
+ "no-bitwise": false,
+ "no-conditional-assignment": true,
+ "no-consecutive-blank-lines": true,
+ "no-console": [
+ true,
+ "debug",
+ "info",
+ "time",
+ "timeEnd",
+ "trace"
+ ],
+ "no-construct": true,
+ "no-constructor-vars": false,
+ "no-debugger": true,
+ "no-duplicate-key": true,
+ "no-duplicate-variable": true,
+ "no-empty": false,
+ "no-eval": true,
+ "no-inferrable-types": false,
+ "no-internal-module": true,
+ "no-require-imports": false,
+ "no-shadowed-variable": true,
+ "no-switch-case-fall-through": true,
+ "no-trailing-whitespace": true,
+ "no-unreachable": true,
+ "no-unused-expression": true,
+ "no-unused-variable": true,
+ "no-use-before-declare": true,
+ "no-var-keyword": true,
+ "no-var-requires": true,
+ "object-literal-sort-keys": false,
+ "one-line": [
+ true,
+ "check-open-brace",
+ "check-catch",
+ "check-else",
+ "check-whitespace"
+ ],
+ "quotemark": [
+ true,
+ "single",
+ "avoid-escape"
+ ],
+ "radix": true,
+ "semicolon": true,
+ "switch-default": true,
+ "trailing-comma": [
+ true,
+ {
+ "multiline": "never",
+ "singleline": "never"
+ }
+ ],
+ "triple-equals": [
+ true,
+ "allow-null-check"
+ ],
+ "typedef": false,
+ "typedef-whitespace": [
+ true,
+ {
+ "call-signature": "nospace",
+ "index-signature": "nospace",
+ "parameter": "nospace",
+ "property-declaration": "nospace",
+ "variable-declaration": "nospace"
+ }
+ ],
+ "use-strict": false,
+ "variable-name": [
+ true,
+ "check-format",
+ "allow-leading-underscore",
+ "ban-keywords"
+ ],
+ "whitespace": [
+ true,
+ "check-branch",
+ "check-operator",
+ "check-separator",
+ "check-type",
+ "check-module",
+ "check-decl"
+ ]
+ }
+}
diff --git a/scripts/npm-build-all.sh b/scripts/npm-build-all.sh
index 3e76086b1c..0b3369e834 100755
--- a/scripts/npm-build-all.sh
+++ b/scripts/npm-build-all.sh
@@ -15,6 +15,7 @@ eval projects=( "ng2-alfresco-core"
"ng2-alfresco-login"
"ng2-alfresco-search"
"ng2-alfresco-tag"
+ "ng2-alfresco-social"
"ng2-alfresco-upload"
"ng2-alfresco-viewer"
"ng2-alfresco-webscript"
diff --git a/scripts/npm-clean.sh b/scripts/npm-clean.sh
index b91689a2be..b1b50bc6e3 100755
--- a/scripts/npm-clean.sh
+++ b/scripts/npm-clean.sh
@@ -13,6 +13,7 @@ eval projects=( "ng2-activiti-diagrams"
"ng2-alfresco-login"
"ng2-alfresco-search"
"ng2-alfresco-tag"
+ "ng2-alfresco-social"
"ng2-alfresco-upload"
"ng2-alfresco-viewer"
"ng2-alfresco-webscript"
diff --git a/scripts/npm-link-all-components-demo.sh b/scripts/npm-link-all-components-demo.sh
index 6120c96caa..bd27ca4483 100755
--- a/scripts/npm-link-all-components-demo.sh
+++ b/scripts/npm-link-all-components-demo.sh
@@ -21,6 +21,7 @@ for PACKAGE in \
ng2-alfresco-tag \
ng2-alfresco-upload \
ng2-alfresco-viewer \
+ ng2-alfresco-social \
ng2-alfresco-webscript \
ng2-alfresco-userinfo
do
diff --git a/scripts/npm-link-demo-shell.sh b/scripts/npm-link-demo-shell.sh
index b999ab85db..dcdedb110e 100755
--- a/scripts/npm-link-demo-shell.sh
+++ b/scripts/npm-link-demo-shell.sh
@@ -15,6 +15,7 @@ for PACKAGE in \
ng2-alfresco-login \
ng2-alfresco-search \
ng2-alfresco-tag \
+ ng2-alfresco-social \
ng2-alfresco-upload \
ng2-alfresco-viewer \
ng2-alfresco-webscript \
@@ -41,6 +42,7 @@ for PACKAGE in \
ng2-alfresco-login \
ng2-alfresco-search \
ng2-alfresco-tag \
+ ng2-alfresco-social \
ng2-alfresco-upload \
ng2-alfresco-viewer \
ng2-alfresco-webscript \
diff --git a/scripts/npm-publish.sh b/scripts/npm-publish.sh
index c6aa28663b..a8ea1ee0ad 100755
--- a/scripts/npm-publish.sh
+++ b/scripts/npm-publish.sh
@@ -16,6 +16,7 @@ for PACKAGE in \
ng2-alfresco-login \
ng2-alfresco-search \
ng2-alfresco-tag \
+ ng2-alfresco-social \
ng2-alfresco-upload \
ng2-alfresco-viewer \
ng2-alfresco-webscript \
diff --git a/scripts/update-version.sh b/scripts/update-version.sh
index c59aa6d4ad..68a11b8c01 100755
--- a/scripts/update-version.sh
+++ b/scripts/update-version.sh
@@ -14,45 +14,32 @@ then
exit 1
fi
-for PACKAGE in \
- ng2-activiti-diagrams \
- ng2-activiti-analytics \
- ng2-activiti-form \
- ng2-activiti-processlist \
- ng2-activiti-tasklist \
- ng2-alfresco-core \
- ng2-alfresco-datatable \
- ng2-alfresco-documentlist \
- ng2-alfresco-login \
- ng2-alfresco-search \
- ng2-alfresco-tag \
- ng2-alfresco-upload \
- ng2-alfresco-viewer \
- ng2-alfresco-webscript \
- ng2-alfresco-userinfo \
- alfresco-js-api
+eval projects=( "ng2-alfresco-core"
+ "ng2-alfresco-datatable"
+ "ng2-activiti-diagrams"
+ "ng2-activiti-analytics"
+ "ng2-activiti-form"
+ "ng2-activiti-tasklist"
+ "ng2-activiti-processlist"
+ "ng2-alfresco-documentlist"
+ "ng2-alfresco-login"
+ "ng2-alfresco-search"
+ "ng2-alfresco-tag"
+ "ng2-alfresco-social"
+ "ng2-alfresco-upload"
+ "ng2-alfresco-viewer"
+ "ng2-alfresco-webscript"
+ "ng2-alfresco-userinfo"
+ "alfresco-js-api" )
+
+for PACKAGE in ${projects[@]}
do
DESTDIR="$DIR/../ng2-components/${PACKAGE}"
echo "====== UPDATE PACKAGE VERSION of ${PACKAGE} to ${VERSION} version in all the package.json ======"
find ././../ -type f -maxdepth 4 -name package.json -print0 | xargs -0 sed -i '' "s/\"${PACKAGE}\": \"[0-9]\\.[0-9]\\.[0-9]\"/\"${PACKAGE}\": \"${VERSION}\"/g"
done
-for PACKAGE in \
- ng2-activiti-diagrams \
- ng2-activiti-analytics \
- ng2-activiti-form \
- ng2-activiti-processlist \
- ng2-activiti-tasklist \
- ng2-alfresco-core \
- ng2-alfresco-datatable \
- ng2-alfresco-documentlist \
- ng2-alfresco-login \
- ng2-alfresco-search \
- ng2-alfresco-tag \
- ng2-alfresco-upload \
- ng2-alfresco-viewer \
- ng2-alfresco-webscript \
- ng2-alfresco-userinfo
+for PACKAGE in ${projects[@]}
do
DESTDIR="$DIR/../ng2-components/${PACKAGE}"
echo "====== UPDATE VERSION OF ${PACKAGE} to ${VERSION} version ======"
@@ -63,45 +50,14 @@ echo "====== UPDATE VERSION OF DEMO-SHELL to ${VERSION} version ======"
sed -i '' "s/\"version\": \"[0-9]\\.[0-9]\\.[0-9]\"/\"version\": \"${VERSION}\"/g" ${DIR}/../demo-shell-ng2/package.json
-for PACKAGE in \
- ng2-activiti-diagrams \
- ng2-activiti-analytics \
- ng2-activiti-form \
- ng2-activiti-processlist \
- ng2-activiti-tasklist \
- ng2-alfresco-core \
- ng2-alfresco-datatable \
- ng2-alfresco-documentlist \
- ng2-alfresco-login \
- ng2-alfresco-search \
- ng2-alfresco-tag \
- ng2-alfresco-upload \
- ng2-alfresco-viewer \
- ng2-alfresco-webscript \
- ng2-alfresco-userinfo \
- alfresco-js-api
+for PACKAGE in ${projects[@]}
do
DESTDIR="$DIR/../ng2-components/${PACKAGE}"
echo "====== UPDATE PACKAGE VERSION of ${PACKAGE} to ~${VERSION} version in all the package.json ======"
find ././../ -type f -maxdepth 4 -name package.json -print0 | xargs -0 sed -i '' "s/\"${PACKAGE}\": \"~[0-9]\\.[0-9]\\.[0-9]\"/\"${PACKAGE}\": \"~${VERSION}\"/g"
done
-for PACKAGE in \
- ng2-activiti-diagrams \
- ng2-activiti-analytics \
- ng2-activiti-form \
- ng2-activiti-processlist \
- ng2-activiti-tasklist \
- ng2-alfresco-core \
- ng2-alfresco-datatable \
- ng2-alfresco-documentlist \
- ng2-alfresco-login \
- ng2-alfresco-search \
- ng2-alfresco-tag \
- ng2-alfresco-upload \
- ng2-alfresco-viewer \
- ng2-alfresco-webscript \
- ng2-alfresco-userinfo
+for PACKAGE in ${projects[@]}
do
DESTDIR="$DIR/../ng2-components/${PACKAGE}"
echo "====== UPDATE VERSION OF ${PACKAGE} to ~${VERSION} version ======"