diff --git a/docs/compodoc/coverage.html b/docs/compodoc/coverage.html index 49ae922abacbc6dde72b5fdf90e797779b2d1a1c..13d717767fcbd9208c61c9a5d4a52f39c71a8de9 100644 --- a/docs/compodoc/coverage.html +++ b/docs/compodoc/coverage.html @@ -43,7 +43,7 @@ - + <ol class="breadcrumb"> @@ -2107,7 +2107,7 @@ <tr class="low"> <td> <!-- miscellaneous --> - <a href="./directives/IqbFilesUploadInputForDirective.html">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts</a> + <a href="./directives/IqbFilesUploadInputForDirective.html">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts</a> </td> <td>directive</td> <td>IqbFilesUploadInputForDirective</td> diff --git a/docs/compodoc/directives/IqbFilesUploadInputForDirective.html b/docs/compodoc/directives/IqbFilesUploadInputForDirective.html index deb824851c3a742de673790d5f698ed2d2e17000..48a0498a41edac7029cadc17a295701445ef17c7 100644 --- a/docs/compodoc/directives/IqbFilesUploadInputForDirective.html +++ b/docs/compodoc/directives/IqbFilesUploadInputForDirective.html @@ -55,7 +55,7 @@ <h3>File</h3> </p> <p class="comment"> - <code>src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts</code> + <code>src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts</code> </p> @@ -161,7 +161,7 @@ </tr> <tr> <td class="col-md-4"> - <div class="io-line">Defined in <a href="" data-line="11" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts:11</a></div> + <div class="io-line">Defined in <a href="" data-line="11" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts:11</a></div> </td> </tr> @@ -180,15 +180,15 @@ <tbody> <tr> <td>element</td> - + <td> <code><a href="https://angular.io/api/core/ElementRef" target="_blank" >ElementRef</a></code> </td> - + <td> No </td> - + </tr> </tbody> </table> @@ -217,7 +217,7 @@ </tr> <tr> <td class="col-md-2" colspan="2"> - <div class="io-line">Defined in <a href="" data-line="18" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts:18</a></div> + <div class="io-line">Defined in <a href="" data-line="18" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts:18</a></div> </td> </tr> </tbody> @@ -249,7 +249,7 @@ <tr> <td class="col-md-4"> <div class="io-line">Defined in <a href="" data-line="25" - class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts:25</a></div> + class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts:25</a></div> </td> </tr> @@ -259,7 +259,7 @@ </section> <section> - + <h3 id="inputs"> Properties </h3> @@ -284,7 +284,7 @@ </tr> <tr> <td class="col-md-4"> - <div class="io-line">Defined in <a href="" data-line="11" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts:11</a></div> + <div class="io-line">Defined in <a href="" data-line="11" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts:11</a></div> </td> </tr> @@ -317,7 +317,7 @@ </tr> <tr> <td class="col-md-4"> - <div class="io-line">Defined in <a href="" data-line="10" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts:10</a></div> + <div class="io-line">Defined in <a href="" data-line="10" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts:10</a></div> </td> </tr> @@ -347,7 +347,7 @@ </tr> <tr> <td class="col-md-4"> - <div class="io-line">Defined in <a href="" data-line="18" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts:18</a></div> + <div class="io-line">Defined in <a href="" data-line="18" class="link-to-prism">src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqb-files-upload-input-for.directive.ts:18</a></div> </td> </tr> <tr> @@ -366,15 +366,15 @@ <tbody> <tr> <td>value</td> - + <td> <code><a href="https://www.typescriptlang.org/docs/handbook/basic-types.html" target="_blank" >any</a></code> </td> - + <td> No </td> - + </tr> </tbody> </table> @@ -441,7 +441,7 @@ export class IqbFilesUploadInputForDirective { - + diff --git a/src/app/workspace-admin/backend.service.ts b/src/app/workspace-admin/backend.service.ts index 15fbbd7e32223cf0e879b2548e7c293f77127560..3575e2b7e5f8c2aef00f18eb871cdb08c3631cd0 100644 --- a/src/app/workspace-admin/backend.service.ts +++ b/src/app/workspace-admin/backend.service.ts @@ -1,13 +1,19 @@ +/* eslint-disable no-console */ import { Injectable, Inject, SkipSelf } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { + HttpClient, HttpErrorResponse, HttpEvent, HttpEventType +} from '@angular/common/http'; import { Observable, of } from 'rxjs'; -import { catchError, map } from 'rxjs/operators'; +import { catchError, filter, map } from 'rxjs/operators'; import { GetFileResponseData, SysCheckStatistics, ReviewData, LogData, UnitResponse, ResultData } from './workspace.interfaces'; import { WorkspaceDataService } from './workspacedata.service'; import { ApiError, WorkspaceData } from '../app.interfaces'; +import { + FileDeletionReport, UploadReport, UploadResponse, UploadStatus +} from './files/files.interfaces'; @Injectable({ providedIn: 'root' @@ -173,11 +179,53 @@ export class BackendService { }) ); } -} -export interface FileDeletionReport { - deleted: string[]; - not_allowed: string[]; - did_not_exist: string[]; - was_used: string[]; + uploadFile(formData: FormData): Observable<UploadResponse> { + return this.http.post<UploadReport>( + `${this.serverUrl}workspace/${this.wds.wsId}/file`, + formData, + { + // TODO de-comment, if backend UploadedFilesHandler.class.php l. 47 was fixed + // headers: new HttpHeaders().set('Content-Type', 'multipart/form-data'), + observe: 'events', + reportProgress: true, + responseType: 'json' + } + ) + .pipe( + catchError((err: ApiError) => { + console.warn(`downloadFile Api-Error: ${err.code} ${err.info} `); + let errorText = 'Hochladen nicht erfolgreich.'; + if (err instanceof HttpErrorResponse) { + errorText = (err as HttpErrorResponse).message; + } else if (err instanceof ApiError) { + const slashPos = err.info.indexOf(' // '); + errorText = (slashPos > 0) ? err.info.substr(slashPos + 4) : err.info; + } + return of({ + progress: 0, + status: UploadStatus.error, + report: { '': { error: [errorText] } } + }); + }), + map((event: HttpEvent<UploadReport>) => { + if (event.type === HttpEventType.UploadProgress) { + return { + progress: Math.floor((event.loaded * 100) / event.total), + status: UploadStatus.busy, + report: {} + }; + } + if (event.type === HttpEventType.Response) { + return { + progress: 100, + status: UploadStatus.ok, + report: event.body + }; + } + return null; + }), + filter((response: UploadResponse|null) => !!response) + ); + } } diff --git a/src/app/workspace-admin/files/files.component.html b/src/app/workspace-admin/files/files.component.html index 4f69deb9fee3f463cae356696d946902f03a8ec5..fc2d4a260f9944732ef8509536aadd6bd6c3de04 100644 --- a/src/app/workspace-admin/files/files.component.html +++ b/src/app/workspace-admin/files/files.component.html @@ -99,7 +99,6 @@ <input #hiddenfileinput type="file" name="fileforvo" multiple [iqbFilesUploadInputFor]="fileUploadQueue" [hidden]="true"/> <iqb-files-upload-queue #fileUploadQueue - [httpUrl]="uploadUrl" [fileAlias]="fileNameAlias" [folderName]="'ws'" [folder]="'workspace'" diff --git a/src/app/workspace-admin/files/files.component.spec.ts b/src/app/workspace-admin/files/files.component.spec.ts index c55f8b4a582cd500b883a062b717e11de8c1db32..e48f3a387d5a72692dbcc13b27306deec006b7d1 100644 --- a/src/app/workspace-admin/files/files.component.spec.ts +++ b/src/app/workspace-admin/files/files.component.spec.ts @@ -11,7 +11,6 @@ import { FilesComponent } from './files.component'; import { BackendService } from '../backend.service'; import { WorkspaceDataService } from '../workspacedata.service'; import { MainDataService } from '../../maindata.service'; -import { IqbFilesUploadQueueComponent, IqbFilesUploadInputForDirective } from './iqb-files'; import { GetFileResponseData } from '../workspace.interfaces'; class MockBackendService { @@ -34,9 +33,7 @@ describe('FilesComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ - FilesComponent, - IqbFilesUploadQueueComponent, - IqbFilesUploadInputForDirective + FilesComponent ], imports: [ HttpClientModule, diff --git a/src/app/workspace-admin/files/files.component.ts b/src/app/workspace-admin/files/files.component.ts index b98eddb40dfcd9a8504283d97ac6737868448b7b..b91e72c00600368aad8783d3e3dfb62d33c6783c 100644 --- a/src/app/workspace-admin/files/files.component.ts +++ b/src/app/workspace-admin/files/files.component.ts @@ -16,9 +16,10 @@ import { WorkspaceDataService } from '../workspacedata.service'; import { IQBFileType, GetFileResponseData, IQBFile, IQBFileTypes } from '../workspace.interfaces'; -import { BackendService, FileDeletionReport } from '../backend.service'; +import { BackendService } from '../backend.service'; import { MainDataService } from '../../maindata.service'; -import { IqbFilesUploadQueueComponent } from './iqb-files'; +import { IqbFilesUploadQueueComponent } from './iqb-files-upload-queue/iqb-files-upload-queue.component'; +import { FileDeletionReport } from './files.interfaces'; interface FileStats { invalid: { @@ -39,8 +40,6 @@ export class FilesComponent implements OnInit { files: { [type in IQBFileType]?: MatTableDataSource<IQBFile> } = {}; fileTypes = IQBFileTypes; displayedColumns = ['checked', 'name', 'size', 'modificationTime']; - - uploadUrl = ''; fileNameAlias = 'fileforvo'; lastSort:Sort = { @@ -79,7 +78,7 @@ export class FilesComponent implements OnInit { ) { } ngOnInit(): void { - this.uploadUrl = `${this.serverUrl}workspace/${this.wds.wsId}/file`; + // this.uploadUrl = `${this.serverUrl}workspace/${this.wds.wsId}/file`; setTimeout(() => { this.mds.setSpinnerOn(); this.updateFileList(); diff --git a/src/app/workspace-admin/files/files.interfaces.ts b/src/app/workspace-admin/files/files.interfaces.ts new file mode 100644 index 0000000000000000000000000000000000000000..3b0c2730219b76b4752886f52ac89af943379b3c --- /dev/null +++ b/src/app/workspace-admin/files/files.interfaces.ts @@ -0,0 +1,27 @@ +export interface FileDeletionReport { + deleted: string[]; + not_allowed: string[]; + did_not_exist: string[]; + was_used: string[]; +} + +export interface UploadReport { + [filename: string]: { + warning?: string[]; + error?: string[]; + info?: string[]; + } +} + +export enum UploadStatus { + ready, + busy, + ok, + error +} + +export interface UploadResponse { + status: UploadStatus; + progress: number; + report: UploadReport; +} diff --git a/src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts b/src/app/workspace-admin/files/iqb-files-upload-input-for/iqb-files-upload-input-for.directive.ts similarity index 72% rename from src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts rename to src/app/workspace-admin/files/iqb-files-upload-input-for/iqb-files-upload-input-for.directive.ts index da6566cf606a623ad83139c29958b161402797a2..b6c07792c1ef16044ff2fdd0ee3e762a2af31de0 100644 --- a/src/app/workspace-admin/files/iqb-files/iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive.ts +++ b/src/app/workspace-admin/files/iqb-files-upload-input-for/iqb-files-upload-input-for.directive.ts @@ -1,13 +1,13 @@ import { Directive, ElementRef, HostListener, Input } from '@angular/core'; +import { IqbFilesUploadQueueComponent } from '../iqb-files-upload-queue/iqb-files-upload-queue.component'; @Directive({ - selector: 'input[iqbFilesUploadInputFor], div[iqbFilesUploadInputFor]', + selector: 'input[iqbFilesUploadInputFor], div[iqbFilesUploadInputFor]' }) export class IqbFilesUploadInputForDirective { - - private _queue: any = null; + private _queue: IqbFilesUploadQueueComponent = null; private _element: HTMLElement; constructor(private element: ElementRef) { @@ -15,14 +15,14 @@ export class IqbFilesUploadInputForDirective { } @Input('iqbFilesUploadInputFor') - set filesUploadQueue(value: any) { + set filesUploadQueue(value: IqbFilesUploadQueueComponent) { if (value) { this._queue = value; } } @HostListener('change') - public onChange(): any { + onChange(): void { const { files } = this.element.nativeElement; // this.onFileSelected.emit(files); diff --git a/src/app/workspace-admin/files/iqb-files/iqbFilesUploadQueue/iqbFilesUploadQueue.component.html b/src/app/workspace-admin/files/iqb-files-upload-queue/iqb-files-upload-queue.component.html similarity index 96% rename from src/app/workspace-admin/files/iqb-files/iqbFilesUploadQueue/iqbFilesUploadQueue.component.html rename to src/app/workspace-admin/files/iqb-files-upload-queue/iqb-files-upload-queue.component.html index 36764c8c6fcc71673e7ecc7ce7c924504b8624a0..0e41ad6c35b01cc4076e6b084a16c978a82b0501 100644 --- a/src/app/workspace-admin/files/iqb-files/iqbFilesUploadQueue/iqbFilesUploadQueue.component.html +++ b/src/app/workspace-admin/files/iqb-files-upload-queue/iqb-files-upload-queue.component.html @@ -7,7 +7,6 @@ *ngFor="let file of files; let i = index" [file]="file" [id]="i" - [httpUrl]="httpUrl" [fileAlias]="fileAlias" [folderName]="folderName" [folder]="folder" diff --git a/src/app/workspace-admin/files/iqb-files/iqbFilesUploadQueue/iqbFilesUploadQueue.component.ts b/src/app/workspace-admin/files/iqb-files-upload-queue/iqb-files-upload-queue.component.ts similarity index 63% rename from src/app/workspace-admin/files/iqb-files/iqbFilesUploadQueue/iqbFilesUploadQueue.component.ts rename to src/app/workspace-admin/files/iqb-files-upload-queue/iqb-files-upload-queue.component.ts index 7357db2331e08eb725f49e4281ac712624501a28..57e9bb3f33ef11a5872813196d18824f55df66bc 100644 --- a/src/app/workspace-admin/files/iqb-files/iqbFilesUploadQueue/iqbFilesUploadQueue.component.ts +++ b/src/app/workspace-admin/files/iqb-files-upload-queue/iqb-files-upload-queue.component.ts @@ -1,35 +1,19 @@ import { Component, EventEmitter, OnDestroy, QueryList, ViewChildren, Input, Output } from '@angular/core'; -import { HttpHeaders, HttpParams } from '@angular/common/http'; -import { IqbFilesUploadComponent, UploadStatus } from '../iqbFilesUpload/iqbFilesUpload.component'; +import { IqbFilesUploadComponent } from '../iqb-files-upload/iqb-files-upload.component'; +import { UploadStatus } from '../files.interfaces'; @Component({ selector: 'iqb-files-upload-queue', - templateUrl: 'iqbFilesUploadQueue.component.html', - exportAs: 'iqbFilesUploadQueue', + templateUrl: 'iqb-files-upload-queue.component.html', styleUrls: ['../iqb-files.scss'] }) export class IqbFilesUploadQueueComponent implements OnDestroy { @ViewChildren(IqbFilesUploadComponent) fileUploads: QueryList<IqbFilesUploadComponent>; - public files: Array<any> = []; - - public disableClearButton = true; - - /* Http request input bindings */ - @Input() - httpUrl: string; - - @Input() - httpRequestHeaders: HttpHeaders | { - [header: string]: string | string[]; - } = new HttpHeaders().set('Content-Type', 'multipart/form-data'); - - @Input() - httpRequestParams: HttpParams | { - [param: string]: string | string[]; - } = new HttpParams(); + files: Array<File> = []; + disableClearButton = true; @Input() fileAlias: string; @@ -40,13 +24,14 @@ export class IqbFilesUploadQueueComponent implements OnDestroy { @Input() folder: string; - @Output() uploadCompleteEvent = new EventEmitter<IqbFilesUploadQueueComponent>(); + @Output() + uploadCompleteEvent = new EventEmitter<IqbFilesUploadQueueComponent>(); - add(file: any): void { + add(file: File): void { this.files.push(file); } - public removeAll(): void { + removeAll(): void { this.files.splice(0, this.files.length); } diff --git a/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.html b/src/app/workspace-admin/files/iqb-files-upload/iqb-files-upload.component.html similarity index 86% rename from src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.html rename to src/app/workspace-admin/files/iqb-files-upload/iqb-files-upload.component.html index 6cdf1a054f7c5ed6fe87f2b8a1db4f449a5554b8..9e50adc56c5fedaac256a42fa6518251e1ab0ad5 100644 --- a/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.html +++ b/src/app/workspace-admin/files/iqb-files-upload/iqb-files-upload.component.html @@ -8,7 +8,7 @@ <ng-container *ngIf="status > 1"> <ng-container *ngFor="let uploadedFile of uploadResponse | keyvalue"> <div class="subheading-2 {{uploadedFile.value.error ? 'error' : 'success'}}"> - {{uploadedFile.key || file.name}} - {{uploadedFile.value.error ? 'Abgelehnt' : 'Erfolgreich hochgeladen'}} + {{uploadedFile.key}} - {{uploadedFile.value.error ? 'Abgelehnt' : 'Erfolgreich hochgeladen'}} </div> <ng-container *ngFor="let report of uploadedFile.value | keyvalue"> <alert *ngFor="let reportEntry of report.value" [level]="report.key" [text]="reportEntry"></alert> diff --git a/src/app/workspace-admin/files/iqb-files-upload/iqb-files-upload.component.ts b/src/app/workspace-admin/files/iqb-files-upload/iqb-files-upload.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..eaee830cafe252c19ed32bc1c83c6a358aa33242 --- /dev/null +++ b/src/app/workspace-admin/files/iqb-files-upload/iqb-files-upload.component.ts @@ -0,0 +1,121 @@ +import { + Component, EventEmitter, HostBinding, Input, OnDestroy, OnInit, Output +} from '@angular/core'; +import { Subscription } from 'rxjs'; +import { BackendService } from '../../backend.service'; +import { UploadReport, UploadStatus } from '../files.interfaces'; + +@Component({ + selector: 'iqb-files-upload', + templateUrl: './iqb-files-upload.component.html', + styleUrls: ['../iqb-files.scss'] +}) +export class IqbFilesUploadComponent implements OnInit, OnDestroy { + @HostBinding('class') myclass = 'iqb-files-upload'; + + constructor( + private bs: BackendService + ) { } + + private _status: UploadStatus; + get status(): UploadStatus { + return this._status; + } + + set status(newstatus: UploadStatus) { + this._status = newstatus; + this.statusChangedEvent.emit(this); + } + + private requestResponse: UploadReport; + get uploadResponse(): UploadReport { + switch (this._status) { + case UploadStatus.busy: + return { '': { info: ['Bitte warten'] } }; + case UploadStatus.ready: + return { '': { info: ['Bereit'] } }; + default: + return this.requestResponse; + } + } + + /* Http request input bindings */ + + @Input() + fileAlias = 'file'; + + @Input() + folderName = ''; + + @Input() + folder = ''; + + @Input() + get file(): File { + return this._file; + } + + set file(file: File) { + this._file = file; + this._filedate = this._file.lastModified; + } + + @Input() + set id(id: number) { + this._id = id; + } + + get id(): number { + return this._id; + } + + @Output() removeFileRequestEvent = new EventEmitter<IqbFilesUploadComponent>(); + @Output() statusChangedEvent = new EventEmitter<IqbFilesUploadComponent>(); + + progressPercentage = 0; + private _file: File; + private _filedate = 0; + private _id: number; + private fileUploadSubscription: Subscription; + + ngOnInit(): void { + this._status = UploadStatus.ready; + this.requestResponse = {}; + this.upload(); + } + + upload(): void { + if (this.status !== UploadStatus.ready) { + return; + } + + this.status = UploadStatus.busy; + const formData = new FormData(); + formData.set(this.fileAlias, this._file, this._file.name); + if ((typeof this.folderName !== 'undefined') && (typeof this.folder !== 'undefined')) { + if (this.folderName.length > 0) { + formData.append(this.folderName, this.folder); + } + } + + this.fileUploadSubscription = this.bs.uploadFile(formData) + .subscribe(res => { + this.requestResponse = res.report; + this.status = res.status; + this.progressPercentage = res.progress; + }); + } + + remove(): void { + if (this.fileUploadSubscription) { + this.fileUploadSubscription.unsubscribe(); + } + this.removeFileRequestEvent.emit(this); + } + + ngOnDestroy(): void { + if (this.fileUploadSubscription) { + this.fileUploadSubscription.unsubscribe(); + } + } +} diff --git a/src/app/workspace-admin/files/iqb-files/iqb-files.scss b/src/app/workspace-admin/files/iqb-files.scss similarity index 99% rename from src/app/workspace-admin/files/iqb-files/iqb-files.scss rename to src/app/workspace-admin/files/iqb-files.scss index d64916d7e593245048045e1ffaa8db98d4ed1d00..a930955eac275fb389d1aeccfa951dfdef19b6f7 100644 --- a/src/app/workspace-admin/files/iqb-files/iqb-files.scss +++ b/src/app/workspace-admin/files/iqb-files.scss @@ -28,5 +28,3 @@ cursor: pointer; outline: none; } - - diff --git a/src/app/workspace-admin/files/iqb-files/index.ts b/src/app/workspace-admin/files/iqb-files/index.ts deleted file mode 100644 index b502832e644589da50860017cdd161fe34b458e4..0000000000000000000000000000000000000000 --- a/src/app/workspace-admin/files/iqb-files/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { IqbFilesUploadQueueComponent } from './iqbFilesUploadQueue/iqbFilesUploadQueue.component'; -export { IqbFilesUploadInputForDirective } from './iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive'; -export { IqbFilesModule } from './iqb-files.module'; diff --git a/src/app/workspace-admin/files/iqb-files/iqb-files.module.ts b/src/app/workspace-admin/files/iqb-files/iqb-files.module.ts deleted file mode 100644 index 3e315635abaab8b04b2e86642e7c54d146241cc2..0000000000000000000000000000000000000000 --- a/src/app/workspace-admin/files/iqb-files/iqb-files.module.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatCardModule } from '@angular/material/card'; -import { MatProgressBarModule } from '@angular/material/progress-bar'; -import { MatIconModule } from '@angular/material/icon'; -import { CommonModule } from '@angular/common'; - -import { IqbComponentsModule } from 'iqb-components'; -import { IqbFilesUploadComponent } from './iqbFilesUpload/iqbFilesUpload.component'; -import { IqbFilesUploadQueueComponent } from './iqbFilesUploadQueue/iqbFilesUploadQueue.component'; -import { IqbFilesUploadInputForDirective } from './iqbFilesUploadInputFor/iqbFilesUploadInputFor.directive'; - -@NgModule({ - imports: [ - MatButtonModule, - MatProgressBarModule, - MatIconModule, - MatCardModule, - IqbComponentsModule, - CommonModule - ], - declarations: [ - IqbFilesUploadComponent, - IqbFilesUploadQueueComponent, - IqbFilesUploadInputForDirective - ], - exports: [ - IqbFilesUploadQueueComponent, - IqbFilesUploadInputForDirective - ] -}) -export class IqbFilesModule { } diff --git a/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts b/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts deleted file mode 100644 index 2e86562a888bf8b25767e5528febe04ae6045be1..0000000000000000000000000000000000000000 --- a/src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts +++ /dev/null @@ -1,178 +0,0 @@ -import { - Component, EventEmitter, HostBinding, Input, OnDestroy, OnInit, Output, SkipSelf -} from '@angular/core'; -import { - HttpClient, HttpErrorResponse, HttpEvent, HttpEventType, HttpHeaders, HttpParams -} from '@angular/common/http'; -import { Subscription } from 'rxjs'; -import { ApiError } from '../../../../app.interfaces'; - -interface UploadResponse { - [filename: string]: { - warning?: string[]; - error?: string[]; - info?: string[]; - } -} - -export enum UploadStatus { - ready, - busy, - ok, - error -} - -@Component({ - selector: 'iqb-files-upload', - templateUrl: './iqbFilesUpload.component.html', - exportAs: 'iqbFilesUpload', - styleUrls: ['../iqb-files.scss'] -}) -export class IqbFilesUploadComponent implements OnInit, OnDestroy { - @HostBinding('class') myclass = 'iqb-files-upload'; - - constructor( - @SkipSelf() private httpClient: HttpClient - ) { } - - private _status: UploadStatus; - get status(): UploadStatus { - return this._status; - } - - set status(newstatus: UploadStatus) { - this._status = newstatus; - this.statusChangedEvent.emit(this); - } - - private requestResponse: UploadResponse; - get uploadResponse(): UploadResponse { - switch (this._status) { - case UploadStatus.busy: - return { '': { info: ['Bitte warten'] } }; - case UploadStatus.ready: - return { '': { info: ['Bereit'] } }; - default: - return this.requestResponse; - } - } - - /* Http request input bindings */ - @Input() - httpUrl = 'http://localhost:8080'; // TODO use normal backend-connection instead - - @Input() - httpRequestHeaders: HttpHeaders | { - [header: string]: string | string[]; - } = new HttpHeaders().set('Content-Type', 'multipart/form-data'); - - @Input() - httpRequestParams: HttpParams | { - [param: string]: string | string[]; - } = new HttpParams(); - - @Input() - fileAlias = 'file'; - - @Input() - folderName = ''; - - @Input() - folder = ''; - - @Input() - get file(): any { - return this._file; - } - - set file(file: any) { - this._file = file; - this._filedate = this._file.lastModified; - this.total = this._file.size; - } - - @Input() - set id(id: number) { - this._id = id; - } - - get id(): number { - return this._id; - } - - @Output() removeFileRequestEvent = new EventEmitter<IqbFilesUploadComponent>(); - @Output() statusChangedEvent = new EventEmitter<IqbFilesUploadComponent>(); - - progressPercentage = 0; - loaded = 0; - private total = 0; - private _file: any; - private _filedate = ''; - private _id: number; - private fileUploadSubscription: Subscription; - - ngOnInit(): void { - this._status = UploadStatus.ready; - this.requestResponse = {}; - this.upload(); - } - - upload(): void { - if (this.status !== UploadStatus.ready) { - return; - } - - this.status = UploadStatus.busy; - const formData = new FormData(); - formData.set(this.fileAlias, this._file, this._file.name); - if ((typeof this.folderName !== 'undefined') && (typeof this.folder !== 'undefined')) { - if (this.folderName.length > 0) { - formData.append(this.folderName, this.folder); - } - } - - this.fileUploadSubscription = this.httpClient.post(this.httpUrl, formData, { - // headers: this.httpRequestHeaders, TODO why is this commented, and would it not be better? - observe: 'events', - params: this.httpRequestParams, - reportProgress: true, - responseType: 'json' - }).subscribe((event: HttpEvent<any>) => { - if (event.type === HttpEventType.UploadProgress) { - this.progressPercentage = Math.floor((event.loaded * 100) / event.total); - this.loaded = event.loaded; - this.total = event.total; - this.status = UploadStatus.busy; - } else if (event.type === HttpEventType.Response) { - this.requestResponse = event.body; - this.status = UploadStatus.ok; - } - }, err => { - if (this.fileUploadSubscription) { - this.fileUploadSubscription.unsubscribe(); - } - this.status = UploadStatus.error; - let errorText = 'Hochladen nicht erfolgreich.'; - if (err instanceof HttpErrorResponse) { - errorText = (err as HttpErrorResponse).message; - } else if (err instanceof ApiError) { - const slashPos = err.info.indexOf(' // '); - errorText = (slashPos > 0) ? err.info.substr(slashPos + 4) : err.info; - } - this.requestResponse = { '': { error: [errorText] } }; - }); - } - - remove(): void { - if (this.fileUploadSubscription) { - this.fileUploadSubscription.unsubscribe(); - } - this.removeFileRequestEvent.emit(this); - } - - ngOnDestroy(): void { - if (this.fileUploadSubscription) { - this.fileUploadSubscription.unsubscribe(); - } - } -} diff --git a/src/app/workspace-admin/workspace.module.ts b/src/app/workspace-admin/workspace.module.ts index 8f5ed6a8104d11f4f8e914d45af74917486bacbb..de8ce24c919744cbd62e4c74b419a788ed8216d2 100644 --- a/src/app/workspace-admin/workspace.module.ts +++ b/src/app/workspace-admin/workspace.module.ts @@ -28,7 +28,10 @@ import { WorkspaceComponent } from './workspace.component'; import { FilesComponent } from './files/files.component'; import { ResultsComponent } from './results/results.component'; import { SyscheckComponent } from './syscheck/syscheck.component'; -import { IqbFilesModule } from './files/iqb-files'; +import { IqbFilesUploadComponent } from './files/iqb-files-upload/iqb-files-upload.component'; +import { IqbFilesUploadQueueComponent } from './files/iqb-files-upload-queue/iqb-files-upload-queue.component'; +import { IqbFilesUploadInputForDirective } from './files/iqb-files-upload-input-for/iqb-files-upload-input-for.directive'; +import {MatProgressBarModule} from '@angular/material/progress-bar'; @NgModule({ imports: [ @@ -55,7 +58,7 @@ import { IqbFilesModule } from './files/iqb-files'; IqbComponentsModule, MatCardModule, FlexLayoutModule, - IqbFilesModule + MatProgressBarModule, ], exports: [ WorkspaceComponent @@ -64,7 +67,10 @@ import { IqbFilesModule } from './files/iqb-files'; WorkspaceComponent, FilesComponent, ResultsComponent, - SyscheckComponent + SyscheckComponent, + IqbFilesUploadComponent, + IqbFilesUploadQueueComponent, + IqbFilesUploadInputForDirective ], providers: [ BackendService,