diff --git a/lib/core/form/components/widgets/upload/upload.widget.ts b/lib/core/form/components/widgets/upload/upload.widget.ts
index c6a50dee7f..9ddb9e029b 100644
--- a/lib/core/form/components/widgets/upload/upload.widget.ts
+++ b/lib/core/form/components/widgets/upload/upload.widget.ts
@@ -94,6 +94,7 @@ export class UploadWidgetComponent extends WidgetComponent implements OnInit {
return this.processContentService.createTemporaryRawRelatedContent(file)
.map((response: any) => {
this.logService.info(response);
+ response.contentBlob = file;
return response;
});
}
diff --git a/lib/core/i18n/en.json b/lib/core/i18n/en.json
index 8b5eaa2c49..e94d77b4f2 100644
--- a/lib/core/i18n/en.json
+++ b/lib/core/i18n/en.json
@@ -9,6 +9,9 @@
"FIELD": {
"LOCALSTORAGE" : "Local storage",
"SOURCE": "Select source from ",
+ "SHOW_FILE": "Show",
+ "DOWNLOAD_FILE": "Download",
+ "REMOVE_FILE":"Remove",
"UPLOAD": "UPLOAD",
"REQUIRED": "*Required",
"VALIDATOR": {
diff --git a/lib/process-services/content-widget/attach-file-widget.component.html b/lib/process-services/content-widget/attach-file-widget.component.html
index 561efd3ac3..d7d83ff0d2 100644
--- a/lib/process-services/content-widget/attach-file-widget.component.html
+++ b/lib/process-services/content-widget/attach-file-widget.component.html
@@ -13,7 +13,7 @@
[multiple]="multipleOption"
type="file"
[id]="field.id"
- (change)="onFileChanged($event)" />
+ (change)="onAttachFileChanged($event)" />
diff --git a/lib/process-services/content-widget/attach-file-widget.component.ts b/lib/process-services/content-widget/attach-file-widget.component.ts
index 9eab0f881f..610f4ca38f 100644
--- a/lib/process-services/content-widget/attach-file-widget.component.ts
+++ b/lib/process-services/content-widget/attach-file-widget.component.ts
@@ -25,7 +25,9 @@ import {
LogService,
ThumbnailService,
ProcessContentService,
- ActivitiContentService
+ ActivitiContentService,
+ ContentService,
+ FormEvent
} from '@alfresco/adf-core';
import { ContentNodeDialogService } from '@alfresco/adf-content-services';
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
@@ -41,12 +43,14 @@ import { Observable } from 'rxjs/Observable';
export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit {
repositoryList = [];
+ private tempFilesList = [];
constructor(public formService: FormService,
private logger: LogService,
public thumbnails: ThumbnailService,
public processContentService: ProcessContentService,
private activitiContentService: ActivitiContentService,
+ private contentService: ContentService,
private contentDialog: ContentNodeDialogService) {
super(formService, logger, thumbnails, processContentService);
}
@@ -58,9 +62,16 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
this.hasFile = true;
}
this.getMultipleFileParam();
+
this.activitiContentService.getAlfrescoRepositories(null, true).subscribe((repoList) => {
this.repositoryList = repoList;
});
+
+ this.formService.taskSaved.subscribe((formSaved: FormEvent) => {
+ if (formSaved.form.id === this.field.form.id) {
+ this.tempFilesList = [];
+ }
+ });
}
isFileSourceConfigured(): boolean {
@@ -99,6 +110,10 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
!!this.field.params.fileSource.selectedFolder;
}
+ isTemporaryFile(file): boolean {
+ return this.tempFilesList.indexOf(file) !== -1 ? true : false;
+ }
+
openSelectDialogFromFileSource() {
let params = this.field.params;
if (this.isDefinedSourceFolder()) {
@@ -111,6 +126,41 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
}
}
+ onAttachFileChanged(event: any) {
+ this.tempFilesList.push(...Array.from(event.target.files));
+ this.onFileChanged(event);
+ }
+
+ onRemoveAttachFile(file: any) {
+ if (this.isTemporaryFile(file.contentBlob)) {
+ this.tempFilesList.splice(this.tempFilesList.indexOf(file.contentBlob), 1);
+ }
+ this.removeFile(file);
+ }
+
+ onAttachFileClicked(file: any) {
+ if (this.isTemporaryFile(file.contentBlob)) {
+ this.formService.formContentClicked.next(file);
+ } else {
+ this.fileClicked(file);
+ }
+ }
+
+ downloadContent(file: any): void {
+ if (this.isTemporaryFile(file.contentBlob)) {
+ this.contentService.downloadBlob(file.contentBlob, file.name);
+ } else {
+ this.processContentService.getFileRawContent(file.id).subscribe(
+ (blob: Blob) => {
+ this.contentService.downloadBlob(blob, file.name);
+ },
+ (err) => {
+ this.logger.error('Impossible retrieve content for download');
+ }
+ );
+ }
+ }
+
openSelectDialog(repoId: string, repoName: string) {
const accountIdentifier = 'alfresco-' + repoId + repoName;
this.contentDialog.openFileBrowseDialogBySite().subscribe(
diff --git a/lib/process-services/content-widget/attach-file-widget.components.spec.ts b/lib/process-services/content-widget/attach-file-widget.components.spec.ts
index 5f52021e8b..d966cb4686 100644
--- a/lib/process-services/content-widget/attach-file-widget.components.spec.ts
+++ b/lib/process-services/content-widget/attach-file-widget.components.spec.ts
@@ -29,7 +29,8 @@ import {
LogService,
ThumbnailService,
SitesService,
- FormFieldMetadata
+ FormFieldMetadata,
+ ContentService
} from '@alfresco/adf-core';
import { ContentNodeDialogService, DocumentListService } from '@alfresco/adf-content-services';
import { MaterialModule } from '../material.module';
@@ -99,6 +100,8 @@ describe('AttachFileWidgetComponent', () => {
let activitiContentService: ActivitiContentService;
let contentNodeDialogService: ContentNodeDialogService;
let processContentService: ProcessContentService;
+ let contentService: ContentService;
+ let formService: FormService;
beforeEach(async(() => {
TestBed.configureTestingModule({
@@ -113,7 +116,8 @@ describe('AttachFileWidgetComponent', () => {
LogService,
SitesService,
DocumentListService,
- ContentNodeDialogService
+ ContentNodeDialogService,
+ ContentService
]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(AttachFileWidgetComponent);
@@ -122,6 +126,8 @@ describe('AttachFileWidgetComponent', () => {
activitiContentService = TestBed.get(ActivitiContentService);
contentNodeDialogService = TestBed.get(ContentNodeDialogService);
processContentService = TestBed.get(ProcessContentService);
+ contentService = TestBed.get(ContentService);
+ formService = TestBed.get(FormService);
});
}));
@@ -133,7 +139,8 @@ describe('AttachFileWidgetComponent', () => {
expect(widget).not.toBeNull();
});
- it('should show up as simple upload when is configured for only local files', () => {
+ it('should show up as simple upload when is configured for only local files', async(() => {
+ spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(Observable.of(null));
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: []
@@ -141,103 +148,187 @@ describe('AttachFileWidgetComponent', () => {
widget.field.id = 'simple-upload-button';
widget.field.params = onlyLocalParams;
fixture.detectChanges();
- expect(element.querySelector('#simple-upload-button')).not.toBeNull();
- });
+ fixture.whenStable().then(() => {
+ expect(element.querySelector('#simple-upload-button')).not.toBeNull();
+ });
+ }));
- it('should show up all the repository option on menu list', () => {
+ it('should show up all the repository option on menu list', async(() => {
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: []
});
widget.field.id = 'attach-file-attach';
- widget.field.params = allSourceParams;
+ widget.field.params = allSourceParams;
spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(Observable.of(fakeRepositoryListAnswer));
fixture.detectChanges();
+ fixture.whenRenderingDone().then(() => {
+ let attachButton: HTMLButtonElement = element.querySelector('#attach-file-attach');
+ expect(attachButton).not.toBeNull();
+ attachButton.click();
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ expect(fixture.debugElement.queryAll(By.css('#attach-local-file'))).not.toBeNull();
+ expect(fixture.debugElement.queryAll(By.css('#attach-local-file'))).not.toBeUndefined();
+ expect(fixture.debugElement.queryAll(By.css('#attach-SHAREME'))).not.toBeNull();
+ expect(fixture.debugElement.queryAll(By.css('#attach-SHAREME'))).not.toBeUndefined();
+ expect(fixture.debugElement.queryAll(By.css('#attach-GOKUSHARE'))).not.toBeNull();
+ expect(fixture.debugElement.queryAll(By.css('#attach-GOKUSHARE'))).not.toBeUndefined();
+ });
+ });
+ }));
- let attachButton: HTMLButtonElement = element.querySelector('#attach-file-attach');
- expect(attachButton).not.toBeNull();
- attachButton.click();
- fixture.detectChanges();
-
- expect(fixture.debugElement.queryAll(By.css('#attach-local-file'))).not.toBeNull();
- expect(fixture.debugElement.queryAll(By.css('#attach-local-file'))).not.toBeUndefined();
- expect(fixture.debugElement.queryAll(By.css('#attach-SHAREME'))).not.toBeNull();
- expect(fixture.debugElement.queryAll(By.css('#attach-SHAREME'))).not.toBeUndefined();
- expect(fixture.debugElement.queryAll(By.css('#attach-GOKUSHARE'))).not.toBeNull();
- expect(fixture.debugElement.queryAll(By.css('#attach-GOKUSHARE'))).not.toBeUndefined();
- });
-
- it('should be able to upload files coming from content node selector', () => {
+ it('should be able to upload files coming from content node selector', async(() => {
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: []
});
widget.field.id = 'attach-file-attach';
- widget.field.params = allSourceParams;
+ widget.field.params = allSourceParams;
spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(Observable.of(fakeRepositoryListAnswer));
spyOn(activitiContentService, 'applyAlfrescoNode').and.returnValue(Observable.of(fakePngAnswer));
spyOn(contentNodeDialogService, 'openFileBrowseDialogBySite').and.returnValue(Observable.of([fakeMinimalNode]));
fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let attachButton: HTMLButtonElement = element.querySelector('#attach-file-attach');
+ expect(attachButton).not.toBeNull();
+ attachButton.click();
+ fixture.detectChanges();
+ fixture.debugElement.query(By.css('#attach-SHAREME')).nativeElement.click();
+ fixture.detectChanges();
- let attachButton: HTMLButtonElement = element.querySelector('#attach-file-attach');
- expect(attachButton).not.toBeNull();
- attachButton.click();
- fixture.detectChanges();
- fixture.debugElement.query(By.css('#attach-SHAREME')).nativeElement.click();
- fixture.detectChanges();
+ expect(element.querySelector('#file-1155-icon')).not.toBeNull();
+ });
+ }));
- expect(element.querySelector('#file-1155-icon')).not.toBeNull();
- });
-
- it('should be able to upload files when a defined folder is selected', () => {
+ it('should be able to upload files when a defined folder is selected', async(() => {
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: []
});
widget.field.id = 'attach-file-attach';
- widget.field.params = definedSourceParams;
+ widget.field.params = definedSourceParams;
spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(Observable.of(fakeRepositoryListAnswer));
spyOn(activitiContentService, 'applyAlfrescoNode').and.returnValue(Observable.of(fakePngAnswer));
spyOn(contentNodeDialogService, 'openFileBrowseDialogByFolderId').and.returnValue(Observable.of([fakeMinimalNode]));
fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let attachButton: HTMLButtonElement = element.querySelector('#attach-file-attach');
+ expect(attachButton).not.toBeNull();
+ attachButton.click();
+ fixture.detectChanges();
+ fixture.debugElement.query(By.css('#attach-pippo-baudo')).nativeElement.click();
+ fixture.detectChanges();
- let attachButton: HTMLButtonElement = element.querySelector('#attach-file-attach');
- expect(attachButton).not.toBeNull();
- attachButton.click();
- fixture.detectChanges();
- fixture.debugElement.query(By.css('#attach-pippo-baudo')).nativeElement.click();
- fixture.detectChanges();
+ expect(element.querySelector('#file-1155-icon')).not.toBeNull();
+ });
+ }));
- expect(element.querySelector('#file-1155-icon')).not.toBeNull();
- });
-
- it('should be able to upload files from local source', () => {
+ it('should be able to upload files from local source', async(() => {
+ spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(Observable.of(null));
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: []
});
widget.field.id = 'attach-file-attach';
- widget.field.params = onlyLocalParams;
+ widget.field.params = onlyLocalParams;
spyOn(processContentService, 'createTemporaryRawRelatedContent').and.returnValue(Observable.of(fakePngAnswer));
fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let inputDebugElement = fixture.debugElement.query(By.css('#attach-file-attach'));
+ inputDebugElement.triggerEventHandler('change', { target: { files: [fakePngAnswer] } });
+ fixture.detectChanges();
- let inputDebugElement = fixture.debugElement.query(By.css('#attach-file-attach'));
- inputDebugElement.triggerEventHandler('change', {target: {files: [fakePngAnswer]}});
- fixture.detectChanges();
+ expect(element.querySelector('#file-1155-icon')).not.toBeNull();
+ });
+ }));
- expect(element.querySelector('#file-1155-icon')).not.toBeNull();
- });
-
- it('should display file list when field has value', () => {
+ it('should display file list when field has value', async(() => {
widget.field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD,
value: [fakePngAnswer]
});
+ spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(Observable.of(null));
widget.field.id = 'attach-file-attach';
- widget.field.params = onlyLocalParams;
+ widget.field.params = onlyLocalParams;
fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ expect(element.querySelector('#file-1155-icon')).not.toBeNull();
+ });
+ }));
+
+ describe('when a file is uploaded', () => {
+
+ beforeEach(async(() => {
+ widget.field = new FormFieldModel(new FormModel(), {
+ type: FormFieldTypes.UPLOAD,
+ value: []
+ });
+ widget.field.id = 'attach-file-attach';
+ widget.field.params = onlyLocalParams;
+ spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(Observable.of(null));
+ spyOn(processContentService, 'createTemporaryRawRelatedContent').and.returnValue(Observable.of(fakePngAnswer));
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let inputDebugElement = fixture.debugElement.query(By.css('#attach-file-attach'));
+ inputDebugElement.triggerEventHandler('change', {target: {files: [fakePngAnswer]}});
+ fixture.detectChanges();
+ expect(element.querySelector('#file-1155-icon')).not.toBeNull();
+ });
+ }));
+
+ it('should show the action menu', async(() => {
+ let menuButton: HTMLButtonElement = element.querySelector('#file-1155-option-menu');
+ expect(menuButton).not.toBeNull();
+ menuButton.click();
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ expect(fixture.debugElement.query(By.css('#file-1155-show-file'))).not.toBeNull();
+ expect(fixture.debugElement.query(By.css('#file-1155-download-file'))).not.toBeNull();
+ expect(fixture.debugElement.query(By.css('#file-1155-remove'))).not.toBeNull();
+ });
+ }));
+
+ it('should remove file when remove is clicked', async(() => {
+ let menuButton: HTMLButtonElement = element.querySelector('#file-1155-option-menu');
+ expect(menuButton).not.toBeNull();
+ menuButton.click();
+ fixture.detectChanges();
+ const removeOption: HTMLButtonElement = fixture.debugElement.query(By.css('#file-1155-remove')).nativeElement;
+ removeOption.click();
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ expect(element.querySelector('#file-1155')).toBeNull();
+ });
+ }));
+
+ it('should download file when download is clicked', async(() => {
+ spyOn(contentService, 'downloadBlob').and.stub();
+ let menuButton: HTMLButtonElement = element.querySelector('#file-1155-option-menu');
+ expect(menuButton).not.toBeNull();
+ menuButton.click();
+ fixture.detectChanges();
+ const downloadOption: HTMLButtonElement = fixture.debugElement.query(By.css('#file-1155-download-file')).nativeElement;
+ downloadOption.click();
+ fixture.whenStable().then(() => {
+ expect(contentService.downloadBlob).toHaveBeenCalled();
+ });
+ }));
+
+ it('should raise formContentClicked event when show file is clicked', async(() => {
+ spyOn(processContentService, 'getFileRawContent').and.returnValue(Observable.of(fakePngAnswer));
+ formService.formContentClicked.subscribe((file) => {
+ expect(file).not.toBeNull();
+ expect(file.id).toBe(1155);
+ });
+ let menuButton: HTMLButtonElement = element.querySelector('#file-1155-option-menu');
+ expect(menuButton).not.toBeNull();
+ menuButton.click();
+ fixture.detectChanges();
+ const showOption: HTMLButtonElement = fixture.debugElement.query(By.css('#file-1155-show-file')).nativeElement;
+ showOption.click();
+ }));
- expect(element.querySelector('#file-1155-icon')).not.toBeNull();
});
});