i18n(labs): say why a biomarker's unit cannot change once it has readings

This commit is contained in:
Marc-André Bombeck committed 2026-10-03 18:22:55 +02:00
1 parent dd7636e147
commit 3a35dbcf37
8 files changed
+122

No files matched your search

+6
View File
@@ -135,6 +135,11 @@
"required": "Bestätige dein aktuelles Passwort, um das zu ändern.",
"failed": "Die Bestätigung ist fehlgeschlagen. Es wurde nichts geändert."
}
},
"biomarkers": {
"unit": {
"locked": "Dieser Marker hat schon Werte, deshalb kannst du seine Einheit nicht ändern. Die gespeicherten Werte würden sonst in der neuen Einheit angezeigt, ohne umgerechnet zu werden."
}
}
},
"doctorReport": {
@@ -8917,6 +8922,7 @@
"namePlaceholder": "z. B. LDL-Cholesterin",
"unit": "Einheit",
"unitPlaceholder": "z. B. mg/dl",
"unitLockedHint": "Sobald dieser Marker Werte hat, bleibt seine Einheit, wie sie ist. Sonst würden die gespeicherten Werte in einer neuen Einheit angezeigt, ohne umgerechnet zu werden.",
"panel": "Panel",
"panelPlaceholder": "z. B. Lipide",
"lowerBound": "Referenz unten",
+6
View File
@@ -135,6 +135,11 @@
"required": "Confirm your current password to change this.",
"failed": "That did not verify. Nothing was changed."
}
},
"biomarkers": {
"unit": {
"locked": "This marker already has readings, so its unit can't be changed. The stored values would be shown in the new unit without being converted."
}
}
},
"doctorReport": {
@@ -8917,6 +8922,7 @@
"namePlaceholder": "e.g. LDL cholesterol",
"unit": "Unit",
"unitPlaceholder": "e.g. mg/dL",
"unitLockedHint": "Once this marker has readings, its unit stays as it is. The stored values would otherwise be shown in a new unit without being converted.",
"panel": "Panel",
"panelPlaceholder": "e.g. Lipids",
"lowerBound": "Reference low",
+6
View File
@@ -135,6 +135,11 @@
"required": "Confirma tu contraseña actual para cambiar esto.",
"failed": "La verificación ha fallado. No se ha cambiado nada."
}
},
"biomarkers": {
"unit": {
"locked": "Este marcador ya tiene valores, así que no puedes cambiar su unidad. Los valores guardados se mostrarían en la nueva unidad sin convertirse."
}
}
},
"doctorReport": {
@@ -8917,6 +8922,7 @@
"namePlaceholder": "p. ej. Colesterol LDL",
"unit": "Unidad",
"unitPlaceholder": "p. ej. mg/dL",
"unitLockedHint": "Cuando este marcador ya tiene valores, su unidad no cambia. De lo contrario, los valores guardados se mostrarían en una unidad nueva sin convertirse.",
"panel": "Panel",
"panelPlaceholder": "p. ej. Lípidos",
"lowerBound": "Referencia mínima",
+6
View File
@@ -135,6 +135,11 @@
"required": "Confirmez votre mot de passe actuel pour modifier ceci.",
"failed": "La vérification a échoué. Rien n'a été modifié."
}
},
"biomarkers": {
"unit": {
"locked": "Ce marqueur a déjà des valeurs, son unité ne peut donc pas être modifiée. Les valeurs enregistrées s'afficheraient dans la nouvelle unité sans être converties."
}
}
},
"doctorReport": {
@@ -8917,6 +8922,7 @@
"namePlaceholder": "ex. Cholestérol LDL",
"unit": "Unité",
"unitPlaceholder": "ex. mg/dL",
"unitLockedHint": "Dès que ce marqueur a des valeurs, son unité reste la même. Sinon, les valeurs enregistrées s'afficheraient dans une nouvelle unité sans être converties.",
"panel": "Panel",
"panelPlaceholder": "ex. Lipides",
"lowerBound": "Référence basse",
+6
View File
@@ -135,6 +135,11 @@
"required": "Conferma la password attuale per modificarlo.",
"failed": "La verifica non è riuscita. Non è stato modificato nulla."
}
},
"biomarkers": {
"unit": {
"locked": "Questo marcatore ha già dei valori, quindi non puoi cambiarne l'unità. I valori salvati verrebbero mostrati nella nuova unità senza essere convertiti."
}
}
},
"doctorReport": {
@@ -8917,6 +8922,7 @@
"namePlaceholder": "es. Colesterolo LDL",
"unit": "Unità",
"unitPlaceholder": "es. mg/dL",
"unitLockedHint": "Quando questo marcatore ha già dei valori, la sua unità resta invariata. Altrimenti i valori salvati verrebbero mostrati in una nuova unità senza essere convertiti.",
"panel": "Panel",
"panelPlaceholder": "es. Lipidi",
"lowerBound": "Riferimento minimo",
+6
View File
@@ -135,6 +135,11 @@
"required": "변경하려면 현재 비밀번호를 확인하세요.",
"failed": "확인에 실패했습니다. 아무것도 변경되지 않았습니다."
}
},
"biomarkers": {
"unit": {
"locked": "이 마커에는 이미 기록된 값이 있어서 단위를 바꿀 수 없어요. 저장된 값이 변환되지 않은 채 새 단위로 표시되기 때문이에요."
}
}
},
"doctorReport": {
@@ -8917,6 +8922,7 @@
"namePlaceholder": "예: LDL 콜레스테롤",
"unit": "단위",
"unitPlaceholder": "예: mg/dL",
"unitLockedHint": "이 마커에 기록된 값이 있으면 단위는 그대로 유지돼요. 그렇지 않으면 저장된 값이 변환되지 않은 채 새 단위로 표시돼요.",
"panel": "패널",
"panelPlaceholder": "예: 지질",
"lowerBound": "참고 하한",
+6
View File
@@ -135,6 +135,11 @@
"required": "Potwierdź obecne hasło, aby to zmienić.",
"failed": "Weryfikacja nie powiodła się. Nic nie zostało zmienione."
}
},
"biomarkers": {
"unit": {
"locked": "Ten marker ma już wyniki, więc nie możesz zmienić jego jednostki. Zapisane wartości byłyby pokazywane w nowej jednostce bez przeliczenia."
}
}
},
"doctorReport": {
@@ -8917,6 +8922,7 @@
"namePlaceholder": "np. Cholesterol LDL",
"unit": "Jednostka",
"unitPlaceholder": "np. mg/dl",
"unitLockedHint": "Gdy ten marker ma już wyniki, jego jednostka pozostaje bez zmian. W przeciwnym razie zapisane wartości byłyby pokazywane w nowej jednostce bez przeliczenia.",
"panel": "Panel",
"panelPlaceholder": "np. Lipidy",
"lowerBound": "Dolna granica",
@@ -0,0 +1,80 @@
import { describe, it, expect, vi } from "vitest";
import { renderToStaticMarkup } from "react-dom/server";
import { I18nProvider } from "@/lib/i18n/context";
import { ApiError } from "@/lib/api/api-fetch";
import { localizedApiError } from "@/lib/api/localized-error";
import en from "../../../../messages/en.json";
/**
* The marker editor says, before a save, that a marker's unit stays as it is
* once readings exist, and the refusal the server sends for such a change
* reads as that sentence rather than the generic save error.
*/
vi.mock("@/lib/api/api-fetch", async (importOriginal) => ({
...(await importOriginal<typeof import("@/lib/api/api-fetch")>()),
apiPost: vi.fn(),
apiPut: vi.fn(),
}));
import { BiomarkerForm } from "../biomarker-form";
import type { BiomarkerDto } from "../types";
const MARKER: BiomarkerDto = {
id: "bm-1",
name: "Glucose",
unit: "mg/dL",
lowerBound: 70,
upperBound: 99,
panel: null,
hasContext: false,
context: null,
hidden: false,
createdAt: "2026-01-01T00:00:00.000Z",
updatedAt: "2026-01-01T00:00:00.000Z",
};
function render(node: React.ReactNode) {
return renderToStaticMarkup(
<I18nProvider initialLocale="en">{node}</I18nProvider>,
);
}
describe("<BiomarkerForm> unit lock", () => {
const hint = en.labs.biomarker.form.unitLockedHint;
it("tells the editor of an existing marker that the unit is locked by readings", () => {
const html = render(<BiomarkerForm existing={MARKER} />);
expect(hint.length).toBeGreaterThan(0);
expect(html).toContain(hint.replace(/'/g, "&#x27;"));
expect(html).toMatch(/aria-describedby="[^"]*-unit-hint"/);
});
it("says nothing of a lock while a new marker is defined", () => {
const html = render(<BiomarkerForm />);
expect(html).not.toContain(hint.replace(/'/g, "&#x27;"));
});
it("reads the server's refusal as its own sentence, not the save error", () => {
const err = new ApiError("locked", 422, {
errorCode: "biomarkers.unit.locked",
readingCount: 2,
});
const t = (key: string) => {
const value = key
.split(".")
.reduce<unknown>(
(node, part) =>
node && typeof node === "object"
? (node as Record<string, unknown>)[part]
: undefined,
en,
);
return typeof value === "string" ? value : key;
};
expect(localizedApiError(err, t, "labs.biomarker.form.saveError")).toBe(
en.apiErrors.biomarkers.unit.locked,
);
});
});