86 lines
2.8 KiB
TypeScript
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;
|
|
}
|
|
}
|
|
}
|