All files / src/pages/flowsheet-page/economics/comparison-panel SelectedStudiesList.tsx

75.86% Statements 22/29
60% Branches 33/55
42.85% Functions 3/7
87.5% Lines 14/16

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          15x                                 35x 15x           7x     22x   15x 22x 15x 29x 15x   34x                                                                 1x                                                                               150x 45x      
import { Trash2 } from "lucide-react";
import { Button } from "@/ahuora-design-system/ui/button";
import { cn } from "@/lib/utils";
import type { DraftComparisonStudy } from "./comparisonTypes";
 
export function SelectedStudiesList({
  activeStudy,
  selectedStudies,
  baselineStudyId,
  showBaselinePicker,
  canEdit,
  onBaselineStudyChange,
  onRemoveStudy,
}: {
  activeStudy: DraftComparisonStudy;
  selectedStudies: DraftComparisonStudy[];
  baselineStudyId: number;
  showBaselinePicker: boolean;
  canEdit: boolean;
  onBaselineStudyChange: (studyId: number) => void;
  onRemoveStudy: (studyId: number) => void;
}) {
  const studies = [activeStudy, ...selectedStudies];
  const gridClassName = showBaselinePicker
    ? "grid-cols-[minmax(0,1fr)_5rem_2.25rem]"
    : "grid-cols-[minmax(0,1fr)_2.25rem]";
  return (
    <div aria-label="Selected studies">
      <div
        className={cn(
          "mb-1 grid items-center gap-2 px-1 text-xs font-medium text-muted-foreground",
          gridClassName,
        )}
      >
        <span>Selected studies</span>
        {showBaselinePicker && <span className="text-center">Baseline</span>}
        <span aria-hidden="true" />
      </div>
      <div className="divide-y border-y">
        {studies.map((selectedStudy) => {
          const isBaseline = baselineStudyId === selectedStudy.id;
          return (
            <div
              key={selectedStudy.id}
              className={cn(
                "grid min-w-0 items-center gap-2 px-1 py-2",
                gridClassName,
                showBaselinePicker && isBaseline && "bg-muted/30",
              )}
            >
              <div className="min-w-0">
                <div className="truncate text-sm font-medium">
                  {selectedStudy.name}
                </div>
                <div className="truncate text-xs text-muted-foreground">
                  {selectedStudy.flowsheetName}
                </div>
              </div>
              {showBaselinePicker && (
                <label
                  className={cn(
                    "flex justify-center",
                    canEdit ? "cursor-pointer" : "cursor-not-allowed",
                  )}
                >
                  <input
                    type="radio"
                    name="comparison-baseline-study"
                    value={selectedStudy.id}
                    checked={isBaseline}
                    disabled={!canEdit}
                    aria-label={`Use ${selectedStudy.name} as baseline`}
                    className="peer sr-only"
                    onChange={() => onBaselineStudyChange(selectedStudy.id)}
                  />
                  <span
                    aria-hidden="true"
                    className={cn(
                      "grid size-4 place-items-center rounded-full border transition-colors peer-focus-visible:ring-1 peer-focus-visible:ring-ring",
                      isBaseline
                        ? "border-primary"
                        : "border-muted-foreground/60",
                      !canEdit && "cursor-not-allowed opacity-50",
                    )}
                  >
                    <span
                      className={cn(
                        "size-2 rounded-full bg-primary transition-opacity",
                        isBaseline ? "opacity-100" : "opacity-0",
                      )}
                    />
                  </span>
                </label>
              )}
              {selectedStudy.id !== activeStudy.id && (
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  aria-label={`Remove ${selectedStudy.name}`}
                  className="size-8"
                  disabled={!canEdit || selectedStudies.length <= 1}
                  onClick={() => onRemoveStudy(selectedStudy.id)}
                >
                  <Trash2 className="size-4" />
                </Button>
              )}
              {selectedStudy.id === activeStudy.id && (
                <span aria-hidden="true" />
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}