export default function useTaskData()

in src/components/Timeline/useTaskData.ts [230:325]


export default function useTaskData(flowId: string, runNumber: string): useTaskDataHook {
  const [rows, dispatch] = useReducer(rowDataReducer, emptyObject);

  const onStepUpdate = useCallback((items: Step[]) => {
    dispatch({ type: 'fillStep', data: items });
  }, []);

  // Fetch & subscribe to steps
  const { error: stepError } = useResource<Step[], Step>({
    url: encodeURI(`/flows/${flowId}/runs/${runNumber}/steps`),
    subscribeToEvents: true,
    initialData: emptyArray,
    onUpdate: onStepUpdate,
    queryParams,
  });

  const onUpdate = useCallback((items: Task[]) => {
    dispatch({
      type: 'fillTasks',
      data: items.map((item) => ({ ...item, status: item.status === 'unknown' ? 'refining' : item.status })),
    });
  }, []);

  const postRequest = useCallback(
    (success: boolean, _target: string, result: DataModel<Task[]> | undefined) => {
      if (success && result) {
        const tasksNeedingRefine = result.data
          .filter((task) => task.status === 'unknown' && task.step_name !== '_parameters')
          .map((task) => task.task_id);

        if (tasksNeedingRefine.length > 0) {
          const target = apiHttp(
            `/flows/${flowId}/runs/${runNumber}/tasks?taskId=${tasksNeedingRefine.join(
              ',',
            )}&postprocess=true&_limit=500`,
          );

          fetch(target)
            .then((response) => response.json())
            .then((response: DataModel<Task[]>) => {
              if (response?.status === 200) {
                dispatch({ type: 'fillTasks', data: response.data });
              }
            })
            .catch((e) => {
              console.log(e);
            });
        }
      }
    },
    [flowId, runNumber],
  );

  // Fetch & subscribe to tasks
  const { status: taskStatus, error: taskError } = useResource<Task[], Task>({
    url: encodeURI(`/flows/${flowId}/runs/${runNumber}/tasks`),
    subscribeToEvents: true,
    initialData: emptyArray2,
    updatePredicate,
    queryParams: initialQueryParams,
    socketParamFilter,
    fetchAllData: true,
    onUpdate,
    postRequest,
    useBatching: true,
  });

  //
  // Counts & steps data
  //
  const [counts, setCounts] = useState<RowCounts>({
    all: 0,
    completed: 0,
    running: 0,
    failed: 0,
    pending: 0,
    unknown: 0,
  });
  const [steps, setStepLines] = useState<StepLineData[]>(emptyStepLineArray);
  const [anyOpen, setAnyOpen] = useState<boolean>(true);

  useEffect(() => {
    // Only update counts if they have changed
    const newCounts = countTaskRowsByStatus(rows);
    if (JSON.stringify(counts) !== JSON.stringify(newCounts)) {
      setCounts(newCounts);
    }
    const newSteps = makeStepLineData(rows);
    if (JSON.stringify(steps) !== JSON.stringify(newSteps)) {
      setStepLines(makeStepLineData(rows));
    }
    setAnyOpen(!!Object.keys(rows).find((key) => rows[key].isOpen));
  }, [rows, counts, steps]);

  return { rows, dispatch, taskStatus, counts, steps, isAnyGroupOpen: anyOpen, taskError, stepError };
}