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",
visionUnmapped: "not mapped to a category",
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",
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",
visionUnmapped: "pa kategori të lidhur",
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",
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;
addLabel: string;
/** 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;
}) {
const { t } = useTranslation();
@@ -71,12 +73,18 @@ function ListEditor({
</div>
{visionMap && (
<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) => {
const on = (it.visionClasses ?? []).includes(cls);
return (
<button key={cls} type="button" className={`btn btn-sm ${on ? "btn-primary" : "btn-ghost"}`} onClick={() => toggleClass(i, cls)}>
{t(`vehicleClass.${cls}`)}
<button
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>
);
})}