mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 23:46:35 +00:00
fix(i18n): add the two keys the client named without en having them
BudgetPanel titled its add button with budget.addCategory (since April) and the trip form labelled its cover remove button with common.remove (since August). Neither key was ever in en, and t() returns an unknown key unchanged, so both rendered as the raw key in every language. Both are added to all 27 locales. Locale parity compares the locales with en, never en with the code, so nothing could catch this. client/scripts/i18n-keys.mjs (npm run lint:i18n-keys) now resolves every literal key src/ names against en: the first argument of t(), tHtml() and tr() (both sides of a conditional included), <TransHtml html>, the fallback of translateApiError and any *Key property or prop. A template key, a prefix with the rest appended and the help registry's key builders pass when their fixed parts match an en key; the one template with no fixed part is on an allow-list that names the keys it resolves to, and an entry nothing uses fails. With --unused it lists the en keys nothing reaches, as information only. en is read with shared/scripts/i18n-catalog.mjs, a reader for the locale tables as text that the parity tooling will share. It refuses a value that is not one string literal instead of skipping the key.
This commit is contained in:
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'إنشاء فئة',
|
||||
'budget.category': 'الفئة',
|
||||
'budget.categoryName': 'اسم الفئة',
|
||||
'budget.addCategory': 'إضافة فئة',
|
||||
'budget.table.name': 'الاسم',
|
||||
'budget.table.total': 'الإجمالي',
|
||||
'budget.table.persons': 'الأشخاص',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'إلغاء',
|
||||
'common.clear': 'مسح',
|
||||
'common.delete': 'حذف',
|
||||
'common.remove': 'إزالة',
|
||||
'common.preview': 'معاينة',
|
||||
'common.edit': 'تعديل',
|
||||
'common.add': 'إضافة',
|
||||
|
||||
@@ -12,6 +12,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Kateqoriya yarat',
|
||||
'budget.category': 'Kateqoriya',
|
||||
'budget.categoryName': 'Kateqoriyanın adı',
|
||||
'budget.addCategory': 'Kateqoriya əlavə et',
|
||||
|
||||
'budget.table.name': 'Ad',
|
||||
'budget.table.total': 'Ümumi',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Ləğv et',
|
||||
'common.clear': 'Təmizlə',
|
||||
'common.delete': 'Sil',
|
||||
'common.remove': 'Sil',
|
||||
'common.preview': 'Önizləmə',
|
||||
'common.edit': 'Redaktə et',
|
||||
'common.add': 'Əlavə et',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Criar categoria',
|
||||
'budget.category': 'Categoria',
|
||||
'budget.categoryName': 'Nome da categoria',
|
||||
'budget.addCategory': 'Adicionar categoria',
|
||||
'budget.table.name': 'Nome',
|
||||
'budget.table.total': 'Total',
|
||||
'budget.table.persons': 'Pessoas',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Cancelar',
|
||||
'common.clear': 'Limpar',
|
||||
'common.delete': 'Excluir',
|
||||
'common.remove': 'Remover',
|
||||
'common.preview': 'Prévia',
|
||||
'common.edit': 'Editar',
|
||||
'common.add': 'Adicionar',
|
||||
|
||||
@@ -9,6 +9,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Crea una categoria',
|
||||
'budget.category': 'Categoria',
|
||||
'budget.categoryName': 'Nom de la categoria',
|
||||
'budget.addCategory': 'Afegeix una categoria',
|
||||
'budget.table.name': 'Nom',
|
||||
'budget.table.total': 'Total',
|
||||
'budget.table.persons': 'Persones',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Cancel·lar',
|
||||
'common.clear': 'Esborrar',
|
||||
'common.delete': 'Eliminar',
|
||||
'common.remove': 'Elimina',
|
||||
'common.preview': 'Vista prèvia',
|
||||
'common.edit': 'Editar',
|
||||
'common.add': 'Afegir',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Vytvořit kategorii',
|
||||
'budget.category': 'Kategorie',
|
||||
'budget.categoryName': 'Název kategorie',
|
||||
'budget.addCategory': 'Přidat kategorii',
|
||||
'budget.table.name': 'Název',
|
||||
'budget.table.total': 'Celkem',
|
||||
'budget.table.persons': 'Osoby',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Zrušit',
|
||||
'common.clear': 'Vymazat',
|
||||
'common.delete': 'Smazat',
|
||||
'common.remove': 'Odstranit',
|
||||
'common.preview': 'Náhled',
|
||||
'common.edit': 'Upravit',
|
||||
'common.add': 'Přidat',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Kategorie erstellen',
|
||||
'budget.category': 'Kategorie',
|
||||
'budget.categoryName': 'Kategoriename',
|
||||
'budget.addCategory': 'Kategorie hinzufügen',
|
||||
'budget.table.name': 'Name',
|
||||
'budget.table.total': 'Gesamt',
|
||||
'budget.table.persons': 'Personen',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Abbrechen',
|
||||
'common.clear': 'Löschen',
|
||||
'common.delete': 'Löschen',
|
||||
'common.remove': 'Entfernen',
|
||||
'common.preview': 'Vorschau',
|
||||
'common.edit': 'Bearbeiten',
|
||||
'common.add': 'Hinzufügen',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Create Category',
|
||||
'budget.category': 'Category',
|
||||
'budget.categoryName': 'Category Name',
|
||||
'budget.addCategory': 'Add category',
|
||||
'budget.table.name': 'Name',
|
||||
'budget.table.total': 'Total',
|
||||
'budget.table.persons': 'Persons',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Cancel',
|
||||
'common.clear': 'Clear',
|
||||
'common.delete': 'Delete',
|
||||
'common.remove': 'Remove',
|
||||
'common.preview': 'Preview',
|
||||
'common.edit': 'Edit',
|
||||
'common.add': 'Add',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Crear categoría',
|
||||
'budget.category': 'Categoría',
|
||||
'budget.categoryName': 'Nombre de la categoría',
|
||||
'budget.addCategory': 'Añadir categoría',
|
||||
'budget.table.name': 'Nombre',
|
||||
'budget.table.total': 'Total',
|
||||
'budget.table.persons': 'Personas',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Cancelar',
|
||||
'common.clear': 'Borrar',
|
||||
'common.delete': 'Eliminar',
|
||||
'common.remove': 'Eliminar',
|
||||
'common.preview': 'Vista previa',
|
||||
'common.edit': 'Editar',
|
||||
'common.add': 'Añadir',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Loo kategooria',
|
||||
'budget.category': 'Kategooria',
|
||||
'budget.categoryName': 'Kategooria nimi',
|
||||
'budget.addCategory': 'Lisa kategooria',
|
||||
'budget.table.name': 'Nimi',
|
||||
'budget.table.total': 'Kokku',
|
||||
'budget.table.persons': 'Inimesi',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Tühista',
|
||||
'common.clear': 'Tühjenda',
|
||||
'common.delete': 'Kustuta',
|
||||
'common.remove': 'Eemalda',
|
||||
'common.preview': 'Eelvaade',
|
||||
'common.edit': 'Muuda',
|
||||
'common.add': 'Lisa',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Créer une catégorie',
|
||||
'budget.category': 'Catégorie',
|
||||
'budget.categoryName': 'Nom de la catégorie',
|
||||
'budget.addCategory': 'Ajouter une catégorie',
|
||||
'budget.table.name': 'Nom',
|
||||
'budget.table.total': 'Total',
|
||||
'budget.table.persons': 'Personnes',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Annuler',
|
||||
'common.clear': 'Effacer',
|
||||
'common.delete': 'Supprimer',
|
||||
'common.remove': 'Supprimer',
|
||||
'common.preview': 'Aperçu',
|
||||
'common.edit': 'Modifier',
|
||||
'common.add': 'Ajouter',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Δημιουργία Κατηγορίας',
|
||||
'budget.category': 'Κατηγορία',
|
||||
'budget.categoryName': 'Όνομα Κατηγορίας',
|
||||
'budget.addCategory': 'Προσθήκη κατηγορίας',
|
||||
'budget.table.name': 'Όνομα',
|
||||
'budget.table.total': 'Σύνολο',
|
||||
'budget.table.persons': 'Άτομα',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Ακύρωση',
|
||||
'common.clear': 'Εκκαθάριση',
|
||||
'common.delete': 'Διαγραφή',
|
||||
'common.remove': 'Αφαίρεση',
|
||||
'common.preview': 'Προεπισκόπηση',
|
||||
'common.edit': 'Επεξεργασία',
|
||||
'common.add': 'Προσθήκη',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Kategória létrehozása',
|
||||
'budget.category': 'Kategória',
|
||||
'budget.categoryName': 'Kategória neve',
|
||||
'budget.addCategory': 'Kategória hozzáadása',
|
||||
'budget.table.name': 'Név',
|
||||
'budget.table.total': 'Összesen',
|
||||
'budget.table.persons': 'Személyek',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Mégse',
|
||||
'common.clear': 'Törlés',
|
||||
'common.delete': 'Törlés',
|
||||
'common.remove': 'Eltávolítás',
|
||||
'common.preview': 'Előnézet',
|
||||
'common.edit': 'Szerkesztés',
|
||||
'common.add': 'Hozzáadás',
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// @ts-expect-error: plain .mjs script with no .d.ts; import as JS module.
|
||||
import { listDomainFiles, listLocales, parseCatalog, readCatalog } from '../../scripts/i18n-catalog.mjs';
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
/**
|
||||
* The reader the i18n scripts (parity, the untranslated ratchet, the client's
|
||||
* key check) share. It reads the tables as text, so it sees the
|
||||
* `// en-fallback` markers, and it refuses what it cannot read rather than
|
||||
* skipping it.
|
||||
*/
|
||||
const ROOT = new URL('../../scripts/fixtures/i18n/', import.meta.url);
|
||||
|
||||
type Entry = { key: string; value: string; marked: boolean; line: number };
|
||||
|
||||
describe('i18n catalogue reader', () => {
|
||||
it('reads single-line, wrapped, double-quoted and escaped values with their markers', () => {
|
||||
const entries = parseCatalog(
|
||||
[
|
||||
" 'a.one': 'One',",
|
||||
" 'a.two':",
|
||||
" 'Two, wrapped', // en-fallback",
|
||||
` 'a.three': "It's",`,
|
||||
" 'a.four': 'Don\\'t \\u00e9',",
|
||||
].join('\r\n'),
|
||||
);
|
||||
expect(entries.map((e: Entry) => [e.key, e.value, e.marked])).toEqual([
|
||||
['a.one', 'One', false],
|
||||
['a.two', 'Two, wrapped', true],
|
||||
['a.three', "It's", false],
|
||||
['a.four', "Don't é", false],
|
||||
]);
|
||||
});
|
||||
|
||||
it('refuses a value that is not one string literal instead of skipping it', () => {
|
||||
expect(() => parseCatalog(" 'a.one': 'One' + 'Two',", 'x.ts')).toThrow(
|
||||
/x\.ts:1: 'a\.one' is not a single string literal/,
|
||||
);
|
||||
expect(() => parseCatalog(" 'a.one': `One`,", 'x.ts')).toThrow(/not a single string literal/);
|
||||
expect(() => parseCatalog(" 'a.one': 'unterminated,", 'x.ts')).toThrow(/not a single string literal/);
|
||||
});
|
||||
|
||||
it('lists locales and domain files and reads a table from disk', () => {
|
||||
expect(listLocales(ROOT).sort()).toEqual(['de', 'en']);
|
||||
expect(listDomainFiles('en', ROOT)).toEqual(['a.ts']);
|
||||
const de: Entry[] = readCatalog('de', 'a.ts', ROOT);
|
||||
expect(de.find((e) => e.key === 'a.lone')).toMatchObject({ value: 'Remove {count} items', marked: true });
|
||||
expect(de.find((e) => e.key === 'a.multi')).toMatchObject({
|
||||
value: 'A long sentence that wraps onto the next line',
|
||||
});
|
||||
});
|
||||
|
||||
it('reads every real locale table', () => {
|
||||
for (const locale of listLocales()) {
|
||||
for (const file of listDomainFiles(locale)) expect(() => readCatalog(locale, file)).not.toThrow();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Buat Kategori',
|
||||
'budget.category': 'Kategori',
|
||||
'budget.categoryName': 'Nama Kategori',
|
||||
'budget.addCategory': 'Tambah kategori',
|
||||
'budget.table.name': 'Nama',
|
||||
'budget.table.total': 'Total',
|
||||
'budget.table.persons': 'Orang',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Batal',
|
||||
'common.clear': 'Hapus',
|
||||
'common.delete': 'Hapus',
|
||||
'common.remove': 'Hapus',
|
||||
'common.preview': 'Pratinjau',
|
||||
'common.edit': 'Sunting',
|
||||
'common.add': 'Tambah',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Crea categoria',
|
||||
'budget.category': 'Categoria',
|
||||
'budget.categoryName': 'Nome categoria',
|
||||
'budget.addCategory': 'Aggiungi categoria',
|
||||
'budget.table.name': 'Nome',
|
||||
'budget.table.total': 'Totale',
|
||||
'budget.table.persons': 'Persone',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Annulla',
|
||||
'common.clear': 'Cancella',
|
||||
'common.delete': 'Elimina',
|
||||
'common.remove': 'Rimuovi',
|
||||
'common.preview': 'Anteprima',
|
||||
'common.edit': 'Modifica',
|
||||
'common.add': 'Aggiungi',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'カテゴリを作成',
|
||||
'budget.category': 'カテゴリ',
|
||||
'budget.categoryName': 'カテゴリ名',
|
||||
'budget.addCategory': 'カテゴリを追加',
|
||||
'budget.table.name': '名前',
|
||||
'budget.table.total': '合計',
|
||||
'budget.table.persons': '人数',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'キャンセル',
|
||||
'common.clear': 'クリア',
|
||||
'common.delete': '削除',
|
||||
'common.remove': '削除',
|
||||
'common.preview': 'プレビュー',
|
||||
'common.edit': '編集',
|
||||
'common.add': '追加',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': '카테고리 만들기',
|
||||
'budget.category': '카테고리',
|
||||
'budget.categoryName': '카테고리 이름',
|
||||
'budget.addCategory': '카테고리 추가',
|
||||
'budget.table.name': '이름',
|
||||
'budget.table.total': '합계',
|
||||
'budget.table.persons': '인원',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': '취소',
|
||||
'common.clear': '지우기',
|
||||
'common.delete': '삭제',
|
||||
'common.remove': '제거',
|
||||
'common.preview': '미리보기',
|
||||
'common.edit': '편집',
|
||||
'common.add': '추가',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Categorie aanmaken',
|
||||
'budget.category': 'Categorie',
|
||||
'budget.categoryName': 'Categorienaam',
|
||||
'budget.addCategory': 'Categorie toevoegen',
|
||||
'budget.table.name': 'Naam',
|
||||
'budget.table.total': 'Totaal',
|
||||
'budget.table.persons': 'Personen',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Annuleren',
|
||||
'common.clear': 'Wissen',
|
||||
'common.delete': 'Verwijderen',
|
||||
'common.remove': 'Verwijderen',
|
||||
'common.preview': 'Voorbeeld',
|
||||
'common.edit': 'Bewerken',
|
||||
'common.add': 'Toevoegen',
|
||||
|
||||
@@ -10,6 +10,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Utwórz kategorię',
|
||||
'budget.category': 'Kategoria',
|
||||
'budget.categoryName': 'Nazwa kategorii',
|
||||
'budget.addCategory': 'Dodaj kategorię',
|
||||
'budget.table.name': 'Nazwa',
|
||||
'budget.table.total': 'Łącznie',
|
||||
'budget.table.persons': 'Osoby',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Anuluj',
|
||||
'common.clear': 'Wyczyść',
|
||||
'common.delete': 'Usuń',
|
||||
'common.remove': 'Usuń',
|
||||
'common.preview': 'Podgląd',
|
||||
'common.edit': 'Edytuj',
|
||||
'common.add': 'Dodaj',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Создать категорию',
|
||||
'budget.category': 'Категория',
|
||||
'budget.categoryName': 'Название категории',
|
||||
'budget.addCategory': 'Добавить категорию',
|
||||
'budget.table.name': 'Название',
|
||||
'budget.table.total': 'Итого',
|
||||
'budget.table.persons': 'Человек',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Отмена',
|
||||
'common.clear': 'Очистить',
|
||||
'common.delete': 'Удалить',
|
||||
'common.remove': 'Удалить',
|
||||
'common.preview': 'Предпросмотр',
|
||||
'common.edit': 'Редактировать',
|
||||
'common.add': 'Добавить',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Vytvoriť kategóriu',
|
||||
'budget.category': 'Kategória',
|
||||
'budget.categoryName': 'Názov kategórie',
|
||||
'budget.addCategory': 'Pridať kategóriu',
|
||||
'budget.table.name': 'Názov',
|
||||
'budget.table.total': 'Spolu',
|
||||
'budget.table.persons': 'Osoby',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Zrušiť',
|
||||
'common.clear': 'Vymazať',
|
||||
'common.delete': 'Odstrániť',
|
||||
'common.remove': 'Odstrániť',
|
||||
'common.preview': 'Náhľad',
|
||||
'common.edit': 'Upraviť',
|
||||
'common.add': 'Pridať',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Skapa kategori',
|
||||
'budget.category': 'Kategori',
|
||||
'budget.categoryName': 'Kategorinamn',
|
||||
'budget.addCategory': 'Lägg till kategori',
|
||||
'budget.table.name': 'Namn',
|
||||
'budget.table.total': 'Totalt',
|
||||
'budget.table.persons': 'Personer',
|
||||
|
||||
@@ -19,6 +19,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Avbryt',
|
||||
'common.clear': 'Rensa',
|
||||
'common.delete': 'Ta bort',
|
||||
'common.remove': 'Ta bort',
|
||||
'common.preview': 'Förhandsvisning',
|
||||
'common.edit': 'Redigera',
|
||||
'common.add': 'Lägg till',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'สร้างหมวดหมู่',
|
||||
'budget.category': 'หมวดหมู่',
|
||||
'budget.categoryName': 'ชื่อหมวดหมู่',
|
||||
'budget.addCategory': 'เพิ่มหมวดหมู่',
|
||||
'budget.table.name': 'ชื่อ',
|
||||
'budget.table.total': 'รวม',
|
||||
'budget.table.persons': 'บุคคล',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'ยกเลิก',
|
||||
'common.clear': 'ล้าง',
|
||||
'common.delete': 'ลบ',
|
||||
'common.remove': 'ลบ',
|
||||
'common.preview': 'ดูตัวอย่าง',
|
||||
'common.edit': 'แก้ไข',
|
||||
'common.add': 'เพิ่ม',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Kategori Oluştur',
|
||||
'budget.category': 'Kategori',
|
||||
'budget.categoryName': 'Kategori Adı',
|
||||
'budget.addCategory': 'Kategori ekle',
|
||||
'budget.table.name': 'İsim',
|
||||
'budget.table.total': 'Toplam',
|
||||
'budget.table.persons': 'Kişiler',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'İptal',
|
||||
'common.clear': 'Temizle',
|
||||
'common.delete': 'Sil',
|
||||
'common.remove': 'Kaldır',
|
||||
'common.preview': 'Önizleme',
|
||||
'common.edit': 'Düzenle',
|
||||
'common.add': 'Ekle',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Створити категорію',
|
||||
'budget.category': 'Категорія',
|
||||
'budget.categoryName': 'Назва категорії',
|
||||
'budget.addCategory': 'Додати категорію',
|
||||
'budget.table.name': 'Назва',
|
||||
'budget.table.total': 'Всього',
|
||||
'budget.table.persons': 'Осіб',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Скасувати',
|
||||
'common.clear': 'Очистити',
|
||||
'common.delete': 'Видалити',
|
||||
'common.remove': 'Видалити',
|
||||
'common.preview': 'Перегляд',
|
||||
'common.edit': 'Редагувати',
|
||||
'common.add': 'Додати',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': 'Tạo danh mục',
|
||||
'budget.category': 'Loại',
|
||||
'budget.categoryName': 'Tên danh mục',
|
||||
'budget.addCategory': 'Thêm danh mục',
|
||||
'budget.table.name': 'Tên',
|
||||
'budget.table.total': 'Tổng cộng',
|
||||
'budget.table.persons': 'Người',
|
||||
|
||||
@@ -19,6 +19,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': 'Hủy',
|
||||
'common.clear': 'Xóa',
|
||||
'common.delete': 'Xóa bỏ',
|
||||
'common.remove': 'Gỡ bỏ',
|
||||
'common.preview': 'Xem trước',
|
||||
'common.edit': 'Chỉnh sửa',
|
||||
'common.add': 'Thêm',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': '建立分類',
|
||||
'budget.category': '分類',
|
||||
'budget.categoryName': '分類名稱',
|
||||
'budget.addCategory': '新增分類',
|
||||
'budget.table.name': '名稱',
|
||||
'budget.table.total': '合計',
|
||||
'budget.table.persons': '人數',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': '取消',
|
||||
'common.clear': '清除',
|
||||
'common.delete': '刪除',
|
||||
'common.remove': '刪除',
|
||||
'common.preview': '預覽',
|
||||
'common.edit': '編輯',
|
||||
'common.add': '新增',
|
||||
|
||||
@@ -11,6 +11,7 @@ const budget: TranslationStrings = {
|
||||
'budget.createCategory': '创建分类',
|
||||
'budget.category': '分类',
|
||||
'budget.categoryName': '分类名称',
|
||||
'budget.addCategory': '添加分类',
|
||||
'budget.table.name': '名称',
|
||||
'budget.table.total': '合计',
|
||||
'budget.table.persons': '人数',
|
||||
|
||||
@@ -7,6 +7,7 @@ const common: TranslationStrings = {
|
||||
'common.cancel': '取消',
|
||||
'common.clear': '清除',
|
||||
'common.delete': '删除',
|
||||
'common.remove': '删除',
|
||||
'common.preview': '预览',
|
||||
'common.edit': '编辑',
|
||||
'common.add': '添加',
|
||||
|
||||
Reference in New Issue
Block a user