diff --git a/messages/de.json b/messages/de.json
index 2baa2f32e..637089669 100644
--- a/messages/de.json
+++ b/messages/de.json
@@ -7889,7 +7889,12 @@
"backupsNone": "Noch keine Sicherung hat die Schlüssel festgehalten, die sie braucht.",
"backupsStillNeed": "Alle Zeilen sind rotiert, aber Sicherungen brauchen noch {keys}",
"backupsUnrecordedBadge": "Alle Zeilen sind rotiert, aber ältere Sicherungen können noch einen ausgemusterten Schlüssel brauchen",
- "backupsDetail": "Die Rotation verschlüsselt jede Zeile neu, aber eine Sicherung behält den Schlüssel, unter dem ihr Inhalt geschrieben wurde, und ihre Wiederherstellung braucht ihn. Behalte einen ausgemusterten Schlüssel in ENCRYPTION_KEYS, bis er unten nicht mehr aufgeführt ist."
+ "backupsDetail": "Die Rotation verschlüsselt jede Zeile neu, aber eine Sicherung behält den Schlüssel, unter dem ihr Inhalt geschrieben wurde, und ihre Wiederherstellung braucht ihn. Behalte einen ausgemusterten Schlüssel in ENCRYPTION_KEYS, bis er unten nicht mehr aufgeführt ist.",
+ "columnsShow": "Tabelle anzeigen ({count} mit Zeilen)",
+ "columnsHide": "Tabelle ausblenden",
+ "columnsShowAll": "Alle {count} Spalten anzeigen",
+ "columnsShowWithRows": "Nur Spalten mit Zeilen",
+ "columnsNoneWithRows": "Noch keine verschlüsselte Spalte enthält Zeilen."
},
"maintenance": {
"title": "Pflege der Messwert-Tabelle",
diff --git a/messages/en.json b/messages/en.json
index 3f2d82afa..185bd2226 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -7889,7 +7889,12 @@
"backupsNone": "No backup has recorded the keys it needs yet.",
"backupsStillNeed": "Every row is rotated, but backups still need {keys}",
"backupsUnrecordedBadge": "Every row is rotated, but older backups may still need a retired key",
- "backupsDetail": "Rotation re-encrypts every row, but a backup keeps the key its content was written under, and restoring it needs that key. Keep a retired key in ENCRYPTION_KEYS until nothing below lists it."
+ "backupsDetail": "Rotation re-encrypts every row, but a backup keeps the key its content was written under, and restoring it needs that key. Keep a retired key in ENCRYPTION_KEYS until nothing below lists it.",
+ "columnsShow": "Show the table ({count} with rows)",
+ "columnsHide": "Hide the table",
+ "columnsShowAll": "Show all {count} columns",
+ "columnsShowWithRows": "Only columns with rows",
+ "columnsNoneWithRows": "No encrypted column holds rows yet."
},
"maintenance": {
"title": "Measurement table maintenance",
diff --git a/messages/es.json b/messages/es.json
index be3c7baf3..787114de2 100644
--- a/messages/es.json
+++ b/messages/es.json
@@ -7889,7 +7889,12 @@
"backupsNone": "Ninguna copia ha registrado todavía las claves que necesita.",
"backupsStillNeed": "Todas las filas están rotadas, pero las copias aún necesitan {keys}",
"backupsUnrecordedBadge": "Todas las filas están rotadas, pero copias antiguas pueden necesitar aún una clave retirada",
- "backupsDetail": "La rotación vuelve a cifrar cada fila, pero una copia conserva la clave con la que se escribió su contenido, y restaurarla necesita esa clave. Mantén una clave retirada en ENCRYPTION_KEYS hasta que no aparezca abajo."
+ "backupsDetail": "La rotación vuelve a cifrar cada fila, pero una copia conserva la clave con la que se escribió su contenido, y restaurarla necesita esa clave. Mantén una clave retirada en ENCRYPTION_KEYS hasta que no aparezca abajo.",
+ "columnsShow": "Mostrar la tabla ({count} con filas)",
+ "columnsHide": "Ocultar la tabla",
+ "columnsShowAll": "Mostrar las {count} columnas",
+ "columnsShowWithRows": "Solo columnas con filas",
+ "columnsNoneWithRows": "Ninguna columna cifrada contiene filas todavía."
},
"maintenance": {
"title": "Mantenimiento de la tabla de mediciones",
diff --git a/messages/fr.json b/messages/fr.json
index b6cf1a77b..7803ab4f4 100644
--- a/messages/fr.json
+++ b/messages/fr.json
@@ -7889,7 +7889,12 @@
"backupsNone": "Aucune sauvegarde n'a encore enregistré les clés dont elle a besoin.",
"backupsStillNeed": "Toutes les lignes sont renouvelées, mais des sauvegardes ont encore besoin de {keys}",
"backupsUnrecordedBadge": "Toutes les lignes sont renouvelées, mais d'anciennes sauvegardes peuvent encore avoir besoin d'une clé retirée",
- "backupsDetail": "La rotation rechiffre chaque ligne, mais une sauvegarde garde la clé sous laquelle son contenu a été écrit, et sa restauration en a besoin. Gardez une clé retirée dans ENCRYPTION_KEYS tant qu'elle figure ci-dessous."
+ "backupsDetail": "La rotation rechiffre chaque ligne, mais une sauvegarde garde la clé sous laquelle son contenu a été écrit, et sa restauration en a besoin. Gardez une clé retirée dans ENCRYPTION_KEYS tant qu'elle figure ci-dessous.",
+ "columnsShow": "Afficher le tableau ({count} avec des lignes)",
+ "columnsHide": "Masquer le tableau",
+ "columnsShowAll": "Afficher les {count} colonnes",
+ "columnsShowWithRows": "Seulement les colonnes avec des lignes",
+ "columnsNoneWithRows": "Aucune colonne chiffrée ne contient encore de lignes."
},
"maintenance": {
"title": "Maintenance de la table des mesures",
diff --git a/messages/it.json b/messages/it.json
index d3a70449a..e959745d9 100644
--- a/messages/it.json
+++ b/messages/it.json
@@ -7889,7 +7889,12 @@
"backupsNone": "Nessun backup ha ancora registrato le chiavi di cui ha bisogno.",
"backupsStillNeed": "Tutte le righe sono ruotate, ma i backup hanno ancora bisogno di {keys}",
"backupsUnrecordedBadge": "Tutte le righe sono ruotate, ma backup più vecchi potrebbero ancora richiedere una chiave ritirata",
- "backupsDetail": "La rotazione cifra di nuovo ogni riga, ma un backup conserva la chiave con cui è stato scritto il suo contenuto, e ripristinarlo richiede quella chiave. Tieni una chiave ritirata in ENCRYPTION_KEYS finché compare qui sotto."
+ "backupsDetail": "La rotazione cifra di nuovo ogni riga, ma un backup conserva la chiave con cui è stato scritto il suo contenuto, e ripristinarlo richiede quella chiave. Tieni una chiave ritirata in ENCRYPTION_KEYS finché compare qui sotto.",
+ "columnsShow": "Mostra la tabella ({count} con righe)",
+ "columnsHide": "Nascondi la tabella",
+ "columnsShowAll": "Mostra tutte le {count} colonne",
+ "columnsShowWithRows": "Solo colonne con righe",
+ "columnsNoneWithRows": "Nessuna colonna cifrata contiene ancora righe."
},
"maintenance": {
"title": "Manutenzione della tabella delle misurazioni",
diff --git a/messages/ko.json b/messages/ko.json
index 8c101e880..b6abad7a8 100644
--- a/messages/ko.json
+++ b/messages/ko.json
@@ -7865,7 +7865,12 @@
"backupsNone": "아직 필요한 키를 기록한 백업이 없습니다.",
"backupsStillNeed": "모든 행이 회전되었지만 백업에 아직 {keys}가 필요합니다",
"backupsUnrecordedBadge": "모든 행이 회전되었지만 이전 백업에는 아직 폐기한 키가 필요할 수 있습니다",
- "backupsDetail": "회전은 모든 행을 다시 암호화하지만, 백업은 내용이 기록된 키를 그대로 유지하며 복원에는 그 키가 필요합니다. 아래에 더 이상 표시되지 않을 때까지 폐기한 키를 ENCRYPTION_KEYS에 유지하세요."
+ "backupsDetail": "회전은 모든 행을 다시 암호화하지만, 백업은 내용이 기록된 키를 그대로 유지하며 복원에는 그 키가 필요합니다. 아래에 더 이상 표시되지 않을 때까지 폐기한 키를 ENCRYPTION_KEYS에 유지하세요.",
+ "columnsShow": "표 보기 (행 있음 {count}개)",
+ "columnsHide": "표 숨기기",
+ "columnsShowAll": "열 {count}개 모두 보기",
+ "columnsShowWithRows": "행이 있는 열만",
+ "columnsNoneWithRows": "아직 행이 있는 암호화 열이 없어요."
},
"maintenance": {
"title": "측정값 테이블 유지 관리",
diff --git a/messages/pl.json b/messages/pl.json
index d78363ee2..a6f21206f 100644
--- a/messages/pl.json
+++ b/messages/pl.json
@@ -7889,7 +7889,12 @@
"backupsNone": "Żadna kopia nie zapisała jeszcze kluczy, których potrzebuje.",
"backupsStillNeed": "Wszystkie wiersze są zrotowane, ale kopie nadal potrzebują {keys}",
"backupsUnrecordedBadge": "Wszystkie wiersze są zrotowane, ale starsze kopie mogą nadal potrzebować wycofanego klucza",
- "backupsDetail": "Rotacja ponownie szyfruje każdy wiersz, ale kopia zachowuje klucz, którym zapisano jej zawartość, a jej przywrócenie wymaga tego klucza. Trzymaj wycofany klucz w ENCRYPTION_KEYS, dopóki widnieje poniżej."
+ "backupsDetail": "Rotacja ponownie szyfruje każdy wiersz, ale kopia zachowuje klucz, którym zapisano jej zawartość, a jej przywrócenie wymaga tego klucza. Trzymaj wycofany klucz w ENCRYPTION_KEYS, dopóki widnieje poniżej.",
+ "columnsShow": "Pokaż tabelę (z wierszami: {count})",
+ "columnsHide": "Ukryj tabelę",
+ "columnsShowAll": "Pokaż wszystkie kolumny ({count})",
+ "columnsShowWithRows": "Tylko kolumny z wierszami",
+ "columnsNoneWithRows": "Żadna zaszyfrowana kolumna nie zawiera jeszcze wierszy."
},
"maintenance": {
"title": "Konserwacja tabeli pomiarów",
diff --git a/src/components/admin/__tests__/encryption-legacy-badge.test.tsx b/src/components/admin/__tests__/encryption-legacy-badge.test.tsx
index 2043f5049..07c461003 100644
--- a/src/components/admin/__tests__/encryption-legacy-badge.test.tsx
+++ b/src/components/admin/__tests__/encryption-legacy-badge.test.tsx
@@ -23,7 +23,7 @@ vi.mock("@tanstack/react-query", () => ({
vi.mock("../key-backup-card", () => ({ KeyBackupCard: () => null }));
import { I18nProvider } from "@/lib/i18n/context";
-import { EncryptionSection } from "../encryption-section";
+import { ColumnCoverage, EncryptionSection } from "../encryption-section";
function statusWith(configuredKeyCount: number) {
return {
@@ -77,9 +77,64 @@ describe("encryption coverage — the legacy-key badge", () => {
});
it("names the per-column table as a focusable scroll region", () => {
- status.current = statusWith(1);
- expect(render()).toMatch(
+ const html = renderToStaticMarkup(
+
| - {t("admin.section.encryption.colColumn")} - | -- {t("admin.section.encryption.colTotal")} - | -- {t("admin.section.encryption.colActive")} - | -- {t("admin.section.encryption.colStale")} - | -
|---|---|---|---|
| - {c.model}.{c.field} - | -{c.total.toLocaleString()} | -{active.toLocaleString()} | -
- {stale > 0 ? (
- |
-
+ {t("admin.section.encryption.columnsNoneWithRows")} +
+ ) : ( + /* Focusable, named scroll region: on a phone the table scrolls + sideways, and a keyboard user has to be able to reach it + (axe scrollable-region-focusable). */ +| + {t("admin.section.encryption.colColumn")} + | ++ {t("admin.section.encryption.colTotal")} + | ++ {t("admin.section.encryption.colActive")} + | ++ {t("admin.section.encryption.colStale")} + | +
|---|---|---|---|
| + {c.model}.{c.field} + | ++ {c.total.toLocaleString()} + | +{active.toLocaleString()} | +
+ {stale > 0 ? (
+ |
+