All files / react-app/src/features/dashboard/Lists/renderCells index.tsx

100% Statements 15/15
100% Branches 4/4
100% Functions 8/8
100% Lines 13/13

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                  7x 92x 5504x 1581x               7x 1214x 1x                                 7x 32x 1379x   1378x                                           575x 1x                                                                    
import { EllipsisVerticalIcon } from "@heroicons/react/24/outline";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { Link } from "react-router";
import { Authority, FullUser, opensearch } from "shared-types";
import { formatDateToET, getAvailableActions } from "shared-utils";
 
import { DASHBOARD_ORIGIN, mapActionLabel, ORIGIN } from "@/utils";
import { sendGAEvent } from "@/utils/ReactGA/SendGAEvent";
 
export const renderCellDate = (key: keyof opensearch.main.Document) =>
  function Cell(data: opensearch.main.Document) {
    if (!data[key]) return null;
    return formatDateToET(data[key] as string, "MM/dd/yyyy", false);
  };
 
export type CellIdLinkProps = {
  id: string;
  authority: Authority | string;
};
 
export const CellDetailsLink = ({ id, authority }: CellIdLinkProps) => {
  const handleLinkClick = () => {
    sendGAEvent("dash_package_link", {
      package_type: authority, // The 'authority' prop is the package type
      package_id: id, // The 'id' prop is the package_id
    });
  };
 
  return (
    <Link
      className="cursor-pointer text-blue-600 hover:underline"
      to={`/details/${encodeURIComponent(authority)}/${encodeURIComponent(id)}`}
      onClick={handleLinkClick} // Track the click event for analytics
    >
      {id}
    </Link>
  );
};
 
export const renderCellActions = (user: FullUser | null) => {
  return function Cell(data: opensearch.main.Document) {
    if (!user) return null;
 
    const actions = getAvailableActions(user, data);
 
    return (
      <DropdownMenu.Root>
        <DropdownMenu.DropdownMenuTrigger
          disabled={!actions.length}
          aria-label="Available package actions"
          data-testid="available-actions"
          asChild
        >
          <button className="group ml-3" type="button" title="Expand Available Package Actions">
            <EllipsisVerticalIcon
              aria-hidden
              className="w-8 text-blue-700 group-disabled:text-gray-500"
            />
          </button>
        </DropdownMenu.DropdownMenuTrigger>
        <DropdownMenu.Content
          className="flex flex-col bg-white rounded-md shadow-lg p-4 border"
          align="start"
        >
          {actions.map((action, idx) => {
            const handleActionClick = () => {
              sendGAEvent("dash_ellipsis_click", {
                action: action,
              });
            };
 
            return (
              <DropdownMenu.Item
                key={`${idx}-${action}`}
                asChild
                aria-label={`${mapActionLabel(action)} for ${data.id}`}
              >
                <Link
                  onClick={handleActionClick}
                  state={{
                    from: `${location.pathname}${location.search}`,
                  }}
                  to={{
                    pathname: `/actions/${action}/${data.authority}/${data.id}`,
                    search: new URLSearchParams({
                      [ORIGIN]: DASHBOARD_ORIGIN,
                    }).toString(),
                  }}
                  className="text-blue-500 flex select-none items-center rounded-sm px-2 py-2 text-sm hover:bg-accent"
                >
                  {mapActionLabel(action)}
                </Link>
              </DropdownMenu.Item>
            );
          })}
        </DropdownMenu.Content>
      </DropdownMenu.Root>
    );
  };
};