diff --git a/web/public/locales/en/common.json b/web/public/locales/en/common.json index 2f976fb0c..a91549a52 100644 --- a/web/public/locales/en/common.json +++ b/web/public/locales/en/common.json @@ -98,6 +98,10 @@ "show": "Show {{item}}", "ID": "ID" }, + "list": { + "two": "{{0}} and {{1}}", + "many": "{{items}}, and {{last}}" + }, "field": { "optional": "Optional", "internalID": "The Internal ID Frigate uses in the configuration and database" diff --git a/web/src/utils/lifecycleUtil.ts b/web/src/utils/lifecycleUtil.ts index fa83436c5..6dced00de 100644 --- a/web/src/utils/lifecycleUtil.ts +++ b/web/src/utils/lifecycleUtil.ts @@ -3,6 +3,23 @@ import { t } from "i18next"; import { getTranslatedLabel } from "./i18n"; import { capitalizeFirstLetter } from "./stringUtil"; +function formatZonesList(zones: string[]): string { + if (zones.length === 0) return ""; + if (zones.length === 1) return zones[0]; + if (zones.length === 2) { + return t("list.two", { + 0: zones[0], + 1: zones[1], + }); + } + + const allButLast = zones.slice(0, -1).join(", "); + return t("list.many", { + items: allButLast, + last: zones[zones.length - 1], + }); +} + export function getLifecycleItemDescription( lifecycleItem: TrackingDetailsSequence, ) { @@ -24,7 +41,7 @@ export function getLifecycleItemDescription( return t("trackingDetails.lifecycleItemDesc.entered_zone", { ns: "views/explore", label, - zones: lifecycleItem.data.zones.join(" and ").replaceAll("_", " "), + zones: formatZonesList(lifecycleItem.data.zones), }); case "active": return t("trackingDetails.lifecycleItemDesc.active", {