From 3d345da616ea0a56fc5e1898c7652683dcef1dd5 Mon Sep 17 00:00:00 2001 From: Will Abson Date: Thu, 25 Aug 2016 18:10:59 -0400 Subject: [PATCH 1/6] Add new attached-file widget for linking to external files Refs #621 --- .../activiti-form.component.spec.ts | 2 +- .../widgets/attach/attach.widget.css | 17 ++ .../widgets/attach/attach.widget.html | 33 ++++ .../widgets/attach/attach.widget.ts | 147 ++++++++++++++++++ .../widgets/container/container.widget.html | 3 +- .../widgets/core/external-content-link.ts | 32 ++++ .../widgets/core/external-content.ts | 23 +++ .../widgets/core/form-field-file-source.ts | 25 +++ .../widgets/core/form-field-metadata.ts | 4 + .../core/form-field-selected-folder.ts | 25 +++ .../widgets/dropdown/dropdown.widget.spec.ts | 2 +- .../src/components/widgets/index.ts | 3 + .../typeahead/typeahead.widget.spec.ts | 2 +- .../src/services/form.service.ts | 69 +++++++- 14 files changed, 381 insertions(+), 6 deletions(-) create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.html create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/core/external-content-link.ts create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/core/external-content.ts create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-file-source.ts create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-selected-folder.ts diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts index 37204d11d6..6602497019 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts @@ -40,7 +40,7 @@ describe('ActivitiForm', () => { ]); window['componentHandler'] = componentHandler; - formService = new FormService(null, null); + formService = new FormService(null, null, null, null); formComponent = new ActivitiForm(formService, visibilityService, null, null); }); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css new file mode 100644 index 0000000000..5a8735e01d --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css @@ -0,0 +1,17 @@ +.attach-widget { + width:100% +} + +.attach-widget__icon { + float: left; +} + +.attach-widget__file { + /*float: left;*/ + margin-top: 4px; +} + +.attach-widget__reset { + /*float: left;*/ + margin-top: 4px; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.html new file mode 100644 index 0000000000..e79e98dbc7 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.html @@ -0,0 +1,33 @@ +
+ + +
+ {{getLinkedFileName()}} + + +
+
+ + +

Select content

