diff --git a/demo-shell-ng2/app/components/patients/createpatient.component.css b/demo-shell-ng2/app/components/patients/createpatient.component.css
new file mode 100644
index 0000000000..81e07b0891
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/createpatient.component.css
@@ -0,0 +1,49 @@
+.upload-border {
+ position: relative;
+ height: 200px;
+ width: 200px;
+ padding: 5px 5px
+}
+
+.drag-area {
+ width: 200px;
+ height: 100px;
+ border: 1px solid #888888;
+}
+
+.image-cell{
+ width: 100px;
+ height: 100px;
+ border-radius: 50px;
+ text-align: center;
+ position: absolute;
+ top: 0;
+ margin-left: -50px;
+ border: 3px #1c597f solid;
+ z-index: 99;
+ margin-top: 45px;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+.container-title-details{
+ background-color: #1c597f;
+ color: #ffffff;
+}
+
+.title-details {
+ margin: auto;
+ text-align: center;
+}
+
+.user-image-wrap{
+ background-color: #1c597f;
+ text-align: center;
+ height: 60px;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+.upload-photo-button{
+ text-align: center;
+ height: 50px;
+ margin-top: 35px;
+}
diff --git a/demo-shell-ng2/app/components/patients/createpatient.component.html b/demo-shell-ng2/app/components/patients/createpatient.component.html
new file mode 100644
index 0000000000..ef8febbf9f
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/createpatient.component.html
@@ -0,0 +1,20 @@
+
+
Create Patient
+
+
+

+
+
+
diff --git a/demo-shell-ng2/app/components/patients/createpatient.component.ts b/demo-shell-ng2/app/components/patients/createpatient.component.ts
new file mode 100644
index 0000000000..91105cb242
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/createpatient.component.ts
@@ -0,0 +1,101 @@
+/*!
+ * @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';
+import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
+import { FormService, ActivitiForm } from 'ng2-activiti-form';
+import { Router } from '@angular/router';
+import { NotificationService } from '../../services/notification.service';
+import { ALFRESCO_ULPOAD_COMPONENTS } from 'ng2-alfresco-upload';
+
+declare let __moduleName: string;
+declare let AlfrescoApi: any;
+
+@Component({
+ moduleId: __moduleName,
+ selector: 'createpatient-component',
+ templateUrl: './createpatient.component.html',
+ styleUrls: ['./createpatient.component.css'],
+ providers: [FormService],
+ directives: [ALFRESCO_ULPOAD_COMPONENTS, ActivitiForm]
+})
+export class CreatePatientComponent {
+
+ currentPath: string = '/Sites/swsdp/documentLibrary';
+
+ metadata: any = {};
+
+ photoNode: string = "";
+
+ imgSrc: string = "app/img/anonymous.gif";
+
+ constructor(private authService: AlfrescoAuthenticationService, private router: Router,
+ private notificationService: NotificationService,
+ private alfrescoSettingsService: AlfrescoSettingsService) {
+ }
+
+ public fileUploaded(data) {
+ if (data && data.value) {
+ this.photoNode = data.value.entry.id;
+ this.imgSrc = this.alfrescoSettingsService.ecmHost + '/alfresco/api/-default-/public/alfresco/versions/1/nodes/' + data.value.entry.id + '/content?attachment=false';
+ console.log(this.photoNode);
+ }
+ }
+
+ saveMetadata(data: any) {
+ let name = '';
+ if (!this.photoNode) {
+ name = this.generateUuid();
+ } else {
+ name = this.photoNode;
+ }
+
+ let body = {
+ name: name,
+ nodeType: 'hc:patientFolder',
+ properties: {},
+ relativePath: this.currentPath
+ };
+
+ for (var key in data) {
+ if (data[key]) {
+ body.properties['hc:' + key] = data[key];
+ }
+ }
+ let opts = {};
+
+ let self = this;
+ this.authService.getAlfrescoApi().nodes.addNode('-root-', body, opts).then(
+ (data) => {
+ console.log('The folder created', data);
+ self.router.navigate(['/patients']);
+ this.notificationService.sendNotification('User Created');
+ },
+ (err) => {
+ window.alert('See console output for error details');
+ console.log(err);
+ }
+ );
+ }
+
+ private generateUuid() {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+ return v.toString(16);
+ });
+ }
+}
diff --git a/demo-shell-ng2/app/components/patients/patient.model.ts b/demo-shell-ng2/app/components/patients/patient.model.ts
new file mode 100644
index 0000000000..5832c4db27
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/patient.model.ts
@@ -0,0 +1,23 @@
+/*!
+ * @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.
+ */
+
+export class PatientModel {
+ folderName: string;
+ firstName: string;
+ lastName: string;
+ doctor: string;
+}
diff --git a/demo-shell-ng2/app/components/patients/patientdetails.component.css b/demo-shell-ng2/app/components/patients/patientdetails.component.css
new file mode 100644
index 0000000000..45c649042c
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/patientdetails.component.css
@@ -0,0 +1,30 @@
+.image-cell{
+ width: 100px;
+ height: 100px;
+ border-radius: 50px;
+ text-align: center;
+ position: absolute;
+ top: 0;
+ margin-left: -50px;
+ border: 3px #1c597f solid;
+ z-index: 99;
+ margin-top: 45px;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+.container-title-details{
+ background-color: #1c597f;
+ color: #ffffff;
+}
+
+.title-details {
+ margin: auto;
+ text-align: center;
+}
+
+.user-image-wrap{
+ background-color: #1c597f;
+ text-align: center;
+ height: 60px;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
diff --git a/demo-shell-ng2/app/components/patients/patientdetails.component.html b/demo-shell-ng2/app/components/patients/patientdetails.component.html
new file mode 100644
index 0000000000..082592d564
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/patientdetails.component.html
@@ -0,0 +1,14 @@
+
+
Patient Details
+
+
+

+
+
+
diff --git a/demo-shell-ng2/app/components/patients/patientdetails.component.ts b/demo-shell-ng2/app/components/patients/patientdetails.component.ts
new file mode 100644
index 0000000000..740fc645ca
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/patientdetails.component.ts
@@ -0,0 +1,82 @@
+/*!
+ * @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, OnInit, OnDestroy } from '@angular/core';
+import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
+import { FormService, ActivitiForm } from 'ng2-activiti-form';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Subscription } from 'rxjs/Rx';
+
+declare let __moduleName: string;
+declare let AlfrescoApi: any;
+
+@Component({
+ moduleId: __moduleName,
+ selector: 'patient-details',
+ templateUrl: './patientdetails.component.html',
+ styleUrls: ['./patientdetails.component.css'],
+ providers: [FormService],
+ directives: [ActivitiForm]
+})
+export class PatientDetailsComponent implements OnInit, OnDestroy {
+
+ private sub: Subscription;
+
+ currentPath: string = '/Sites/swsdp/documentLibrary';
+
+ metadata: any = {};
+
+ nodeId: string;
+
+ photoNodeId: string;
+
+ ticket: string = localStorage.getItem('ticket-ECM');
+
+ constructor(private route: ActivatedRoute,
+ private router: Router,
+ private authService: AlfrescoAuthenticationService,
+ public alfrescoSettingsService: AlfrescoSettingsService) {
+ }
+
+ ngOnInit() {
+ this.sub = this.route.params.subscribe(params => {
+ this.retriveNodeMetadataFromEcm(params['id']);
+ });
+ }
+
+ ngOnDestroy() {
+ if (this.sub) {
+ this.sub.unsubscribe();
+ }
+ }
+
+ private retriveNodeMetadataFromEcm(nodeId: string): void{
+ var self = this;
+ this.nodeId = nodeId;
+ this.authService.getAlfrescoApi().nodes.getNodeInfo(this.nodeId).then(function (data) {
+ console.log(data.properties);
+ self.photoNodeId = data.name;
+ for (var key in data.properties) {
+ console.log(key + ' => ' + data[key]);
+ self.metadata [key.replace('hc:','')] = data.properties[key];
+ }
+
+ }, function (error) {
+ console.log('This node does not exist');
+ });
+ }
+}
diff --git a/demo-shell-ng2/app/components/patients/patients.component.css b/demo-shell-ng2/app/components/patients/patients.component.css
new file mode 100644
index 0000000000..73ef4cae95
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/patients.component.css
@@ -0,0 +1,72 @@
+.container {
+ /*margin: 10px;*/
+}
+
+@media only screen and (max-width: 640px) {
+ .container {
+ margin: 0;
+ }
+}
+
+.patients-debug-container {
+ padding: 10px;
+}
+
+.patients-debug-container .debug-toggle-text {
+ padding-left: 15px;
+ cursor: pointer;
+}
+
+.patients-debug-container .debug-toggle-text:hover {
+ font-weight: bold;
+}
+
+alfresco-document-list >>> .image-cell {
+ width: 50px;
+ height: 50px;
+ cursor: default;
+ border: 2px solid #aaaaaa;
+ border-radius: 30px;
+}
+
+alfresco-document-list >>> .mdl-data-table {
+ border: 0px;
+}
+
+.image-cell{
+ background-color: #ffffff;
+ width: 100px;
+ height: 100px;
+ border-radius: 50px;
+ text-align: center;
+ position: absolute;
+ top: 17px;
+ margin-left: -50px;
+ border: 3px #1c597f solid;
+ z-index: 99;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+.container-title-details{
+ background-color: #1c597f;
+ color: #ffffff;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+.title-details {
+ margin: auto;
+ text-align: center;
+}
+
+.user-image-wrap{
+ background-color: #1c597f;
+ text-align: center;
+ height: 64px;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+@media only screen and (max-width: 840px) {
+ #tags {
+ width: 100%;
+ }
+}
diff --git a/demo-shell-ng2/app/components/patients/patients.component.html b/demo-shell-ng2/app/components/patients/patients.component.html
new file mode 100644
index 0000000000..d556a1ddee
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/patients.component.html
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
No patient data available.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+ -
+
+ {{prop.name}}
+ {{prop.value}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo-shell-ng2/app/components/patients/patients.component.ts b/demo-shell-ng2/app/components/patients/patients.component.ts
new file mode 100644
index 0000000000..dc29fbcb76
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/patients.component.ts
@@ -0,0 +1,402 @@
+/*!
+ * @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, OnInit, ViewChild, ChildNode } from '@angular/core';
+import { Router } from '@angular/router';
+import {
+ PaginationComponent,
+ DataColumn,
+ DataRow,
+ ObjectDataColumn
+} from 'ng2-alfresco-datatable';
+import {
+ DOCUMENT_LIST_DIRECTIVES,
+ DOCUMENT_LIST_PROVIDERS,
+ DocumentList,
+ ShareDataRow,
+ RowFilter,
+ MinimalNodeEntity,
+ ImageResolver
+} from 'ng2-alfresco-documentlist';
+import {
+ MDL,
+ AlfrescoContentService,
+ CONTEXT_MENU_DIRECTIVES,
+ AlfrescoPipeTranslate,
+ AlfrescoSettingsService
+} from 'ng2-alfresco-core';
+import { ALFRESCO_ULPOAD_COMPONENTS } from 'ng2-alfresco-upload';
+import { VIEWERCOMPONENT } from 'ng2-alfresco-viewer';
+import { FormService } from 'ng2-activiti-form';
+import { PatientModel } from './patient.model';
+import { TagModel, TagCache, TagFilter } from './tag.model';
+import { TagService } from './tag.service';
+
+declare let __moduleName: string;
+
+@Component({
+ moduleId: __moduleName,
+ selector: 'patients-component',
+ templateUrl: './patients.component.html',
+ styleUrls: ['./patients.component.css'],
+ directives: [
+ DOCUMENT_LIST_DIRECTIVES,
+ MDL,
+ ALFRESCO_ULPOAD_COMPONENTS,
+ VIEWERCOMPONENT,
+ CONTEXT_MENU_DIRECTIVES,
+ PaginationComponent
+ ],
+ providers: [DOCUMENT_LIST_PROVIDERS, FormService, TagService],
+ pipes: [AlfrescoPipeTranslate]
+})
+export class PatientsComponent implements OnInit {
+
+ private DEFAULT_PATH: string = '/Sites/swsdp/documentLibrary';
+
+ currentPath: string = this.DEFAULT_PATH;
+
+ urlFile: string;
+ fileName: string;
+ mimeType: string;
+ fileShowed: boolean = false;
+
+ acceptedFilesType: string = '.jpg,.pdf,.js';
+
+ @ViewChild(DocumentList)
+ documentList: DocumentList;
+
+ newPatient: PatientModel;
+ debugMode: boolean = false;
+
+ tags: TagCache = {};
+ tagFilters: TagFilter[] = [];
+ selectedNode: MinimalNodeEntity;
+ selectedNodeProperties: NodePropertyModel[] = [];
+ selectedNodePropertiesName: string;
+ tagFilter: RowFilter;
+ folderImageResolver: ImageResolver;
+ ticket: string = localStorage.getItem('ticket-ECM');
+ ecmHost: string;
+ detailsAvatarImage: string;
+ isVisitFolder: boolean = false;
+ private patientLayout: DataColumn[] = [];
+ private fileLayout: DataColumn[] = [];
+ emptyimgSrc: string = "app/img/anonymous.gif";
+
+ constructor(private contentService: AlfrescoContentService,
+ private router: Router,
+ private tagService: TagService,
+ private alfrescoSettingsService: AlfrescoSettingsService) {
+ this.newPatient = new PatientModel();
+ this.ecmHost = alfrescoSettingsService.ecmHost;
+ this.tagFilter = (row: ShareDataRow) => {
+ let selectedTags = this.tagFilters
+ .filter(f => f.isSelected)
+ .map(f => f.id);
+
+ if (selectedTags.length > 0) {
+ let properties = row.node.entry.properties;
+ if (properties) {
+ let tags = properties['cm:taggable'];
+ if (tags && tags instanceof Array && tags.length > 0) {
+
+ let result = false;
+
+ for (let i = 0; i < selectedTags.length; i++) {
+ if (tags.indexOf(selectedTags[i]) > -1) {
+ result = true;
+ break;
+ }
+ }
+
+ return result;
+ }
+ }
+ return false;
+ }
+
+ return true;
+ };
+
+ this.folderImageResolver = (row: DataRow, col: DataColumn) => {
+ let isFolder = row.getValue('isFolder');
+ if (isFolder) {
+ let value = row.getValue(col.key);
+ return this.alfrescoSettingsService.ecmHost + `/alfresco/api/-default-/public/alfresco/versions/1/nodes/` +
+ value + '/content?attachment=false&alf_ticket=' + this.ticket;
+ }
+ return null;
+ };
+
+ this.patientLayout = this.getPatientLayout();
+ this.fileLayout = this.getFileLayout();
+ }
+
+ isAdmin() {
+ if (localStorage.getItem(`username`) === 'admin') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ resetFilters() {
+ if (this.tagFilters && this.tagFilters.length > 0) {
+ this.tagFilters.map(f => f.isSelected = false);
+ this.documentList.reload();
+ }
+ }
+
+ patientDetails(event: any) {
+ this.router.navigate(['/patientdetails', event.value.entry.id]);
+ }
+
+ showFile(event) {
+ if (event.value.entry.isFile) {
+ this.fileName = event.value.entry.name;
+ this.mimeType = event.value.entry.content.mimeType;
+ this.urlFile = this.contentService.getContentUrl(event.value);
+ this.fileShowed = true;
+ } else {
+ this.fileShowed = false;
+ }
+ }
+
+ onFolderChanged(event?: any) {
+ if (event) {
+ this.selectedNode = null;
+ this.selectedNodeProperties = null;
+
+
+ this.currentPath = event.path;
+ this.loadTags();
+ if (this.currentPath === this.DEFAULT_PATH) {
+ this.folderImageResolver = (row: DataRow, col: DataColumn) => {
+ let isFolder = row.getValue('isFolder');
+ if (isFolder) {
+ let value = row.getValue(col.key);
+ return this.alfrescoSettingsService.ecmHost + `/alfresco/api/-default-/public/alfresco/versions/1/nodes/` +
+ value + '/content?attachment=false&alf_ticket=' + this.ticket;
+ }
+ return null;
+ };
+ this.documentList.data.setColumns(this.patientLayout);
+ this.isVisitFolder = false;
+ } else {
+ this.documentList.data.setColumns(this.fileLayout);
+ this.folderImageResolver = (row: DataRow, col: DataColumn) => {
+ return 'app/img/checklist.svg';
+ };
+ this.isVisitFolder = true;
+ }
+ }
+ }
+
+ ngOnInit() {
+ // this.loadTags();
+ }
+
+ onNodeClicked(event?: any) {
+ console.log(event);
+ if (event && event.value) {
+ this.selectedNodeProperties = null;
+ this.selectedNode = event.value;
+ this.selectedNodePropertiesName = event.value.entry.name;
+ if(this.isVisitFolder){
+ this.detailsAvatarImage = 'app/img/checklist.svg';
+ }else{
+ this.detailsAvatarImage = this.ecmHost + '/alfresco/api/-default-/public/alfresco/versions/1/nodes/' + this.selectedNodePropertiesName + '/content?attachment=false&alf_ticket=' + this.ticket;
+ }
+ if (this.selectedNode) {
+ this.selectedNodeProperties = this.getNodeProperties(this.selectedNode);
+ console.log(this.selectedNodeProperties);
+ }
+ }
+ }
+
+ onFilterChanged(event) {
+ setTimeout(() => {
+ this.documentList.reload();
+ }, 500);
+ }
+
+ addTag(event){
+ let self = this;
+ let nodeId = event.value.entry.id;
+ let dialog = document.querySelector('dialog');
+ if (! dialog.showModal) {
+ dialogPolyfill.registerDialog(dialog);
+ }
+ dialog.showModal();
+ dialog.querySelector('.close').addEventListener('click', function() {
+ dialog.close();
+ });
+ dialog.querySelector('.save').addEventListener('click', function() {
+ self.setNodeTags(nodeId, dialog.querySelector('#node-tags').value);
+ dialog.close();
+ });
+ }
+
+ setNodeTags(nodeId: string, value: string) {
+ if (nodeId && value) {
+ let tags = value.split(',').map(val => {
+ return {
+ tag: val.trim()
+ }
+ });
+
+ this.tagService.addTags(nodeId, tags).then(
+ data => {
+ console.log(data);
+ // TODO: share seems to have issues with returning newly created tags
+ // it sometimes takes several seconds for changes to global tags to propagate
+ // and become visible
+ /*
+ this.getTags().then(
+ res => {
+ console.log('after tags updated');
+ console.log(res);
+ this.tags = res || [];
+ this.documentList.reload();
+ },
+ this.handleError
+ );
+ */
+ },
+ this.handleError
+ );
+ }
+ }
+
+
+ scheduleAppointment(event?: any) {
+ this.router.navigate(['/startvisit', event.value.entry.id]);
+ }
+
+ private getNodeProperties(node: MinimalNodeEntity): NodePropertyModel[] {
+ let result = [];
+
+ if (node && node.entry && node.entry.properties) {
+ let props = node.entry.properties;
+ Object.keys(props).forEach(key => {
+ result.push(new NodePropertyModel(key, props[key]));
+ });
+ }
+
+ return result;
+ }
+
+ private loadTags() {
+ this.tagService.getTags().then(
+ (tags: TagModel[]) => {
+ this.tagFilters = tags.map((tag) => new TagFilter(tag.id, tag.tag));
+ tags.forEach(tag => this.tags[tag.id] = tag);
+ },
+ this.handleError
+ );
+ }
+
+ private handleError(err) {
+ console.log(err);
+ }
+
+ private getPatientLayout(): DataColumn[] {
+ return [
+ new ObjectDataColumn({
+ key: 'name',
+ type: 'image'
+ }),
+ new ObjectDataColumn({
+ title: 'First Name',
+ key: 'properties.hc:firstName',
+ sortable: true,
+ cssClass: 'desktop-only'
+ }),
+ new ObjectDataColumn({
+ title: 'Last Name',
+ key: 'properties.hc:lastName',
+ sortable: true,
+ cssClass: 'desktop-only'
+ }),
+ new ObjectDataColumn({
+ title: 'Doctor',
+ key: 'properties.hc:doctor',
+ sortable: true,
+ cssClass: 'desktop-only'
+ }),
+ new ObjectDataColumn({
+ title: 'Created On',
+ key: 'createdAt',
+ type: 'date',
+ format: 'shortDate',
+ sortable: true,
+ cssClass: 'desktop-only'
+ })
+ ];
+ }
+
+ private getFileLayout(): DataColumn[] {
+ return [
+ new ObjectDataColumn({
+ key: '$thumbnail',
+ type: 'image'
+ }),
+ new ObjectDataColumn({
+ title: 'Display Name',
+ key: 'name',
+ sortable: true,
+ cssClass: 'full-width ellipsis-cell'
+ }),
+ new ObjectDataColumn({
+ title: 'Created By',
+ key: 'createdByUser.displayName',
+ sortable: true,
+ cssClass: 'desktop-only'
+ }),
+ new ObjectDataColumn({
+ title: 'Created On',
+ key: 'createdAt',
+ type: 'date',
+ format: 'shortDate',
+ sortable: true,
+ cssClass: 'desktop-only'
+ })
+ ];
+ }
+}
+
+class NodePropertyModel {
+
+ prefix: string;
+ name: string;
+ value: string;
+ fullName: string;
+
+ constructor(name: string, value: string) {
+ this.fullName = name;
+ this.name = name;
+ if (name) {
+ let idx = name.indexOf(':');
+ if (idx > -1) {
+ this.prefix = name.substring(0, idx);
+ this.name = name.substring(idx + 1);
+ }
+ }
+ this.value = value;
+ }
+}
diff --git a/demo-shell-ng2/app/components/patients/tag.model.ts b/demo-shell-ng2/app/components/patients/tag.model.ts
new file mode 100644
index 0000000000..22bffb5181
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/tag.model.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.
+ */
+
+export class TagModel {
+ id: string;
+ tag: string;
+
+ constructor(id: string, tag: string) {
+ this.id = id;
+ this.tag = tag;
+ }
+}
+
+export interface TagCache {
+ [key: string]: TagModel;
+}
+
+export class TagFilter extends TagModel {
+ count: number = 0;
+ isSelected: boolean = false;
+
+ constructor(id: string, tag: string) {
+ super(id, tag);
+ }
+}
diff --git a/demo-shell-ng2/app/components/patients/tag.service.ts b/demo-shell-ng2/app/components/patients/tag.service.ts
new file mode 100644
index 0000000000..21b50da699
--- /dev/null
+++ b/demo-shell-ng2/app/components/patients/tag.service.ts
@@ -0,0 +1,49 @@
+/*!
+ * @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 { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
+import { TagModel } from './tag.model';
+
+@Injectable()
+export class TagService {
+
+ constructor(private authService: AlfrescoAuthenticationService) {}
+
+ getTags(): Promise {
+ return new Promise((resolve, reject) => {
+ this.authService.getAlfrescoApi().core.tagsApi.getTags({}).then(
+ data => {
+ let entries = data.list.entries || [];
+ let tags = entries.map(obj => obj.entry);
+ resolve(tags);
+ },
+ err => reject(err)
+ );
+ });
+ }
+
+ addTags(nodeId: string, tags: { tag: string }[]): Promise {
+ return new Promise((resolve, reject) => {
+ this.authService.getAlfrescoApi().core.tagsApi.addTag(nodeId, tags).then(
+ data => resolve(data),
+ err => reject(err)
+ );
+ });
+ }
+
+}
diff --git a/demo-shell-ng2/app/components/visit/process.data.ts b/demo-shell-ng2/app/components/visit/process.data.ts
new file mode 100644
index 0000000000..d5049424fb
--- /dev/null
+++ b/demo-shell-ng2/app/components/visit/process.data.ts
@@ -0,0 +1,12 @@
+export interface Process {
+ category: string;
+ deploymentId: string;
+ description: string;
+ hasStartForm: boolean;
+ id: string;
+ key: string;
+ name: string;
+ tenantId: string;
+ version: number;
+ metaDataValues: any[];
+}
diff --git a/demo-shell-ng2/app/components/visit/process.service.ts b/demo-shell-ng2/app/components/visit/process.service.ts
new file mode 100644
index 0000000000..6d807f825a
--- /dev/null
+++ b/demo-shell-ng2/app/components/visit/process.service.ts
@@ -0,0 +1,121 @@
+/*!
+ * @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, Http, Headers, RequestOptions } from '@angular/http';
+import { Observable } from 'rxjs/Observable';
+import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
+
+import { Process } from './process.data';
+
+
+@Injectable()
+export class ProcessService {
+
+ constructor(private http: Http,
+ private authService: AlfrescoAuthenticationService,
+ private alfrescoSettingsService: AlfrescoSettingsService) {
+ }
+
+ getDeployedApplications(name: string): Observable {
+ let url = `${this.alfrescoSettingsService.bpmHost}/activiti-app/api/enterprise/runtime-app-definitions`;
+ let options = this.getRequestOptions();
+ return this.http
+ .get(url, options)
+ .map((response: Response) => response.json().data.find(p => p.name === name))
+ .do(data => console.log('Application: ' + JSON.stringify(data)))
+ .catch(this.handleError);
+ }
+
+
+ getProcessDefinitions(): Observable {
+ let url = `${this.alfrescoSettingsService.bpmHost}/activiti-app/api/enterprise/process-definitions`;
+ let options = this.getRequestOptions();
+ return this.http
+ .get(url, options)
+ .map((response: Response) => response.json())
+ .do(data => console.log('All: ' + JSON.stringify(data)))
+ .catch(this.handleError);
+ }
+
+ getProcessDefinitionByApplication(application: any): Observable {
+ return this.getProcessDefinitions()
+ .map((processes: Process[]) => processes.data.find(p => p.deploymentId === application.deploymentId));
+ }
+
+ getStartFormForProcess(processDefinitionId: string): Observable {
+ let url = `${this.alfrescoSettingsService.bpmHost}/activiti-app/api/enterprise/process-definitions/${processDefinitionId}/start-form`;
+ let options = this.getRequestOptions();
+ return this.http
+ .get(url, options)
+ .map((response: Response) => response.json())
+ .catch(this.handleError);
+ }
+
+ startProcessByID(processDefinitionId: string, processName: string): void {
+ let url = `${this.alfrescoSettingsService.bpmHost}/activiti-app/api/enterprise/process-instances`;
+ let options = this.getRequestOptions();
+ let body = JSON.stringify({processDefinitionId: processDefinitionId, name: processName});
+ console.log(body);
+ return this.http
+ .post(url, body, options)
+ .map(this.toJson)
+ .catch(this.handleError);
+ }
+
+ getTaskIdFromProcessID(processDefinitionId: string, appDefinitionId: string, processInstanceId: string): Observable {
+ let url = `${this.alfrescoSettingsService.bpmHost}/activiti-app/api/enterprise/tasks/query`;
+ let options = this.getRequestOptions();
+ let body = JSON.stringify({
+ processDefinitionId: processDefinitionId,
+ appDefinitionId: appDefinitionId,
+ processInstanceId: processInstanceId
+ });
+ console.log(body);
+ return this.http
+ .post(url, body, options)
+ .map(this.toJson)
+ .catch(this.handleError);
+ }
+
+
+ private getHeaders(): Headers {
+ return new Headers({
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ 'Authorization': this.authService.getTicket('BPM')
+ });
+ }
+
+ private getRequestOptions(): RequestOptions {
+ let headers = this.getHeaders();
+ return new RequestOptions({headers: headers});
+ }
+
+ private toJson(res: Response) {
+ let body = res.json();
+ return body || {};
+ }
+
+ private handleError(error: any) {
+ console.log("ERROR");
+ let errMsg = (error.message) ? error.message :
+ error.status ? `${error.status} - ${error.statusText}` : 'Server error';
+ console.error(errMsg);
+ return Observable.throw(errMsg);
+ }
+}
diff --git a/demo-shell-ng2/app/components/visit/start-visit.component.css b/demo-shell-ng2/app/components/visit/start-visit.component.css
new file mode 100644
index 0000000000..69a8081965
--- /dev/null
+++ b/demo-shell-ng2/app/components/visit/start-visit.component.css
@@ -0,0 +1,39 @@
+.image-cell{
+ width: 100px;
+ height: 100px;
+ border-radius: 50px;
+ text-align: center;
+ position: absolute;
+ top: 0;
+ margin-left: -50px;
+ border: 3px #1c597f solid;
+ z-index: 99;
+ margin-top: 45px;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+.container-title-details{
+ background-color: #1c597f;
+ color: #ffffff;
+}
+
+.title-details {
+ margin: auto;
+ text-align: center;
+}
+
+.user-image-wrap{
+ background-color: #1c597f;
+ text-align: center;
+ height: 60px;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+}
+
+.upload-photo-button{
+ text-align: center;
+ height: 50px;
+ margin-top: 35px;
+}
+.wrap-form{
+ margin-top: 35px;
+}
diff --git a/demo-shell-ng2/app/components/visit/start-visit.component.html b/demo-shell-ng2/app/components/visit/start-visit.component.html
new file mode 100644
index 0000000000..35776643a7
--- /dev/null
+++ b/demo-shell-ng2/app/components/visit/start-visit.component.html
@@ -0,0 +1,10 @@
+
+
Schedule Appointment
+
+
+

+
+
diff --git a/demo-shell-ng2/app/components/visit/start-visit.component.ts b/demo-shell-ng2/app/components/visit/start-visit.component.ts
new file mode 100644
index 0000000000..bcdbc92aa3
--- /dev/null
+++ b/demo-shell-ng2/app/components/visit/start-visit.component.ts
@@ -0,0 +1,134 @@
+/*!
+ * @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';
+import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Subscription } from 'rxjs/Rx';
+import { ProcessService } from './process.service';
+import { Process } from './process.data';
+
+import { FormService, ActivitiForm } from 'ng2-activiti-form';
+import { NotificationService } from '../../services/notification.service';
+
+declare let __moduleName: string;
+declare let AlfrescoApi: any;
+
+@Component({
+ moduleId: __moduleName,
+ selector: 'start-visit-component',
+ templateUrl: './start-visit.component.html',
+ styleUrls: ['./start-visit.component.css'],
+ providers: [ProcessService, FormService],
+ directives: [ActivitiForm]
+})
+
+export class StartVisitComponent {
+
+ private sub: Subscription;
+
+ currentPath: string = '/Sites/swsdp/documentLibrary';
+
+ metadata: any = {};
+
+ nodeId: string;
+
+ nodeName: string;
+
+ errorMessage: string;
+
+ processName: string = "TEST";
+
+ process: Process;
+
+ taskId: string;
+
+ constructor(private route: ActivatedRoute,
+ private router: Router,
+ private processService: ProcessService,
+ private authService: AlfrescoAuthenticationService,
+ private notificationService: NotificationService) {
+ }
+
+ ngOnInit() {
+ this.sub = this.route.params.subscribe(params => {
+ this.retriveNodeMetadataFromEcm(params['id']);
+ });
+
+
+ let self = this;
+ this.processService.getDeployedApplications("Visit").subscribe(
+ application => {
+ console.log("I'm the application hello", application);
+ this.processService.getProcessDefinitionByApplication(application).subscribe(
+ process => {
+ console.log("this is the process", process);
+ self.processService.startProcessByID(process.id, process.name).subscribe(
+ startedProcess => {
+ console.log(startedProcess);
+ this.processService.getTaskIdFromProcessID(process.id, application.id, startedProcess.id).subscribe(
+ response => {
+ console.log(response.data[0].id);
+ self.taskId = response.data[0].id;
+ },
+ error => {
+ console.log(error)
+ }
+ );
+ },
+ error => {
+ console.log(error);
+ }
+ );
+ },
+ error => this.errorMessage = error
+ );
+ console.log(application);
+ },
+ error => this.errorMessage = error
+ );
+ }
+
+ public saveData(){
+ this.router.navigate(['/patients']);
+ this.notificationService.sendNotification('New Visit Created');
+ }
+
+ private retriveNodeMetadataFromEcm(nodeId: string): void {
+ var self = this;
+ this.nodeId = nodeId;
+ this.authService.getAlfrescoApi().nodes.getNodeInfo(this.nodeId).then(function (data) {
+ console.log(data.properties);
+ self.nodeName = data.name;
+ for (var key in data.properties) {
+ console.log(key + ' => ' + data[key]);
+ self.metadata [key.replace('hc:', '')] = data.properties[key];
+ }
+ self.metadata.nodeId = self.nodeName;
+
+ }, function (error) {
+ console.log('This node does not exist');
+ });
+ }
+
+ private generateUuid() {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+ return v.toString(16);
+ });
+ }
+}
diff --git a/demo-shell-ng2/app/img/admin.jpeg b/demo-shell-ng2/app/img/admin.jpeg
new file mode 100644
index 0000000000..0efd7dbd02
Binary files /dev/null and b/demo-shell-ng2/app/img/admin.jpeg differ
diff --git a/demo-shell-ng2/app/img/anonymous.gif b/demo-shell-ng2/app/img/anonymous.gif
new file mode 100644
index 0000000000..e1b58fa57d
Binary files /dev/null and b/demo-shell-ng2/app/img/anonymous.gif differ
diff --git a/demo-shell-ng2/app/img/background.jpg b/demo-shell-ng2/app/img/background.jpg
new file mode 100644
index 0000000000..792f58a231
Binary files /dev/null and b/demo-shell-ng2/app/img/background.jpg differ
diff --git a/demo-shell-ng2/app/img/checklist.svg b/demo-shell-ng2/app/img/checklist.svg
new file mode 100644
index 0000000000..603b46fef5
--- /dev/null
+++ b/demo-shell-ng2/app/img/checklist.svg
@@ -0,0 +1,782 @@
+
+
+
+
diff --git a/demo-shell-ng2/app/img/completed.svg b/demo-shell-ng2/app/img/completed.svg
new file mode 100644
index 0000000000..84f75fa8a2
--- /dev/null
+++ b/demo-shell-ng2/app/img/completed.svg
@@ -0,0 +1,20 @@
+
+
+
diff --git a/demo-shell-ng2/app/img/createvisit.jpg b/demo-shell-ng2/app/img/createvisit.jpg
new file mode 100644
index 0000000000..7505e347e4
Binary files /dev/null and b/demo-shell-ng2/app/img/createvisit.jpg differ
diff --git a/demo-shell-ng2/app/img/users.png b/demo-shell-ng2/app/img/users.png
new file mode 100644
index 0000000000..b1cca051a4
Binary files /dev/null and b/demo-shell-ng2/app/img/users.png differ
diff --git a/demo-shell-ng2/app/img/visit.jpg b/demo-shell-ng2/app/img/visit.jpg
new file mode 100644
index 0000000000..b07d287404
Binary files /dev/null and b/demo-shell-ng2/app/img/visit.jpg differ
diff --git a/demo-shell-ng2/app/img/visitor.jpg b/demo-shell-ng2/app/img/visitor.jpg
new file mode 100644
index 0000000000..813426332c
Binary files /dev/null and b/demo-shell-ng2/app/img/visitor.jpg differ
diff --git a/demo-shell-ng2/app/services/notification.service.ts b/demo-shell-ng2/app/services/notification.service.ts
new file mode 100644
index 0000000000..d93a12144b
--- /dev/null
+++ b/demo-shell-ng2/app/services/notification.service.ts
@@ -0,0 +1,31 @@
+/*!
+ * @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 { Subject } from 'rxjs/Subject';
+
+@Injectable()
+export class NotificationService {
+
+ notificationsdSource = new Subject();
+
+ notifications = this.notificationsdSource.asObservable();
+
+ sendNotification(message: string) {
+ this.notificationsdSource.next(message);
+ }
+}
diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html
index afa87b40af..ebb380d9ff 100644
--- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html
+++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html
@@ -1,11 +1,10 @@
-
Please select a Task
+ Please select a Visit