All files / store/components/PackageList PackageList.tsx

57.89% Statements 11/19
33.33% Branches 9/27
40% Functions 2/5
57.89% Lines 11/19

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 114 115 116 117 118 119 120 121 122 123 124 125 126 127                                        1x   1x                 4x 4x   4x   4x 4x   4x     4x                   4x                                                               48x                                                                                    
import {
  Button,
  Col,
  Pagination,
  Row,
  Strip,
} from "@canonical/react-components";
import Banner from "../Banner";
import { PackageFilter } from "../PackageFilter";
import Topics from "../Topics";
import {
  BundleCard,
  CharmCard,
  LoadingCard,
} from "@canonical/store-components";
import { useSearchParams } from "react-router-dom";
import { useRef } from "react";
 
import { Store } from "../../types";
 
const ITEMS_PER_PAGE = 12;
 
export const PackageList = ({
  isFetching,
  data,
  status,
}: {
  isFetching: boolean;
  status: "success" | "idle" | "error" | "loading";
  data?: Store;
}) => {
  const [searchParams, setSearchParams] = useSearchParams();
  const topicsQuery = searchParams ? searchParams.get("categories") : null;
 
  const searchRef = useRef<HTMLInputElement | null>(null);
 
  const currentPage = searchParams.get("page") || "1";
  const firstResultNumber = (parseInt(currentPage) - 1) * ITEMS_PER_PAGE + 1;
  const lastResultNumber =
    (parseInt(currentPage) - 1) * ITEMS_PER_PAGE +
    (data ? data.packages.length : 0);
 
  const onClear = () => {
    searchParams.delete("q");
    searchParams.delete("page");
    setSearchParams(searchParams);
 
    if (searchRef.current) {
      searchRef.current.value = "";
    }
  };
 
  return (
    <>
      <Banner searchRef={searchRef as React.RefObject<HTMLInputElement>} />
      <Strip>
        <Row>
          <Col size={3}>
            <PackageFilter disabled={isFetching} data={data} />
          </Col>
          <Col size={9}>
            <Topics topicsQuery={topicsQuery} />
            {data && (
              <div className="u-fixed-width">
                {searchParams.get("q") ? (
                  <p>
                    Showing {currentPage === "1" ? "1" : firstResultNumber} to{" "}
                    {lastResultNumber} of {data.total_items} results for{" "}
                    <strong>"{searchParams.get("q")}"</strong>.{" "}
                    <Button appearance="link" onClick={onClear}>
                      Clear search
                    </Button>
                  </p>
                ) : (
                  <p>
                    Showing {currentPage === "1" ? "1" : firstResultNumber} to{" "}
                    {lastResultNumber} of {data.total_items} items
                  </p>
                )}
              </div>
            )}
            <Row>
              {isFetching &&
                [...Array(ITEMS_PER_PAGE)].map((_item, index) => (
                  <Col size={3} key={index}>
                    <LoadingCard />
                  </Col>
                ))}
 
              {!isFetching &&
                status === "success" &&
                data &&
                data.packages.map((packageData) => (
                  <Col
                    size={3}
                    style={{ marginBottom: "1.5rem" }}
                    key={packageData.id}
                  >
                    {packageData.package.type === "bundle" ? (
                      <BundleCard data={packageData} />
                    ) : (
                      <CharmCard data={packageData} />
                    )}
                  </Col>
                ))}
            </Row>
 
            {status === "success" && data && (
              <Pagination
                itemsPerPage={ITEMS_PER_PAGE}
                totalItems={data.total_items}
                paginate={(pageNumber) => {
                  searchParams.set("page", pageNumber.toString());
                  setSearchParams(searchParams);
                }}
                currentPage={parseInt(currentPage)}
                centered
                scrollToTop
              />
            )}
          </Col>
        </Row>
      </Strip>
    </>
  );
};