Timer component
The Timer component provides a way to start and stop timers. It also provides a way to log the time between two events, attach it to tasks, and more.
Global timer (in the navbar) is configured in MmoProLayout.jsx.
Socket events
This app uses socket.io to communicate with the server. The main idea behind Socket.IO is that you can send and receive any events you want, with any data you want. Any objects that can be encoded as JSON will do, and binary data is supported too.
Please refer to the Socket.IO documentation (opens in a new tab) for more information.
When the application is initialize the users enters the room host-[HOST-NAME]:user-[USER-ID]
and the server sends the future events to this room.
The following events are used:
Timer related events
timer:start
- Start the timertimer:stop
- Stop the timertimer:reset
- Reset the timertimer:log
- Log the time between two eventstimer:attach
- Attach the timer to a tasktimer:detach
- Detach the timer from a task
Task related events
task:created
- Task createdtask:completed
- Task completedtask:reopened
- Task reopenedtask:updated
- Task updatedtask:deleted
- Task deletedtask:reorder
- Reorder taskstask:view
- View task (for displaying other task viewers)task:assign
- Assign task to a usertask:unassign
- Unassign task from a usertask:comment
- Comment on a tasktask:comment:delete
- Delete a comment on a tasktask:comment:edit
- Edit a comment on a tasktask:attachment:delete
- Delete an attachment on a tasktask:attachment:edit
- Edit an attachment on a tasktask:attachment:upload
- Upload an attachment on a tasktask:attachment:download
- Download an attachment on a task
Project related events
project:updated
- Project updatedproject:deleted
- Project deletedproject:created
- Project createdproject:members:updated
- Project members updatedproject:members:deleted
- Project members deletedproject:members:added
- Project members addedproject:owner:updated
- Project owner updatedproject:status:updated
- Project status updated
Usage
Timer start
{
"event": "timer:start",
"data": {
"name": "timer name",
"time": 1234567890
}
}
Timer stop
{
"event": "timer:stop",
"data": {
"name": "timer name",
"time": 1234567890
}
}
Timer reset
{
"event": "timer:reset",
"data": {
"name": "timer name",
"time": 1234567890
}
}
Timer log
{
"event": "timer:log",
"data": {
"name": "timer name",
"time": 1234567890
}
}
Start timer
// Future state
// <Timer start={true} />
import { getCurrentTimeZone } from "@/utils/common";
import { nowFormatted } from "@/utils/dateTime/dateTimeUtils";
dispatch({
type: "timer/startTimer",
payload: {
from: nowFormatted(), // start time
status: "START", // START, STOP, PAUSE
task: {
// optional
id: taskId,
},
project: {
// optional
id: task?.project?.id,
},
description: "", // description
comment: "", // comment
workLogId: alreadyRunningTask.timeLogId,
reqFromGlobalHeader: true,
billable: false, // true, false
client: {
// optional
id: task?.client?.id,
},
},
});
Stop timer
// Future state
// <Timer start={true} />
import { getCurrentTimeZone } from "@/utils/common";
import { nowFormatted } from "@/utils/dateTime/dateTimeUtils";
dispatch({
type: "timer/startTimer", // TODO: change to stopTimer
payload: {
to: nowFormatted(), // end time
status: "STOP", // START, STOP, PAUSE
description: "", // description
task: {
// optional
id: taskId,
},
comment: "", // comment
calendarEvent: {
name: "Meeting with John",
description: "Discuss the new project",
participants: [
{
id: "123",
},
{
id: "456",
},
],
inviteParticipants: false, // if true, invite participants to the calendar event
},
},
});