mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
The decimal lint covered components and app only, and sentences for people are built in src/lib too: the weekday weight correlation printed "0.8 kg" into a German sentence, and the no-key fallback and the period narrative's fallback spelled fractions with a full stop. Those three use the new formatDecimal from format-locale with the reader's locale. The rule now covers src/lib and src/hooks; text for the model, operator log lines, SVG data, zone checks and wire values a client re-formats carry a reasoned directive.
46 lines
1.9 KiB
TypeScript
46 lines
1.9 KiB
TypeScript
/**
|
|
* The numeric value of a lab reading in the edit sheet.
|
|
*
|
|
* A converted reading is stored at full precision (5.6 mmol/L of glucose is
|
|
* 100.90191999999999 mg/dL), and the sheet must not open with that tail. The
|
|
* field starts from the value at the precision every lab surface shows it:
|
|
* whole numbers bare, two decimals. Two decimals carry too little of a small
|
|
* value, though (a TSH of 0.004 would open as "0"), so below 1 the field keeps
|
|
* three significant figures instead. Written with a dot, which the sheet's
|
|
* parser reads, rather than in the reader's locale, which an input cannot
|
|
* round-trip, and never in exponent notation.
|
|
*/
|
|
export function valueEditSeed(value: number): string {
|
|
if (Number.isInteger(value)) return String(value);
|
|
const magnitude = Math.floor(Math.log10(Math.abs(value)));
|
|
const decimals = Math.min(
|
|
MAX_SEED_DECIMALS,
|
|
Math.max(DISPLAY_DECIMALS, SEED_SIGNIFICANT_FIGURES - 1 - magnitude),
|
|
);
|
|
// eslint-disable-next-line healthlog/no-unlocalised-decimal -- seeds an input whose parser reads the full stop back
|
|
return value
|
|
.toFixed(decimals)
|
|
.replace(/(\.\d*?)0+$/, "$1")
|
|
.replace(/\.$/, "");
|
|
}
|
|
|
|
const DISPLAY_DECIMALS = 2;
|
|
const SEED_SIGNIFICANT_FIGURES = 3;
|
|
/** `toFixed` accepts up to 100; no lab value needs more than this. */
|
|
const MAX_SEED_DECIMALS = 20;
|
|
|
|
/**
|
|
* What the edit PUT sends for the value. A field the person did not touch is
|
|
* omitted (`undefined`), so the stored full-precision number stays as it is and
|
|
* a converted reading keeps its "converted from" record: sending the rounded
|
|
* start value back would both lose precision and read to the server as a new
|
|
* number. A changed field sends the parsed number.
|
|
*/
|
|
export function resolveValueForUpdate(args: {
|
|
seed: string;
|
|
editorValue: string;
|
|
parsed: number;
|
|
}): number | undefined {
|
|
return args.editorValue.trim() === args.seed.trim() ? undefined : args.parsed;
|
|
}
|