blob: e82ceb76d2d894c7827db96d65b7e052ec0f7283 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (c) 2018 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************
*/
import {
Component, OnInit, Input, ElementRef, ViewChild, AfterContentChecked,
SimpleChanges, OnChanges, Output, AfterViewChecked
} from '@angular/core';
import { FormGroup } from '@angular/forms';
import { SessionContext } from '../../common/session-context';
import { GridMeasure } from '../../model/grid-measure';
import { Globals } from '../../common/globals';
import { ErrorType } from '../../common/enums';
import { DocumentService } from '../../services/document.service';
import { Document } from './../../model/document';
import { saveAs } from 'file-saver/FileSaver';
import { RoleAccessHelperService } from '../../services/jobs/role-access-helper.service';
import { EventEmitter, AfterViewInit } from '@angular/core';
import { Util } from '../../common/util';
import { GridMeasureService } from '../../services/grid-measure.service';
import { ToasterMessageService } from '../../services/toaster-message.service';
@Component({
selector: 'app-grid-measure-detail-tab',
templateUrl: './grid-measure-detail-tab.component.html',
styleUrls: ['./grid-measure-detail-tab.component.css', '../grid-measure-detail/grid-measure-detail.component.css']
})
export class GridMeasureDetailTabComponent implements OnInit, OnChanges, AfterViewChecked, AfterViewInit {
@Input() showSpinnerGrid: boolean;
@Input() id: any;
@Input() gridMeasureDetail: GridMeasure = new GridMeasure();
@Input() readOnlyForm: boolean;
@Output() isValidForSave: EventEmitter<boolean> = new EventEmitter<boolean>();
Globals = Globals;
fileToUpload: File = null;
fileName: string;
fileSelected: boolean;
documentToUpload: Document = null;
listOfDocuments: Document[] = null;
listOfDocumentsNames: string[] = [];
dataURI: string;
showSpinnerFileUpload = false;
dragEntered = false;
isAppointmentNumberOfValid: boolean;
appointmentRepetitionList: string[];
showSpinnerGridFileUpload: boolean;
dateFormatLocale = 'dd.MM.yyyy HH:mm';
affectedResourcesList: Array<string> = [];
inactiveFields: Array<string> = [];
departmentList: any;
datePattern = '^(([0-2]?[0-9]|3[0-1])\.([0]?[1-9]|1[0-2])\.[1-2][0-9]{3})$';
dateTimePattern = '^(([0-2]?[0-9]|3[0-1])\.([0]?[1-9]|1[0-2])\.[1-2][0-9]{3}) (20|21|22|23|[0-1]?[0-9]{1}):([0-5]?[0-9]{1})$';
calcDatepickerDropOrientation = Util.calcDatepickerDropOrientation;
@ViewChild('gridMeasureDetailForm') gridMeasureDetailForm: FormGroup;
@ViewChild('gridMeasureDetailTabContainer') gridMeasureDetailTabContainer: ElementRef;
constructor(public sessionContext: SessionContext,
private documentService: DocumentService,
public roleAccessHelper: RoleAccessHelperService,
protected gridMeasureService: GridMeasureService,
private toasterMessageService: ToasterMessageService,
private gridMeasuresService: GridMeasureService) { }
ngOnInit() {
this.inactiveFields = this.sessionContext.getInactiveFields();
this.isAppointmentNumberOfValid = true;
this.getAffectedResourcesDistinct();
this.appointmentRepetitionList = this.sessionContext.getBackendsettings().appointmentRepetition.map(ap => ap.name);
this.gridMeasuresService.getUserDepartmentsModified()
.subscribe(departments => this.departmentList = departments,
error => {
console.log(error);
});
}
ngAfterViewInit() {
this.initInactiveFields();
}
ngAfterViewChecked() {
if (this.gridMeasureDetailForm) {
this.gridMeasureDetail._isValide = this.gridMeasureDetailForm.valid;
}
}
ngOnChanges(changes: SimpleChanges) {
if (changes['id'] && changes['id'].currentValue) {
this.getDocumentsForId();
}
if (changes['readOnlyForm']) {
this.initInactiveFields();
}
if (changes['gridMeasureDetail'] && changes['gridMeasureDetail'].currentValue) {
this.gridMeasureDetail.appointmentNumberOf = this.gridMeasureDetail.appointmentNumberOf || 0;
this.appointmentRepetitionList = this.sessionContext.getBackendsettings().appointmentRepetition.map(ap => ap.name);
if (!this.gridMeasureDetail.appointmentRepetition) {
this.gridMeasureDetail.appointmentRepetition = this.appointmentRepetitionList[0];
}
this.setCurrTimeIfEmpty(this.gridMeasureDetail);
}
}
getAffectedResourcesDistinct() {
this.gridMeasureService.getAffectedResourcesDistinct().subscribe(aResource =>
this.affectedResourcesList = aResource);
}
public initInactiveFields() {
const el: HTMLElement = this.gridMeasureDetailTabContainer.nativeElement as HTMLElement;
const fields = el.querySelectorAll('*[id]:not(button)');
for (let index = 0; index < fields.length; index++) {
const field = fields[index];
if (this.readOnlyForm || this.isFieldInactive(field['id'])) {
field.setAttribute('disabled', 'disabled');
} else {
field.removeAttribute('disabled');
}
}
}
private isFieldInactive(fieldName: string): boolean {
if ((fieldName === 'fileUploadLabel' || fieldName === 'file') && !this.id) {
return true;
} else {
return this.inactiveFields.filter(field => field === fieldName).length > 0;
}
}
setCurrTimeIfEmpty(gridMeasure: GridMeasure) {
const dateFields = [
'appointmentStartdate',
'plannedStarttimeFirstSinglemeasure'
];
if (gridMeasure.id) {
return;
}
dateFields.forEach(field => {
if (gridMeasure[field] === undefined) {
gridMeasure[field] = this.getCurrentDateTime();
}
});
}
public selectedDate(value: any, datepicker?: any) {
this.gridMeasureDetail[datepicker] = value.start._d;
}
onGridMeasureDetailFormValidation(valid: boolean) {
this.gridMeasureDetail._isValide = valid;
}
getCurrentDateTime(): string {
return new Date().toISOString();
}
checkAppointmentNumberOfValue(event) {
if (event < Globals.APPOINTMENT_NUMBER_OF_MAX_VALUE + 1) {
this.isAppointmentNumberOfValid = true;
} else {
this.gridMeasureDetail.appointmentNumberOf = 0;
this.isAppointmentNumberOfValid = false;
}
}
onGridMeasureTitleChange(value) {
if (value) {
this.isValidForSave.emit(true);
} else {
this.isValidForSave.emit(false);
}
}
handleFileInput(file: FileList) {
if (!file || file.length === 0) {
return;
}
if (file.length > 1) {
this.toasterMessageService.showWarn('Es kann nur jeweils eine Datei hochgeladen werden! '
+ 'Die erste Datei ihrer Auswahl wurde übernommen.');
}
this.fileToUpload = file.item(0);
this.fileName = this.fileToUpload.name;
if (this.gridMeasureDetail.statusId === Globals.STATUS.APPLIED && this.checkIfFileExists(this.fileToUpload.name)) {
this.toasterMessageService.showWarn('Im Status Beantragt können Dateien nicht geändert werden!');
return;
}
if (!this.fileSizeCheck() || !this.fileTypeCheck()) {
return;
}
this.fileSelected = true;
}
private checkIfFileExists(fileName: string) {
if (this.listOfDocumentsNames.includes(fileName)) {
return true;
} else {
return false;
}
}
private fileTypeCheck(): boolean {
const fileType = this.fileToUpload.type;
if (!Globals.TYPE_WHITELIST.includes(fileType)) {
this.toasterMessageService.showWarn('Dieser Dateityp ist nicht erlaubt!');
return false;
} else {
return true;
}
}
private fileSizeCheck(): boolean {
const fileUploadSize = this.fileToUpload.size;
const allowed = Globals.MEGABYT_UNIT * Globals.MAX_UPLOADFILE_SIZE;
if (fileUploadSize > allowed) {
// Globals.MAX_UPLOADFILE_SIZE + ' Megabytes!', MessageScopeEn.local);
this.toasterMessageService.showWarn('Die ausgewählte Datei überschreitet die maximale zulässige Größe von ' +
Globals.MAX_UPLOADFILE_SIZE + ' Megabytes!');
return false;
} else {
return true;
}
}
uploadDocument() {
if (!this.fileSelected) {
return;
}
this.showSpinnerFileUpload = true;
// convertFileToBas64
const reader = new FileReader();
reader.onload = (e) => {
this.dataURI = reader.result;
this.proccessFile();
};
reader.readAsDataURL(this.fileToUpload);
}
private proccessFile() {
const byteString = this.dataURI.split(',')[1];
const documentToUpload = new Document();
documentToUpload.data = byteString;
// TODO send to backend to check file type against whitelist
// const mimeString = this.dataURI.split(',')[0].split(':')[1].split(';')[0];
documentToUpload.documentName = this.fileToUpload.name;
this.documentToUpload = documentToUpload;
this.processUpload();
}
private processUpload() {
this.documentService.uploadGridMeasureAttachments(this.id, this.documentToUpload).subscribe(resp => {
this.showSpinnerFileUpload = false;
this.getDocumentsForId();
this.fileSelected = false;
this.toasterMessageService.showSuccess('Datei erfolgreich hochgeladen!');
},
error => {
this.toasterMessageService.showError(ErrorType.upload, '');
this.showSpinnerFileUpload = false;
console.log(error);
});
}
private getDocumentsForId() {
this.documentService.getGridMeasureAttachments(this.id).subscribe(gm => {
this.listOfDocuments = gm;
for (let index = 0; index < this.listOfDocuments.length; index++) {
this.listOfDocumentsNames.push(this.listOfDocuments[index].documentName);
}
},
error => {
this.toasterMessageService.showError(ErrorType.retrieve, 'GridMeasure');
console.log(error);
});
}
downloadDocument(documentId) {
this.showSpinnerFileUpload = true;
this.documentService.downloadGridMeasureAttachment(documentId).subscribe(resp => {
this.saveFile(resp);
this.toasterMessageService.showSuccess('Datei erfolgreich heruntergeladen!');
this.showSpinnerFileUpload = false;
},
error => {
this.toasterMessageService.showError(ErrorType.retrieve, 'Datei');
this.showSpinnerFileUpload = false;
console.log(error);
});
}
deleteDocument(documentId: number, index: number) {
this.documentService.deleteGridMeasureAttachment(documentId).subscribe(resp => {
this.toasterMessageService.showSuccess('Datei erfolgreich gelöscht!');
this.listOfDocuments.splice(index, 1);
},
error => {
this.toasterMessageService.showError(ErrorType.delete, 'Datei');
this.showSpinnerFileUpload = false;
console.log(error);
});
}
private saveFile(document: Document) {
const byteString = atob(document.data);
// write the bytes of the string to an ArrayBuffer
const ab = new ArrayBuffer(byteString.length);
// create a view into the buffer
const ia = new Uint8Array(ab);
// set the bytes of the buffer to the correct values
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
const blob = new Blob([ab], { type: 'application/octet-stream' });
saveAs(blob, document.documentName);
}
allowDrop(ev) {
ev.preventDefault();
ev.stopPropagation();
}
drop(ev) {
ev.preventDefault();
ev.stopPropagation();
// cancel drop if upload is disabled
const el: HTMLElement = this.gridMeasureDetailTabContainer.nativeElement as HTMLElement;
const uploadField = el.querySelector('#fileUploadLabel');
if (uploadField.getAttribute('disabled')) {
this.dragEntered = false;
return;
}
if (!this.readOnlyForm && this.id) {
const files = ev.target.files || ev.dataTransfer.files;
this.handleFileInput(files);
}
this.dragEntered = false;
}
dragenter(ev) {
this.dragEntered = true;
}
dragleave(ev) {
this.dragEntered = false;
}
}