All files / src/hooks/cache useUpdateTaskCache.ts

71.73% Statements 33/46
66.66% Branches 8/12
62.5% Functions 5/8
78.12% Lines 25/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                                  424x 1617x     424x                   329x       66x 66x                 423x   1619x   324x       355x     47439x 47439x 47439x 47439x       28x         11881x       425x 425x         355x     425x           7804x     254x   254x               69x       142521x    
import { useSelector } from "react-redux";
import {
  api,
  PaginatedTaskListRead,
  TaskStatusEnum as StatusEnum,
  TaskRead,
  TaskTypeEnum,
} from "@/api/apiStore.gen.ts";
import { useFlowsheetId } from "@/hooks/project.ts";
import { useAppDispatch } from "@/store/hooks.ts";
import { ApiQueries, RootState } from "@/store/store";
 
function updateTaskInList(
  task: TaskRead,
  paginatedTasks: PaginatedTaskListRead,
  updateOnly: boolean,
) {
  const tasks = paginatedTasks?.results || ([] as TaskRead[]);
  const taskIndex = tasks.findIndex((t) => t.id === task.id);
 
  // If results is null, initialize it with the current tasks
  Iif (paginatedTasks.results == null) paginatedTasks.results = tasks;
 
  // Update the task in the list if it exists
  if (taskIndex !== -1) {
    if (
      task.status == StatusEnum.Pending &&
      tasks[taskIndex].status !== StatusEnum.Pending
    ) {
      return; // We have had an update since the task was pending. Don't overwrite with potentially stale data.
    } else {
      tasks[taskIndex] = task;
    }
  } else if (!updateOnly) {
    // If the task does not exist, add it to the list
    tasks.unshift(task);
    paginatedTasks.count += 1;
  }
}
 
function findTaskPageInList(
  taskId: number,
  tasks: [string, ApiQueries[string]][],
): number {
  for (const [, value] of tasks) {
    const paginatedTasks = value?.data as PaginatedTaskListRead | undefined;
    if (paginatedTasks) {
      const foundTask = paginatedTasks.results?.find((t) => t.id === taskId);
      if (foundTask) {
        return Number(value?.originalArgs?.page || 1);
      }
    }
  }
  return 1; // If not on any page, add to page 1
}
 
export function useUpdateTaskCache() {
  const dispatch = useAppDispatch();
  const flowsheetId = useFlowsheetId();
  const queries: ApiQueries = useSelector(
    (state: RootState) => state.api.queries,
  );
  return (updatedTask: TaskRead) => {
    Iif (updatedTask.task_type === TaskTypeEnum.BuildState) return;
 
    // Update the standard task list cache if this task is not a child task
    if (updatedTask.parent === null) {
      const endpointName = "coreTasksList";
      const allResults = Object.entries(queries).filter(([key]) =>
        key.startsWith(endpointName),
      );
 
      const pageNumber = findTaskPageInList(updatedTask.id, allResults);
      dispatch(
        api.util.updateQueryData(
          "coreTasksList",
          { page: pageNumber, flowsheet: flowsheetId },
          (paginatedTasks) => {
            updateTaskInList(updatedTask, paginatedTasks, false);
          },
        ),
      );
 
      return;
    }
 
    const endpointName = "coreTasksChildrenList";
    const allResults = Object.entries(queries).filter(([key]) =>
      key.startsWith(endpointName),
    );
    const pageNumber = findTaskPageInList(updatedTask.id, allResults);
    // Update the child task list cache
    dispatch(
      api.util.updateQueryData(
        "coreTasksChildrenList",
        {
          id: updatedTask.parent as number,
          page: pageNumber,
        },
        (paginatedTasks) => {
          updateTaskInList(updatedTask, paginatedTasks, true);
        },
      ),
    );
  };
}