File

src/app/workspace-admin/files/iqb-files/iqbFilesUpload/iqbFilesUpload.component.ts

Implements

OnInit OnDestroy

Metadata

exportAs iqbFilesUpload
selector iqb-files-upload
styleUrls ../iqb-files.scss
templateUrl ./iqbFilesUpload.component.html

Index

Properties
Methods
Inputs
Outputs
HostBindings
Accessors

Constructor

constructor(myHttpClient: HttpClient)
Parameters :
Name Type Optional
myHttpClient HttpClient No

Inputs

file
Type : any
fileAlias
Default value : 'file'
folder
Default value : ''
folderName
Default value : ''
httpRequestHeaders
Type : HttpHeaders | literal type
Default value : new HttpHeaders().set('Content-Type', 'multipart/form-data')
httpRequestParams
Type : HttpParams | literal type
Default value : new HttpParams()
httpUrl
Default value : 'http://localhost:8080'
id
Type : number

Outputs

removeFileRequestEvent
Type : EventEmitter
statusChangedEvent
Type : EventEmitter

HostBindings

class
Default value : 'iqb-files-upload'

Methods

ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Public remove
remove()
Returns : void
upload
upload()
Returns : void

Properties

Private _file
Type : any
Private _filedate
Type : string
Default value : ''
Private _id
Type : number
Private _status
Type : UploadStatus
Private fileUploadSubscription
Type : Subscription
Public loaded
Type : number
Default value : 0
Public progressPercentage
Type : number
Default value : 0
Private requestResponse
Type : UploadResponse
Private total
Type : number
Default value : 0

Accessors

status
getstatus()
setstatus(newstatus)
Parameters :
Name Optional
newstatus No
Returns : void
uploadResponse
getuploadResponse()
file
setfile(file: any)
Parameters :
Name Type Optional
file any No
Returns : void
id
getid()
setid(id: number)
Parameters :
Name Type Optional
id number No
Returns : void
import {
  Component, EventEmitter, HostBinding, Input, OnDestroy, OnInit, Output
} 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(
    private myHttpClient: 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>();

  public progressPercentage = 0;
  public 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.myHttpClient.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] } };
    });
  }

  public remove(): void {
    if (this.fileUploadSubscription) {
      this.fileUploadSubscription.unsubscribe();
    }
    this.removeFileRequestEvent.emit(this);
  }

  ngOnDestroy(): void {
    if (this.fileUploadSubscription) {
      this.fileUploadSubscription.unsubscribe();
    }
  }
}
<div class="mat-body">
  <div *ngIf="status == 1" class="upload-progress">
    <mat-progress-bar class="example-margin" [value]="progressPercentage"></mat-progress-bar><br/>
    <span class="file-info">{{progressPercentage}}%</span><br/>
    <mat-icon class="action" (click)="remove()">cancel</mat-icon>
  </div>

  <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'}}
      </div>
      <ng-container *ngFor="let report of uploadedFile.value | keyvalue">
        <alert *ngFor="let reportEntry of report.value" [level]="report.key" [text]="reportEntry"></alert>
      </ng-container>
    </ng-container>
  </ng-container>
</div>

../iqb-files.scss

.subheading-2 {
  color: #003333;
  margin-bottom: 0.7em;
  margin-top: 1.7em;
  border-bottom: 1px solid silver;
}

.subheading-2.success {
  color: green
}

.subheading-2.error {
  color: #821324
}

.upload-progress {
  display: flex;
  align-content: center;
  align-items: center;
  height: 25px;
}

.file-info {
  font-size: .85rem;
}

.action {
  cursor: pointer;
  outline: none;
}


Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""