All files / src/pages/flowsheet-page/economics/capital EconomicsCapitalBreakdown.tsx

32.55% Statements 14/43
27.65% Branches 13/47
14.28% Functions 1/7
40% Lines 12/30

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                    80x           80x                 80x         5x   80x   90x     5x   80x 5x       85x 85x                                         560x                                                                                                                  
import { Badge } from "@/ahuora-design-system/ui/badge";
import type { EconomicsResultLineRead } from "@/api/apiStore.gen";
import { cn } from "@/lib/utils";
import {
  capitalFactorLabel,
  capitalFactorMeta,
  capitalFactorsFromPayload,
  formatAmountWithUnit,
} from "./economicsCapitalFactors";
 
export function CapitalCostBreakdown({
  lines,
  stale,
  runId,
  unitName,
  className,
  fullWidth = false,
}: {
  lines: EconomicsResultLineRead[];
  stale: boolean;
  runId: number | null;
  unitName?: string;
  className?: string;
  fullWidth?: boolean;
}) {
  const matchingLines = lines.filter((line) =>
    line.kind.toString().includes("capital"),
  );
  return (
    <div
      className={cn(
        "mt-3 w-full rounded-md border border-input bg-muted/20 p-3 text-left",
        !fullWidth && "md:w-1/2",
        className,
      )}
    >
      <div className="flex flex-wrap items-center justify-between gap-2">
        <span className="text-sm font-semibold text-muted-foreground">
          Capital cost
        </span>
        {stale && (
          <Badge variant="secondary" size="xs" borderRadius="round">
            Stale
          </Badge>
        )}
      </div>
      {matchingLines.length === 0 ? (
        <div className="mt-2 text-xs text-muted-foreground">
          {runId
            ? "No capital result is available for this unit."
            : "Calculate results to see capital cost."}
        </div>
      ) : (
        <div className="mt-3 space-y-3">
          {matchingLines.map((line) => (
            <div key={line.id}>
              {resultLineLabel(line.label, unitName) !== "Capital cost" && (
                <div className="mb-2 text-xs text-muted-foreground">
                  {resultLineLabel(line.label, unitName)}
                </div>
              )}
              <CapitalFactorBreakdown line={line} />
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
 
export function CapitalFactorBreakdown({
  line,
}: {
  line: EconomicsResultLineRead;
}) {
  const factors = capitalFactorsFromPayload(line.warning_payload);
  return (
    <dl className="space-y-2.5">
      {factors.map((factor, index) => (
        <div
          key={`${factor.kind}-${index}`}
          className="grid grid-cols-[minmax(0,1fr)_auto] items-start gap-x-3"
        >
          <dt className="min-w-0">
            <div className="truncate text-sm text-muted-foreground">
              {capitalFactorLabel(factor)}
            </div>
            {capitalFactorMeta(factor) && (
              <div className="mt-0.5 truncate text-xs leading-4 text-muted-foreground/70">
                {capitalFactorMeta(factor)}
              </div>
            )}
          </dt>
          <dd className="justify-self-end text-right text-sm tabular-nums text-muted-foreground">
            {formatAmountWithUnit(factor.amount, line.unit)}
          </dd>
        </div>
      ))}
      <div className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 border-t border-input/70 pt-2">
        <dt className="text-sm font-semibold text-foreground">Total</dt>
        <dd className="justify-self-end text-right text-sm font-semibold tabular-nums text-foreground">
          {formatAmountWithUnit(line.amount, line.unit)}
        </dd>
      </div>
    </dl>
  );
}
 
function resultLineLabel(label: string, unitName?: string) {
  const trimmedLabel = label.trim();
  const trimmedUnitName = unitName?.trim();
  Iif (!trimmedUnitName) return trimmedLabel;
  if (trimmedLabel.toLowerCase().startsWith(trimmedUnitName.toLowerCase())) {
    return capitalizeFirst(
      trimmedLabel.slice(trimmedUnitName.length).trim() || "Result",
    );
  }
  return trimmedLabel;
}
 
function capitalizeFirst(value: string) {
  return value ? `${value[0].toUpperCase()}${value.slice(1)}` : value;
}