| /******************************************************************************** |
| * 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 {Actions, createEffect, ofType} from "@ngrx/effects"; |
| import {Action} from "@ngrx/store"; |
| import {concat, EMPTY, Observable, of, throwError} from "rxjs"; |
| import {catchError, endWith, filter, map, mergeMap, startWith, switchMap} from "rxjs/operators"; |
| import {AttachmentsApiService} from "../../../../core/api/attachments"; |
| import {arrayJoin, endWithObservable, ignoreError} from "../../../../util"; |
| import {setErrorAction} from "../../../root/actions"; |
| import {EErrorCode} from "../../../root/model"; |
| import {setStatementLoadingAction, submitConsiderationFilesAction} from "../../../statements/actions"; |
| import {addAttachmentEntityAction, setAttachmentCacheAction} from "../../actions"; |
| import {IAttachmentControlValue, IAttachmentError} from "../../model"; |
| import {FetchAttachmentsEffect} from "../fetch"; |
| |
| @Injectable({providedIn: "root"}) |
| export class SubmitConsiderationsEffect { |
| |
| public submit$ = createEffect(() => this.actions.pipe( |
| ofType(submitConsiderationFilesAction), |
| switchMap((action) => { |
| return this.submit(action.statementId, action.value).pipe( |
| ignoreError() |
| ); |
| }) |
| )); |
| |
| public constructor( |
| public readonly actions: Actions, |
| public readonly attachmentsApiService: AttachmentsApiService, |
| public readonly fetchAttachmentsEffect: FetchAttachmentsEffect |
| ) { |
| |
| } |
| |
| |
| public submit( |
| statementId: number, |
| value: IAttachmentControlValue[] |
| ): Observable<Action> { |
| const errors: IAttachmentError[] = []; |
| |
| return concat( |
| this.addConsiderations(statementId, value, errors), |
| this.fetchAttachmentsEffect.fetchAttachments(statementId) |
| ).pipe( |
| endWithObservable(() => { |
| const lastError = errors.reverse()[0]; |
| return lastError == null ? EMPTY : concat( |
| of(setErrorAction({statementId, error: lastError.message})), |
| throwError(lastError.error) |
| ); |
| }), |
| startWith(setStatementLoadingAction({loading: {submittingConsiderationFiles: true}})), |
| endWith(setStatementLoadingAction({loading: {submittingConsiderationFiles: false}})) |
| ); |
| } |
| |
| public addConsiderations( |
| statementId: number, |
| considerations: IAttachmentControlValue[], |
| errors: IAttachmentError[] = [] |
| ): Observable<Action> { |
| const items: IAttachmentControlValue[] = []; |
| return of(...arrayJoin(considerations)).pipe( |
| filter((item) => item?.file instanceof File), |
| mergeMap((item) => { |
| return this.addSingleConsiderationFile(statementId, item.file).pipe( |
| catchError((error) => { |
| items.push(item); |
| errors.push({statementId, attachment: item, error, message: EErrorCode.FAILED_FILE_UPLOAD}); |
| return EMPTY; |
| }) |
| ); |
| }, 2), |
| startWith(setAttachmentCacheAction({statementId, items: considerations})), |
| endWithObservable(() => of(setAttachmentCacheAction({statementId, items}))) |
| ); |
| } |
| |
| private addSingleConsiderationFile( |
| statementId: number, |
| file: File |
| ): Observable<Action> { |
| return this.attachmentsApiService.postConsideration(statementId, file).pipe( |
| map((entity) => addAttachmentEntityAction({statementId, entity})) |
| ); |
| } |
| |
| } |