blob: 67d7bb63b56e317311e994e34ba38b9aa66fad7f [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 {Injectable} from "@angular/core";
import {Router} from "@angular/router";
import {Actions, createEffect, ofType} from "@ngrx/effects";
import {Action} from "@ngrx/store";
import {concat, EMPTY, Observable} from "rxjs";
import {catchError, endWith, exhaustMap, filter, finalize, map, startWith, switchMap} from "rxjs/operators";
import {StatementsApiService} from "../../../core";
import {addAttachmentsAction, addNewStatementAction, addStatementsAction, setNewStatementProgressAction} from "../actions";
import {ENewStatementError, INewStatementForm} from "../model";
@Injectable({providedIn: "root"})
export class AddStatementEffect {
public readonly addNewStatement$ = createEffect(() => this.actions.pipe(
ofType(addNewStatementAction),
filter((action) => action?.form != null),
exhaustMap((action) => this.addNewStatement(action.form))
));
public constructor(
private readonly actions: Actions,
private readonly statementsApiService: StatementsApiService,
private readonly router: Router
) {
}
public async navigateToStatement(statementId: number) {
if (Number.isInteger(statementId)) {
return this.router.navigate(["/details"], {queryParams: {id: statementId}});
}
}
public addNewStatement(form: INewStatementForm): Observable<Action> {
return this.createStatement(form).pipe(
startWith(setNewStatementProgressAction({isLoading: true})),
catchError(async (error) => {
console.error(error);
return setNewStatementProgressAction({isLoading: false, error: ENewStatementError.UNKNOWN_ERROR});
}),
endWith(setNewStatementProgressAction({isLoading: false}))
);
}
public createStatement(form: INewStatementForm): Observable<Action> {
return this.statementsApiService.postStatement({
title: form?.title,
dueDate: form?.dueDate,
receiptDate: form?.receiptDate,
typeId: form?.typeId,
city: form?.city,
district: form?.district
}).pipe(
switchMap((statement) => {
return this.attachFiles(statement.id, form?.attachments).pipe(
startWith(addStatementsAction({statements: [statement]})),
finalize(() => this.navigateToStatement(statement?.id))
);
})
);
}
public attachFiles(statementId: number, attachments?: File[]): Observable<Action> {
attachments = (Array.isArray(attachments) ? attachments : [])
.filter((file) => file instanceof File);
return concat(...attachments.map((file) => this.attachFile(statementId, file)));
}
private attachFile(statementId: number, file: File): Observable<Action> {
return this.statementsApiService.postAttachment(statementId, file).pipe(
map((attachment) => addAttachmentsAction({statementId, attachments: [attachment]})),
catchError((error) => {
console.error(error);
return EMPTY;
})
);
}
}