diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index a4cb55a2c..7e6751b5a 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -95,6 +95,7 @@ defineExpose({
     getChanges,
     formData,
     vnPaginateRef,
+    resetData,
 });
 
 onBeforeRouteLeave((to, from, next) => {
diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js
index f7e0d780e..e7753a660 100644
--- a/src/i18n/en/index.js
+++ b/src/i18n/en/index.js
@@ -817,6 +817,11 @@ export default {
         hasToSendMail: 'Send check-ins by email',
         departmentRemoved: 'Department removed',
     },
+    translations: {
+        pageTitles: {
+            translations: 'Translations',
+        },
+    },
     worker: {
         pageTitles: {
             workers: 'Workers',
@@ -826,7 +831,7 @@ export default {
             notifications: 'Notifications',
             workerCreate: 'New worker',
             department: 'Department',
-            TranslationsVn: 'Translations',
+            translations: 'Translations',
         },
         list: {
             name: 'Name',
diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js
index cdbc55574..1121f485c 100644
--- a/src/i18n/es/index.js
+++ b/src/i18n/es/index.js
@@ -819,9 +819,10 @@ export default {
         hasToSendMail: 'Enviar fichadas por mail',
         departmentRemoved: 'Departamento eliminado',
     },
-    TranslationsVn: {
-        OriginalLanguage: 'Idioma Original',
-        SecondLanguage: 'Idioma Secundario',
+    translations: {
+        pageTitles: {
+            translations: 'Traducciones',
+        },
     },
     worker: {
         pageTitles: {
@@ -832,7 +833,7 @@ export default {
             notifications: 'Notificaciones',
             workerCreate: 'Nuevo trabajador',
             department: 'Departamentos',
-            TranslationsVn: 'Traducciones',
+            translations: 'Traducciones',
         },
         list: {
             name: 'Nombre',
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index b73395df2..aba5bea86 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -277,6 +277,7 @@ globals:
         medical: Mutual
         RouteExtendedList: Router
         wasteRecalc: Waste recaclulate
+        translations: Translations
     supplier: Supplier
     created: Created
     worker: Worker
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index 2552c9549..94ffcedf2 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -281,6 +281,7 @@ globals:
         serial: Facturas por serie
         medical: Mutua
         wasteRecalc: Recalcular mermas
+        translations: Traducciones
     supplier: Proveedor
     created: Fecha creación
     worker: Trabajador
diff --git a/src/pages/Worker/TranslationsVn.vue b/src/pages/Worker/TranslationsVn.vue
index 83e0ec098..a69801585 100644
--- a/src/pages/Worker/TranslationsVn.vue
+++ b/src/pages/Worker/TranslationsVn.vue
@@ -13,92 +13,113 @@ const { t } = useI18n();
 const columns = computed(() => [
     {
         align: 'left',
-        name: 'companyFk',
-        label: t('company18n'),
-        chip: {
-            condition: () => true,
-        },
-        isId: true,
+        name: primaryKey,
+        label: t('primaryKey'),
     },
     {
         align: 'left',
-        name: 'footnotes',
+        name: field,
         label: t('defaultLang(en)'),
+        component: 'input',
     },
     {
         align: 'left',
         name: 'secondLang',
         label: t('secondLang'),
+        component: 'input',
     },
 ]);
 
 const tableRef = ref({});
 const langs = ref([]);
-const pk = ref('companyFk');
-const value = ref('footnotes');
+const tables = ref([]);
 const lang = ref('es');
+const primaryKey = computed(() => table.value.primaryKey);
+const field = computed(() => table.value.field);
+const table = ref();
 const originalData = ref();
-const englishData = ref();
+const url = computed(() => table.value?.tableName + 's');
 // onMounted(() => {
 //     loadTable();
 // });
 
 async function loadTable() {
-    console.log('lang.value.code: ', lang.value);
     const data = tableRef.value.CrudModelRef.formData;
     if (!originalData.value) originalData.value = data;
-
+    if (!originalData.value) return;
     const en = originalData.value.filter((d) => d.lang === 'en');
     for (const translation of en) {
         translation['secondLang'] = originalData.value.find(
-            (d) => d[pk.value] == translation[pk.value] && d['lang'] == lang.value
-        )?.[value.value];
+            (d) =>
+                d[primaryKey.value] == translation[primaryKey.value] &&
+                d['lang'] == lang.value
+        )?.[field.value];
     }
     console.log('data: ', en);
 
-    tableRef.value.CrudModelRef.formData = en;
+    await tableRef.value.CrudModelRef.resetData(en);
 }
 
 function resetOriginalData() {
     originalData.value = null;
 }
+
+function upsertI18n() {
+    axios.patch(url.value, {});
+}
 </script>
 
 <template>
     <FetchData url="Languages" @on-fetch="(data) => (langs = data)" auto-load />
-    <VnSubToolbar />
+    <FetchData
+        url="Applications/get-i18n-tables"
+        @on-fetch="(data) => (tables = data)"
+        auto-load
+    />
+    <VnSubToolbar>
+        <template #st-data>
+            <VnSelect
+                :label="t('table')"
+                v-model="table"
+                :options="tables"
+                option-label="tableName"
+                option-value="tableName"
+                @update:model-value="resetOriginalData()"
+                :emit-value="false"
+            />
+            <VnSelect
+                :label="t('lang')"
+                v-model="lang"
+                :options="langs"
+                option-label="code"
+                option-value="code"
+                @update:model-value="loadTable()"
+            />
+        </template>
+    </VnSubToolbar>
     <VnTable
         ref="tableRef"
         data-key="translations"
-        url="CompanyI18ns"
+        :url="url"
         :columns="columns"
         :right-search="false"
         :is-editable="true"
-        auto-load
         @on-fetch="loadTable()"
-    >
-        <template #top-left>
-            <div class="row no-wrap q-gutter-x-sm">
-                <VnSelect
-                    v-model="lang"
-                    :options="langs"
-                    option-label="code"
-                    option-value="code"
-                    @update:model-value="resetOriginalData()"
-                />
-                <VnSelect
-                    :label="t('lang')"
-                    v-model="lang"
-                    :options="langs"
-                    option-label="code"
-                    option-value="code"
-                    @update:model-value="loadTable()"
-                />
-            </div>
-        </template>
-    </VnTable>
+        :save-fn="upsertI18n"
+    />
 </template>
 
 <i18n>
-
+    es:
+        primaryKey: Clave primaria
+        defaultLang(en): Idioma por defecto(Eng)
+        secondLang: Idioma secundario
+        table: Tabla
+        lang: Idioma
+    en:
+        primaryKey: Primary key
+        defaultLang(en): Default language(Eng)
+        secondLang: Second language
+        table: Table
+        lang: Language
 </i18n>