ui(carwash): mapping chips show the camera's canonical class ids, not translations

The vocabulary is a code constant (the model's contract), the site only maps it; a chip
reading VETURË beside a site category named Veture blurred exactly that (user, 2026-09-06).
Translation stays as the tooltip; a hint names where the list lives.

Claude-Session: https://claude.ai/code/session_01FWncR69HgGPuei1dLrW3cU
This commit is contained in:
2026-09-06 21:25:08 +02:00
parent 20a3cb3e80
commit 78ca58d264
3 changed files with 14 additions and 4 deletions
+1
View File
@@ -140,6 +140,7 @@ export const en: Catalog = {
visionSaw: "Camera saw", visionSaw: "Camera saw",
visionUnmapped: "not mapped to a category", visionUnmapped: "not mapped to a category",
visionClasses: "Camera classes", visionClasses: "Camera classes",
visionClassesHint: "The camera's fixed vocabulary (set in code, not here). Tick the classes this category covers.",
visionThreshold: "Camera confidence to flag a downgrade", visionThreshold: "Camera confidence to flag a downgrade",
visionThresholdHint: "When the camera is at least this sure and the operator picks a cheaper category than the one its class maps to, the order is flagged for review. It is never blocked.", visionThresholdHint: "When the camera is at least this sure and the operator picks a cheaper category than the one its class maps to, the order is flagged for review. It is never blocked.",
}, },
+1
View File
@@ -142,6 +142,7 @@ export const sq = {
visionSaw: "Kamera pa", visionSaw: "Kamera pa",
visionUnmapped: "pa kategori të lidhur", visionUnmapped: "pa kategori të lidhur",
visionClasses: "Klasat e kamerës", visionClasses: "Klasat e kamerës",
visionClassesHint: "Fjalori i fiksuar i kamerës (vendoset në kod, jo këtu). Shëno klasat që mbulon kjo kategori.",
visionThreshold: "Siguria e kamerës për të shënuar një ulje kategorie", visionThreshold: "Siguria e kamerës për të shënuar një ulje kategorie",
visionThresholdHint: "Kur kamera është të paktën kaq e sigurt dhe operatori zgjedh një kategori më të lirë se ajo ku lidhet klasa, porosia shënohet për shqyrtim. Nuk bllokohet kurrë.", visionThresholdHint: "Kur kamera është të paktën kaq e sigurt dhe operatori zgjedh një kategori më të lirë se ajo ku lidhet klasa, porosia shënohet për shqyrtim. Nuk bllokohet kurrë.",
}, },
+12 -4
View File
@@ -32,7 +32,9 @@ function ListEditor({
onChange: (items: Item[]) => void; onChange: (items: Item[]) => void;
addLabel: string; addLabel: string;
/** Categories only: offer the vision vocabulary as chips under each row — the site's /** Categories only: offer the vision vocabulary as chips under each row — the site's
* own "car, sedan → Vetura" mapping (venue-modules.md §Vehicle category). */ * own "car, sedan → Vetura" mapping (venue-modules.md §Vehicle category). The chips
* show the CANONICAL ids (the model's fixed vocabulary, a code constant), never a
* translation, so they read as what they are: not site text (user, 2026-09-06). */
visionMap?: boolean; visionMap?: boolean;
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -71,12 +73,18 @@ function ListEditor({
</div> </div>
{visionMap && ( {visionMap && (
<div className="flex flex-wrap items-center gap-1 pl-1"> <div className="flex flex-wrap items-center gap-1 pl-1">
<span className="mr-1 text-[0.625rem] uppercase tracking-wider text-term-muted">{t("wash.visionClasses")}</span> <span className="mr-1 text-[0.625rem] uppercase tracking-wider text-term-muted" title={t("wash.visionClassesHint")}>{t("wash.visionClasses")}</span>
{VEHICLE_CLASSES.map((cls) => { {VEHICLE_CLASSES.map((cls) => {
const on = (it.visionClasses ?? []).includes(cls); const on = (it.visionClasses ?? []).includes(cls);
return ( return (
<button key={cls} type="button" className={`btn btn-sm ${on ? "btn-primary" : "btn-ghost"}`} onClick={() => toggleClass(i, cls)}> <button
{t(`vehicleClass.${cls}`)} key={cls}
type="button"
className={`btn btn-sm font-mono lowercase ${on ? "btn-primary" : "btn-ghost"}`}
title={t(`vehicleClass.${cls}`)}
onClick={() => toggleClass(i, cls)}
>
{cls}
</button> </button>
); );
})} })}