diff --git a/demo-shell-ng2/app/components/files/files.component.html b/demo-shell-ng2/app/components/files/files.component.html
index 701a09374b..e5772ef0b2 100644
--- a/demo-shell-ng2/app/components/files/files.component.html
+++ b/demo-shell-ng2/app/components/files/files.component.html
@@ -1,4 +1,4 @@
-
@@ -8,6 +8,10 @@
source="name"
class="full-width name-column">
+
+
@@ -74,4 +78,4 @@
-
+
\ No newline at end of file
diff --git a/ng2-components/ng2-alfresco-upload/src/components/upload-button.component.ts b/ng2-components/ng2-alfresco-upload/src/components/upload-button.component.ts
index b375d65c0a..c0ceb65e54 100644
--- a/ng2-components/ng2-alfresco-upload/src/components/upload-button.component.ts
+++ b/ng2-components/ng2-alfresco-upload/src/components/upload-button.component.ts
@@ -76,6 +76,9 @@ export class UploadButtonComponent {
@Input()
acceptedFilesType: string = '*';
+ @Input()
+ currentFolderPath: string = '/Sites/swsdp/documentLibrary';
+
@Input()
uploaddirectory: string = '';
@@ -92,15 +95,14 @@ export class UploadButtonComponent {
@Optional() translate: TranslateService) {
console.log('UploadComponent constructor', el);
+ let site = this.getSiteId();
+ let container = this.getContainerId();
+
this._uploaderService = new UploadService({
- url: 'http://192.168.99.100:8080/alfresco/service/api/upload',
- withCredentials: true,
- authToken: btoa('admin:admin'),
- authTokenPrefix: 'Basic',
fieldName: 'filedata',
formFields: {
- siteid: 'swsdp',
- containerid: 'documentLibrary'
+ siteid: site,
+ containerid: container
}
});
@@ -171,4 +173,20 @@ export class UploadButtonComponent {
private _showDialog(): void {
this.fileUploadingDialogComponent.showDialog();
}
+
+ /**
+ * Return the site from the path
+ * @returns {any}
+ */
+ private getSiteId(): string {
+ return this.currentFolderPath.replace('/Sites/','').split('/')[0];
+ }
+
+ /**
+ * Return the container from the path
+ * @returns {any}
+ */
+ private getContainerId(): string {
+ return this.currentFolderPath.replace('/Sites/','').split('/')[1];
+ }
}
diff --git a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.html b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.html
index e96794623e..59e660ae70 100644
--- a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.html
+++ b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.html
@@ -1,4 +1,7 @@
-
diff --git a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts
index 7d39da46c8..958bf038bb 100644
--- a/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts
+++ b/ng2-components/ng2-alfresco-upload/src/components/upload-drag-area.component.ts
@@ -55,21 +55,23 @@ export class UploadDragAreaComponent {
@Input()
uploaddirectory: string = '';
+ @Input()
+ currentFolderPath: string = '/Sites/swsdp/documentLibrary';
+
@Output()
onSuccess = new EventEmitter();
constructor(public el: ElementRef) {
console.log('UploadComponent constructor', el);
+ let site = this.getSiteId();
+ let container = this.getContainerId();
+
this._uploaderService = new UploadService({
- url: 'http://192.168.99.100:8080/alfresco/service/api/upload',
- withCredentials: true,
- authToken: btoa('admin:admin'),
- authTokenPrefix: 'Basic',
fieldName: 'filedata',
formFields: {
- siteid: 'swsdp',
- containerid: 'documentLibrary'
+ siteid: site,
+ containerid: container
}
});
}
@@ -90,10 +92,88 @@ export class UploadDragAreaComponent {
}
}
+ /**
+ * Called when the file are dropped in the drag area
+ * @param item - FileEntity
+ */
+ onFilesEntityDropped(item: any): void {
+ let self = this;
+ item.file(function (file: any) {
+ self._uploaderService.addToQueue([file]);
+ let path = item.fullPath.replace(item.name, '');
+ let filePath = self.uploaddirectory + path;
+ self._uploaderService.uploadFilesInTheQueue(filePath, self.onSuccess);
+ self.filesUploadingList = self._uploaderService.getQueue();
+ if (self.showUploadDialog) {
+ self._showDialog();
+ }
+ });
+ }
+
+ /**
+ * Called when a folder are dropped in the drag area
+ * @param folder - name of the dropped folder
+ */
+ onFolderEntityDropped(folder: any): void {
+ if (folder.isDirectory) {
+ let relativePath = folder.fullPath.replace(folder.name, '');
+ relativePath = this.currentFolderPath + relativePath;
+
+ this._uploaderService.createFolder(relativePath, folder.name)
+ .subscribe(
+ message => {
+ let self = this;
+ let dirReader = folder.createReader();
+ dirReader.readEntries(function (entries: any) {
+ for (let i = 0; i < entries.length; i++) {
+ self._traverseFileTree(entries[i]);
+ }
+ });
+ },
+ error => {
+ error;
+ }
+ );
+ }
+ }
+
+ /**
+ * Travers all the files and folders, and create it on the alfresco.
+ *
+ * @param {Object} item - can contains files or folders.
+ */
+ private _traverseFileTree(item: any): void {
+ if (item.isFile) {
+ let self = this;
+ self.onFilesEntityDropped(item);
+ } else {
+ if (item.isDirectory) {
+ let self = this;
+ self.onFolderEntityDropped(item);
+ }
+ }
+ }
+
/**
* Show the upload dialog.
*/
private _showDialog(): void {
this.fileUploadingDialogComponent.showDialog();
}
+
+ /**
+ * Return the site from the path
+ * @returns {string}
+ */
+ private getSiteId(): string {
+ return this.currentFolderPath.replace('/Sites/','').split('/')[0];
+ }
+
+ /**
+ * Return the container from the path
+ * @returns {string}
+ */
+ private getContainerId(): string {
+ return this.currentFolderPath.replace('/Sites/','').split('/')[1];
+ }
}
diff --git a/ng2-components/ng2-alfresco-upload/src/directives/file-draggable.directive.ts b/ng2-components/ng2-alfresco-upload/src/directives/file-draggable.directive.ts
index b315b7c450..33965cdd59 100644
--- a/ng2-components/ng2-alfresco-upload/src/directives/file-draggable.directive.ts
+++ b/ng2-components/ng2-alfresco-upload/src/directives/file-draggable.directive.ts
@@ -43,6 +43,12 @@ export class FileDraggableDirective {
@Output()
onFilesDropped: EventEmitter = new EventEmitter();
+ @Output()
+ onFilesEntityDropped: EventEmitter = new EventEmitter();
+
+ @Output()
+ onFolderEntityDropped: EventEmitter = new EventEmitter();
+
files: File [];
private _inputFocusClass: boolean = false;
@@ -75,25 +81,17 @@ export class FileDraggableDirective {
}
/**
- * Travers all the files and folders, and emit an event for each file.
+ * Travers all the files and folders, and emit an event for each file or directory.
*
* @param {Object} item - can contains files or folders.
*/
private _traverseFileTree(item: any): void {
if (item.isFile) {
let self = this;
- item.file(function (file: File) {
- self.onFilesDropped.emit([file]);
- });
+ self.onFilesEntityDropped.emit(item);
} else {
if (item.isDirectory) {
- let self = this;
- let dirReader = item.createReader();
- dirReader.readEntries(function (entries: any) {
- for (let i = 0; i < entries.length; i++) {
- self._traverseFileTree(entries[i]);
- }
- });
+ this.onFolderEntityDropped.emit(item);
}
}
}
diff --git a/ng2-components/ng2-alfresco-upload/src/services/upload.service.spec.ts b/ng2-components/ng2-alfresco-upload/src/services/upload.service.spec.ts
index 83eb896e5d..e2d8c773e7 100644
--- a/ng2-components/ng2-alfresco-upload/src/services/upload.service.spec.ts
+++ b/ng2-components/ng2-alfresco-upload/src/services/upload.service.spec.ts
@@ -21,19 +21,13 @@ import { FileModel } from './../models/file.model';
declare let jasmine: any;
-describe('AlfrescoUploadService', () => {
- let service: UploadService,
- options: any,
- xhr: XMLHttpRequest,
- doneFn: any,
- errorFn: any;
+let doneFn = jasmine.createSpy('success');
+let errorFn = jasmine.createSpy('error');
- beforeEach(() => {
- jasmine.Ajax.install();
+class MockUploadService extends UploadService {
- doneFn = jasmine.createSpy('success');
- errorFn = jasmine.createSpy('error');
- xhr = new XMLHttpRequest();
+ createXMLHttpRequestInstance() {
+ let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState === this.DONE && this.status === 200) {
doneFn(this.responseText);
@@ -42,6 +36,16 @@ describe('AlfrescoUploadService', () => {
}
};
xhr.abort = jasmine.createSpy('abort');
+ return xhr;
+ }
+}
+
+describe('AlfrescoUploadService', () => {
+ let service: MockUploadService,
+ options: any;
+
+ beforeEach(() => {
+ jasmine.Ajax.install();
options = {
url: '/some/cool/url',
@@ -54,7 +58,7 @@ describe('AlfrescoUploadService', () => {
containerid: 'fakeFolder'
}
};
- service = new UploadService(options);
+ service = new MockUploadService(options);
});
afterEach(() => {
@@ -78,12 +82,27 @@ describe('AlfrescoUploadService', () => {
});
it('should make XHR done request after the file is added in the queue', () => {
- service.setXMLHttpRequest(xhr);
+ let mockUploadSuccessResponses = {
+ upload: {
+ success: {
+ status: 200,
+ responseText: '{"nodeRef":"workspace://SpacesStore/fake","fileName": "fake-name.png","status":' +
+ '{"code": 200,"name": "OK","description": "fake file uploaded successfully"}}'
+ }
+ }
+ };
let filesFake = [{name: 'fake-name', size: 10}];
service.addToQueue(filesFake);
service.uploadFilesInTheQueue('', null);
- expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
+
+ let request = jasmine.Ajax.requests.mostRecent();
+ // request.respondWith(mockUploadSuccessResponses.upload.success);
+ expect(request.url).toBe('/some/cool/url');
+ expect(request.method).toBe('POST');
+ // expect(request.data()).toEqual({fileName: 'fake-name.png'});
+
expect(doneFn).not.toHaveBeenCalled();
+ console.log(mockUploadSuccessResponses);
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'text/plain',
@@ -93,12 +112,10 @@ describe('AlfrescoUploadService', () => {
});
it('should make XHR error request after an error occur', () => {
- service.setXMLHttpRequest(xhr);
let filesFake = [{name: 'fake-name', size: 10}];
service.addToQueue(filesFake);
service.uploadFilesInTheQueue('', null);
expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
- expect(doneFn).not.toHaveBeenCalled();
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 404,
contentType: 'text/plain',
@@ -108,30 +125,27 @@ describe('AlfrescoUploadService', () => {
});
it('should make XHR abort request after the xhr abort is called', () => {
- service.setXMLHttpRequest(xhr);
let filesFake = [{name: 'fake-name', size: 10}];
service.addToQueue(filesFake);
service.uploadFilesInTheQueue('', null);
let file = service.getQueue();
file[0].setAbort();
- expect(xhr.abort).toHaveBeenCalled();
+ expect(file[0]._xmlHttpRequest.abort).toHaveBeenCalled();
});
it('should make XHR done request after the file is upload', () => {
- service.setXMLHttpRequest(xhr);
let filesFake = {name: 'fake-name', size: 10};
let uploadingFileModel = new FileModel(filesFake);
service.uploadFile(uploadingFileModel, '', null);
expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
- expect(doneFn).not.toHaveBeenCalled();
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'text/plain',
- responseText: 'File uploaded'
+ responseText: 'Single File uploaded'
});
- expect(doneFn).toHaveBeenCalledWith('File uploaded');
+ expect(doneFn).toHaveBeenCalledWith('Single File uploaded');
});
});
diff --git a/ng2-components/ng2-alfresco-upload/src/services/upload.service.ts b/ng2-components/ng2-alfresco-upload/src/services/upload.service.ts
index a6681b82f4..87484cb6d4 100644
--- a/ng2-components/ng2-alfresco-upload/src/services/upload.service.ts
+++ b/ng2-components/ng2-alfresco-upload/src/services/upload.service.ts
@@ -18,7 +18,8 @@
import { FileModel } from '../models/file.model';
import { EventEmitter } from 'angular2/core';
-
+import { Observable } from 'rxjs/Observable';
+import { Response } from 'angular2/http';
/**
*
@@ -27,28 +28,77 @@ import { EventEmitter } from 'angular2/core';
* @returns {UploadService} .
*/
export class UploadService {
- private _url: string;
+ private _host: string = 'http://192.168.99.100:8080';
+ private _baseUrlPath: string = '/alfresco/api/-default-/public/alfresco/versions/1';
+ private _url: string = '/alfresco/service/api/upload';
+
private _method: string = 'POST';
- private _authTokenPrefix: string = 'Basic';
- private _authToken: string = undefined;
private _fieldName: string = 'file';
private _formFields: Object = {};
- private _withCredentials: boolean;
- private _xmlHttpRequest: XMLHttpRequest;
private _queue: FileModel[] = [];
+ private _alfrescoClient: any;
+
constructor(private options: any) {
console.log('UploadService constructor');
- this._withCredentials = options.withCredentials != null ? options.withCredentials : this._withCredentials;
- this._url = options.url != null ? options.url : this._url;
- this._authTokenPrefix = options.authTokenPrefix != null ? options.authTokenPrefix : this._authTokenPrefix;
- this._authToken = options.authToken != null ? options.authToken : this._authToken;
+ this._alfrescoClient = this.getAlfrescoClient();
+
+ this._host = options.host || this._host;
+ this._baseUrlPath = options.baseUrlPath || this._baseUrlPath;
this._fieldName = options.fieldName != null ? options.fieldName : this._fieldName;
this._formFields = options.formFields != null ? options.formFields : this._formFields;
}
+ /**
+ * Get the host
+ * @returns {string}
+ */
+ public get host(): string {
+ return this._host;
+ }
+
+ /**
+ * Set the host
+ * @param value
+ */
+ public set host(value: string) {
+ this._host = value;
+ }
+
+ /**
+ * Get the base url
+ * @returns {string}
+ */
+ private getBaseUrl(): string {
+ return this._host + this._baseUrlPath;
+ }
+
+ /**
+ * Get the token from the local storage
+ * @returns {any}
+ */
+ private getAlfrescoTicket(): string {
+ return localStorage.getItem('token');
+ }
+
+ /**
+ * Get the alfresco client
+ * @returns {AlfrescoApi.ApiClient}
+ */
+ private getAlfrescoClient() {
+ let defaultClient = new AlfrescoApi.ApiClient();
+ defaultClient.basePath = this.getBaseUrl();
+
+ // Configure HTTP basic authorization: basicAuth
+ let basicAuth = defaultClient.authentications['basicAuth'];
+ basicAuth.username = 'ROLE_TICKET';
+ basicAuth.password = this.getAlfrescoTicket();
+
+ return defaultClient;
+ }
+
/**
* Add files to the uploading queue to be uploaded.
*
@@ -83,43 +133,43 @@ export class UploadService {
};
/**
- * The method create a new XMLHttpRequest instance if doesn't exist
+ * Create an XMLHttpRequest and return it
+ * @returns {XMLHttpRequest}
*/
- private _configureXMLHttpRequest(uploadingFileModel: any, elementEmit: EventEmitter) {
- if (this._xmlHttpRequest === undefined) {
- this._xmlHttpRequest = new XMLHttpRequest();
- this._xmlHttpRequest.upload.onprogress = (e) => {
- if (e.lengthComputable) {
- let percent = Math.round(e.loaded / e.total * 100);
- uploadingFileModel.setProgres({
- total: e.total,
- loaded: e.loaded,
- percent: percent
- });
- }
- };
+ createXMLHttpRequestInstance(uploadingFileModel: any, elementEmit: EventEmitter) {
+ let xmlHttpRequest = new XMLHttpRequest();
+ xmlHttpRequest.upload.onprogress = (e) => {
+ if (e.lengthComputable) {
+ let percent = Math.round(e.loaded / e.total * 100);
+ uploadingFileModel.setProgres({
+ total: e.total,
+ loaded: e.loaded,
+ percent: percent
+ });
+ }
+ };
- this._xmlHttpRequest.upload.onabort = (e) => {
- uploadingFileModel.setAbort();
- };
+ xmlHttpRequest.upload.onabort = (e) => {
+ uploadingFileModel.setAbort();
+ };
- this._xmlHttpRequest.upload.onerror = (e) => {
- uploadingFileModel.setError();
- };
+ xmlHttpRequest.upload.onerror = (e) => {
+ uploadingFileModel.setError();
+ };
- this._xmlHttpRequest.onreadystatechange = () => {
- if (this._xmlHttpRequest.readyState === XMLHttpRequest.DONE) {
- elementEmit.emit({
- value: 'File uploaded'
- });
- uploadingFileModel.onFinished(
- this._xmlHttpRequest.status,
- this._xmlHttpRequest.statusText,
- this._xmlHttpRequest.response
- );
- }
- };
- }
+ xmlHttpRequest.onreadystatechange = () => {
+ if (xmlHttpRequest.readyState === XMLHttpRequest.DONE) {
+ elementEmit.emit({
+ value: 'File uploaded'
+ });
+ uploadingFileModel.onFinished(
+ xmlHttpRequest.status,
+ xmlHttpRequest.statusText,
+ xmlHttpRequest.response
+ );
+ }
+ };
+ return xmlHttpRequest;
}
/**
@@ -129,6 +179,11 @@ export class UploadService {
*
*/
uploadFile(uploadingFileModel: FileModel, directory: string, elementEmit: EventEmitter): void {
+ // Configure HTTP basic authorization: basicAuth
+ let basicAuth = this._alfrescoClient.authentications['basicAuth'];
+ basicAuth.username = 'ROLE_TICKET';
+ basicAuth.password = this.getAlfrescoTicket();
+
let form = new FormData();
form.append(this._fieldName, uploadingFileModel.file, uploadingFileModel.name);
Object.keys(this._formFields).forEach((key: any) => {
@@ -137,17 +192,15 @@ export class UploadService {
form.append('uploaddirectory', directory);
- this._configureXMLHttpRequest(uploadingFileModel, elementEmit);
- uploadingFileModel.setXMLHttpRequest(this._xmlHttpRequest);
+ let xmlHttpRequest = this.createXMLHttpRequestInstance(uploadingFileModel, elementEmit);
- this._xmlHttpRequest.open(this._method, this._url, true);
- this._xmlHttpRequest.withCredentials = this._withCredentials;
-
- if (this._authToken) {
- this._xmlHttpRequest.setRequestHeader('Authorization', `${this._authTokenPrefix} ${this._authToken}`);
+ xmlHttpRequest.open(this._method, this._host + this._url, true);
+ let authToken = btoa(basicAuth.username +':'+ basicAuth.password);
+ if (authToken) {
+ xmlHttpRequest.setRequestHeader('Authorization', `${basicAuth.type} ${authToken}`);
}
- this._xmlHttpRequest.send(form);
+ xmlHttpRequest.send(form);
}
/**
@@ -169,10 +222,35 @@ export class UploadService {
}
/**
- * Set XMLHttpRequest method
- * @param xhr
+ * Create a folder
+ * @param name - the folder name
*/
- public setXMLHttpRequest(xhr: XMLHttpRequest) {
- this._xmlHttpRequest = xhr;
+ createFolder(relativePath: string, name: string) {
+ console.log('Directory created' + name);
+ let apiInstance = new AlfrescoApi.NodesApi(this._alfrescoClient);
+ let nodeId = '-root-';
+ let nodeBody = {
+ 'name':name,
+ 'nodeType':'cm:folder',
+ 'relativePath':relativePath
+ };
+ return Observable.fromPromise(apiInstance.addNode(nodeId, nodeBody))
+ .map(res => {
+ console.log(res);
+ } )
+ .do(data => console.log('Node data', data)) // eyeball results in the console
+ .catch(this.handleError);
+ }
+
+ /**
+ * Throw the error
+ * @param error
+ * @returns {ErrorObservable}
+ */
+ private handleError(error: Response) {
+ // in a real world app, we may send the error to some remote logging infrastructure
+ // instead of just logging it to the console
+ console.error(error);
+ return Observable.throw(error || 'Server error');
}
}