Updated export functionality

This commit is contained in:
Erik Tiekstra
2021-11-11 12:31:06 +01:00
parent f332dd41e2
commit c6adc71f77
5 changed files with 36 additions and 14 deletions

View File

@@ -4,10 +4,11 @@
<header class="deltagare-export__header"> <header class="deltagare-export__header">
<h1>Exportera information om deltagare</h1> <h1>Exportera information om deltagare</h1>
<p> <p>
Här kan du exportera deltagarinformation. Informationen laddas ner till din dator i CSV-format. Du kan endast Här kan du exportera deltagarinformation. Informationen laddas ner till din dator i CSV eller Excel format. Du
exportera deltagare som du har behörighet att se. Detta innebär att du bara kan få ut de deltagare som är kan endast exportera deltagare som du har behörighet att se. Detta innebär att du bara kan få ut de deltagare
kopplade till samma utförande verksamhet och adress som du är inloggad på. Du kan även välja att inkludera som är kopplade till samma utförande verksamhet och adress som du är inloggad på. Du kan även välja att
deltagare som exporterats vid tidigare tillfälle. Deltagare som exporterats tidigare markeras i filen. inkludera deltagare som exporterats vid tidigare tillfälle. Deltagare som exporterats tidigare markeras i
filen.
</p> </p>
</header> </header>
<form class="deltagare-export__form" [formGroup]="formGroup" (ngSubmit)="fetchExportFile()"> <form class="deltagare-export__form" [formGroup]="formGroup" (ngSubmit)="fetchExportFile()">
@@ -41,6 +42,7 @@
[formControl]="includeExportedDeltagareFormControl" [formControl]="includeExportedDeltagareFormControl"
uiLabel="Inkludera redan exporterade deltagare" uiLabel="Inkludera redan exporterade deltagare"
></ui-checkbox> ></ui-checkbox>
<ui-checkbox [formControl]="isExcelFormControl" uiLabel="Exportera i Excel format"></ui-checkbox>
<footer class="deltagare-export__footer"> <footer class="deltagare-export__footer">
<digi-notification-alert <digi-notification-alert
*ngIf="fetchError$ | async as error" *ngIf="fetchError$ | async as error"

View File

@@ -2,6 +2,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'; import { FormControl, FormGroup } from '@angular/forms';
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model'; import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
import { CustomError } from '@msfa-models/error/custom-error'; import { CustomError } from '@msfa-models/error/custom-error';
import { formatDate } from '@msfa-shared/utils/format-to-date.util';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
@@ -25,6 +26,7 @@ export class DeltagareExportComponent {
startDate: new FormControl(null), startDate: new FormControl(null),
endDate: new FormControl(null), endDate: new FormControl(null),
includeExportedDeltagare: new FormControl(false), includeExportedDeltagare: new FormControl(false),
isExcel: new FormControl(false),
}, },
[DeltagareExportValidator.isDeltagareExportValid()] [DeltagareExportValidator.isDeltagareExportValid()]
); );
@@ -39,6 +41,9 @@ export class DeltagareExportComponent {
get includeExportedDeltagareFormControl(): FormControl { get includeExportedDeltagareFormControl(): FormControl {
return this.formGroup.get('includeExportedDeltagare') as FormControl; return this.formGroup.get('includeExportedDeltagare') as FormControl;
} }
get isExcelFormControl(): FormControl {
return this.formGroup.get('isExcel') as FormControl;
}
get deltagagareExportFormData(): DeltagareExportFormData { get deltagagareExportFormData(): DeltagareExportFormData {
return this.formGroup.value as DeltagareExportFormData; return this.formGroup.value as DeltagareExportFormData;
@@ -53,22 +58,23 @@ export class DeltagareExportComponent {
} }
fetchExportFile(): void { fetchExportFile(): void {
this.fetchError$.next(null);
if (this.formGroup.invalid) { if (this.formGroup.invalid) {
this.shouldValidate$.next(true); this.shouldValidate$.next(true);
return; return;
} }
const requestData = this._formDataToRequestData(this.deltagagareExportFormData);
this.fetchIsLoading$.next(true); this.fetchIsLoading$.next(true);
this.deltagareExportService this.deltagareExportService
.fetchExportFile$(requestData) .fetchExportFile$(this._formDataToRequestData)
.pipe(take(1)) .pipe(take(1))
.subscribe({ .subscribe({
next: response => { next: response => {
const blob = new Blob([response], { type: 'text/csv' }); const isExcel = this._formDataToRequestData.exportToExcel;
saveAs(blob, 'deltagare-export.csv'); const blob = new Blob([response], { type: this._getFileType(isExcel) });
saveAs(blob, this._getFileName(isExcel));
this.fetchIsLoading$.next(false); this.fetchIsLoading$.next(false);
this.formGroup.reset();
}, },
error: (customError: CustomError) => { error: (customError: CustomError) => {
this.fetchError$.next({ ...customError, message: customError.error.message }); this.fetchError$.next({ ...customError, message: customError.error.message });
@@ -78,10 +84,22 @@ export class DeltagareExportComponent {
}); });
} }
private _formDataToRequestData(formData: DeltagareExportFormData): DeltagareExportRequest { private _getFileName(isExcel: boolean): string {
const { startDate, endDate, includeExportedDeltagare } = formData; const baseFileName = 'deltagare-export';
const extension = isExcel ? 'xlsx' : 'csv';
return `${baseFileName}-${formatDate(new Date())}.${extension}`;
}
private _getFileType(isExcel: boolean): string {
return isExcel ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' : 'text/csv';
}
private get _formDataToRequestData(): DeltagareExportRequest {
const { startDate, endDate, includeExportedDeltagare, isExcel } = this.deltagagareExportFormData;
const requestData: DeltagareExportRequest = { const requestData: DeltagareExportRequest = {
includeExportedDeltagare, includeExportedDeltagare: !!includeExportedDeltagare,
exportToExcel: !!isExcel,
}; };
if (startDate) { if (startDate) {
requestData.startDate = startDate; requestData.startDate = startDate;

View File

@@ -2,6 +2,7 @@ export interface DeltagareExportFormData {
startDate: string; startDate: string;
endDate: string; endDate: string;
includeExportedDeltagare: boolean; includeExportedDeltagare: boolean;
isExcel: boolean;
} }
export type DeltagareExportFormKeys = keyof DeltagareExportFormData; export type DeltagareExportFormKeys = keyof DeltagareExportFormData;

View File

@@ -2,4 +2,5 @@ export interface DeltagareExportRequest {
startDate?: string; startDate?: string;
endDate?: string; endDate?: string;
includeExportedDeltagare: boolean; includeExportedDeltagare: boolean;
exportToExcel?: boolean;
} }

View File

@@ -1,9 +1,9 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Params } from '@angular/router';
import { ErrorType } from '@msfa-enums/error-type.enum'; import { ErrorType } from '@msfa-enums/error-type.enum';
import { environment } from '@msfa-environment'; import { environment } from '@msfa-environment';
import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model'; import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model';
import { Params } from '@msfa-models/api/params.model';
import { CustomError } from '@msfa-models/error/custom-error'; import { CustomError } from '@msfa-models/error/custom-error';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
@@ -23,7 +23,7 @@ export class ExportApiService {
}; };
return this.httpClient return this.httpClient
.post<Blob>(`${this._apiBaseUrl}/deltagare`, { params, responseType: 'blob' }) .get<Blob>(`${this._apiBaseUrl}/deltagare`, { params, responseType: 'blob' as 'json' })
.pipe( .pipe(
catchError((error: Error) => { catchError((error: Error) => {
throw new CustomError({ throw new CustomError({