diff --git a/src/frontend/apps/drive/src/features/i18n/__tests__/translations.test.ts b/src/frontend/apps/drive/src/features/i18n/__tests__/translations.test.ts new file mode 100644 index 00000000..2696b78f --- /dev/null +++ b/src/frontend/apps/drive/src/features/i18n/__tests__/translations.test.ts @@ -0,0 +1,56 @@ +import translations from "../translations.json"; + +type TranslationNode = { [key: string]: string | TranslationNode }; + +const flattenKeys = (node: TranslationNode, prefix = ""): string[] => { + return Object.entries(node).flatMap(([key, value]) => { + const path = prefix ? `${prefix}.${key}` : key; + return typeof value === "string" ? [path] : flattenKeys(value, path); + }); +}; + +const flattenEntries = ( + node: TranslationNode, + prefix = "" +): [string, string][] => { + return Object.entries(node).flatMap(([key, value]) => { + const path = prefix ? `${prefix}.${key}` : key; + return typeof value === "string" + ? ([[path, value]] as [string, string][]) + : flattenEntries(value, path); + }); +}; + +const languages = Object.keys(translations) as (keyof typeof translations)[]; + +describe("translations.json", () => { + it("declares the same keys in every language", () => { + const keysByLanguage = Object.fromEntries( + languages.map((language) => [ + language, + flattenKeys(translations[language].translation).sort(), + ]) + ); + + for (const language of languages) { + // Compared pairwise against every other language so the failure + // diff shows exactly which keys are missing on which side. + for (const other of languages) { + const missing = keysByLanguage[language].filter( + (key) => !keysByLanguage[other].includes(key) + ); + expect({ language: other, missing }).toEqual({ + language: other, + missing: [], + }); + } + } + }); + + it.each(languages)("has no empty values in %s", (language) => { + const empty = flattenEntries(translations[language].translation) + .filter(([, value]) => value.trim() === "") + .map(([key]) => key); + expect(empty).toEqual([]); + }); +}); diff --git a/src/frontend/apps/drive/src/features/i18n/translations.json b/src/frontend/apps/drive/src/features/i18n/translations.json index 89a91954..499937ba 100644 --- a/src/frontend/apps/drive/src/features/i18n/translations.json +++ b/src/frontend/apps/drive/src/features/i18n/translations.json @@ -376,6 +376,9 @@ "settings_workspace": "Workspace settings", "settings_folder": "Folder settings", "delete_item": "Delete", + "delete_workspace": "Delete workspace", + "delete_folder": "Delete folder", + "delete_file": "Delete file", "share": "Share", "share_view": "View shares" }, @@ -560,6 +563,10 @@ "toast_one": "Item deleted forever", "toast_other": "{{count}} items deleted forever" }, + "restore": { + "toast_one": "Item restored", + "toast_other": "{{count}} items restored" + }, "move": { "toast_one": "{{count}} item moved", "toast_other": "{{count}} items moved", @@ -641,6 +648,7 @@ "explorer": { "cancel": "Cancel", "choose": "Choose", + "picker_caption": "Select one or more files", "picker_label_zero": "No files selected", "picker_label_one": "{{count}} file selected", "picker_label_other": "{{count}} files selected", @@ -1698,6 +1706,15 @@ } }, "filters": { + "location": { + "label": "Locatie", + "options": { + "my_files": "Mijn bestanden", + "shared_with_me": "Gedeeld met mij", + "starred": "Favorieten", + "trashbin": "Prullenbak" + } + }, "scopes": { "label": "Locatie", "options": { @@ -1714,6 +1731,39 @@ "reset": "Reset" } }, + "category": { + "label": "Type", + "options": { + "doc": "Tekstdocument", + "powerpoint": "Presentatie", + "calc": "Spreadsheet", + "pdf": "PDF", + "image": "Afbeelding", + "video": "Video", + "audio": "Audio", + "archive": "Archief", + "other": "Overig" + } + }, + "contact": { + "label": "Gedeeld met", + "placeholder": "Zoek een naam", + "empty": "Geen contacten gevonden", + "reset": "Opnieuw instellen" + }, + "modified": { + "label": "Gewijzigd", + "options": { + "today": "Vandaag", + "last_7_days": "Laatste 7 dagen", + "last_30_days": "Laatste 30 dagen", + "this_year": "Dit jaar", + "more_than_a_year": "Meer dan een jaar geleden", + "custom": "Aangepaste periode" + }, + "start": "Begin", + "end": "Einde" + }, "workspace": { "label": "Werkruimte" }, @@ -1744,6 +1794,9 @@ "settings_workspace": "Werkruimte instellingen", "settings_folder": "Map instellingen", "delete_item": "Verwijder", + "delete_workspace": "Ruimte verwijderen", + "delete_folder": "Map verwijderen", + "delete_file": "Bestand verwijderen", "share": "Deel", "share_view": "Bekijk delen" }, @@ -1928,6 +1981,10 @@ "toast_one": "Item permanent verwijderd", "toast_other": "{{count}} items permanent verwijderd" }, + "restore": { + "toast_one": "Item hersteld", + "toast_other": "{{count}} items hersteld" + }, "move": { "toast_one": "{{count}} item verplaatst", "toast_other": "{{count}} items verplaatst", @@ -1990,7 +2047,6 @@ "copy_link": "Kopieer link", "languages": "Talen" }, - "time": { "years_ago_one": "{{count}} jaar geleden", "years_ago_other": "{{count}} jaren geleden", @@ -2010,6 +2066,7 @@ "explorer": { "choose": "Kiezen", "cancel": "Annuleren", + "picker_caption": "Selecteer een of meerdere bestanden", "picker_label_zero": "Geen bestanden geselecteerd", "picker_label_one": "{{count}} bestand geselecteerd", "picker_label_other": "{{count}} bestanden geselecteerd",