All files / src/features/ChangeLog/hooks useChangelogData.ts

94% Statements 47/50
87.87% Branches 29/33
100% Functions 9/9
95.55% Lines 43/45

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 108 109 110 111 112 113                  117x                 717x         717x 717x 717x             717x             717x 717x 717x 306x     717x 160x 121x 121x 121x 121x   160x     717x 115x 3x 3x 3x 3x       717x 178x         33x     33x 33x 3x 3x 3x   30x 29x 29x 1x   1x 1x 1x 1x                   717x 1x 1x     717x                    
import {
  ChangelogData,
  useGetChangelog,
} from "@services/api/changelog/changelog";
import { useEffect, useMemo, useRef, useState } from "react";
import useChangelogFilters from "./useChangelogFilters";
import { sortChangelogDataFieldChanges } from "../utils/sortFieldChanges";
import { normalizeChangelogData } from "../utils/normalizeFieldChanges";
 
export const useChangelogData = ({
  id,
  enabled = true,
  isOpen,
}: {
  id: number;
  enabled?: boolean;
  isOpen: boolean;
}) => {
  const [data, setData] = useState<ChangelogData[]>([]);
  // Rows the server has actually returned so far. Tracked separately from
  // `data` because normalizeChangelogData can drop unrenderable rows: comparing
  // kept rows against the server total would leave "Load Previous Changes"
  // permanently visible on a merchant with a dropped row.
  const [receivedCount, setReceivedCount] = useState(0);
  const [page, setPage] = useState(1);
  const { filtersQuery, filtersForm, resetFilters } = useChangelogFilters();
 
  const {
    data: pageData,
    isLoading,
    isFetching,
    refetch,
  } = useGetChangelog({
    id,
    page,
    filter: filtersQuery,
    sorting: "-changeDate",
    enabled,
  });
  const searchQueryRef = useRef(false);
  const pageRef = useRef(1);
  const showMoreDataAvailable = useMemo(() => {
    return data.length > 0 && receivedCount < pageData?.total;
  }, [data, receivedCount, pageData?.total]);
 
  useEffect(() => {
    if (!isOpen) {
      setPage(1);
      setData([]);
      setReceivedCount(0);
      resetFilters();
    }
    if (isOpen && data.length === 0 && enabled) refetch();
  }, [isOpen]);
 
  useEffect(() => {
    if (data.length > 0) {
      setData([]);
      setReceivedCount(0);
      setPage(1);
      searchQueryRef.current = true;
    }
  }, [filtersQuery]);
 
  useEffect(() => {
    if (pageData?.data && !isFetching) {
      //normalizeChangelogData guards against rows whose fieldChanges is not a
      //list (free-form JSON column on the BE), which used to crash the panel (GB-21601)
      //the sortChangelogDataFieldChanges is a work around FE side bc the req was
      //to have a certain order for the changelog items (GB-21057)
      const normalizedData = sortChangelogDataFieldChanges(
        normalizeChangelogData(pageData.data),
      );
      const pageReceived = pageData.data.length;
      if (searchQueryRef.current) {
        setData([...normalizedData]);
        setReceivedCount(pageReceived);
        searchQueryRef.current = false;
      } else {
        if (data.length === 0 && pageData?.data) {
          setData(normalizedData);
          setReceivedCount(pageReceived);
        } else Eif (data.length > 0) {
          //if the page was not updated it means query was invalidated
          if (pageRef.current !== page) {
            setData((prev) => [...prev, ...normalizedData]);
            setReceivedCount((prev) => prev + pageReceived);
            pageRef.current = page;
          } else E{
            setData(normalizedData);
            setReceivedCount(pageReceived);
          }
        }
      }
    }
  }, [pageData, isFetching]);
 
  const handleLoadMore = () => {
    Iif (isLoading || pageData?.data === null) return;
    setPage((prev) => prev + 1);
  };
 
  return {
    handleLoadMore,
    data,
    isLoading: isLoading || (data.length === 0 && isFetching),
    isMoreData: pageData?.data !== null,
    showMoreDataAvailable,
    filtersForm,
    isFiltersApplied: !!filtersQuery,
  };
};