blob: aeed52bbfe95b96bd7d52f5f2ad6df4548e66ea1 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2020 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 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import {Component, Inject, OnDestroy, OnInit} from "@angular/core";
import {DomSanitizer, SafeUrl} from "@angular/platform-browser";
import {select, Store} from "@ngrx/store";
import {Observable, of, Subject} from "rxjs";
import {map, switchMap, takeUntil} from "rxjs/operators";
import {IAPIDepartmentTable, URL_TOKEN} from "../../../../core";
import {
EErrorCode,
fetchDepartmentsSettingsAction,
getDepartmentsSettingsSelector,
getSettingsLoadingSelector,
setErrorAction,
submitDepartmentsSettingsAction
} from "../../../../store";
import {catchErrorTo} from "../../../../util";
import {parseDepartmentTableFromCsv, reduceDepartmentTableToCsv} from "../util";
@Component({
selector: "app-departments-settings",
templateUrl: "./departments-settings.component.html",
styleUrls: ["./departments-settings.component.scss"]
})
export class DepartmentsSettingsComponent implements OnInit, OnDestroy {
public currentConfigFileName = "departments.config.csv";
public loading$ = this.store.pipe(select(getSettingsLoadingSelector));
public searching = false;
public currentData$ = this.store.pipe(select(getDepartmentsSettingsSelector));
public currentConfigFile$: Observable<File> = this.currentData$.pipe(
switchMap((data) => {
return of(data).pipe(
map(() => new File([reduceDepartmentTableToCsv(data)], this.currentConfigFileName)),
catchErrorTo(null)
);
})
);
public currentFileUrl: SafeUrl;
public selectedFile: File;
public selectedFileData: IAPIDepartmentTable;
private currentFileObjectUrl: string;
private destroy$ = new Subject();
public constructor(public store: Store, @Inject(URL_TOKEN) public url: typeof URL, public sanitizer: DomSanitizer) {
}
public ngOnInit() {
this.currentConfigFile$.pipe(takeUntil(this.destroy$)).subscribe((file) => this.createObjectURLForCurrentFile(file));
this.currentData$.pipe(takeUntil(this.destroy$)).subscribe(() => this.clearFileSelection());
this.store.dispatch(fetchDepartmentsSettingsAction());
}
public ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
this.revokeObjectUrl();
}
public submit(data: IAPIDepartmentTable) {
this.store.dispatch(submitDepartmentsSettingsAction({data}));
}
public async selectFile(file: File) {
try {
const text = await file.text();
this.selectedFileData = parseDepartmentTableFromCsv(text);
this.selectedFile = file;
} catch (e) {
this.store.dispatch(setErrorAction({error: EErrorCode.INVALID_FILE_FORMAT}));
}
}
public clearFileSelection() {
this.selectedFile = null;
this.selectedFileData = null;
}
private createObjectURLForCurrentFile(file: File) {
this.revokeObjectUrl();
if (file != null) {
this.currentFileObjectUrl = this.url.createObjectURL(file);
this.currentFileUrl = this.sanitizer.bypassSecurityTrustUrl(this.currentFileObjectUrl);
}
}
private revokeObjectUrl() {
if (this.currentFileObjectUrl != null) {
this.url.revokeObjectURL(this.currentFileObjectUrl);
this.currentFileObjectUrl = null;
this.currentFileUrl = null;
}
}
}