Skip to content

Tasks ‐ Front End

Ryan Eaton edited this page Nov 17, 2023 · 3 revisions

This is just a little page describing how the tasks are implemented on the front end.

Overview

HomePage -> TaskBox -> TaskType -> TaskCard

The tasks are in a state variable called tasks inside the HomePage component, following the defined JSON structure. The data is passed to TaskBox for handling the display and drag-and-drop. The components TaskType and TaskCard are generated dynamically according to their names. When a change is made to a card on the front end, changes are propagated upward to TaskType via a property function called callback(). The function of callback in TaskCard is described below. TaskType similarly accepts this change and propagates it upward to TaskBox. There is a similar callback for this purpose, but it should not need to be used for anything else at this level. At this point the setTasks state function which was passed into TaskBox as updateTasksData is called with the changes, then HomePage detects this page in a useEffect() and updates the database.

So if you want to change the tasks data, pass setTasks into your component, then call it when ready and the useEffect() in HomePage will handle the rest.

Callback

In TaskCard, there is a function available called callback() which takes 3 parameters: idx, task, and saveWorthy. The first two parameters should always be idx and task because these are the index and the actual task data respectively. saveWorthy is a boolean value for whether this specific change should trigger a database update. For the most part, it should be true.

Below is an example of how to use callback() from within a TaskCard to update the tasks list with a change from the variable show. At the time of writing, we have not decided on whether a task being opened or not should be saved in the database.

  1. Update the task
  2. Call the callback function with idx, the task itself, and a boolean for whether this change is save-worthy

https://github.com/R2bEEaton/njit-pending-cs490/blob/1553692909f0891b49af290c60bed1fec6443882/web/src/components/TaskCard/TaskCard.jsx#L38C1-L43C15

This concept can be extended for any front-end change to a card. For example, when updating notes, the checkmark button could be used to call a function that does something similar, modifying task.notes then executing callback() on the updated data.

Why do this stuff with callbacks? (not super important)

Changes made by child components are reflected in the parent if the data has the same memory address, which is true for JavaScript objects. So why is it necessary to do all this nonsense with callbacks?

React doesn't know when to render these changes unless the items are modified in a state variable.

  1. But we're not sending the whole variable to each component. The TaskCard only has information about its current task, and likewise the TaskType only has information about all its tasks. The TaskBox is the only component that has everything.
  2. And when modifying a state variable, React only does a shallow check for changes. In other words, even if we're using a state variable, and even if the variable is updated, React won't realize.

That's why we have to pass data from child to parent and instead of just updating the object, set it to a copy of itself. (That's why you will see temp_x = {...x} or similar sometimes in the code.)

I'm not exactly sure if this is entirely true, but by testing and after many failures, it seems consistent.

Dragging

Dragging is mostly handled by react-beautiful-dnd, with a custom function for handling reordering when a card is dropped. The function removes the item from the previous array and inserts it in the new array. Use of the spread operator ... is seen here for reasons described above.

https://github.com/R2bEEaton/njit-pending-cs490/blob/1553692909f0891b49af290c60bed1fec6443882/web/src/components/TaskBox/TaskBox.jsx#L49C7-L62C8

For react-beautiful-dnd purposes, it's crucial that all the TaskCard elements have a unique key={} property. I was thinking of using the task name, but that might not be unique, so some sort of unique ID is required for any tasks on the same day.

Clone this wiki locally