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

97.05% Statements 33/34
65.47% Branches 55/84
66.66% Functions 2/3
100% Lines 28/28

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 128 129 130 131 132 133 134                        18x                                                                   18x         3x 103x                 18x   18x   28x   14x           46x 18x 46x 46x     15x     18x     63x     14x             18x           18x     88x                 18x   54x 54x 54x   15x         18x 18x       123x 72x      
import { AlertTriangle, Check, Loader2, Plus } from "lucide-react";
import { Button } from "@/ahuora-design-system/ui/button";
import {
  EconomicsBaselineMode,
  type EconomicsStudyRead,
} from "@/api/apiStore.gen";
import { GroupedEconomicsStudySelect } from "../shared/ui";
import { BaselineModePicker } from "./BaselineModePicker";
import type { DraftComparisonStudy } from "./comparisonTypes";
import { NO_COMPARISON_STUDY_SELECTION } from "./comparisonTypes";
import { SelectedStudiesList } from "./SelectedStudiesList";
 
export function ComparisonSetupPanel({
  activeStudy,
  baselineMode,
  baselineStudyId,
  canEdit,
  candidateStudies,
  saveFailed,
  saveLoading,
  selectedCandidateStudyId,
  selectedStudies,
  studiesLoading,
  onAddStudy,
  onBaselineModeChange,
  onBaselineStudyChange,
  onCandidateStudyChange,
  onRemoveStudy,
}: {
  activeStudy: DraftComparisonStudy;
  baselineMode: EconomicsBaselineMode;
  baselineStudyId: number;
  canEdit: boolean;
  candidateStudies: EconomicsStudyRead[];
  saveFailed: boolean;
  saveLoading: boolean;
  selectedCandidateStudyId: string;
  selectedStudies: DraftComparisonStudy[];
  studiesLoading: boolean;
  onAddStudy: () => void;
  onBaselineModeChange: (mode: EconomicsBaselineMode) => void;
  onBaselineStudyChange: (studyId: number) => void;
  onCandidateStudyChange: (studyId: string) => void;
  onRemoveStudy: (studyId: number) => void;
}) {
  const addDisabled =
    !canEdit ||
    saveLoading ||
    selectedStudies.length >= 10 ||
    selectedCandidateStudyId === NO_COMPARISON_STUDY_SELECTION ||
    !candidateStudies.some(
      (candidate) => String(candidate.id) === selectedCandidateStudyId,
    );
 
  return (
    <section
      className="rounded-md border bg-card p-3"
      aria-label="Comparison setup"
    >
      <div className="mb-3 flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2">
        <div className="flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1">
          <h4 className="text-sm font-semibold">Study comparison</h4>
          <span className="text-xs text-muted-foreground">
            {selectedStudies.length + 1} selected
          </span>
        </div>
        <div className="flex items-center gap-2 text-xs text-muted-foreground">
          {saveLoading ? (
            <Loader2 className="size-4 animate-spin" />
          ) : saveFailed ? (
            <AlertTriangle className="size-4 text-destructive" />
          ) : (
            <Check className="size-4" />
          )}
          {saveLoading ? "Saving" : saveFailed ? "Not saved" : "Saved"}
        </div>
      </div>
 
      <div className="grid gap-3 min-[640px]:grid-cols-[minmax(14rem,1fr)_minmax(14rem,1fr)_auto] min-[640px]:items-end">
        <div className="min-w-0">
          <BaselineModePicker
            value={baselineMode}
            disabled={!canEdit || saveLoading}
            onChange={onBaselineModeChange}
          />
        </div>
 
        <div className="flex min-w-0 items-end gap-3 min-[640px]:contents">
          <div className="min-w-0 flex-1">
            <GroupedEconomicsStudySelect
              label="Study"
              ariaLabel="Select comparison study"
              value={selectedCandidateStudyId}
              studies={candidateStudies}
              disabled={
                !canEdit ||
                saveLoading ||
                studiesLoading ||
                candidateStudies.length === 0 ||
                selectedStudies.length >= 10
              }
              placeholder={studiesLoading ? "Loading studies" : "Select study"}
              onChange={onCandidateStudyChange}
            />
          </div>
 
          <Button
            type="button"
            variant="outline"
            className="shrink-0"
            onClick={onAddStudy}
            disabled={addDisabled}
          >
            <Plus className="size-4" />
            Add
          </Button>
        </div>
      </div>
 
      <div className="mt-4">
        <SelectedStudiesList
          activeStudy={activeStudy}
          selectedStudies={selectedStudies}
          baselineStudyId={baselineStudyId}
          showBaselinePicker={baselineMode === EconomicsBaselineMode.Study}
          canEdit={canEdit && !saveLoading}
          onBaselineStudyChange={onBaselineStudyChange}
          onRemoveStudy={onRemoveStudy}
        />
      </div>
    </section>
  );
}