diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html
index 74a40a6d7b..5fb15efc40 100644
--- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html
+++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html
@@ -37,7 +37,7 @@
[sort]="taskFilter.filter.sort"
[data]="dataTasks"
[landingTaskId]="currentTaskId"
- (rowClick)="onTaskRowClick($event)"
+ (rowClick)="onTaskRowClick($event)"
(onSuccess)="onSuccessTaskList($event)"
(row-click)="onRowClick($event)"
(row-dblclick)="onRowDblClick($event)"
@@ -55,6 +55,7 @@
@@ -142,3 +143,11 @@
+
+
diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts
index f883fe09c5..81c6f54b41 100644
--- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts
+++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts
@@ -78,6 +78,11 @@ export class ActivitiDemoComponent implements AfterViewInit {
@Input()
appId: number = null;
+ fileShowed: boolean = false;
+
+ content: Blob;
+ contentName: string;
+
layoutType: string;
currentTaskId: string;
currentProcessInstanceId: string;
@@ -92,6 +97,8 @@ export class ActivitiDemoComponent implements AfterViewInit {
processFilter: FilterProcessRepresentationModel;
sub: Subscription;
+ blobFile: any;
+ flag: boolean = true;
dataTasks: ObjectDataTableAdapter;
dataProcesses: ObjectDataTableAdapter;
@@ -113,6 +120,7 @@ export class ActivitiDemoComponent implements AfterViewInit {
);
this.dataProcesses.setSorting(new DataSorting('started', 'desc'));
+
// Uncomment this line to replace all 'text' field editors with custom component
// formRenderingService.setComponentTypeResolver('text', () => CustomEditorComponent, true);
@@ -126,6 +134,7 @@ export class ActivitiDemoComponent implements AfterViewInit {
formService.formFieldValueChanged.subscribe((e: FormFieldEvent) => {
console.log(`Field value changed. Form: ${e.form.id}, Field: ${e.field.id}, Value: ${e.field.value}`);
});
+
}
ngOnInit() {
@@ -242,6 +251,12 @@ export class ActivitiDemoComponent implements AfterViewInit {
this.currentTaskId = null;
}
+ onFormContentClick(content: any) {
+ this.fileShowed = true;
+ this.content = content.contentBlob;
+ this.contentName = content.name;
+ }
+
onTaskCreated(data: any) {
this.currentTaskId = data.parentTaskId;
this.activititasklist.reload();
diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-content.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-content.component.ts
index 5b5f55517d..14b1073067 100644
--- a/ng2-components/ng2-activiti-form/src/components/activiti-content.component.ts
+++ b/ng2-components/ng2-activiti-form/src/components/activiti-content.component.ts
@@ -94,8 +94,15 @@ export class ActivitiContent implements OnChanges {
}
openViewer(content: ContentLinkModel): void {
- this.contentClick.emit(content);
- this.logService.info('Content clicked' + content.id);
+ this.formService.getFileRawContent(content.id).subscribe(
+ (blob: Blob) => {
+ content.contentBlob = blob;
+ this.contentClick.emit(content);
+ this.logService.info('Content clicked' + content.id);
+ this.formService.formContentClicked.next(content);
+ },
+ error => this.logService.error(error)
+ );
}
/**
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 a591ee9a0b..e3ea619a73 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
@@ -21,6 +21,7 @@ import { EcmModelService } from './../services/ecm-model.service';
import { FormService } from './../services/form.service';
import { NodeService } from './../services/node.service';
import { FormModel, FormOutcomeModel, FormValues, FormFieldModel, FormOutcomeEvent } from './widgets/core/index';
+import { ContentLinkModel } from './widgets/core/content-link.model';
import { FormEvent, FormErrorEvent } from './../events/index';
import { WidgetVisibilityService } from './../services/widget-visibility.service';
@@ -134,6 +135,9 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
@Output()
formCompleted: EventEmitter = new EventEmitter();
+ @Output()
+ formContentClicked: EventEmitter = new EventEmitter();
+
@Output()
formLoaded: EventEmitter = new EventEmitter();
@@ -202,6 +206,10 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
}
ngOnInit() {
+ this.formService.formContentClicked.subscribe((content: ContentLinkModel) => {
+ this.formContentClicked.emit(content);
+ });
+
if (this.nodeId) {
this.loadFormForEcmNode();
} else {
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/content-link.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/content-link.model.ts
index 0e8e47c0e7..6db04842a6 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/core/content-link.model.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/content-link.model.ts
@@ -29,6 +29,7 @@ export class ContentLinkModel {
simpleType: string;
thumbnailUrl: string;
contentRawUrl: string;
+ contentBlob: Blob;
thumbnailStatus: string;
constructor(obj?: any) {
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 fb2a4a14db..070d0510be 100644
--- a/ng2-components/ng2-activiti-form/src/services/form.service.ts
+++ b/ng2-components/ng2-activiti-form/src/services/form.service.ts
@@ -24,6 +24,7 @@ import { EcmModelService } from './ecm-model.service';
import { GroupModel } from './../components/widgets/core/group.model';
import { GroupUserModel } from './../components/widgets/core/group-user.model';
import { FormEvent, FormErrorEvent, FormFieldEvent } from './../events/index';
+import { ContentLinkModel } from './../components/widgets/core/content-link.model';
@Injectable()
export class FormService {
@@ -37,6 +38,7 @@ export class FormService {
taskCompletedError: Subject = new Subject();
taskSaved: Subject = new Subject();
taskSavedError: Subject = new Subject();
+ formContentClicked: Subject = new Subject();
constructor(private ecmModelService: EcmModelService,
private apiService: AlfrescoApiService,
diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html
index 28c74fdd1b..9fbb193a4f 100644
--- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html
+++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html
@@ -53,6 +53,7 @@
[readOnly]="readOnlyForm"
(formSaved)='onFormSaved($event)'
(formCompleted)='onFormCompleted($event)'
+ (formContentClicked)='onFormContentClick($event)'
(formLoaded)='onFormLoaded($event)'
(onError)='onFormError($event)'
(executeOutcome)='onFormExecuteOutcome($event)'>
diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts
index fe0919a4c9..88b0b24d7a 100644
--- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts
+++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts
@@ -20,7 +20,7 @@ import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core';
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
import { TaskDetailsModel } from '../models/task-details.model';
import { User } from '../models/user.model';
-import { FormService, FormModel, FormOutcomeEvent } from 'ng2-activiti-form';
+import { FormService, FormModel, FormOutcomeEvent, ContentLinkModel } from 'ng2-activiti-form';
import { TaskQueryRequestRepresentationModel } from '../models/filter.model';
@Component({
@@ -87,6 +87,9 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
@Output()
formCompleted: EventEmitter = new EventEmitter();
+ @Output()
+ formContentClicked: EventEmitter = new EventEmitter();
+
@Output()
formLoaded: EventEmitter = new EventEmitter();
@@ -228,6 +231,10 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
);
}
+ onFormContentClick(content: ContentLinkModel) {
+ this.formContentClicked.emit(content);
+ }
+
onFormSaved(form: FormModel) {
this.formSaved.emit(form);
}
diff --git a/ng2-components/ng2-alfresco-viewer/README.md b/ng2-components/ng2-alfresco-viewer/README.md
index 41bfe6bae1..039e8ef82b 100644
--- a/ng2-components/ng2-alfresco-viewer/README.md
+++ b/ng2-components/ng2-alfresco-viewer/README.md
@@ -210,10 +210,12 @@ platformBrowserDynamic().bootstrapModule(AppModule);
Attribute | Options | Default | Description | Mandatory
--- | --- | --- | --- | ---
`fileNodeId` | *string* | | node Id of the file to load the file |
-`urlFile` | *string* | | If you want laod an external file that not comes from the ECM you can use this Url where to load the file |
+`urlFile` | *string* | | If you want load an external file that not comes from the ECM you can use this Url where to load the file |
+`urlBlob` | *Blob* | | If you want load a Blob File |
`overlayMode` | *boolean* | `false` | if true Show the Viewer full page over the present content otherwise will fit the parent div |
`showViewer` | *boolean* | `true` | Hide or show the viewer |
`showToolbar` | *boolean* | `true` | Hide or show the toolbars |
+`displayName` | *string* | | You can specify the name of the file|
#### Supported file formats
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.html b/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.html
index 5f4d71b098..2a65bf5dac 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.html
+++ b/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.html
@@ -1,8 +1,7 @@
-

+
-
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.spec.ts b/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.spec.ts
index cd0911947a..3458199c2f 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.spec.ts
+++ b/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.spec.ts
@@ -17,21 +17,28 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { ImgViewerComponent } from './imgViewer.component';
-import { DebugElement } from '@angular/core';
+import { DebugElement, SimpleChange } from '@angular/core';
import {
AlfrescoAuthenticationService,
AlfrescoSettingsService,
AlfrescoApiService,
- CoreModule
+ CoreModule,
+ ContentService
} from 'ng2-alfresco-core';
describe('Test ng2-alfresco-viewer Img viewer component ', () => {
let component: ImgViewerComponent;
+ let service: ContentService;
let fixture: ComponentFixture;
let debug: DebugElement;
let element: HTMLElement;
+ function createFakeBlob() {
+ let data = atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==');
+ return new Blob([data], {type: 'image/png'});
+ }
+
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
@@ -44,6 +51,7 @@ describe('Test ng2-alfresco-viewer Img viewer component ', () => {
AlfrescoApiService
]
}).compileComponents();
+ service = TestBed.get(ContentService);
}));
beforeEach(() => {
@@ -55,17 +63,18 @@ describe('Test ng2-alfresco-viewer Img viewer component ', () => {
fixture.detectChanges();
});
- it('If no url is passed should thrown an error', () => {
+ it('If no url or blob are passed should thrown an error', () => {
+ let change = new SimpleChange(null, null);
expect(() => {
- component.ngOnChanges(null);
- }).toThrow(new Error('Attribute urlFile is required'));
+ component.ngOnChanges({ 'blobFile': change });
+ }).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('If url is passed should not thrown an error', () => {
component.urlFile = 'fake-url';
expect(() => {
component.ngOnChanges(null);
- }).not.toThrow(new Error('Attribute urlFile is required'));
+ }).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('The file Name should be present in the alt attribute', () => {
@@ -73,4 +82,15 @@ describe('Test ng2-alfresco-viewer Img viewer component ', () => {
fixture.detectChanges();
expect(element.querySelector('#viewer-image').getAttribute('alt')).toEqual('fake-name');
});
+
+ it('If blob is passed should not thrown an error', () => {
+ let blob = createFakeBlob();
+
+ spyOn(service, 'createTrustedUrl').and.returnValue('fake-blob-url');
+ let change = new SimpleChange(null, blob);
+ expect(() => {
+ component.ngOnChanges({ 'blobFile': change });
+ }).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
+ expect(component.urlFile).toEqual('fake-blob-url');
+ });
});
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.ts b/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.ts
index a41b696646..d222a5e7da 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.ts
+++ b/ng2-components/ng2-alfresco-viewer/src/components/imgViewer.component.ts
@@ -15,7 +15,8 @@
* limitations under the License.
*/
-import { Component, Input } from '@angular/core';
+import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
+import { ContentService } from 'ng2-alfresco-core';
@Component({
moduleId: module.id,
@@ -23,17 +24,27 @@ import { Component, Input } from '@angular/core';
templateUrl: './imgViewer.component.html',
styleUrls: ['./imgViewer.component.css']
})
-export class ImgViewerComponent {
+export class ImgViewerComponent implements OnChanges {
@Input()
urlFile: string;
+ @Input()
+ blobFile: any;
+
@Input()
nameFile: string;
- ngOnChanges(changes) {
- if (!this.urlFile) {
- throw new Error('Attribute urlFile is required');
+ constructor(private contentService: ContentService) {}
+
+ ngOnChanges(changes: SimpleChanges) {
+ let blobFile = changes['blobFile'];
+ if (blobFile && blobFile.currentValue) {
+ this.urlFile = this.contentService.createTrustedUrl(this.blobFile);
+ return;
+ }
+ if (!this.urlFile && !this.blobFile) {
+ throw new Error('Attribute urlFile or blobFile is required');
}
}
}
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.spec.ts b/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.spec.ts
index 8093cb51d6..097721afbb 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.spec.ts
+++ b/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.spec.ts
@@ -17,7 +17,9 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { MediaPlayerComponent } from './mediaPlayer.component';
-import { DebugElement } from '@angular/core';
+import { DebugElement, SimpleChange } from '@angular/core';
+import { ContentService } from 'ng2-alfresco-core';
+
import {
AlfrescoAuthenticationService,
AlfrescoSettingsService,
@@ -28,10 +30,16 @@ import {
describe('Test ng2-alfresco-viewer Media player component ', () => {
let component: MediaPlayerComponent;
+ let service: ContentService;
let fixture: ComponentFixture;
let debug: DebugElement;
let element: HTMLElement;
+ function createFakeBlob() {
+ let data = atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==');
+ return new Blob([data], {type: 'image/png'});
+ }
+
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
@@ -44,6 +52,7 @@ describe('Test ng2-alfresco-viewer Media player component ', () => {
AlfrescoApiService
]
}).compileComponents();
+ service = TestBed.get(ContentService);
}));
beforeEach(() => {
@@ -55,23 +64,35 @@ describe('Test ng2-alfresco-viewer Media player component ', () => {
fixture.detectChanges();
});
- it('If no url is passed should thrown an error', () => {
+ it('If no url or no blob are passed should thrown an error', () => {
+ let change = new SimpleChange(null, null);
expect(() => {
- component.ngOnChanges(null);
- }).toThrow(new Error('Attribute urlFile is required'));
+ component.ngOnChanges({ 'blobFile': change });
+ }).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('If url is passed should not thrown an error', () => {
component.urlFile = 'fake-url';
expect(() => {
component.ngOnChanges(null);
- }).not.toThrow(new Error('Attribute urlFile is required'));
+ }).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('If url is passed should not thrown an error', () => {
component.urlFile = 'fake-url';
expect(() => {
component.ngOnChanges(null);
- }).not.toThrow(new Error('Attribute urlFile is required'));
+ }).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
+ });
+
+ it('If blob is passed should not thrown an error', () => {
+ let blob = createFakeBlob();
+
+ spyOn(service, 'createTrustedUrl').and.returnValue('fake-blob-url');
+ let change = new SimpleChange(null, blob);
+ expect(() => {
+ component.ngOnChanges({ 'blobFile': change });
+ }).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
+ expect(component.urlFile).toEqual('fake-blob-url');
});
});
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.ts b/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.ts
index 734f0be58e..c7185f92ef 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.ts
+++ b/ng2-components/ng2-alfresco-viewer/src/components/mediaPlayer.component.ts
@@ -15,7 +15,8 @@
* limitations under the License.
*/
-import { Component, Input } from '@angular/core';
+import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
+import { ContentService } from 'ng2-alfresco-core';
@Component({
moduleId: module.id,
@@ -23,21 +24,31 @@ import { Component, Input } from '@angular/core';
templateUrl: './mediaPlayer.component.html',
styleUrls: ['./mediaPlayer.component.css']
})
-export class MediaPlayerComponent {
+export class MediaPlayerComponent implements OnChanges {
@Input()
urlFile: string;
+ @Input()
+ blobFile: Blob;
+
@Input()
mimeType: string;
@Input()
nameFile: string;
- ngOnChanges(changes) {
- if (!this.urlFile) {
- throw new Error('Attribute urlFile is required');
+ constructor(private contentService: ContentService ) {}
+
+ ngOnChanges(changes: SimpleChanges) {
+ let blobFile = changes['blobFile'];
+ if (blobFile && blobFile.currentValue) {
+ this.urlFile = this.contentService.createTrustedUrl(this.blobFile);
+ return;
+ }
+
+ if (!this.urlFile && !this.blobFile) {
+ throw new Error('Attribute urlFile or blobFile is required');
}
}
-
}
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.spec.ts b/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.spec.ts
index e81ee5b622..eb8771872a 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.spec.ts
+++ b/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.spec.ts
@@ -49,6 +49,24 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
}).compileComponents();
}));
+ function createFakeBlob(): Blob {
+ let pdfData = atob(
+ 'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
+ 'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
+ 'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
+ 'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
+ 'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
+ 'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
+ 'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
+ 'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
+ 'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
+ 'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
+ 'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
+ 'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
+ 'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
+ return new Blob([pdfData], {type: 'application/pdf'});
+ }
+
beforeEach(() => {
fixture = TestBed.createComponent(PdfViewerComponent);
@@ -57,21 +75,71 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
component = fixture.componentInstance;
component.showToolbar = true;
- component.urlFile = 'base/src/assets/fake-test-file.pdf';
- fixture.detectChanges();
});
- describe('View', () => {
+ describe('View with url file', () => {
+ beforeEach(() => {
+ component.urlFile = 'base/src/assets/fake-test-file.pdf';
+ fixture.detectChanges();
+ });
- it('If urlfile is not present should not be thrown any error ', () => {
+ it('If urlfile is not present should thrown an error ', () => {
component.urlFile = undefined;
fixture.detectChanges();
expect(() => {
component.ngOnChanges(null);
- }).toThrow();
+ }).toThrow(new Error('Attribute urlFile or blobFile is required'));
+ });
+
+ it('Canvas should be present', () => {
+ expect(element.querySelector('#viewer-viewerPdf')).not.toBeNull();
+ expect(element.querySelector('#viewer-pdf-container')).not.toBeNull();
+ });
+
+ it('Loader should be present', () => {
+ expect(element.querySelector('#loader-container')).not.toBeNull();
+ });
+
+ it('Next an Previous Buttons should be present', () => {
+ expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull();
+ expect(element.querySelector('#viewer-next-page-button')).not.toBeNull();
+ });
+
+ it('Input Page elements should be present', () => {
+ expect(element.querySelector('#viewer-pagenumber-input')).toBeDefined();
+ expect(element.querySelector('#viewer-total-pages')).toBeDefined();
+
+ expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull();
+ expect(element.querySelector('#viewer-next-page-button')).not.toBeNull();
+ });
+
+ it('Toolbar should be hide if showToolbar is false', () => {
+ component.showToolbar = false;
+
+ fixture.detectChanges();
+
+ expect(element.querySelector('#viewer-toolbar-command')).toBeNull();
+ expect(element.querySelector('#viewer-toolbar-pagination')).toBeNull();
+ });
+ });
+
+ describe('View with blob file', () => {
+
+ beforeEach(() => {
+ component.urlFile = undefined;
+ component.blobFile = createFakeBlob();
+
+ fixture.detectChanges();
+ });
+
+ it('If blobFile is not present should thrown an error ', () => {
+ component.blobFile = undefined;
+ expect(() => {
+ component.ngOnChanges(null);
+ }).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('Canvas should be present', () => {
@@ -109,6 +177,8 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
describe('User interaction', () => {
beforeEach(() => {
+ component.urlFile = 'base/src/assets/fake-test-file.pdf';
+ fixture.detectChanges();
component.inputPage('1');
});
@@ -244,6 +314,10 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
describe('Resize interaction', () => {
+ beforeEach(() => {
+ component.urlFile = 'base/src/assets/fake-test-file.pdf';
+ component.inputPage('1');
+ });
it('resize event should trigger setScaleUpdatePages', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
@@ -256,6 +330,10 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
describe('scroll interaction', () => {
+ beforeEach(() => {
+ component.urlFile = 'base/src/assets/fake-test-file.pdf';
+ fixture.detectChanges();
+ });
it('scroll page should return the current page', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.ts b/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.ts
index d2f1a5d58c..e9b5177b1f 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.ts
+++ b/ng2-components/ng2-alfresco-viewer/src/components/pdfViewer.component.ts
@@ -33,6 +33,9 @@ export class PdfViewerComponent {
@Input()
urlFile: string;
+ @Input()
+ blobFile: Blob;
+
@Input()
nameFile: string;
@@ -58,40 +61,52 @@ export class PdfViewerComponent {
}
ngOnChanges(changes) {
- if (!this.urlFile) {
- throw new Error('Attribute urlFile is required');
+ if (!this.urlFile && !this.blobFile) {
+ throw new Error('Attribute urlFile or blobFile is required');
}
if (this.urlFile) {
return new Promise((resolve, reject) => {
- let loadingTask = this.getPDFJS().getDocument(this.urlFile);
-
- loadingTask.onProgress = (progressData) => {
- let level = progressData.loaded / progressData.total;
- this.laodingPercent = Math.round(level * 100);
+ this.executePdf(this.urlFile, resolve, reject);
+ });
+ } else {
+ return new Promise((resolve, reject) => {
+ let reader = new FileReader();
+ reader.onload = () => {
+ this.executePdf(reader.result, resolve, reject);
};
-
- loadingTask.then((pdfDocument) => {
- this.currentPdfDocument = pdfDocument;
- this.totalPages = pdfDocument.numPages;
- this.page = 1;
- this.displayPage = 1;
- this.initPDFViewer(this.currentPdfDocument);
-
- this.currentPdfDocument.getPage(1).then(() => {
- this.scalePage('auto');
- resolve();
- }, (error) => {
- reject(error);
- });
-
- }, (error) => {
- reject(error);
- });
+ reader.readAsArrayBuffer(this.blobFile);
});
}
}
+ executePdf(src, resolve, reject) {
+ let loadingTask = this.getPDFJS().getDocument(src);
+
+ loadingTask.onProgress = (progressData) => {
+ let level = progressData.loaded / progressData.total;
+ this.laodingPercent = Math.round(level * 100);
+ };
+
+ loadingTask.then((pdfDocument) => {
+ this.currentPdfDocument = pdfDocument;
+ this.totalPages = pdfDocument.numPages;
+ this.page = 1;
+ this.displayPage = 1;
+ this.initPDFViewer(this.currentPdfDocument);
+
+ this.currentPdfDocument.getPage(1).then(() => {
+ this.scalePage('auto');
+ resolve();
+ }, (error) => {
+ reject(error);
+ });
+
+ }, (error) => {
+ reject(error);
+ });
+ }
+
/**
* return the PDFJS global object (exist to facilitate the mock of PDFJS in the test)
*
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.html b/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.html
index af5dd646cb..67e47c4b6b 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.html
+++ b/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.html
@@ -41,14 +41,14 @@
-
diff --git a/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.ts b/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.ts
index d3e6309de6..c9dda5fcf9 100644
--- a/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.ts
+++ b/ng2-components/ng2-alfresco-viewer/src/components/viewer.component.ts
@@ -31,6 +31,9 @@ export class ViewerComponent {
@Input()
urlFile: string = '';
+ @Input()
+ blobFile: Blob;
+
@Input()
fileNodeId: string = null;
@@ -43,6 +46,9 @@ export class ViewerComponent {
@Input()
showToolbar: boolean = true;
+ @Input()
+ displayName: string;
+
@Output()
showViewerChange: EventEmitter = new EventEmitter();
@@ -55,7 +61,6 @@ export class ViewerComponent {
urlFileContent: string;
otherMenu: any;
- displayName: string;
extension: string;
mimeType: string;
loaded: boolean = false;
@@ -70,12 +75,16 @@ export class ViewerComponent {
if (this.showViewer) {
this.hideOtherHeaderBar();
this.blockOtherScrollBar();
- if (!this.urlFile && !this.fileNodeId) {
- throw new Error('Attribute urlFile or fileNodeId is required');
+ if (!this.urlFile && !this.blobFile && !this.fileNodeId) {
+ throw new Error('Attribute urlFile or fileNodeId or blobFile is required');
}
return new Promise((resolve, reject) => {
let alfrescoApi = this.apiService.getInstance();
- if (this.urlFile) {
+ if (this.blobFile) {
+ this.mimeType = this.blobFile.type;
+ this.extensionChange.emit(this.mimeType);
+ resolve();
+ } else if (this.urlFile) {
let filenameFromUrl = this.getFilenameFromUrl(this.urlFile);
this.displayName = filenameFromUrl ? filenameFromUrl : '';
this.extension = this.getFileExtension(filenameFromUrl);