system-praktyk-front/src/state/reducer/submission.ts
2020-11-11 15:04:59 +01:00

86 lines
2.8 KiB
TypeScript

import { DeanApproval } from "@/data/deanApproval";
import { Action } from "@/state/actions";
import { momentSerializationTransformer } from "@/serialization";
import moment from "moment-timezone";
import { ReceiveSubmissionApproveAction, ReceiveSubmissionDeclineAction, SubmissionAction } from "@/state/actions/submission";
export type SubmissionStatus = "draft" | "awaiting" | "accepted" | "declined";
export type SubmissionState = {
accepted: boolean;
sent: boolean;
sentOn: string | null;
declined: boolean;
comment: string | null;
overwritten: boolean;
}
export type MayRequireDeanApproval = {
requiredDeanApprovals: DeanApproval[],
}
export const defaultSubmissionState: SubmissionState = {
accepted: false,
sent: false,
sentOn: null,
declined: false,
comment: null,
overwritten: false,
}
export const defaultDeanApprovalsState: MayRequireDeanApproval = {
requiredDeanApprovals: [],
}
export const getSubmissionStatus = ({ accepted, declined, sent }: SubmissionState): SubmissionStatus => {
switch (true) {
case !sent:
return "draft";
case sent && accepted:
return "accepted"
case sent && declined:
return "declined"
case sent && (!accepted && !declined):
return "awaiting"
default:
throw new Error("Invalid submission state " + JSON.stringify({ accepted, declined, sent }));
}
}
export function createSubmissionReducer<TState, TActionType, TAction extends Action>(mapping: { [TAction in keyof TActionType]: SubmissionAction }) {
return (state: TState, action: TAction) => {
const mappedAction = mapping[action.type as keyof TActionType];
switch (mappedAction) {
case SubmissionAction.Approve:
return {
...state,
accepted: true,
declined: false,
comment: (action as ReceiveSubmissionApproveAction<any>).comment,
overwritten: true,
}
case SubmissionAction.Decline:
return {
...state,
accepted: false,
declined: true,
comment: (action as ReceiveSubmissionDeclineAction<any>).comment,
overwritten: true,
}
case SubmissionAction.Send:
return {
...state,
sent: true,
sentOn: momentSerializationTransformer.transform(moment()),
accepted: false,
declined: false,
comment: null,
overwritten: false,
}
default:
return state;
}
}
}