+
+ +
+
+ +
+
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts new file mode 100644 index 0000000000..f592fc4a67 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts @@ -0,0 +1,147 @@ +/*! + * @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, Input, Output, EventEmitter, ViewChild } from '@angular/core'; +import { WidgetComponent } from './../widget.component'; +import { FormService } from '../../../services/form.service'; +import { ExternalContent } from '../core/external-content'; +import { ExternalContentLink } from '../core/external-content-link'; +import { FormFieldModel } from '../core/form-field.model'; + +declare let __moduleName: string; +declare var componentHandler; + +@Component({ + moduleId: __moduleName, + selector: 'attach-widget', + templateUrl: './attach.widget.html', + styleUrls: ['./attach.widget.css'] +}) +export class AttachWidget extends WidgetComponent implements OnInit { + + selectedFolderPathId: string; + selectedFolderSiteId: string; + selectedFolderSiteName: string; + selectedFolderAccountId: string; + fileName: string; + hasFile: boolean; + selectedFolderNodes: [ExternalContent]; + selectedFile: ExternalContent; + + @Input() + field: FormFieldModel; + + @Output() + fieldChanged: EventEmitter = new EventEmitter(); + + @ViewChild('dialog') + dialog: any; + + constructor(private formService: FormService) { + super(); + } + + ngOnInit() { + console.log('init', this.field); + if (this.field && + this.field.value) { + this.hasFile = true; + } + if (this.field && + this.field.params && + this.field.params.fileSource && + this.field.params.fileSource.selectedFolder) { + this.selectedFolderSiteId = this.field.params.fileSource.selectedFolder.siteId; + this.selectedFolderSiteName = this.field.params.fileSource.selectedFolder.site; + this.setupFileBrowser(); + this.getExternalContentNodes(); + } + } + + private setupFileBrowser() { + this.selectedFolderPathId = this.field.params.fileSource.selectedFolder.pathId; + this.selectedFolderAccountId = this.field.params.fileSource.selectedFolder.accountId; + } + + getLinkedFileName(): string { + let result = this.fileName; + + if (this.selectedFile && + this.selectedFile.title) { + result = this.selectedFile.title; + } + if (this.field.value && + this.field.value.length > 0 && + this.field.value[0].name) { + result = this.field.value[0].name; + } + + return result; + } + + private getExternalContentNodes() { + + this.formService.getAlfrescoNodes(this.selectedFolderAccountId, this.selectedFolderPathId) + .subscribe( + (nodes) => { + this.selectedFolderNodes = nodes; + }, + error => console.error(error)); + } + + selectFile(node: ExternalContent, $event: any) { + this.formService.linkAlfrescoNode(this.selectedFolderAccountId, node, this.selectedFolderSiteId).subscribe( + (link: ExternalContentLink) => { + this.selectedFile = node; + this.field.value = [link]; + this.field.json.value = [link]; + this.closeDialog(); + this.fieldChanged.emit(this.field); + } + ); + } + + selectFolder(node: ExternalContent, $event: any) { + this.selectedFolderPathId = node.id; + this.getExternalContentNodes(); + } + + public showDialog() { + this.setupFileBrowser(); + this.getExternalContentNodes(); + if (this.dialog) { + this.dialog.nativeElement.showModal(); + } + } + + private closeDialog() { + if (this.dialog) { + this.dialog.nativeElement.close(); + } + } + + public cancel() { + this.closeDialog(); + } + + reset() { + this.field.value = null; + this.field.json.value = null; + this.hasFile = false; + } + +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html index 5b136d1bf1..bc22014766 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html @@ -44,7 +44,8 @@
- + +
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/external-content-link.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/external-content-link.ts new file mode 100644 index 0000000000..2fc6f8ad09 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/external-content-link.ts @@ -0,0 +1,32 @@ +/*! + * @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 interface ExternalContentLink { + contentAvailable: boolean; + created: string; + createdBy: any; + id: number; + link: boolean; + mimeType: string; + name: string; + previewStatus: string; + relatedContent: boolean; + simpleType: string; + source: string; + sourceId: string; + thumbnailStatus: string; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/external-content.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/external-content.ts new file mode 100644 index 0000000000..88bc0dece1 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/external-content.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 interface ExternalContent { + folder: boolean; + id: string; + simpleType: string; + title: string; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-file-source.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-file-source.ts new file mode 100644 index 0000000000..6b86dcb5d1 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-file-source.ts @@ -0,0 +1,25 @@ +/*! + * @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 {FormFieldSelectedFolder} from './form-field-selected-folder'; + +export interface FormFieldFileSource { + metadataAllowed: boolean; + name: string; + selectedFolder: FormFieldSelectedFolder; + serviceId: string; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-metadata.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-metadata.ts index 02378e3b41..102695019c 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-metadata.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-metadata.ts @@ -15,6 +15,10 @@ * limitations under the License. */ +import {FormFieldFileSource} from './form-field-file-source'; + export interface FormFieldMetadata { [key: string]: any; + fileSource?: FormFieldFileSource; + link?: boolean; } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-selected-folder.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-selected-folder.ts new file mode 100644 index 0000000000..abd472f109 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-selected-folder.ts @@ -0,0 +1,25 @@ +/*! + * @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 interface FormFieldSelectedFolder { + accountId: string; + folderTree: [any]; + path: string; + pathId: string; + site: string; + siteId: string; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts index 292ffd54dc..fd80f8dc23 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts @@ -28,7 +28,7 @@ describe('DropdownWidget', () => { let widget: DropdownWidget; beforeEach(() => { - formService = new FormService(null, null); + formService = new FormService(null, null, null, null); widget = new DropdownWidget(formService); widget.field = new FormFieldModel(new FormModel()); }); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts index 47846bc631..c5a65c051e 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts @@ -28,6 +28,7 @@ import { RadioButtonsWidget } from './radio-buttons/radio-buttons.widget'; import { DisplayValueWidget } from './display-value/display-value.widget'; import { DisplayTextWidget } from './display-text/display-text.widget'; import { UploadWidget } from './upload/upload.widget'; +import { AttachWidget } from './attach/attach.widget'; import { TypeaheadWidget } from './typeahead/typeahead.widget'; import { FunctionalGroupWidget } from './functional-group/functional-group.widget'; import { PeopleWidget } from './people/people.widget'; @@ -51,6 +52,7 @@ export * from './radio-buttons/radio-buttons.widget'; export * from './display-value/display-value.widget'; export * from './display-text/display-text.widget'; export * from './upload/upload.widget'; +export * from './attach/attach.widget'; export * from './typeahead/typeahead.widget'; export * from './functional-group/functional-group.widget'; export * from './people/people.widget'; @@ -71,6 +73,7 @@ export const PRIMITIVE_WIDGET_DIRECTIVES: [any] = [ DisplayValueWidget, DisplayTextWidget, UploadWidget, + AttachWidget, TypeaheadWidget, FunctionalGroupWidget, PeopleWidget diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts index 5dbfdd09eb..fac9461a8b 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts @@ -29,7 +29,7 @@ describe('TypeaheadWidget', () => { let widget: TypeaheadWidget; beforeEach(() => { - formService = new FormService(null, null); + formService = new FormService(null, null, null, null); widget = new TypeaheadWidget(formService); widget.field = new FormFieldModel(new FormModel()); }); diff --git a/ng2-components/ng2-activiti-form/src/services/form.service.ts b/ng2-components/ng2-activiti-form/src/services/form.service.ts index 95ab51d0cc..a7164fc307 100644 --- a/ng2-components/ng2-activiti-form/src/services/form.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/form.service.ts @@ -17,13 +17,17 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; -import { AlfrescoApiService } from 'ng2-alfresco-core'; +import 'rxjs/add/operator/map'; +import { AlfrescoApiService, AlfrescoSettingsService } from 'ng2-alfresco-core'; import { FormValues } from './../components/widgets/core/index'; import { FormDefinitionModel } from '../models/form-definition.model'; import { EcmModelService } from './ecm-model.service'; import { GroupModel } from './../components/widgets/core/group.model'; import { GroupUserModel } from './../components/widgets/core/group-user.model'; +import { ExternalContent } from '../components/widgets/core/external-content'; +import { ExternalContentLink } from '../components/widgets/core/external-content-link'; +import {Http, Response, RequestOptions, Headers} from '@angular/http'; @Injectable() export class FormService { @@ -31,7 +35,8 @@ export class FormService { static GENERIC_ERROR_MESSAGE: string = 'Server error'; constructor(private ecmModelService: EcmModelService, - private apiService: AlfrescoApiService) { + private apiService: AlfrescoApiService, + private alfrescoSettingsService: AlfrescoSettingsService, private http: Http) { } /** @@ -273,6 +278,66 @@ export class FormService { }); } + /** + * Returns a list of child nodes below the specified folder + * + * @param accountId + * @param nodeId + * @returns {null} + */ + getAlfrescoNodes(accountId: string, nodeId: string): Observable<[ExternalContent]> { + let accountPath = accountId.replace('-', '/'); + let headers = new Headers(); + headers.append('Authorization', this.authService.getTicketBpm()); + return this.http.get( + `${this.alfrescoSettingsService.bpmHost}/activiti-app/` + + `app/rest/integration/${accountPath}/folders/${nodeId}/content`, + new RequestOptions({ + headers: headers, + withCredentials: true + })) + .map(this.extractData) + .catch(this.handleError); + } + + /** + * Returns a list of child nodes below the specified folder + * + * @param accountId + * @param node + * @param siteId + * @returns {null} + */ + linkAlfrescoNode(accountId: string, node: ExternalContent, siteId: string): Observable { + let headers = new Headers(); + headers.append('Content-Type', 'application/json'); + headers.append('Authorization', this.authService.getTicketBpm()); + return this.http.post( + `${this.alfrescoSettingsService.bpmHost}/activiti-app/app/rest/content`, + JSON.stringify({ + link: true, + name: node.title, + simpleType: node.simpleType, + source: accountId, + sourceId: node.id + '@' + siteId + }), + new RequestOptions({ + headers: headers, + withCredentials: true + })) + .map(this.extractBody) + .catch(this.handleError); + } + + private extractBody(res: Response) { + let body = res.json(); + return body || { }; + } + + private extractData(res: Response) { + let body = res.json(); + return body.data || { }; + } getFormId(res: any) { let result = null; From 34634818296cabe2740d7ed6040213db4a818790 Mon Sep 17 00:00:00 2001 From: Will Abson Date: Wed, 7 Sep 2016 12:56:52 +0100 Subject: [PATCH 2/6] Remove console.log() output --- .../src/components/widgets/attach/attach.widget.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts index f592fc4a67..2477a5ad94 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts @@ -56,7 +56,6 @@ export class AttachWidget extends WidgetComponent implements OnInit { } ngOnInit() { - console.log('init', this.field); if (this.field && this.field.value) { this.hasFile = true; From 25f475d742255458eaeb7ff2ee7d0c049a3e3159 Mon Sep 17 00:00:00 2001 From: Will Abson Date: Thu, 8 Sep 2016 01:44:50 +0100 Subject: [PATCH 3/6] Use JS API to fetch node info and set related attached content - Add new service - Remove old HTTP-based methods from FormService - Refactoring Refs #621 --- .../activiti-form.component.spec.ts | 2 +- .../src/components/activiti-form.component.ts | 3 +- .../widgets/attach/attach.widget.ts | 8 +- .../widgets/dropdown/dropdown.widget.spec.ts | 2 +- .../typeahead/typeahead.widget.spec.ts | 2 +- .../src/services/activiti-alfresco.service.ts | 90 +++++++++++++++++++ .../src/services/form.service.ts | 69 +------------- 7 files changed, 101 insertions(+), 75 deletions(-) create mode 100644 ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts index 6602497019..37204d11d6 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts @@ -40,7 +40,7 @@ describe('ActivitiForm', () => { ]); window['componentHandler'] = componentHandler; - formService = new FormService(null, null, null, null); + formService = new FormService(null, null); formComponent = new ActivitiForm(formService, visibilityService, null, null); }); diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts index 2c5151d877..5ef0780417 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts @@ -26,6 +26,7 @@ import { import { MATERIAL_DESIGN_DIRECTIVES } from 'ng2-alfresco-core'; import { EcmModelService } from './../services/ecm-model.service'; import { FormService } from './../services/form.service'; +import { ActivitiAlfrescoContentService } from './../services/activiti-alfresco.service'; import { NodeService } from './../services/node.service'; import { FormModel, FormOutcomeModel, FormValues, FormFieldModel, FormOutcomeEvent } from './widgets/core/index'; @@ -85,7 +86,7 @@ import { WidgetVisibilityService } from './../services/widget-visibility.servic templateUrl: './activiti-form.component.html', styleUrls: ['./activiti-form.component.css'], directives: [MATERIAL_DESIGN_DIRECTIVES, ContainerWidget, TabsWidget], - providers: [EcmModelService, FormService, WidgetVisibilityService, NodeService] + providers: [EcmModelService, FormService, ActivitiAlfrescoContentService, WidgetVisibilityService, NodeService] }) export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts index 2477a5ad94..fbb2293625 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts @@ -17,7 +17,7 @@ import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core'; import { WidgetComponent } from './../widget.component'; -import { FormService } from '../../../services/form.service'; +import { ActivitiAlfrescoContentService } from '../../../services/activiti-alfresco.service'; import { ExternalContent } from '../core/external-content'; import { ExternalContentLink } from '../core/external-content-link'; import { FormFieldModel } from '../core/form-field.model'; @@ -51,7 +51,7 @@ export class AttachWidget extends WidgetComponent implements OnInit { @ViewChild('dialog') dialog: any; - constructor(private formService: FormService) { + constructor(private contentService: ActivitiAlfrescoContentService) { super(); } @@ -94,7 +94,7 @@ export class AttachWidget extends WidgetComponent implements OnInit { private getExternalContentNodes() { - this.formService.getAlfrescoNodes(this.selectedFolderAccountId, this.selectedFolderPathId) + this.contentService.getAlfrescoNodes(this.selectedFolderAccountId, this.selectedFolderPathId) .subscribe( (nodes) => { this.selectedFolderNodes = nodes; @@ -103,7 +103,7 @@ export class AttachWidget extends WidgetComponent implements OnInit { } selectFile(node: ExternalContent, $event: any) { - this.formService.linkAlfrescoNode(this.selectedFolderAccountId, node, this.selectedFolderSiteId).subscribe( + this.contentService.linkAlfrescoNode(this.selectedFolderAccountId, node, this.selectedFolderSiteId).subscribe( (link: ExternalContentLink) => { this.selectedFile = node; this.field.value = [link]; diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts index fd80f8dc23..292ffd54dc 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts @@ -28,7 +28,7 @@ describe('DropdownWidget', () => { let widget: DropdownWidget; beforeEach(() => { - formService = new FormService(null, null, null, null); + formService = new FormService(null, null); widget = new DropdownWidget(formService); widget.field = new FormFieldModel(new FormModel()); }); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts index fac9461a8b..5dbfdd09eb 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.spec.ts @@ -29,7 +29,7 @@ describe('TypeaheadWidget', () => { let widget: TypeaheadWidget; beforeEach(() => { - formService = new FormService(null, null, null, null); + formService = new FormService(null, null); widget = new TypeaheadWidget(formService); widget.field = new FormFieldModel(new FormModel()); }); diff --git a/ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts b/ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts new file mode 100644 index 0000000000..dec92c19e3 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/services/activiti-alfresco.service.ts @@ -0,0 +1,90 @@ +/*! + * @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 { Observable } from 'rxjs/Rx'; +import { AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { ExternalContent } from '../components/widgets/core/external-content'; +import { ExternalContentLink } from '../components/widgets/core/external-content-link'; + +@Injectable() +export class ActivitiAlfrescoContentService { + + static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error'; + static GENERIC_ERROR_MESSAGE: string = 'Server error'; + + constructor(private authService: AlfrescoAuthenticationService) { + } + + /** + * Returns a list of child nodes below the specified folder + * + * @param accountId + * @param folderId + * @returns {null} + */ + getAlfrescoNodes(accountId: string, folderId: string): Observable<[ExternalContent]> { + let apiService: any = this.authService.getAlfrescoApi(); + let accountShortId = accountId.replace('alfresco-', ''); + return Observable.fromPromise(apiService.activiti.alfrescoApi.getContentInFolder(accountShortId, folderId)) + .map(this.toJsonArray) + .catch(this.handleError); + } + + /** + * Returns a list of child nodes below the specified folder + * + * @param accountId + * @param node + * @param siteId + * @returns {null} + */ + linkAlfrescoNode(accountId: string, node: ExternalContent, siteId: string): Observable { + let apiService: any = this.authService.getAlfrescoApi(); + return Observable.fromPromise(apiService.activiti.contentApi.createTemporaryRelatedContent({ + link: true, + name: node.title, + simpleType: node.simpleType, + source: accountId, + sourceId: node.id + '@' + siteId + })).map(this.toJson).catch(this.handleError); + } + + toJson(res: any) { + if (res) { + return res || {}; + } + return {}; + } + + toJsonArray(res: any) { + if (res) { + return res.data || []; + } + return []; + } + + handleError(error: any): Observable { + let errMsg = ActivitiAlfrescoContentService.UNKNOWN_ERROR_MESSAGE; + if (error) { + errMsg = (error.message) ? error.message : + error.status ? `${error.status} - ${error.statusText}` : ActivitiAlfrescoContentService.GENERIC_ERROR_MESSAGE; + } + console.error(errMsg); + return Observable.throw(errMsg); + } +} diff --git a/ng2-components/ng2-activiti-form/src/services/form.service.ts b/ng2-components/ng2-activiti-form/src/services/form.service.ts index a7164fc307..e04d3f8d93 100644 --- a/ng2-components/ng2-activiti-form/src/services/form.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/form.service.ts @@ -18,16 +18,13 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; import 'rxjs/add/operator/map'; -import { AlfrescoApiService, AlfrescoSettingsService } from 'ng2-alfresco-core'; +import { AlfrescoApiService } from 'ng2-alfresco-core'; import { FormValues } from './../components/widgets/core/index'; import { FormDefinitionModel } from '../models/form-definition.model'; import { EcmModelService } from './ecm-model.service'; import { GroupModel } from './../components/widgets/core/group.model'; import { GroupUserModel } from './../components/widgets/core/group-user.model'; -import { ExternalContent } from '../components/widgets/core/external-content'; -import { ExternalContentLink } from '../components/widgets/core/external-content-link'; -import {Http, Response, RequestOptions, Headers} from '@angular/http'; @Injectable() export class FormService { @@ -35,8 +32,7 @@ export class FormService { static GENERIC_ERROR_MESSAGE: string = 'Server error'; constructor(private ecmModelService: EcmModelService, - private apiService: AlfrescoApiService, - private alfrescoSettingsService: AlfrescoSettingsService, private http: Http) { + private apiService: AlfrescoApiService) { } /** @@ -278,67 +274,6 @@ export class FormService { }); } - /** - * Returns a list of child nodes below the specified folder - * - * @param accountId - * @param nodeId - * @returns {null} - */ - getAlfrescoNodes(accountId: string, nodeId: string): Observable<[ExternalContent]> { - let accountPath = accountId.replace('-', '/'); - let headers = new Headers(); - headers.append('Authorization', this.authService.getTicketBpm()); - return this.http.get( - `${this.alfrescoSettingsService.bpmHost}/activiti-app/` + - `app/rest/integration/${accountPath}/folders/${nodeId}/content`, - new RequestOptions({ - headers: headers, - withCredentials: true - })) - .map(this.extractData) - .catch(this.handleError); - } - - /** - * Returns a list of child nodes below the specified folder - * - * @param accountId - * @param node - * @param siteId - * @returns {null} - */ - linkAlfrescoNode(accountId: string, node: ExternalContent, siteId: string): Observable { - let headers = new Headers(); - headers.append('Content-Type', 'application/json'); - headers.append('Authorization', this.authService.getTicketBpm()); - return this.http.post( - `${this.alfrescoSettingsService.bpmHost}/activiti-app/app/rest/content`, - JSON.stringify({ - link: true, - name: node.title, - simpleType: node.simpleType, - source: accountId, - sourceId: node.id + '@' + siteId - }), - new RequestOptions({ - headers: headers, - withCredentials: true - })) - .map(this.extractBody) - .catch(this.handleError); - } - - private extractBody(res: Response) { - let body = res.json(); - return body || { }; - } - - private extractData(res: Response) { - let body = res.json(); - return body.data || { }; - } - getFormId(res: any) { let result = null; From 01906f68eab894e5c256d0064a3177e98feb2001 Mon Sep 17 00:00:00 2001 From: Will Abson Date: Thu, 8 Sep 2016 01:46:48 +0100 Subject: [PATCH 4/6] Remove commented-out CSS Refs #622 --- .../src/components/widgets/attach/attach.widget.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css index 5a8735e01d..8bb37584c6 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.css @@ -7,11 +7,9 @@ } .attach-widget__file { - /*float: left;*/ margin-top: 4px; } .attach-widget__reset { - /*float: left;*/ margin-top: 4px; } From 6831b377a3cd7a0058fe46fb27b61c91d30bd66a Mon Sep 17 00:00:00 2001 From: Will Abson Date: Thu, 8 Sep 2016 09:38:46 +0100 Subject: [PATCH 5/6] Remove map operator import which is not required --- ng2-components/ng2-activiti-form/src/services/form.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ng2-components/ng2-activiti-form/src/services/form.service.ts b/ng2-components/ng2-activiti-form/src/services/form.service.ts index e04d3f8d93..d9b90bb419 100644 --- a/ng2-components/ng2-activiti-form/src/services/form.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/form.service.ts @@ -17,7 +17,6 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; -import 'rxjs/add/operator/map'; import { AlfrescoApiService } from 'ng2-alfresco-core'; import { FormValues } from './../components/widgets/core/index'; import { FormDefinitionModel } from '../models/form-definition.model'; From 544759af34057609ab13ab87df5074404c11afb1 Mon Sep 17 00:00:00 2001 From: Will Abson Date: Thu, 8 Sep 2016 10:55:06 +0100 Subject: [PATCH 6/6] Add notes on attachfield usage to README --- ng2-components/ng2-activiti-form/README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ng2-components/ng2-activiti-form/README.md b/ng2-components/ng2-activiti-form/README.md index 311cdeaa50..32da58c14e 100644 --- a/ng2-components/ng2-activiti-form/README.md +++ b/ng2-components/ng2-activiti-form/README.md @@ -243,10 +243,17 @@ will also be executed after your custom code.** - Header * [x] Plain header * [x] Collapsible header -- [ ] Attach +- [x] Attach file ** - [x] Display value - [x] Display text +** Files may be uploaded from a user's device if the file source selected is +'Local file' or 'All sources' and 'link to files' is not selected. Alternatively +you can link to files in a configured Alfresco repository by selecting this source +explicitly from the list and making sure that 'link to files' is selected. Copying +files from Alfresco into Activiti via the control (no linking) is not currently +supported, nor is allowing the user to choose between more than one source. + ## Build from sources Alternatively you can build component from sources with the following commands: