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 | 7x 14x 16x 12x 2x 2x 2x 2x 7x 15x 1170x 7x 15x 7x 7x 77x 151x 14x 14x 18x 8x 30x 30x 30x 30x 148x 60x | import type { ComparisonPayload } from "@/api/apiStore.gen";
import { formatPercentageDifference } from "../comparisonFormatters";
import {
type ComparisonTone,
deltaToneForDirection,
} from "./comparisonStatusPresentation";
export type ComparisonRow = ComparisonPayload["rows"][number];
export type ComparisonStudy = ComparisonPayload["studies"][number];
export type ComparisonValue = ComparisonRow["values"][number];
export type ComparisonSummaryItem = {
key: string;
label: string;
value: string;
tone: ComparisonTone;
status?: string;
};
export function comparisonFinancialRows(
comparison: ComparisonPayload,
): ComparisonRow[] {
return comparison.rows;
}
/** Present the selected baseline as the first study column without changing the saved study order. */
export function comparisonStudiesWithBaselineFirst(
comparison: ComparisonPayload,
): ComparisonStudy[] {
const baselineIndex = comparison.studies.findIndex(
(study) => study.id === comparison.baseline_study_id,
);
if (baselineIndex <= 0) {
return comparison.studies;
}
const ordered = [...comparison.studies];
const [baselineStudy] = ordered.splice(baselineIndex, 1);
ordered.unshift(baselineStudy);
return ordered;
}
export function comparisonStudyCount(comparison: ComparisonPayload) {
return comparison.studies.filter(
(study) => study.id !== comparison.baseline_study_id,
).length;
}
/** Keep comparison study cell lookup shared between cell styling and cell content. */
export function comparisonValueForStudy(
row: ComparisonRow,
studyId: number | null,
): ComparisonValue | undefined {
return row.values.find((rowValue) => rowValue.study_id === studyId);
}
export function comparisonSummaryItems(
comparison: ComparisonPayload,
): ComparisonSummaryItem[] {
const studyNames = new Map(
comparison.studies.map((study) => [study.id, study.name] as const),
);
const targetStudyCount = comparisonStudyCount(comparison);
return comparison.rows
.flatMap((row) =>
row.values.flatMap((value) => {
if (
value.study_id === comparison.baseline_study_id ||
value.percentage_difference == null
) {
return [];
}
const parsed = Number(value.percentage_difference);
return Number.isFinite(parsed)
? [
{
key: `${row.row_key}-${value.study_id}`,
label:
targetStudyCount > 1
? `${row.label} - ${studyNames.get(value.study_id) ?? "Study"}`
: row.label,
value: formatPercentageDifference(value.percentage_difference),
magnitude: Math.abs(parsed),
tone: deltaToneForDirection(row.comparison_direction, parsed),
},
]
: [];
}),
)
.sort((left, right) => right.magnitude - left.magnitude)
.slice(0, 2)
.map(({ key, label, value, tone }) => ({ key, label, value, tone }));
}
export function studyHeaderTitle(
study: ComparisonStudy,
comparison: ComparisonPayload,
) {
return duplicateStudyNames(comparison) ? study.flowsheet_name : study.name;
}
export function studyHeaderSubtitle(
study: ComparisonStudy,
comparison: ComparisonPayload,
) {
return duplicateStudyNames(comparison) ? "" : study.flowsheet_name;
}
export function studyHeaderMeta(
study: ComparisonStudy,
comparison: ComparisonPayload,
) {
const parts = [
studyHeaderSubtitle(study, comparison),
study.id === comparison.baseline_study_id ? "Baseline" : "",
].filter(Boolean);
return parts.join(" - ");
}
/** Force subtitles to carry flowsheet context when names alone are ambiguous. */
export function duplicateStudyNames(comparison: ComparisonPayload) {
const names = comparison.studies.map((study) => study.name);
return new Set(names).size < names.length;
}
|