All files / src/pages/flowsheet-page/economics/results-panel/tables KeyFinancialMetricsTable.tsx

78.94% Statements 45/57
65.21% Branches 15/23
30.76% Functions 4/13
86.11% Lines 31/36

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                                          120x                     7x   55x   629x 12x 7x 5x     55x 7x 5x         55x             12x 12x     5x               55x 55x 12x   55x     55x 19x     32x       24x                   24x       24x   24x   24x     48x 24x   48x   72x 72x      
import { Table2 } from "lucide-react";
import type { ReactNode } from "react";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/ahuora-design-system/ui/accordion";
import type { EconomicsResultLineRead } from "@/api/apiStore.gen";
import {
  formatAmount,
  formatUnit,
} from "../../shared/model/economicsFormatters";
import {
  KEY_FINANCIAL_METRIC_ROWS,
  maximumFractionDigitsForKeyFinancialMetric,
} from "../model/financialMetricCatalog";
import { resultLineRowClassName, resultLineRowRef } from "./resultRowState";
import { ResultDataTable } from "./resultTable";
import { resultColumn } from "./resultTableColumns";
 
export function KeyFinancialMetricsTable({
  lines,
  resultCurrency,
  selectedSourceRowId,
  rowRefs,
}: {
  lines: EconomicsResultLineRead[];
  resultCurrency: string;
  selectedSourceRowId?: number;
  rowRefs: Map<number, HTMLElement>;
}) {
  const rows = [...KEY_FINANCIAL_METRIC_ROWS]
    .sort((left, right) => left.label.localeCompare(right.label))
    .map((item) => ({
      ...item,
      line: lines.find((line) => line.row_key === item.rowKey),
    }));
  const columns = [
    resultColumn<(typeof rows)[number]>({
      key: "metric",
      header: "Metric",
      render: ({ label }: (typeof rows)[number]) => label,
    }),
    resultColumn<(typeof rows)[number]>({
      key: "value",
      header: "Value",
      headClassName: "text-right",
      cellClassName: "text-right tabular-nums",
      render: ({ rowKey, line }: (typeof rows)[number]) =>
        line
          ? `${formatAmount(line.amount, {
              maximumFractionDigits:
                maximumFractionDigitsForKeyFinancialMetric(rowKey),
            })} ${formatUnit(line.unit, resultCurrency)}`
          : "-",
    }),
  ];
 
  return (
    <KeyFinancialMetricsFrame
      ariaLabel="Key financial metrics"
      title="Key financial metrics"
    >
      <ResultDataTable
        ariaLabel="Key financial metric rows"
        columns={columns}
        rows={rows}
        getRowKey={({ label, rowKey }) => `${label}-${rowKey}`}
        getRowRef={({ line }) =>
          line ? resultLineRowRef(rowRefs, line.id) : undefined
        }
        getRowAriaSelected={({ line }) =>
          line ? selectedSourceRowId === line.id : undefined
        }
        getRowClassName={({ line }) =>
          resultLineRowClassName({ line, selectedSourceRowId })
        }
      />
    </KeyFinancialMetricsFrame>
  );
}
 
export function KeyFinancialMetricsFrame({
  ariaLabel,
  title,
  children,
}: {
  ariaLabel: string;
  title: string;
  children: ReactNode;
}) {
  return (
    <section
      className="min-w-0 max-w-full rounded-md border bg-background p-3 [contain:inline-size]"
      aria-label={ariaLabel}
    >
      <Accordion type="single" collapsible defaultValue="metrics">
        <AccordionItem value="metrics" className="border-0 text-sm">
          <AccordionTrigger className="mb-2 gap-2 px-0 py-0 text-sm font-semibold text-foreground hover:bg-transparent [&[data-state=open]]:bg-transparent [&>div]:ml-auto">
            <span className="flex min-w-0 items-center gap-2">
              <Table2 className="size-4 shrink-0 text-primary" />
              <span className="truncate">{title}</span>
            </span>
          </AccordionTrigger>
          <AccordionContent className="mt-0 px-0 pb-0 pt-0">
            {children}
          </AccordionContent>
        </AccordionItem>
      </Accordion>
    </section>
  );
}