mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
fix(import): pluralise the note on records HealthLog wrote itself
The note had one form per locale, so a single left-out record read as a plural. It now resolves One, Few and Other through tCount like the other counted strings, with the singular in every locale and the Polish few form.
This commit is contained in:
1 parent
4dabc83513
commit
67e8e7c4f2
9 files changed
+106
-19
No files matched your search
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* The note under a finished Apple Health import that says how many records
|
||||
* were left out because HealthLog wrote them into Apple Health itself.
|
||||
*
|
||||
* The count is often 1, and a single string rendered "1 Einträge". The note
|
||||
* reads the plural tier of the active locale, so each locale's own singular
|
||||
* (and the Polish few form) reaches the screen.
|
||||
*/
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
|
||||
import { I18nProvider } from "@/lib/i18n/context";
|
||||
import type { MessageBundle } from "@/lib/i18n/load-locale";
|
||||
import { locales, type Locale } from "@/lib/i18n/config";
|
||||
|
||||
import { AppleHealthOwnRecordsNote } from "../apple-health-import-card";
|
||||
|
||||
function bundle(locale: Locale): MessageBundle {
|
||||
return JSON.parse(
|
||||
readFileSync(join(process.cwd(), "messages", `${locale}.json`), "utf8"),
|
||||
) as MessageBundle;
|
||||
}
|
||||
|
||||
function render(locale: Locale, count: number): string {
|
||||
return renderToStaticMarkup(
|
||||
<I18nProvider initialLocale={locale} initialMessages={bundle(locale)}>
|
||||
<AppleHealthOwnRecordsNote count={count} />
|
||||
</I18nProvider>,
|
||||
)
|
||||
.replace(/<[^>]+>/g, "")
|
||||
.trim();
|
||||
}
|
||||
|
||||
describe("<AppleHealthOwnRecordsNote>", () => {
|
||||
it("uses the singular for one record", () => {
|
||||
expect(render("de", 1)).toMatch(/^1 Eintrag,/);
|
||||
expect(render("en", 1)).toMatch(/^1 record that/);
|
||||
expect(render("es", 1)).toContain("1 registro que");
|
||||
expect(render("fr", 1)).toMatch(/^1 enregistrement que/);
|
||||
expect(render("it", 1)).toMatch(/^1 registrazione che/);
|
||||
expect(render("pl", 1)).toContain("1 wpis,");
|
||||
});
|
||||
|
||||
it("uses the plural for several, and the Polish few form for 2 to 4", () => {
|
||||
expect(render("de", 5)).toMatch(/^5 Einträge,/);
|
||||
expect(render("en", 5)).toMatch(/^5 records that/);
|
||||
expect(render("pl", 3)).toContain("3 wpisy,");
|
||||
expect(render("pl", 5)).toContain("5 wpisów,");
|
||||
});
|
||||
|
||||
it("renders a sentence with the count in every locale", () => {
|
||||
for (const locale of locales) {
|
||||
for (const count of [1, 2, 5]) {
|
||||
const text = render(locale, count);
|
||||
expect(text, `${locale} ${count}`).toContain(String(count));
|
||||
expect(text, `${locale} ${count}`).not.toContain("writtenByHealthLog");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -32,7 +32,11 @@ interface JobStatus {
|
||||
clinical?: { skipped?: number };
|
||||
cumulativeEstimates?: { days?: number; rows?: number };
|
||||
/** Records HealthLog wrote into Apple Health itself, left out here. */
|
||||
writtenByHealthLog?: { byMarker?: number; matchedManual?: number };
|
||||
writtenByHealthLog?: {
|
||||
byMarker?: number;
|
||||
byExternalId?: number;
|
||||
matchedManual?: number;
|
||||
};
|
||||
/** HK types deferred by design — read but not (yet) imported. */
|
||||
deferred?: Record<string, number>;
|
||||
/** Per-key drop counters — plain HK types are unsupported-by-design,
|
||||
@@ -249,6 +253,22 @@ export function AppleHealthSkipLines({
|
||||
);
|
||||
}
|
||||
|
||||
/** How many records the import left out because HealthLog wrote them. */
|
||||
export function AppleHealthOwnRecordsNote({ count }: { count: number }) {
|
||||
const { tCount } = useTranslations();
|
||||
return (
|
||||
<p
|
||||
data-testid="import-apple-health-own-skipped"
|
||||
className="text-muted-foreground text-sm"
|
||||
>
|
||||
{tCount(
|
||||
"settings.sections.export.import.appleHealth.writtenByHealthLog",
|
||||
count,
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
export function AppleHealthImportCard() {
|
||||
const { t } = useTranslations();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -346,6 +366,7 @@ export function AppleHealthImportCard() {
|
||||
const isDone = status?.status === "done";
|
||||
const ownRecordsSkipped =
|
||||
(status?.result?.writtenByHealthLog?.byMarker ?? 0) +
|
||||
(status?.result?.writtenByHealthLog?.byExternalId ?? 0) +
|
||||
(status?.result?.writtenByHealthLog?.matchedManual ?? 0);
|
||||
const isFailed = status?.status === "failed";
|
||||
const busy = uploading || isRunning;
|
||||
@@ -498,17 +519,7 @@ export function AppleHealthImportCard() {
|
||||
</p>
|
||||
)}
|
||||
{isDone && ownRecordsSkipped > 0 && (
|
||||
<p
|
||||
data-testid="import-apple-health-own-skipped"
|
||||
className="text-muted-foreground text-sm"
|
||||
>
|
||||
{t(
|
||||
"settings.sections.export.import.appleHealth.writtenByHealthLog",
|
||||
{
|
||||
count: ownRecordsSkipped,
|
||||
},
|
||||
)}
|
||||
</p>
|
||||
<AppleHealthOwnRecordsNote count={ownRecordsSkipped} />
|
||||
)}
|
||||
{isDone && (status?.result?.cumulativeEstimates?.days ?? 0) > 0 && (
|
||||
<AppleHealthEstimateWarning
|
||||
|
||||
Reference in new issue
Block a user