All files / components/MenuItem MenuItemTable.js

100% Statements 38/38
100% Branches 20/20
100% Functions 7/7
100% Lines 37/37

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              2x 30x 30x   30x     316x 37x 279x 273x 183x     183x     183x 47x     183x       30x 30x       25x 25x 25x   25x 1x 1x         25x                         19x   19x   28x 28x   28x   19x 5x     14x 14x 20x   14x 14x         25x 8x         25x    
// src/main/components/MenuItem/MenuItemTable.jsx
 
import React from "react";
import OurTable, { ButtonColumn } from "../OurTable";
import { hasRole } from "../../utils/currentUser";
import { useNavigate, useLocation } from "react-router-dom";
 
export const extractAllReviewsForItem = (raw, itemId) => {
  const seen = new Set();
  const reviews = [];
 
  const recurse = (node) => {
    // known issue with Stryker on recursion with array checking
    // Stryker disable next-line all : recursion
    if (Array.isArray(node)) {
      node.forEach(recurse);
    } else if (node) {
      if (seen.has(node)) return;
      seen.add(node);
 
      const isReviewForItem =
        typeof node.itemsStars !== "undefined" &&
        (node.item.id === itemId || node.item === itemId);
 
      if (isReviewForItem) {
        reviews.push(node);
      }
 
      Object.values(node).forEach(recurse);
    }
  };
 
  recurse(raw);
  return reviews;
};
 
export default function MenuItemTable({ menuItems, currentUser }) {
  const testid = "MenuItemTable";
  const navigate = useNavigate();
  const location = useLocation();
 
  const reviewCallback = (cell) => {
    const id = cell.row.original.id;
    navigate(`/reviews/create/${id}`, {
      state: { from: location.pathname },
    });
  };
 
  const columns = [
    {
      Header: "Item Name",
      accessor: "name",
    },
    {
      Header: "Station",
      accessor: "station",
    },
    {
      Header: "Average Review",
      id: "averageReview",
      accessor: (row) => {
        const extracted = extractAllReviewsForItem(row.reviews, row.id);
 
        const validRatings = extracted
          .map((r) => {
            const num = Number(r.itemsStars);
            return Number.isFinite(num) && num >= 1 && num <= 5 ? num : null;
          })
          .filter((num) => num !== null);
 
        if (validRatings.length === 0) {
          return "🤷‍♂️ No Rating";
        }
 
        let total = 0;
        for (const stars of validRatings) {
          total = total + stars;
        }
        const avg = total / validRatings.length;
        return `${avg.toFixed(1)} ⭐`;
      },
    },
  ];
 
  if (hasRole(currentUser, "ROLE_USER")) {
    columns.push(
      ButtonColumn("Review Item", "warning", reviewCallback, testid),
    );
  }
 
  return <OurTable columns={columns} data={menuItems} testid={testid} />;
}