guesstimate/src/hooks/use-project-reducer.ts

94 lines
2.7 KiB
TypeScript

import { Project } from "../models/project";
import { Task, TaskID, EstimationConfidence } from "../models/task";
import { useReducer } from "preact/hooks";
export interface Action {
type: string
}
export type ProjectReducerActions =
AddTaskAction |
RemoveTaskAction |
UpdateTaskEstimation
export function useProjectReducer(project: Project) {
return useReducer(projectReducer, project);
}
export function projectReducer(project: Project, action: ProjectReducerActions): Project {
switch(action.type) {
case ADD_TASK:
const task = { ...(action as AddTaskAction).task };
return {
...project,
tasks: {
...project.tasks,
[task.id]: task,
}
};
case REMOVE_TASK:
action = action as RemoveTaskAction;
const tasks = { ...project.tasks };
delete tasks[action.id];
return {
...project,
tasks
};
case UPDATE_TASK_ESTIMATION:
action = action as UpdateTaskEstimation;
const estimations = {
...project.tasks[action.id].estimations,
[(action as UpdateTaskEstimation).confidence]: (action as UpdateTaskEstimation).value
};
if (estimations.likely <= estimations.optimistic) {
estimations.likely = estimations.optimistic + 1;
}
if (estimations.pessimistic <= estimations.likely) {
estimations.pessimistic = estimations.likely + 1;
}
return {
...project,
tasks: {
...project.tasks,
[action.id]: {
...project.tasks[action.id],
estimations: estimations,
}
}
};
}
return project;
}
export interface AddTaskAction extends Action {
task: Task
}
export const ADD_TASK = "ADD_TASK";
export function addTask(task: Task): AddTaskAction {
return { type: ADD_TASK, task };
}
export interface RemoveTaskAction extends Action {
id: TaskID
}
export const REMOVE_TASK = "REMOVE_TASK";
export function removeTask(id: TaskID): RemoveTaskAction {
return { type: REMOVE_TASK, id };
}
export interface UpdateTaskEstimation extends Action {
id: TaskID
confidence: string
value: number
}
export const UPDATE_TASK_ESTIMATION = "UPDATE_TASK_ESTIMATION";
export function updateTaskEstimation(id: TaskID, confidence: EstimationConfidence, value: number): UpdateTaskEstimation {
return { type: UPDATE_TASK_ESTIMATION, id, confidence, value };
}