status: getStepStatus()

in src/components/Timeline/useTaskData.ts [177:270]


            status: getStepStatus(data),
            finished_at: endTime,
            duration: startTime ? endTime - startTime : 0,
            data,
          },
        };
      }, state);

      return newState;
    }
    case 'toggle':
      if (state[action.id]) {
        return { ...state, [action.id]: { ...state[action.id], isOpen: !state[action.id].isOpen } };
      }
      return state;
    case 'open':
      if (state[action.id]) {
        return { ...state, [action.id]: { ...state[action.id], isOpen: true } };
      }
      return state;
    case 'close':
      if (state[action.id]) {
        return { ...state, [action.id]: { ...state[action.id], isOpen: false } };
      }
      return state;
    case 'openAll':
      return Object.keys(state).reduce((obj, current) => {
        return { ...obj, [current]: { ...obj[current], isOpen: true } };
      }, state);
    case 'closeAll':
      return Object.keys(state).reduce((obj, current) => {
        return { ...obj, [current]: { ...obj[current], isOpen: false } };
      }, state);
    case 'reset':
      return emptyObject;
  }
}

//
// Hook
//

export type useTaskDataHook = {
  rows: RowDataModel;
  dispatch: React.Dispatch<RowDataAction>;
  taskStatus: AsyncStatus;
  counts: RowCounts;
  steps: StepLineData[];
  isAnyGroupOpen: boolean;
  taskError: APIError | null;
  stepError: APIError | null;
};

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) {