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;