Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

save all done tasks to collection #2064

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
6 changes: 6 additions & 0 deletions src/api/GoalsAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { getInstallId } from "@src/utils";
import { IHintRequestBody } from "@src/models/HintItem";
import { sortGoalsByProps } from "../GCustomAPI";
import { deleteAvailableGoalHint, deleteHintItem, getGoalHintItem } from "../HintsAPI";
import { deleteTasksDoneTodayByGoalId } from "../TasksDoneTodayAPI";
import { deleteTaskHistoryItem } from "../TaskHistoryAPI";

export const addDeletedGoal = async (goal: GoalItem) => {
await db
Expand Down Expand Up @@ -173,6 +175,8 @@ export const removeChildrenGoals = async (parentGoalId: string) => {
childrenGoals.forEach((goal) => {
removeChildrenGoals(goal.id);
removeGoal(goal);
deleteTasksDoneTodayByGoalId(goal.id);
deleteTaskHistoryItem(goal.id);
});
};

Expand Down Expand Up @@ -315,6 +319,8 @@ export const notifyNewColabRequest = async (id: string, relId: string) => {
export const removeGoalWithChildrens = async (goal: GoalItem) => {
await removeChildrenGoals(goal.id);
await removeGoal(goal);
await deleteTasksDoneTodayByGoalId(goal.id);
await deleteTaskHistoryItem(goal.id);
if (goal.parentGoalId !== "root") {
getGoal(goal.parentGoalId).then(async (parentGoal: GoalItem) => {
const parentGoalSublist = parentGoal.sublist;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
/* eslint-disable no-param-reassign */
import { db } from "@models";
import { DumpboxItem } from "@src/models/DumpboxItem";
import { SchedulerOutputCacheItem } from "@src/models/SchedulerOutputCacheItem";
import { v4 as uuidv4 } from "uuid";

export const getFromOutbox = async (key: string) => {
export const getSchedulerCachedRes = async (key: string) => {
try {
const dumpbox = await db.dumpboxCollection.where("key").equals(key).toArray();
return dumpbox[0];
const schedulerOutputCache = await db.schedulerOutputCacheCollection.where("key").equals(key).toArray();
return schedulerOutputCache[0];
} catch (err) {
return null;
}
};

export const addSchedulerRes = async (uniqueId: string, output: string) => {
export const addSchedulerResToCache = async (uniqueId: string, output: string) => {
let newId;
await db
.transaction("rw", db.dumpboxCollection, async () => {
newId = await db.dumpboxCollection.add({
.transaction("rw", db.schedulerOutputCacheCollection, async () => {
newId = await db.schedulerOutputCacheCollection.add({
key: "scheduler",
value: JSON.stringify({
uniqueId,
Expand All @@ -32,11 +32,11 @@ export const addSchedulerRes = async (uniqueId: string, output: string) => {
};

export const updateSchedulerCachedRes = async (uniqueId: string, output: string) => {
db.transaction("rw", db.dumpboxCollection, async () => {
await db.dumpboxCollection
db.transaction("rw", db.schedulerOutputCacheCollection, async () => {
await db.schedulerOutputCacheCollection
.where("key")
.equals("scheduler")
.modify((obj: DumpboxItem) => {
.modify((obj: SchedulerOutputCacheItem) => {
obj.value = JSON.stringify({
uniqueId,
output,
Expand Down
22 changes: 22 additions & 0 deletions src/api/TaskHistoryAPI/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { db } from "@src/models";
import { TaskHistoryEvents, TaskHistoryItem } from "@src/models/TaskHistoryItem";
import { ITask } from "@src/Interfaces/Task";

export async function addTaskActionEvent(task: ITask, eventType: TaskHistoryEvents) {
if (!task) return;

const newEvent: TaskHistoryItem = {
goalId: task.goalid,
eventType,
duration: task.duration,
scheduledStart: task.start,
scheduledEnd: task.deadline,
eventTime: new Date().toISOString(),
};

await db.taskHistoryCollection.add(newEvent);
}

export async function deleteTaskHistoryItem(goalId: string) {
await db.taskHistoryCollection.where("goalId").equals(goalId).delete();
}
40 changes: 0 additions & 40 deletions src/api/TasksAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { blockedSlotOfTask, TaskItem } from "@src/models/TaskItem";
import { GoalItem } from "@src/models/GoalItem";
import { calDays, convertDateToString, getLastDayDate } from "@src/utils";
import { convertDateToDay } from "@src/utils/SchedulerUtils";
import { ITask } from "@src/Interfaces/Task";
import { ISchedulerInputGoal } from "@src/Interfaces/IScheduler";
import { getGoal } from "../GoalsAPI";

Expand Down Expand Up @@ -106,45 +105,6 @@ export const refreshTaskCollection = async () => {
console.error("Error updating field:", error);
}
};
export const completeTask = async (id: string, duration: number, task: ITask) => {
db.transaction("rw", db.taskCollection, async () => {
await db.taskCollection
.where("id")
.equals(id)
.modify((obj: TaskItem) => {
obj.completedToday += duration;
obj.completedTodayTimings.push({
goalid: task.goalid,
start: task.start,
deadline: task.deadline,
});
obj.completedTodayIds.push(task.taskid);
});
}).catch((e) => {
console.log(e.stack || e);
});
};

export const skipTask = async (id: string, period: string, task: ITask) => {
db.transaction("rw", db.taskCollection, async () => {
await db.taskCollection
.where("id")
.equals(id)
.modify((obj: TaskItem) => {
obj.skippedToday.push(period);
obj.completedTodayTimings.push({
goalid: task.goalid,
start: task.start,
deadline: task.deadline,
});
if (obj.skippedToday.length > 1) {
obj.skippedToday.sort((a, b) => Number(a.split("-")[0]) - Number(b.split("-")[0]));
}
});
}).catch((e) => {
console.log(e.stack || e);
});
};

export const getAllTasks = async () => {
const allGoals = await db.taskCollection.toArray();
Expand Down
44 changes: 44 additions & 0 deletions src/api/TasksDoneTodayAPI/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { db } from "@src/models";
import { TasksDoneTodayItem } from "@src/models/TasksDoneTodayItem";

export const addTaskDoneToday = async (completedTask: TasksDoneTodayItem) => {
try {
await db.tasksDoneTodayCollection.add(completedTask);
} catch (error) {
console.error("Error adding task:", error);
}
};

export const getAllTasksDoneToday = async () => {
try {
const tasks = await db.tasksDoneTodayCollection.toArray();
return tasks;
} catch (error) {
console.error("Error fetching tasks:", error);
return [];
}
};

export const deleteTaskDoneToday = async (id: string) => {
try {
await db.tasksDoneTodayCollection.delete(id);
} catch (error) {
console.error("Error deleting task:", error);
}
};

export const deleteTasksDoneTodayByGoalId = async (goalId: string) => {
try {
await db.tasksDoneTodayCollection.where("goalId").equals(goalId).delete();
} catch (error) {
console.error("Error deleting tasks by goalId:", error);
}
};

export const deleteAllTasksDoneToday = async () => {
try {
await db.tasksDoneTodayCollection.clear();
} catch (error) {
console.error("Error clearing tasks:", error);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ITagsChanges } from "@src/Interfaces/IDisplayChangesModal";
import { sendNewGoals } from "@src/helpers/BatchPublisher";
import { darkModeState, lastAction } from "@src/store";
import { getAllContacts } from "@src/api/ContactsAPI";
import { sendUpdatedGoal } from "@src/helpers/PubSubController";
import { sendUpdatedGoal } from "@src/controllers/PubSubController";
import { typeOfChange, typeOfIntent } from "@src/models/InboxItem";
import { archiveUserGoal, getGoal, removeGoalWithChildrens, updateGoal } from "@src/api/GoalsAPI";
import { deleteGoalChangesInID, getInboxItem, removeGoalInbox, removePPTFromInboxOfGoal } from "@src/api/InboxAPI";
Expand Down
63 changes: 21 additions & 42 deletions src/components/MyTimeComponents/MyTimeline/MyTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ import chevronLeftIcon from "@assets/images/chevronLeft.svg";

import { ITask, TaskAction } from "@src/Interfaces/Task";
import { getGoal } from "@src/api/GoalsAPI";
import { TaskItem } from "@src/models/TaskItem";
import { GoalItem } from "@src/models/GoalItem";
import { useTranslation } from "react-i18next";
import { displayToast, focusTaskTitle } from "@src/store";
import { addTask, completeTask, getTaskByGoalId } from "@src/api/TasksAPI";
import { addTask, getTaskByGoalId } from "@src/api/TasksAPI";

import "./index.scss";
import { displayReschedule } from "@src/store/TaskState";
import { TasksDoneTodayItem } from "@src/models/TasksDoneTodayItem";
import { addTaskActionEvent } from "@src/api/TaskHistoryAPI";
import { completeTask } from "@src/controllers/TaskDoneTodayController";
import { GoalTiming } from "./GoalTiming";
import { TaskOptions } from "./TaskOptions";
import { updateImpossibleGoals } from "./updateImpossibleGoals";
Expand All @@ -27,21 +29,16 @@ type ImpossibleTaskId = string;

interface MyTimelineProps {
day: string;
taskDetails: { [goalid: string]: TaskItem };
setTaskDetails: React.Dispatch<
React.SetStateAction<{
[goalid: string]: TaskItem;
}>
>;
myTasks: {
scheduled: ITask[];
impossible: ImpossibleTaskId[];
freeHrsOfDay: number;
scheduledHrs: number;
};
doneTasks: TasksDoneTodayItem[];
}

export const MyTimeline: React.FC<MyTimelineProps> = ({ day, myTasks, taskDetails, setTaskDetails }) => {
export const MyTimeline: React.FC<MyTimelineProps> = ({ day, myTasks, doneTasks }) => {
const { t } = useTranslation();
const navigate = useNavigate();
const { state } = useLocation();
Expand Down Expand Up @@ -89,13 +86,25 @@ export const MyTimeline: React.FC<MyTimelineProps> = ({ day, myTasks, taskDetail
navigate("/", { state: { ...state, displayFocus: true } });
};

const handleDoneClick = async (task: ITask) => {
await completeTask(task.taskid, task.goalid, task.start, task.deadline);
await addTaskActionEvent(task, "completed");
await doneSound.play();
};

const handleActionClick = async (actionName: TaskAction, task: ITask) => {
if (actionName === TaskAction.Goal) {
return handleOpenGoal(task.goalid);
}
if (actionName === TaskAction.Focus) {
return handleFocusClick(task);
}
if (actionName === TaskAction.Done) {
return handleDoneClick(task);
}
if (actionName === TaskAction.NotNow) {
return setOpenReschedule({ ...task });
}
if (day === "Today") {
const taskItem = await getTaskByGoalId(task.goalid);
if (!taskItem) {
Expand All @@ -107,40 +116,12 @@ export const MyTimeline: React.FC<MyTimelineProps> = ({ day, myTasks, taskDetail
title: task.title,
completedTodayIds: [],
skippedToday: [],
completedToday: actionName === TaskAction.Done ? Number(task.duration) : 0,
completedToday: 0,
lastSkipped: "",
lastCompleted: actionName === TaskAction.Done ? new Date().toLocaleDateString() : "",
lastCompleted: "",
hoursSpent: 0,
completedTodayTimings:
actionName === TaskAction.Done
? [
{
goalid: task.goalid,
start: task.start,
deadline: task.deadline,
},
]
: [],
blockedSlots: [],
});
} else if (actionName === TaskAction.Done) {
const markDone = !!taskDetails[task.goalid]?.completedTodayIds.includes(task.taskid);
if (markDone) return null;
await completeTask(taskItem.id, Number(task.duration), task);
} else if (actionName === TaskAction.NotNow) {
setOpenReschedule(task);
}
if (actionName === TaskAction.Done) {
await doneSound.play();
const updatedTask = await getTaskByGoalId(task.goalid);
if (updatedTask) {
setTaskDetails({
...taskDetails,
[task.goalid]: updatedTask,
});
}
} else if (actionName === TaskAction.NotNow) {
setOpenReschedule({ ...task });
}
} else {
setShowToast({ open: true, message: "Let's focus on Today :)", extra: "" });
Expand All @@ -160,9 +141,7 @@ export const MyTimeline: React.FC<MyTimelineProps> = ({ day, myTasks, taskDetail
const nextTask = myTasks.scheduled[index + 1];
const nextStartTime = nextTask ? nextTask.start.split("T")[1].slice(0, 2) : null;
const displayEndTime = endTime !== nextStartTime;
const markDone = !!taskDetails[task.goalid]?.completedTodayTimings.find(
(ele) => ele.start === task.start && ele.deadline === task.deadline,
);
const markDone = doneTasks.some((doneTask) => doneTask.scheduledTaskId === task.taskid);
const showTaskOptions = displayOptionsIndex === task.taskid;
return (
<button
Expand Down
21 changes: 12 additions & 9 deletions src/components/MyTimeComponents/NotNow/NotNowModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import React, { useEffect, useState } from "react";
import { lastAction } from "@src/store";
import "./NotNowModal.scss";
import ZModal from "@src/common/ZModal";
import { addBlockedSlot, getTaskByGoalId, skipTask } from "@src/api/TasksAPI"; // Assume getGoalById exists
import { addBlockedSlot } from "@src/api/TasksAPI";
import { displayReschedule } from "@src/store/TaskState";
import { MILLISECONDS_IN_HOUR, RESCHEDULE_OPTIONS } from "@src/constants/rescheduleOptions";
import { convertDateToString } from "@src/utils";
import ActionDiv from "@components/GoalsComponents/MyGoalActions/ActionDiv";
import { getGoalById } from "@src/api/GoalsAPI";
import { getHrFromDateString } from "@src/utils/SchedulerUtils";
import forgetTune from "@assets/forget.mp3";
import { addTaskActionEvent } from "@src/api/TaskHistoryAPI";
import { addTaskDoneToday } from "@src/api/TasksDoneTodayAPI";

const NotNowModal = () => {
const [task, setDisplayReschedule] = useRecoilState(displayReschedule);
Expand All @@ -36,7 +37,7 @@ const NotNowModal = () => {

if (!task) return null;

const handleReschedule = (hours: number) => {
const handleReschedule = async (hours: number) => {
const startTime = new Date(task.start);
const endTime = new Date(startTime.getTime() + hours * MILLISECONDS_IN_HOUR);
const start = convertDateToString(startTime, false);
Expand All @@ -46,19 +47,21 @@ const NotNowModal = () => {
start,
end,
});
await addTaskActionEvent(task, "postponed");

console.log(`Task rescheduled from ${start} to ${end}`);
setDisplayReschedule(null);
setLastAction("TaskRescheduled");
};

const handleSkip = async () => {
const taskItem = await getTaskByGoalId(task.goalid);
if (!taskItem) {
return;
}
const period = `${getHrFromDateString(task.start)}-${getHrFromDateString(task.deadline)}`;
await skipTask(taskItem?.id, period, task);
await addTaskDoneToday({
scheduledTaskId: task.taskid,
scheduledStart: task.start,
scheduledEnd: task.deadline,
goalId: task.goalid,
});
await addTaskActionEvent(task, "skipped");
setDisplayReschedule(null);
setLastAction("TaskSkipped");
forgetSound.play();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GoalItem } from "@src/models/GoalItem";
import { getSelectedLanguage, inheritParentProps } from "@src/utils";
import { inheritParentProps } from "@src/utils";
import { sendUpdatesToSubscriber } from "@src/services/contact.service";
import { getSharedWMGoal, removeSharedWMChildrenGoals, updateSharedWMGoal } from "@src/api/SharedWMAPI";
import {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { GoalItem, IParticipant } from "@src/models/GoalItem";
import { sendUpdatesToSubscriber } from "@src/services/contact.service";
import { getSelectedLanguage, inheritParentProps } from "@src/utils";

import { createGoalObjectFromTags } from "./GoalProcessor";
import { createGoalObjectFromTags } from "../helpers/GoalProcessor";

const sendUpdate = (
subscribers: IParticipant[],
Expand Down
Loading
Loading