blob: 7cb78a2ea6638e873db2ae10174bc06c6ee870fc [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 {Actions, createEffect, ofType} from "@ngrx/effects";
import {Action} from "@ngrx/store";
import {concat, EMPTY, Observable, throwError} from "rxjs";
import {endWith, filter, ignoreElements, map, retry, startWith, switchMap, tap} from "rxjs/operators";
import {
EAPIProcessTaskDefinitionKey,
EAPIStaticAttachmentTagIds,
IAPITextArrangementItemModel,
StatementsApiService,
TCompleteTaskVariable,
TextApiService
} from "../../../../core";
import {arrayJoin, endWithObservable, ignoreError} from "../../../../util";
import {SubmitAttachmentsEffect} from "../../../attachments/effects";
import {ProcessTaskEffect} from "../../../process/effects";
import {setStatementLoadingAction, submitStatementEditorFormAction, updateStatementEntityAction} from "../../actions";
import {IDepartmentOptionValue, IStatementEditorFormValue} from "../../model";
import {CompileStatementArrangementEffect} from "../compile-statement-arrangement";
@Injectable({providedIn: "root"})
export class SubmitStatementEditorFormEffect {
public submit$ = createEffect(() => this.actions.pipe(
ofType(submitStatementEditorFormAction),
filter((action) => action.statementId != null && action.taskId != null),
switchMap((action) => this.submit(action.statementId, action.taskId, action.value, action.options))
));
public constructor(
private readonly actions: Actions,
private readonly submitAttachmentsEffect: SubmitAttachmentsEffect,
private readonly compileStatementArrangementEffect: CompileStatementArrangementEffect,
private readonly textApiService: TextApiService,
private readonly taskEffect: ProcessTaskEffect,
private readonly statementsApiService: StatementsApiService
) {
}
public submit(
statementId: number,
taskId: string,
value: IStatementEditorFormValue,
options: {
completeTask?: TCompleteTaskVariable,
claimNext?: boolean | EAPIProcessTaskDefinitionKey,
compile?: boolean,
contribute?: boolean,
file?: File
}
): Observable<Action> {
options = options == null ? {} : options;
return concat<Action>(
value.contributions ? this.submitContributions(statementId, taskId, value.contributions.selected) : EMPTY,
this.submitArrangement(statementId, taskId, value.arrangement),
this.submitAttachmentsEffect.submit(statementId, taskId, value.attachments),
options.compile ? this.compile(statementId, taskId, value.arrangement) : EMPTY,
options.file instanceof File ? this.submitStatementFile(statementId, taskId, options.file) : EMPTY,
options.contribute ?
this.contribute(statementId, taskId) :
options.completeTask != null ?
this.taskEffect.completeTask(statementId, taskId, options.completeTask, options.claimNext) :
EMPTY
).pipe(
ignoreError(),
startWith(setStatementLoadingAction({loading: {submittingStatementEditorForm: true}})),
endWith(setStatementLoadingAction({loading: {submittingStatementEditorForm: false}}))
);
}
public submitArrangement(statementId: number, taskId: string, arrangement: IAPITextArrangementItemModel[]): Observable<Action> {
return this.textApiService.postArrangement(statementId, taskId, arrangement).pipe(
map(() => updateStatementEntityAction({statementId, entity: {arrangement}})),
retry(2)
);
}
public submitContributions(statementId: number, taskId: string, contributions: IDepartmentOptionValue[]): Observable<Action> {
const departmentGroups = contributions.reduce((current, value) => {
return {
...current,
[value.groupName]: arrayJoin(current[value.groupName], [value.name])
};
}, {});
return this.statementsApiService.postContributions(statementId, taskId, departmentGroups).pipe(
map(() => updateStatementEntityAction({statementId, entity: {contributions: departmentGroups}})),
retry(2)
);
}
public contribute(statementId: number, taskId: string): Observable<Action> {
return this.statementsApiService.contribute(statementId, taskId)
.pipe(switchMap(() => this.taskEffect.navigateTo(statementId)));
}
private submitStatementFile(statementId: number, taskId: string, file: File) {
return this.submitAttachmentsEffect.submit(statementId, taskId, {
add: [{
tagIds: [EAPIStaticAttachmentTagIds.STATEMENT, EAPIStaticAttachmentTagIds.OUTBOX],
name: file.name,
file
}]
}).pipe(
ignoreElements()
);
}
private compile(statementId: number, taskId: string, arrangement: IAPITextArrangementItemModel[]) {
let err: any;
return this.textApiService.compileArrangement(statementId, taskId, arrangement).pipe(
map((file) => updateStatementEntityAction({statementId, entity: {file}})),
tap({error: (_) => err = _}),
this.compileStatementArrangementEffect.catchArrangementError(statementId),
endWithObservable(() => err == null ? EMPTY : throwError(err))
);
}
}