159 lines
4.0 KiB
TypeScript
159 lines
4.0 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 =
|
|
AddTask |
|
|
RemoveTask |
|
|
UpdateTaskEstimation |
|
|
UpdateProjectLabel |
|
|
UpdateTaskLabel
|
|
|
|
export function useProjectReducer(project: Project) {
|
|
return useReducer(projectReducer, project);
|
|
}
|
|
|
|
export function projectReducer(project: Project, action: ProjectReducerActions): Project {
|
|
switch(action.type) {
|
|
case ADD_TASK:
|
|
return handleAddTask(project, action as AddTask);
|
|
|
|
case REMOVE_TASK:
|
|
return handleRemoveTask(project, action as RemoveTask);
|
|
|
|
case UPDATE_TASK_ESTIMATION:
|
|
return handleUpdateTaskEstimation(project, action as UpdateTaskEstimation);
|
|
|
|
case UPDATE_PROJECT_LABEL:
|
|
return handleUpdateProjectLabel(project, action as UpdateProjectLabel);
|
|
|
|
case UPDATE_TASK_LABEL:
|
|
return handleUpdateTaskLabel(project, action as UpdateTaskLabel);
|
|
}
|
|
|
|
return project;
|
|
}
|
|
|
|
export interface AddTask extends Action {
|
|
task: Task
|
|
}
|
|
|
|
export const ADD_TASK = "ADD_TASK";
|
|
|
|
export function addTask(task: Task): AddTask {
|
|
return { type: ADD_TASK, task };
|
|
}
|
|
|
|
export function handleAddTask(project: Project, action: AddTask): Project {
|
|
const task = { ...action.task };
|
|
return {
|
|
...project,
|
|
tasks: {
|
|
...project.tasks,
|
|
[task.id]: task,
|
|
}
|
|
};
|
|
}
|
|
|
|
export interface RemoveTask extends Action {
|
|
id: TaskID
|
|
}
|
|
|
|
export const REMOVE_TASK = "REMOVE_TASK";
|
|
|
|
export function removeTask(id: TaskID): RemoveTask {
|
|
return { type: REMOVE_TASK, id };
|
|
}
|
|
|
|
export function handleRemoveTask(project: Project, action: RemoveTask): Project {
|
|
const tasks = { ...project.tasks };
|
|
delete tasks[action.id];
|
|
return {
|
|
...project,
|
|
tasks
|
|
};
|
|
}
|
|
|
|
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 };
|
|
}
|
|
|
|
export function handleUpdateTaskEstimation(project: Project, action: UpdateTaskEstimation): Project {
|
|
const estimations = {
|
|
...project.tasks[action.id].estimations,
|
|
[action.confidence]: action.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,
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
export interface UpdateProjectLabel extends Action {
|
|
label: string
|
|
}
|
|
|
|
export const UPDATE_PROJECT_LABEL = "UPDATE_PROJECT_LABEL";
|
|
|
|
export function updateProjectLabel(label: string): UpdateProjectLabel {
|
|
return { type: UPDATE_PROJECT_LABEL, label };
|
|
}
|
|
|
|
export function handleUpdateProjectLabel(project: Project, action: UpdateProjectLabel): Project {
|
|
return {
|
|
...project,
|
|
label: action.label
|
|
};
|
|
}
|
|
|
|
export interface UpdateTaskLabel extends Action {
|
|
id: TaskID
|
|
label: string
|
|
}
|
|
|
|
export const UPDATE_TASK_LABEL = "UPDATE_TASK_LABEL";
|
|
|
|
export function updateTaskLabel(id: TaskID, label: string): UpdateTaskLabel {
|
|
return { type: UPDATE_TASK_LABEL, id, label };
|
|
}
|
|
|
|
export function handleUpdateTaskLabel(project: Project, action: UpdateTaskLabel): Project {
|
|
return {
|
|
...project,
|
|
tasks: {
|
|
...project.tasks,
|
|
[action.id]: {
|
|
...project.tasks[action.id],
|
|
label: action.label,
|
|
}
|
|
}
|
|
};
|
|
} |