From 720d735d02c6bddb2796daa6b672801fc74ababa Mon Sep 17 00:00:00 2001 From: Infad Kachancheri Date: Fri, 2 Jun 2017 13:59:25 +0530 Subject: [PATCH] [ADF-713] Process Attachment - Provide a way to attach a new content (#1920) * added service to get all the related content of the process instance * added new component to create/upload attachment for process instance * added unit test cases for create-process-attachment component * exported create-process-attachment component * added documentation for create-process-attachment component --- .../src/services/activiti-content-service.ts | 10 ++ .../ng2-activiti-processlist/README.md | 28 +++++ .../docs/assets/process-create-attachment.png | Bin 0 -> 5312 bytes .../ng2-activiti-processlist/index.ts | 7 +- ...ti-create-process-attachment.component.css | 19 ++++ ...i-create-process-attachment.component.html | 15 +++ ...reate-process-attachment.component.spec.ts | 100 ++++++++++++++++++ ...iti-create-process-attachment.component.ts | 68 ++++++++++++ .../src/components/index.ts | 1 + 9 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 ng2-components/ng2-activiti-processlist/docs/assets/process-create-attachment.png create mode 100644 ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.css create mode 100644 ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.html create mode 100644 ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.spec.ts create mode 100644 ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.ts diff --git a/ng2-components/ng2-activiti-form/src/services/activiti-content-service.ts b/ng2-components/ng2-activiti-form/src/services/activiti-content-service.ts index 36dd1d1e2b..fbcd24056f 100644 --- a/ng2-components/ng2-activiti-form/src/services/activiti-content-service.ts +++ b/ng2-components/ng2-activiti-form/src/services/activiti-content-service.ts @@ -95,6 +95,16 @@ export class ActivitiContentService { .catch(err => this.handleError(err)); } + /** + * Return all the related content of the process instance + * @param processInstanceId + * @returns {any} + */ + createProcessRelatedContent(processInstanceId: string, content: any): Observable { + return Observable.fromPromise(this.apiService.getInstance().activiti.contentApi.createRelatedContentOnProcessInstance(processInstanceId, content)) + .catch(err => this.handleError(err)); + } + toJson(res: any) { if (res) { return res || {}; diff --git a/ng2-components/ng2-activiti-processlist/README.md b/ng2-components/ng2-activiti-processlist/README.md index ab523f7adc..8ca863df02 100644 --- a/ng2-components/ng2-activiti-processlist/README.md +++ b/ng2-components/ng2-activiti-processlist/README.md @@ -405,6 +405,34 @@ This component displays attached documents on a specified process instance | --- | --- | | `attachmentClick` | Emitted when the attachment double clicked or selected view option from context menu by the user from within the component | +### Create Process Attachment component + +This component displays Upload Component(Drag and Click) to upload the attachment to a specified process instance + +```html + +``` + +![process-create-attachment](docs/assets/process-create-attachment.png) + +#### Options + + +| Name | Description | +| --- | --- | +| `processInstanceId` | (required): The numeric ID of the process instance to display | + +#### Events + + +| Name | Description | +| --- | --- | +| `error` | Emitted when the error occured while creating/uploading the attachment by the user from within the component | +| `success` | Emitted when the attachement created/uploaded successfully from within the component | + ## Build from sources Alternatively you can build component from sources with the following commands: diff --git a/ng2-components/ng2-activiti-processlist/docs/assets/process-create-attachment.png b/ng2-components/ng2-activiti-processlist/docs/assets/process-create-attachment.png new file mode 100644 index 0000000000000000000000000000000000000000..f755633f7c68ec755333818118921c9dff249e0d GIT binary patch literal 5312 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 literal 0 HcmV?d00001 diff --git a/ng2-components/ng2-activiti-processlist/index.ts b/ng2-components/ng2-activiti-processlist/index.ts index f779eb0e8e..d4abc2f117 100644 --- a/ng2-components/ng2-activiti-processlist/index.ts +++ b/ng2-components/ng2-activiti-processlist/index.ts @@ -30,7 +30,8 @@ import { ActivitiProcessComments, ActivitiProcessInstanceDetails, ActivitiStartProcessInstance, - ActivitiProcessAttachmentListComponent + ActivitiProcessAttachmentListComponent, + ActivitiCreateProcessAttachmentComponent } from './src/components/index'; import { ActivitiProcessService } from './src/services/activiti-process.service'; @@ -41,6 +42,7 @@ export * from './src/components/activiti-filters.component'; export * from './src/components/activiti-process-instance-details.component'; export * from './src/components/activiti-start-process.component'; export * from './src/components/activiti-process-attachment-list.component'; +export * from './src/components/activiti-create-process-attachment.component'; // models export * from './src/models/index'; @@ -57,7 +59,8 @@ export const ACTIVITI_PROCESSLIST_DIRECTIVES: [any] = [ ActivitiProcessInstanceVariables, ActivitiProcessComments, ActivitiStartProcessInstance, - ActivitiProcessAttachmentListComponent + ActivitiProcessAttachmentListComponent, + ActivitiCreateProcessAttachmentComponent ]; export const ACTIVITI_PROCESSLIST_PROVIDERS: [any] = [ diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.css new file mode 100644 index 0000000000..59422a60f7 --- /dev/null +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.css @@ -0,0 +1,19 @@ +.upload-attachment-container { + border: 1px solid rgb(224, 224, 224); + background: #fff; + text-align: left; + border-top: none; + padding: 10px; + text-align: center; +} + +.drag-area { + border: 1px solid #eee; + padding: 100px 10px; + margin-bottom: 10px; +} + +.upload-attachment-container button { + color: rgb(253, 145, 0); + opacity: 0.64; +} diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.html new file mode 100644 index 0000000000..6638e1d2d6 --- /dev/null +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.html @@ -0,0 +1,15 @@ +
+
+ Drop Files Here... +
+ +
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.spec.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.spec.ts new file mode 100644 index 0000000000..91631267c8 --- /dev/null +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.spec.ts @@ -0,0 +1,100 @@ +/*! + * @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 { SimpleChange } from '@angular/core'; +import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { Observable } from 'rxjs/Rx'; + +import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core'; +import { ActivitiContentService } from 'ng2-activiti-form'; + +import { ActivitiCreateProcessAttachmentComponent } from './activiti-create-process-attachment.component'; +import { TranslationMock } from './../assets/translation.service.mock'; + +describe('Activiti Process Instance Create Attachment', () => { + + let componentHandler: any; + let service: ActivitiContentService; + let component: ActivitiCreateProcessAttachmentComponent; + let fixture: ComponentFixture; + let createProcessRelatedContentSpy: jasmine.Spy; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + CoreModule.forRoot() + ], + declarations: [ + ActivitiCreateProcessAttachmentComponent + ], + providers: [ + { provide: AlfrescoTranslationService, useClass: TranslationMock }, + ActivitiContentService + ] + }).compileComponents(); + })); + + beforeEach(() => { + + fixture = TestBed.createComponent(ActivitiCreateProcessAttachmentComponent); + component = fixture.componentInstance; + service = fixture.debugElement.injector.get(ActivitiContentService); + + createProcessRelatedContentSpy = spyOn(service, 'createProcessRelatedContent').and.returnValue(Observable.of({successCode: true})); + + componentHandler = jasmine.createSpyObj('componentHandler', [ + 'upgradeAllRegistered', + 'upgradeElement' + ]); + window['componentHandler'] = componentHandler; + }); + + it('should not call createProcessRelatedContent service when processInstanceId changed', () => { + let change = new SimpleChange(null, '123', true); + component.ngOnChanges({ 'processInstanceId': change }); + expect(createProcessRelatedContentSpy).not.toHaveBeenCalled(); + }); + + it('should not call createProcessRelatedContent service when there is no file uploaded', () => { + let change = new SimpleChange(null, '123', true); + component.ngOnChanges({ 'processInstanceId': change }); + let customEvent = { + detail: { + files: [ + ] + } + }; + component.onFileUpload(customEvent); + expect(createProcessRelatedContentSpy).not.toHaveBeenCalled(); + }); + + it('should call createProcessRelatedContent service when there is a file uploaded', () => { + let change = new SimpleChange(null, '123', true); + component.ngOnChanges({ 'processInstanceId': change }); + let file = new File([new Blob()], 'Test'); + let customEvent = { + detail: { + files: [ + file + ] + } + }; + component.onFileUpload(customEvent); + expect(createProcessRelatedContentSpy).toHaveBeenCalled(); + }); +}); diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.ts new file mode 100644 index 0000000000..a3ee2c6183 --- /dev/null +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-create-process-attachment.component.ts @@ -0,0 +1,68 @@ +/*! + * @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, OnChanges, Input, SimpleChanges, Output, EventEmitter } from '@angular/core'; +import { AlfrescoTranslationService } from 'ng2-alfresco-core'; +import { ActivitiContentService } from 'ng2-activiti-form'; + +@Component({ + selector: 'activiti-create-process-attachment', + styleUrls: ['./activiti-create-process-attachment.component.css'], + templateUrl: './activiti-create-process-attachment.component.html' +}) +export class ActivitiCreateProcessAttachmentComponent implements OnChanges { + + @Input() + processInstanceId: string; + + @Output() + error: EventEmitter = new EventEmitter(); + + @Output() + success: EventEmitter = new EventEmitter(); + + constructor(private translateService: AlfrescoTranslationService, + private activitiContentService: ActivitiContentService) { + + if (translateService) { + translateService.addTranslationFolder('ng2-activiti-processlist', 'node_modules/ng2-activiti-processlist/src'); + } + } + + ngOnChanges(changes: SimpleChanges) { + if (changes['processInstanceId'] && changes['processInstanceId'].currentValue) { + this.processInstanceId = changes['processInstanceId'].currentValue; + } + } + + onFileUpload(event: any) { + let files: File[] = event.detail.files; + + for (let i = 0; i < files.length; i++) { + let file: File = files[i]; + + this.activitiContentService.createProcessRelatedContent(this.processInstanceId, file).subscribe( + (res) => { + this.success.emit(res); + }, + (err) => { + this.error.emit(err); + } + ); + } + } +} diff --git a/ng2-components/ng2-activiti-processlist/src/components/index.ts b/ng2-components/ng2-activiti-processlist/src/components/index.ts index ab3d5f1a07..32baa76c79 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/index.ts +++ b/ng2-components/ng2-activiti-processlist/src/components/index.ts @@ -24,3 +24,4 @@ export * from './activiti-process-comments.component'; export * from './activiti-process-instance-details.component'; export * from './activiti-start-process.component'; export * from './activiti-process-attachment-list.component'; +export * from './activiti-create-process-attachment.component';