diff --git a/.eslintrc.js b/.eslintrc.cjs
similarity index 100%
rename from .eslintrc.js
rename to .eslintrc.cjs
diff --git a/package.json b/package.json
index 4668d2d56..71d80d401 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "salix-front",
-    "version": "24.28.1",
+    "version": "24.30.1",
     "description": "Salix frontend",
     "productName": "Salix",
     "author": "Verdnatura",
diff --git a/public/no-image-dark.png b/public/no-image-dark.png
new file mode 100644
index 000000000..2a20d7eb4
Binary files /dev/null and b/public/no-image-dark.png differ
diff --git a/public/no-image.png b/public/no-image.png
new file mode 100644
index 000000000..11d5317a9
Binary files /dev/null and b/public/no-image.png differ
diff --git a/public/no-user.png b/public/no-user.png
new file mode 100644
index 000000000..e090bc2eb
Binary files /dev/null and b/public/no-user.png differ
diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index d5d8e2a91..fa7761c5f 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -10,6 +10,7 @@ import VnPaginate from 'components/ui/VnPaginate.vue';
 import VnConfirm from 'components/ui/VnConfirm.vue';
 import SkeletonTable from 'components/ui/SkeletonTable.vue';
 import { tMobile } from 'src/composables/tMobile';
+import VnSubToolbar from './ui/VnSubToolbar.vue';
 
 const { push } = useRouter();
 const quasar = useQuasar();
@@ -67,7 +68,7 @@ const $props = defineProps({
         default: '',
         description: 'It is used for redirect on click "save and continue"',
     },
-    hasSubtoolbar: {
+    hasSubToolbar: {
         type: Boolean,
         default: true,
     },
@@ -313,8 +314,11 @@ watch(formUrl, async () => {
             ></slot>
         </template>
     </VnPaginate>
-    <SkeletonTable v-if="!formData" :columns="$attrs.columns?.length" />
-    <Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown() && hasSubtoolbar">
+    <SkeletonTable
+        v-if="!formData && $attrs.autoLoad"
+        :columns="$attrs.columns?.length"
+    />
+    <Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown() && hasSubToolbar">
         <QBtnGroup push style="column-gap: 10px">
             <slot name="moreBeforeActions" />
             <QBtn
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index f10dee61a..becc1c174 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -90,7 +90,7 @@ const $props = defineProps({
 });
 const emit = defineEmits(['onFetch', 'onDataSaved']);
 const modelValue = computed(
-    () => $props.model ?? `formModel_${route?.meta?.title ?? route.name}`
+    () => $props.model ?? `formModel_${route?.meta?.title ?? route.name}`,
 ).value;
 const componentIsRendered = ref(false);
 const arrayData = useArrayData(modelValue);
@@ -137,7 +137,7 @@ onMounted(async () => {
                     JSON.stringify(newVal) !== JSON.stringify(originalData.value);
                 isResetting.value = false;
             },
-            { deep: true }
+            { deep: true },
         );
     }
 });
@@ -145,7 +145,7 @@ onMounted(async () => {
 if (!$props.url)
     watch(
         () => arrayData.store.data,
-        (val) => updateAndEmit('onFetch', val)
+        (val) => updateAndEmit('onFetch', val),
     );
 
 watch(formUrl, async () => {
@@ -206,11 +206,11 @@ async function save() {
 
         updateAndEmit('onDataSaved', formData.value, response?.data);
         if ($props.reload) await arrayData.fetch({});
+        hasChanges.value = false;
     } catch (err) {
         console.error(err);
         notify('errors.writeRequest', 'negative');
     } finally {
-        hasChanges.value = false;
         isLoading.value = false;
     }
 }
@@ -239,7 +239,7 @@ function filter(value, update, filterOptions) {
         (ref) => {
             ref.setOptionIndex(-1);
             ref.moveOptionSelection(1, true);
-        }
+        },
     );
 }
 
@@ -262,7 +262,7 @@ defineExpose({
 <template>
     <div class="column items-center full-width">
         <QForm
-            v-if="formData"
+            
             @submit="save"
             @reset="reset"
             class="q-pa-md"
@@ -270,11 +270,13 @@ defineExpose({
         >
             <QCard>
                 <slot
+                    v-if="formData"
                     name="form"
                     :data="formData"
                     :validate="validate"
                     :filter="filter"
                 />
+                <SkeletonForm v-else/>
             </QCard>
         </QForm>
     </div>
@@ -337,7 +339,7 @@ defineExpose({
             </QBtnGroup>
         </div>
     </Teleport>
-    <SkeletonForm v-if="!formData" />
+    
     <QInnerLoading
         :showing="isLoading"
         :label="t('globals.pleaseWait')"
diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue
index 3cccd0d2f..213c08d7e 100644
--- a/src/components/LeftMenu.vue
+++ b/src/components/LeftMenu.vue
@@ -58,6 +58,7 @@ function addChildren(module, route, parent) {
 }
 
 const items = ref([]);
+
 function getRoutes() {
     if (props.source === 'main') {
         const modules = Object.assign([], navigation.getModules().value);
@@ -66,9 +67,8 @@ function getRoutes() {
             const moduleDef = routes.find(
                 (route) => toLowerCamel(route.name) === item.module
             );
-            item.children = [];
-
             if (!moduleDef) continue;
+            item.children = [];
 
             addChildren(item.module, moduleDef, item.children);
         }
diff --git a/src/components/LeftMenuItem.vue b/src/components/LeftMenuItem.vue
index d12fb8428..f3f2315a3 100644
--- a/src/components/LeftMenuItem.vue
+++ b/src/components/LeftMenuItem.vue
@@ -21,7 +21,7 @@ const itemComputed = computed(() => {
 </script>
 <template>
     <QItem
-        active-class="bg-hover"
+        active-class="bg-vn-hover"
         class="min-height"
         :to="{ name: itemComputed.name }"
         clickable
diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue
index c6722d875..3051e8b99 100644
--- a/src/components/NavBar.vue
+++ b/src/components/NavBar.vue
@@ -1,21 +1,19 @@
 <script setup>
 import { onMounted, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useSession } from 'src/composables/useSession';
 import { useState } from 'src/composables/useState';
 import { useStateStore } from 'stores/useStateStore';
 import { useQuasar } from 'quasar';
 import PinnedModules from './PinnedModules.vue';
 import UserPanel from 'components/UserPanel.vue';
 import VnBreadcrumbs from './common/VnBreadcrumbs.vue';
+import VnImg from 'src/components/ui/VnImg.vue';
 
 const { t } = useI18n();
 const stateStore = useStateStore();
 const quasar = useQuasar();
 const state = useState();
 const user = state.getUser();
-const { getTokenMultimedia } = useSession();
-const token = getTokenMultimedia();
 const appName = 'Lilium';
 
 onMounted(() => stateStore.setMounted());
@@ -83,11 +81,12 @@ const pinnedModulesRef = ref();
                     id="user"
                 >
                     <QAvatar size="lg">
-                        <QImg
-                            :src="`/api/Images/user/160x160/${user.id}/download?access_token=${token}`"
-                            spinner-color="primary"
-                        >
-                        </QImg>
+                        <VnImg
+                            :id="user.id"
+                            collection="user"
+                            size="160x160"
+                            :zoom-size="null"
+                        />
                     </QAvatar>
                     <QTooltip bottom>
                         {{ t('globals.userPanel') }}
diff --git a/src/components/TransferInvoiceForm.vue b/src/components/TransferInvoiceForm.vue
index 1af23583d..0a8c1272e 100644
--- a/src/components/TransferInvoiceForm.vue
+++ b/src/components/TransferInvoiceForm.vue
@@ -70,14 +70,11 @@ const makeInvoice = async () => {
                     });
             });
             if (!response) {
-                console.log('entra cuando no checkbox');
                 return;
             }
         }
 
-        console.log('params: ', params);
         const { data } = await axios.post('InvoiceOuts/transferInvoice', params);
-        console.log('data: ', data);
         notify(t('Transferred invoice'), 'positive');
         const id = data?.[0];
         if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue
index 9c3b456b1..589524258 100644
--- a/src/components/UserPanel.vue
+++ b/src/components/UserPanel.vue
@@ -12,12 +12,14 @@ import VnRow from 'components/ui/VnRow.vue';
 import FetchData from 'components/FetchData.vue';
 import { useClipboard } from 'src/composables/useClipboard';
 import VnImg from 'src/components/ui/VnImg.vue';
+import { useRole } from 'src/composables/useRole';
 
 const state = useState();
 const session = useSession();
 const router = useRouter();
 const { t, locale } = useI18n();
 const { copyText } = useClipboard();
+
 const userLocale = computed({
     get() {
         return locale.value;
@@ -99,6 +101,7 @@ function saveUserData(param, value) {
     axios.post('UserConfigs/setUserConfig', { [param]: value });
     localUserData();
 }
+const isEmployee = computed(() => useRole().isEmployee());
 </script>
 
 <template>
@@ -109,12 +112,14 @@ function saveUserData(param, value) {
         auto-load
     />
     <FetchData
+        v-if="isEmployee"
         url="Companies"
         order="name"
         @on-fetch="(data) => (companiesData = data)"
         auto-load
     />
     <FetchData
+        v-if="isEmployee"
         url="Accountings"
         order="name"
         @on-fetch="(data) => (accountBankData = data)"
diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue
index 6cd62d83e..aeccdb2d6 100644
--- a/src/components/VnTable/VnColumn.vue
+++ b/src/components/VnTable/VnColumn.vue
@@ -46,6 +46,7 @@ const defaultComponents = {
         component: markRaw(VnInput),
         attrs: {
             disable: !$props.isEditable,
+            class: 'fit',
         },
         forceAttrs: {
             label: $props.showLabel && $props.column.label,
@@ -55,6 +56,7 @@ const defaultComponents = {
         component: markRaw(VnInput),
         attrs: {
             disable: !$props.isEditable,
+            class: 'fit',
         },
         forceAttrs: {
             label: $props.showLabel && $props.column.label,
@@ -66,6 +68,7 @@ const defaultComponents = {
             readonly: true,
             disable: !$props.isEditable,
             style: 'min-width: 125px',
+            class: 'fit',
         },
         forceAttrs: {
             label: $props.showLabel && $props.column.label,
@@ -77,7 +80,7 @@ const defaultComponents = {
             const defaultAttrs = {
                 disable: !$props.isEditable,
                 'model-value': Boolean(prop),
-                class: 'no-padding',
+                class: 'no-padding fit',
             };
 
             if (typeof prop == 'number') {
@@ -94,6 +97,7 @@ const defaultComponents = {
         component: markRaw(VnSelect),
         attrs: {
             disable: !$props.isEditable,
+            class: 'fit',
         },
         forceAttrs: {
             label: $props.showLabel && $props.column.label,
@@ -134,7 +138,7 @@ const col = computed(() => {
 const components = computed(() => $props.components ?? defaultComponents);
 </script>
 <template>
-    <div class="row no-wrap fit">
+    <div class="row no-wrap">
         <VnComponent
             v-if="col.before"
             :prop="col.before"
diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue
index 3d489cf73..b3386899f 100644
--- a/src/components/VnTable/VnFilter.vue
+++ b/src/components/VnTable/VnFilter.vue
@@ -7,6 +7,7 @@ import { useArrayData } from 'composables/useArrayData';
 import VnSelect from 'components/common/VnSelect.vue';
 import VnInput from 'components/common/VnInput.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
+import VnInputTime from 'components/common/VnInputTime.vue';
 import VnTableColumn from 'components/VnTable/VnColumn.vue';
 
 const $props = defineProps({
@@ -39,7 +40,7 @@ const enterEvent = {
 
 const defaultAttrs = {
     filled: !$props.showTitle,
-    class: 'q-px-sm q-pb-xs q-pt-none',
+    class: 'q-px-sm q-pb-xs q-pt-none fit',
     dense: true,
 };
 
@@ -75,12 +76,23 @@ const components = {
         },
         forceAttrs,
     },
+    time: {
+        component: markRaw(VnInputTime),
+        event: updateEvent,
+        attrs: {
+            ...defaultAttrs,
+            disable: !$props.isEditable,
+        },
+        forceAttrs: {
+            label: $props.showLabel && $props.column.label,
+        },
+    },
     checkbox: {
         component: markRaw(QCheckbox),
         event: updateEvent,
         attrs: {
             dense: true,
-            class: $props.showTitle ? 'q-py-sm q-mt-md' : 'q-px-md q-py-xs',
+            class: $props.showTitle ? 'q-py-sm q-mt-md' : 'q-px-md q-py-xs fit',
             'toggle-indeterminate': true,
         },
         forceAttrs,
@@ -89,7 +101,7 @@ const components = {
         component: markRaw(VnSelect),
         event: updateEvent,
         attrs: {
-            class: 'q-px-md q-pb-xs q-pt-none',
+            class: 'q-px-md q-pb-xs q-pt-none fit',
             dense: true,
             filled: !$props.showTitle,
         },
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index cb691de69..13b12a05b 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -59,6 +59,14 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
+    hasSubToolbar: {
+        type: Boolean,
+        default: true,
+    },
+    disableOption: {
+        type: Object,
+        default: () => ({ card: false, table: false }),
+    },
 });
 const { t } = useI18n();
 const stateStore = useStateStore();
@@ -81,11 +89,13 @@ const tableModes = [
         icon: 'view_column',
         title: t('table view'),
         value: TABLE_MODE,
+        disable: $props.disableOption?.table,
     },
     {
         icon: 'grid_view',
         title: t('grid view'),
         value: DEFAULT_MODE,
+        disable: $props.disableOption?.card,
     },
 ];
 
@@ -176,11 +186,14 @@ function columnName(col) {
 }
 
 function getColAlign(col) {
-    return 'text-' + (col.align ?? 'left')
+    return 'text-' + (col.align ?? 'left');
 }
+
+const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
 defineExpose({
     reload,
     redirect: redirectFn,
+    selected,
 });
 </script>
 <template>
@@ -235,11 +248,18 @@ defineExpose({
             :search-url="searchUrl"
             :disable-infinite-scroll="mode == TABLE_MODE"
             @save-changes="reload"
-            :has-subtoolbar="isEditable"
+            :has-sub-toolbar="$attrs['hasSubToolbar'] ?? isEditable"
         >
+            <template
+                v-for="(_, slotName) in $slots"
+                #[slotName]="slotData"
+                :key="slotName"
+            >
+                <slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
+            </template>
             <template #body="{ rows }">
                 <QTable
-                    v-bind="$attrs['QTable']"
+                    v-bind="$attrs['q-table']"
                     class="vnTable"
                     :columns="splittedColumns.columns"
                     :rows="rows"
@@ -256,6 +276,7 @@ defineExpose({
                             CrudModelRef.vnPaginateRef.paginate()
                     "
                     @row-click="(_, row) => rowClickFunction(row)"
+                    @update:selected="emit('update:selected', $event)"
                 >
                     <template #top-left>
                         <slot name="top-left"></slot>
@@ -320,13 +341,15 @@ defineExpose({
                             class="no-margin q-px-xs"
                             :class="getColAlign(col)"
                         >
-                            <VnTableColumn
-                                :column="col"
-                                :row="row"
-                                :is-editable="false"
-                                v-model="row[col.name]"
-                                component-prop="columnField"
-                            />
+                            <slot :name="`column-${col.name}`" :col="col" :row="row">
+                                <VnTableColumn
+                                    :column="col"
+                                    :row="row"
+                                    :is-editable="false"
+                                    v-model="row[col.name]"
+                                    component-prop="columnField"
+                                />
+                            </slot>
                         </QTd>
                     </template>
                     <template #body-cell-tableActions="{ col, row }">
@@ -411,9 +434,9 @@ defineExpose({
                                         >
                                             <VnLv
                                                 :label="
-                                                    !col.component &&
-                                                    col.label &&
-                                                    `${col.label}:`
+                                                    !col.component && col.label
+                                                        ? `${col.label}:`
+                                                        : ''
                                                 "
                                             >
                                                 <template #value>
@@ -422,14 +445,20 @@ defineExpose({
                                                             stopEventPropagation($event)
                                                         "
                                                     >
-                                                        <VnTableColumn
-                                                            :column="col"
+                                                        <slot
+                                                            :name="`column-${col.name}`"
+                                                            :col="col"
                                                             :row="row"
-                                                            :is-editable="false"
-                                                            v-model="row[col.name]"
-                                                            component-prop="columnField"
-                                                            :show-label="true"
-                                                        />
+                                                        >
+                                                            <VnTableColumn
+                                                                :column="col"
+                                                                :row="row"
+                                                                :is-editable="false"
+                                                                v-model="row[col.name]"
+                                                                component-prop="columnField"
+                                                                :show-label="true"
+                                                            />
+                                                        </slot>
                                                     </span>
                                                 </template>
                                             </VnLv>
@@ -487,6 +516,7 @@ defineExpose({
                         default="input"
                         v-model="data[column.name]"
                         :show-label="true"
+                        component-prop="columnCreate"
                     />
                     <slot name="more-create-dialog" :data="data" />
                 </div>
diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 8517525df..17fa74317 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -1,6 +1,6 @@
 <script setup>
 import { onBeforeMount, computed } from 'vue';
-import { useRoute } from 'vue-router';
+import { useRoute, onBeforeRouteUpdate } from 'vue-router';
 import { useArrayData } from 'src/composables/useArrayData';
 import { useStateStore } from 'stores/useStateStore';
 import useCardSize from 'src/composables/useCardSize';
@@ -39,8 +39,17 @@ const arrayData = useArrayData(props.dataKey, {
 
 onBeforeMount(async () => {
     if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
-    await arrayData.fetch({ append: false });
+    await arrayData.fetch({ append: false, updateRouter: false });
 });
+
+if (props.baseUrl) {
+    onBeforeRouteUpdate(async (to, from) => {
+        if (to.params.id !== from.params.id) {
+            arrayData.store.url = `${props.baseUrl}/${to.params.id}`;
+            await arrayData.fetch({ append: false, updateRouter: false });
+        }
+    });
+}
 </script>
 <template>
     <QDrawer
diff --git a/src/components/common/VnComponent.vue b/src/components/common/VnComponent.vue
index 318b5ee5f..d7719034a 100644
--- a/src/components/common/VnComponent.vue
+++ b/src/components/common/VnComponent.vue
@@ -12,7 +12,7 @@ const $props = defineProps({
         default: () => {},
     },
     value: {
-        type: [Object, Number, String],
+        type: [Object, Number, String, Boolean],
         default: () => {},
     },
 });
@@ -54,7 +54,6 @@ function toValueAttrs(attrs) {
             v-bind="mix(toComponent).attrs"
             v-on="mix(toComponent).event ?? {}"
             v-model="model"
-            class="fit"
         />
     </span>
 </template>
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 4cd964012..33b97e29d 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -93,7 +93,12 @@ const inputRules = [
                     name="close"
                     size="xs"
                     v-if="hover && value && !$attrs.disabled && $props.clearable"
-                    @click="value = null"
+                    @click="
+                        () => {
+                            value = null;
+                            emit('remove');
+                        }
+                    "
                 ></QIcon>
                 <QIcon v-if="info" name="info">
                     <QTooltip max-width="350px">
diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue
index 77ab2692d..184f8a158 100644
--- a/src/components/common/VnInputDate.vue
+++ b/src/components/common/VnInputDate.vue
@@ -1,84 +1,31 @@
 <script setup>
-import { computed, ref } from 'vue';
+import { onMounted, watch, computed, ref } from 'vue';
+import { date } from 'quasar';
 import { useI18n } from 'vue-i18n';
-import isValidDate from 'filters/isValidDate';
 
-const props = defineProps({
-    modelValue: {
-        type: String,
-        default: null,
-    },
-    readonly: {
-        type: Boolean,
-        default: false,
-    },
+const model = defineModel({ type: String });
+const $props = defineProps({
     isOutlined: {
         type: Boolean,
         default: false,
     },
-    emitDateFormat: {
-        type: Boolean,
-        default: false,
-    },
 });
-const hover = ref(false);
-
-const emit = defineEmits(['update:modelValue']);
 
 const { t } = useI18n();
 const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
 
-const joinDateAndTime = (date, time) => {
-    if (!date) {
-        return null;
-    }
-    if (!time) {
-        return new Date(date).toISOString();
-    }
-    const [year, month, day] = date.split('/');
-    return new Date(`${year}-${month}-${day}T${time}`).toISOString();
-};
+const dateFormat = 'DD/MM/YYYY';
+const isPopupOpen = ref();
+const hover = ref();
+const mask = ref();
 
-const time = computed(() => (props.modelValue ? props.modelValue.split('T')?.[1] : null));
-const value = computed({
-    get() {
-        return props.modelValue;
-    },
-    set(value) {
-        emit(
-            'update:modelValue',
-            props.emitDateFormat ? new Date(value) : joinDateAndTime(value, time.value)
-        );
-    },
+onMounted(() => {
+    // fix quasar bug
+    mask.value = '##/##/####';
 });
 
-const isPopupOpen = ref(false);
-
-const onDateUpdate = (date) => {
-    value.value = date;
-    isPopupOpen.value = false;
-};
-
-const padDate = (value) => value.toString().padStart(2, '0');
-const formatDate = (dateString) => {
-    const date = new Date(dateString || '');
-    return `${date.getFullYear()}/${padDate(date.getMonth() + 1)}/${padDate(
-        date.getDate()
-    )}`;
-};
-const displayDate = (dateString) => {
-    if (!dateString || !isValidDate(dateString)) {
-        return '';
-    }
-    return new Date(dateString).toLocaleDateString([], {
-        year: 'numeric',
-        month: '2-digit',
-        day: '2-digit',
-    });
-};
-
 const styleAttrs = computed(() => {
-    return props.isOutlined
+    return $props.isOutlined
         ? {
               dense: true,
               outlined: true,
@@ -86,42 +33,101 @@ const styleAttrs = computed(() => {
           }
         : {};
 });
+
+const formattedDate = computed({
+    get() {
+        if (!model.value) return model.value;
+        return date.formatDate(new Date(model.value), dateFormat);
+    },
+    set(value) {
+        if (value == model.value) return;
+        let newDate;
+        if (value) {
+            // parse input
+            if (value.includes('/') && value.length >= 10) {
+                if (value.at(2) == '/') value = value.split('/').reverse().join('/');
+                value = date.formatDate(
+                    new Date(value).toISOString(),
+                    'YYYY-MM-DDTHH:mm:ss.SSSZ'
+                );
+            }
+            let ymd = value.split('-').map((e) => parseInt(e));
+            newDate = new Date(ymd[0], ymd[1] - 1, ymd[2]);
+            if (model.value) {
+                const orgDate =
+                    model.value instanceof Date ? model.value : new Date(model.value);
+
+                newDate.setHours(
+                    orgDate.getHours(),
+                    orgDate.getMinutes(),
+                    orgDate.getSeconds(),
+                    orgDate.getMilliseconds()
+                );
+            }
+        }
+        if (!isNaN(newDate)) model.value = newDate.toISOString();
+    },
+});
+
+const popupDate = computed(() =>
+    model.value ? date.formatDate(new Date(model.value), 'YYYY/MM/DD') : model.value
+);
+
+watch(
+    () => model.value,
+    (val) => (formattedDate.value = val),
+    { immediate: true }
+);
 </script>
 
 <template>
     <div @mouseover="hover = true" @mouseleave="hover = false">
         <QInput
+            v-model="formattedDate"
             class="vn-input-date"
-            readonly
-            :model-value="displayDate(value)"
+            :mask="mask"
+            placeholder="dd/mm/aaaa"
             v-bind="{ ...$attrs, ...styleAttrs }"
             :class="{ required: $attrs.required }"
             :rules="$attrs.required ? [requiredFieldRule] : null"
-            @click="isPopupOpen = true"
+            :clearable="false"
         >
             <template #append>
                 <QIcon
                     name="close"
                     size="xs"
-                    v-if="hover && value && !readonly"
-                    @click="onDateUpdate(null)"
-                ></QIcon>
-                <QIcon name="event" class="cursor-pointer">
-                    <QPopupProxy
-                        v-model="isPopupOpen"
-                        cover
-                        transition-show="scale"
-                        transition-hide="scale"
-                        :no-parent-event="props.readonly"
-                    >
-                        <QDate
-                            :today-btn="true"
-                            :model-value="formatDate(value)"
-                            @update:model-value="onDateUpdate"
-                        />
-                    </QPopupProxy>
-                </QIcon>
+                    v-if="
+                        ($attrs.clearable == undefined || $attrs.clearable) &&
+                        hover &&
+                        model &&
+                        !$attrs.disable
+                    "
+                    @click="
+                        model = null;
+                        isPopupOpen = false;
+                    "
+                />
+                <QIcon name="event" class="cursor-pointer" />
             </template>
+            <QMenu
+                transition-show="scale"
+                transition-hide="scale"
+                v-model="isPopupOpen"
+                anchor="bottom left"
+                self="top start"
+                :no-focus="true"
+            >
+                <QDate
+                    v-model="popupDate"
+                    :today-btn="true"
+                    @update:model-value="
+                        (date) => {
+                            formattedDate = date;
+                            isPopupOpen = false;
+                        }
+                    "
+                />
+            </QMenu>
         </QInput>
     </div>
 </template>
diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue
index 5c84951cb..9344ff869 100644
--- a/src/components/common/VnInputTime.vue
+++ b/src/components/common/VnInputTime.vue
@@ -1,14 +1,11 @@
 <script setup>
-import { computed, ref } from 'vue';
+import { watch, computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
-import isValidDate from 'filters/isValidDate';
+import { date } from 'quasar';
 
+const model = defineModel({ type: String });
 const props = defineProps({
-    modelValue: {
-        type: String,
-        default: null,
-    },
-    readonly: {
+    timeOnly: {
         type: Boolean,
         default: false,
     },
@@ -17,43 +14,12 @@ const props = defineProps({
         default: false,
     },
 });
-const emit = defineEmits(['update:modelValue']);
 const { t } = useI18n();
 const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
 
-const value = computed({
-    get() {
-        return props.modelValue;
-    },
-    set(value) {
-        const [hours, minutes] = value.split(':');
-        const date = new Date(props.modelValue);
-        date.setHours(Number.parseInt(hours) || 0, Number.parseInt(minutes) || 0, 0, 0);
-        emit('update:modelValue', value ? date.toISOString() : null);
-    },
-});
-
-const isPopupOpen = ref(false);
-const onDateUpdate = (date) => {
-    internalValue.value = date;
-};
-
-const save = () => {
-    value.value = internalValue.value;
-};
-const formatTime = (dateString) => {
-    if (!dateString || !isValidDate(dateString)) {
-        return '';
-    }
-
-    const date = new Date(dateString || '');
-    return date.toLocaleTimeString([], {
-        hour: '2-digit',
-        minute: '2-digit',
-    });
-};
-
-const internalValue = ref(formatTime(value));
+const dateFormat = 'HH:mm';
+const isPopupOpen = ref();
+const hover = ref();
 
 const styleAttrs = computed(() => {
     return props.isOutlined
@@ -64,54 +30,87 @@ const styleAttrs = computed(() => {
           }
         : {};
 });
+
+const formattedTime = computed({
+    get() {
+        if (!model.value || model.value?.length <= 5) return model.value;
+        return dateToTime(model.value);
+    },
+    set(value) {
+        if (value == model.value) return;
+        let time = value;
+        if (time) {
+            if (time?.length > 5) time = dateToTime(time);
+            if (!props.timeOnly) {
+                const hours = time.split(':');
+                const date = new Date();
+                date.setHours(hours[0], hours[1], 0);
+                time = date.toISOString();
+            }
+        }
+        model.value = time;
+    },
+});
+
+function dateToTime(newDate) {
+    return date.formatDate(new Date(newDate), dateFormat);
+}
+
+watch(
+    () => model.value,
+    (val) => (formattedTime.value = val),
+    { immediate: true }
+);
 </script>
 
 <template>
-    <QInput
-        class="vn-input-time"
-        readonly
-        :model-value="formatTime(value)"
-        v-bind="{ ...$attrs, ...styleAttrs }"
-        :class="{ required: $attrs.required }"
-        :rules="$attrs.required ? [requiredFieldRule] : null"
-        @click="isPopupOpen = true"
-    >
-        <template #append>
-            <QIcon name="Schedule" class="cursor-pointer">
-                <QPopupProxy
-                    v-model="isPopupOpen"
-                    cover
-                    transition-show="scale"
-                    transition-hide="scale"
-                    :no-parent-event="props.readonly"
-                >
-                    <QTime
-                        :format24h="false"
-                        :model-value="formatTime(value)"
-                        @update:model-value="onDateUpdate"
-                    >
-                        <div class="row items-center justify-end q-gutter-sm">
-                            <QBtn
-                                :label="t('Cancel')"
-                                color="primary"
-                                flat
-                                v-close-popup
-                            />
-                            <QBtn
-                                label="Ok"
-                                color="primary"
-                                flat
-                                @click="save"
-                                v-close-popup
-                            />
-                        </div>
-                    </QTime>
-                </QPopupProxy>
-            </QIcon>
-        </template>
-    </QInput>
+    <div @mouseover="hover = true" @mouseleave="hover = false">
+        <QInput
+            class="vn-input-time"
+            mask="##:##"
+            placeholder="--:--"
+            v-model="formattedTime"
+            v-bind="{ ...$attrs, ...styleAttrs }"
+            :class="{ required: $attrs.required }"
+            style="min-width: 100px"
+            :rules="$attrs.required ? [requiredFieldRule] : null"
+        >
+            <template #append>
+                <QIcon
+                    name="close"
+                    size="xs"
+                    v-if="
+                        ($attrs.clearable == undefined || $attrs.clearable) &&
+                        hover &&
+                        model &&
+                        !$attrs.disable
+                    "
+                    @click="
+                        model = null;
+                        isPopupOpen = false;
+                    "
+                />
+                <QIcon name="Schedule" class="cursor-pointer" />
+            </template>
+            <QMenu
+                transition-show="scale"
+                transition-hide="scale"
+                v-model="isPopupOpen"
+                anchor="bottom left"
+                self="top start"
+                :no-focus="true"
+            >
+                <QTime
+                    :format24h="false"
+                    v-model="formattedTime"
+                    mask="HH:mm"
+                    landscape
+                    now-btn
+                />
+            </QMenu>
+        </QInput>
+    </div>
 </template>
-
 <style lang="scss">
 .vn-input-time.q-field--standard.q-field--readonly .q-field__control:before {
     border-bottom-style: solid;
@@ -121,8 +120,3 @@ const styleAttrs = computed(() => {
     border-style: solid;
 }
 </style>
-
-<i18n>
-es:
-    Cancel: Cancelar
-</i18n>
diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue
index 61436b7e8..19765b1f7 100644
--- a/src/components/common/VnLog.vue
+++ b/src/components/common/VnLog.vue
@@ -49,6 +49,7 @@ const filter = {
         'changedModelId',
         'changedModelValue',
         'description',
+        'summaryId',
     ],
     include: [
         {
@@ -459,12 +460,12 @@ onUnmounted(() => {
                                 :style="{
                                     backgroundColor: useColor(modelLog.model),
                                 }"
-                                :title="modelLog.model"
+                                :title="`${modelLog.model} #${modelLog.id}`"
                             >
                                 {{ t(modelLog.modelI18n) }}
                             </QChip>
-                            <span class="model-id" v-if="modelLog.id"
-                                >#{{ modelLog.id }}</span
+                            <span class="model-id" v-if="modelLog.summaryId"
+                                >#{{ modelLog.summaryId }}</span
                             >
                             <span class="model-value" :title="modelLog.showValue">
                                 {{ modelLog.showValue }}
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index 52cb68438..3e5cd4216 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -61,6 +61,10 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
+    useLike: {
+        type: Boolean,
+        default: true,
+    },
 });
 
 const { t } = useI18n();
@@ -114,11 +118,14 @@ async function fetchFilter(val) {
     if (!$props.url || !dataRef.value) return;
 
     const { fields, sortBy, limit } = $props;
-    let key = optionLabel.value;
+    let key = optionFilter.value ?? optionLabel.value;
 
-    if (new RegExp(/\d/g).test(val)) key = optionFilter.value ?? optionValue.value;
+    if (new RegExp(/\d/g).test(val)) key = optionValue.value;
 
-    const where = { ...{ [key]: { like: `%${val}%` } }, ...$props.where };
+    const defaultWhere = $props.useLike
+        ? { [key]: { like: `%${val}%` } }
+        : { [key]: val };
+    const where = { ...defaultWhere, ...$props.where };
     const fetchOptions = { where, order: sortBy, limit };
     if (fields) fetchOptions.fields = fields;
     return dataRef.value.fetch(fetchOptions);
diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue
index 8bb2a603e..2bb5234ad 100644
--- a/src/components/ui/CardDescriptor.vue
+++ b/src/components/ui/CardDescriptor.vue
@@ -46,7 +46,7 @@ let arrayData;
 let store;
 let entity;
 const isLoading = ref(false);
-
+const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
 defineExpose({ getData });
 
 onBeforeMount(async () => {
@@ -58,10 +58,12 @@ onBeforeMount(async () => {
     store = arrayData.store;
     entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
     // It enables to load data only once if the module is the same as the dataKey
-    if ($props.dataKey !== route.meta.moduleName || !route.params.id) await getData();
+    if (!isSameDataKey.value || !route.params.id) await getData();
     watch(
         () => [$props.url, $props.filter],
-        async () => await getData()
+        async () => {
+            if (!isSameDataKey.value) await getData();
+        }
     );
 });
 
@@ -77,14 +79,50 @@ async function getData() {
         isLoading.value = false;
     }
 }
+
+function getValueFromPath(path) {
+    if (!path) return;
+    const keys = path.toString().split('.');
+    let current = entity.value;
+
+    for (let i = 0; i < keys.length; i++) {
+        if (current[keys[i]] === undefined) return undefined;
+        else current = current[keys[i]];
+    }
+    return current;
+}
+
 const emit = defineEmits(['onFetch']);
+
+const iconModule = computed(() => route.matched[1].meta.icon);
+const toModule = computed(() =>
+    route.matched[1].path.split('/').length > 2
+        ? route.matched[1].redirect
+        : route.matched[1].children[0].redirect
+);
 </script>
 
 <template>
     <div class="descriptor">
         <template v-if="entity && !isLoading">
             <div class="header bg-primary q-pa-sm justify-between">
-                <slot name="header-extra-action" />
+                <slot name="header-extra-action"
+                    ><QBtn
+                        round
+                        flat
+                        dense
+                        size="md"
+                        :icon="iconModule"
+                        color="white"
+                        class="link"
+                        :to="toModule"
+                    >
+                        <QTooltip>
+                            {{ t('globals.goToModuleIndex') }}
+                        </QTooltip>
+                    </QBtn></slot
+                >
+
                 <QBtn
                     @click.stop="viewSummary(entity.id, $props.summary)"
                     round
@@ -139,8 +177,8 @@ const emit = defineEmits(['onFetch']);
                 <QList dense>
                     <QItemLabel header class="ellipsis text-h5" :lines="1">
                         <div class="title">
-                            <span v-if="$props.title" :title="$props.title">
-                                {{ entity[title] ?? $props.title }}
+                            <span v-if="$props.title" :title="getValueFromPath(title)">
+                                {{ getValueFromPath(title) ?? $props.title }}
                             </span>
                             <slot v-else name="description" :entity="entity">
                                 <span :title="entity.name">
@@ -151,7 +189,7 @@ const emit = defineEmits(['onFetch']);
                     </QItemLabel>
                     <QItem dense>
                         <QItemLabel class="subtitle" caption>
-                            #{{ $props.subtitle ?? entity.id }}
+                            #{{ getValueFromPath(subtitle) ?? entity.id }}
                         </QItemLabel>
                     </QItem>
                 </QList>
diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue
index 253683889..11dcbee3b 100644
--- a/src/components/ui/CardSummary.vue
+++ b/src/components/ui/CardSummary.vue
@@ -187,15 +187,10 @@ function existSummary(routes) {
                 color: lighten($primary, 20%);
             }
             .q-checkbox {
-                display: flex;
-                margin-bottom: 9px;
                 & .q-checkbox__label {
-                    margin-left: 31px;
                     color: var(--vn-text-color);
                 }
                 & .q-checkbox__inner {
-                    position: absolute;
-                    left: 0;
                     color: var(--vn-label-color);
                 }
             }
diff --git a/src/components/ui/SkeletonForm.vue b/src/components/ui/SkeletonForm.vue
index 4ae4fb5bb..8d3a4b5bf 100644
--- a/src/components/ui/SkeletonForm.vue
+++ b/src/components/ui/SkeletonForm.vue
@@ -1,20 +1,14 @@
 <template>
-    <div class="q-pa-md">
-        <div class="row q-gutter-md q-mb-md">
-            <QSkeleton type="QInput" square />
-            <QSkeleton type="QInput" square />
-        </div>
-        <div class="row q-gutter-md q-mb-md">
-            <QSkeleton type="QInput" square />
-            <QSkeleton type="QInput" square />
-        </div>
-        <div class="row q-gutter-md q-mb-md">
-            <QSkeleton type="QInput" square />
-            <QSkeleton type="QInput" square />
-        </div>
-        <div class="row q-gutter-md">
-            <QSkeleton type="QBtn" />
-            <QSkeleton type="QBtn" />
-        </div>
+    <div class="row q-gutter-md q-mb-md">
+        <QSkeleton type="QInput" class="col" square />
+        <QSkeleton type="QInput" class="col" square />       
     </div>
-</template>
+    <div class="row q-gutter-md q-mb-md">
+        <QSkeleton type="QInput" class="col" square />
+        <QSkeleton type="QInput" class="col" square />       
+    </div>
+    <div class="row q-gutter-md q-mb-md">
+        <QSkeleton type="QInput" class="col" square />
+        <QSkeleton type="QInput" class="col" square />       
+    </div>
+</template>
\ No newline at end of file
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
index f6241ffe8..9b2345825 100644
--- a/src/components/ui/VnFilterPanel.vue
+++ b/src/components/ui/VnFilterPanel.vue
@@ -7,8 +7,11 @@ import toDate from 'filters/toDate';
 import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
 
 const { t } = useI18n();
-const params = defineModel({ default: {}, required: true, type: Object });
 const $props = defineProps({
+    modelValue: {
+        type: Object,
+        default: () => {},
+    },
     dataKey: {
         type: String,
         required: true,
@@ -56,7 +59,14 @@ const $props = defineProps({
 });
 
 defineExpose({ search });
-const emit = defineEmits(['refresh', 'clear', 'search', 'init', 'remove']);
+const emit = defineEmits([
+    'update:modelValue',
+    'refresh',
+    'clear',
+    'search',
+    'init',
+    'remove',
+]);
 
 const arrayData = useArrayData($props.dataKey, {
     exprBuilder: $props.exprBuilder,
@@ -65,9 +75,10 @@ const arrayData = useArrayData($props.dataKey, {
 });
 const route = useRoute();
 const store = arrayData.store;
-
+const userParams = ref({});
 onMounted(() => {
-    emit('init', { params: params.value });
+    userParams.value = $props.modelValue ?? {};
+    emit('init', { params: userParams.value });
 });
 
 function setUserParams(watchedParams) {
@@ -76,7 +87,7 @@ function setUserParams(watchedParams) {
     if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams);
     watchedParams = { ...watchedParams, ...watchedParams.filter?.where };
     delete watchedParams.filter;
-    params.value = { ...params.value, ...watchedParams };
+    userParams.value = { ...userParams.value, ...watchedParams };
 }
 
 watch(
@@ -89,18 +100,22 @@ watch(
     (val) => setUserParams(val)
 );
 
+watch(
+    () => $props.modelValue,
+    (val) => (userParams.value = val ?? {})
+);
+
 const isLoading = ref(false);
 async function search(evt) {
     if (evt && $props.disableSubmitEvent) return;
 
     store.filter.where = {};
     isLoading.value = true;
-    const filter = { ...params.value };
+    const filter = { ...userParams.value };
     store.userParamsChanged = true;
-    store.filter.skip = 0;
-    store.skip = 0;
-    const { params: newParams } = await arrayData.addFilter({ params: params.value });
-    params.value = newParams;
+    arrayData.reset(['skip', 'filter.skip', 'page']);
+    const { params: newParams } = await arrayData.addFilter({ params: userParams.value });
+    userParams.value = newParams;
 
     if (!$props.showAll && !Object.values(filter).length) store.data = [];
 
@@ -110,8 +125,9 @@ async function search(evt) {
 
 async function reload() {
     isLoading.value = true;
-    const params = Object.values(params.value).filter((param) => param);
-
+    const params = Object.values(userParams.value).filter((param) => param);
+    store.skip = 0;
+    store.page = 1;
     await arrayData.fetch({ append: false });
     if (!$props.showAll && !params.length) store.data = [];
     isLoading.value = false;
@@ -121,20 +137,19 @@ async function reload() {
 async function clearFilters() {
     isLoading.value = true;
     store.userParamsChanged = true;
-    store.filter.skip = 0;
-    store.skip = 0;
+    arrayData.reset(['skip', 'filter.skip', 'page']);
     // Filtrar los params no removibles
-    const removableFilters = Object.keys(params.value).filter((param) =>
+    const removableFilters = Object.keys(userParams.value).filter((param) =>
         $props.unremovableParams.includes(param)
     );
     const newParams = {};
     // Conservar solo los params que no son removibles
     for (const key of removableFilters) {
-        newParams[key] = params.value[key];
+        newParams[key] = userParams.value[key];
     }
-    params.value = {};
-    params.value = { ...newParams }; // Actualizar los params con los removibles
-    await arrayData.applyFilter({ params: params.value });
+    userParams.value = {};
+    userParams.value = { ...newParams }; // Actualizar los params con los removibles
+    await arrayData.applyFilter({ params: userParams.value });
 
     if (!$props.showAll) {
         store.data = [];
@@ -142,12 +157,13 @@ async function clearFilters() {
 
     isLoading.value = false;
     emit('clear');
+    emit('update:modelValue', userParams.value);
 }
 
 const tagsList = computed(() => {
     const tagList = [];
-    for (const key of Object.keys(params.value)) {
-        const value = params.value[key];
+    for (const key of Object.keys(userParams.value)) {
+        const value = userParams.value[key];
         if (value == null || ($props.hiddenTags || []).includes(key)) continue;
         tagList.push({ label: key, value });
     }
@@ -162,9 +178,10 @@ const customTags = computed(() =>
 );
 
 async function remove(key) {
-    params.value[key] = undefined;
+    userParams.value[key] = undefined;
     search();
     emit('remove', key);
+    emit('update:modelValue', userParams.value);
 }
 
 function formatValue(value) {
@@ -237,7 +254,7 @@ function formatValue(value) {
                     <slot
                         v-if="$slots.customTags"
                         name="customTags"
-                        :params="params"
+                        :params="userParams"
                         :tags="customTags"
                         :format-fn="formatValue"
                         :search-fn="search"
@@ -247,7 +264,7 @@ function formatValue(value) {
             <QSeparator />
         </QList>
         <QList dense class="list q-gutter-y-sm q-mt-sm">
-            <slot name="body" :params="params" :search-fn="search"></slot>
+            <slot name="body" :params="userParams" :search-fn="search"></slot>
         </QList>
     </QForm>
     <QInnerLoading
diff --git a/src/components/ui/VnImg.vue b/src/components/ui/VnImg.vue
index 37c1edefc..8d747963b 100644
--- a/src/components/ui/VnImg.vue
+++ b/src/components/ui/VnImg.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, onMounted } from 'vue';
+import { ref, computed } from 'vue';
 import { useSession } from 'src/composables/useSession';
 
 const $props = defineProps({
@@ -28,21 +28,29 @@ const $props = defineProps({
 const show = ref(false);
 const token = useSession().getTokenMultimedia();
 const timeStamp = ref(`timestamp=${Date.now()}`);
-const url = computed(
-    () =>
-        `/api/${$props.storage}/${$props.collection}/${$props.size}/${$props.id}/download?access_token=${token}&${timeStamp.value}`
-);
+import noImage from '/public/no-user.png';
+import { useRole } from 'src/composables/useRole';
+const url = computed(() => {
+    const isEmployee = useRole().isEmployee();
+    return isEmployee
+        ? `/api/${$props.storage}/${$props.collection}/${$props.size}/${$props.id}/download?access_token=${token}&${timeStamp.value}`
+        : noImage;
+});
 const reload = () => {
     timeStamp.value = `timestamp=${Date.now()}`;
 };
 defineExpose({
     reload,
 });
-
-onMounted(() => {});
 </script>
 <template>
-    <QImg :src="url" v-bind="$attrs" @click="show = !show" spinner-color="primary" />
+    <QImg
+        :class="{ zoomIn: $props.zoomSize }"
+        :src="url"
+        v-bind="$attrs"
+        @click="show = !show"
+        spinner-color="primary"
+    />
     <QDialog v-model="show" v-if="$props.zoomSize">
         <QImg
             :src="url"
@@ -56,7 +64,9 @@ onMounted(() => {});
 
 <style lang="scss" scoped>
 .q-img {
-    cursor: zoom-in;
+    &.zoomIn {
+        cursor: zoom-in;
+    }
     min-width: 50px;
 }
 .rounded {
diff --git a/src/components/ui/VnLv.vue b/src/components/ui/VnLv.vue
index 3220bce6a..ff65f759b 100644
--- a/src/components/ui/VnLv.vue
+++ b/src/components/ui/VnLv.vue
@@ -2,6 +2,7 @@
 import { dashIfEmpty } from 'src/filters';
 import { useI18n } from 'vue-i18n';
 import { useClipboard } from 'src/composables/useClipboard';
+import { computed } from 'vue';
 
 const $props = defineProps({
     label: { type: String, default: null },
@@ -24,52 +25,67 @@ function copyValueText() {
         },
     });
 }
+const val = computed(() => $props.value);
 </script>
-<style scoped>
-.label,
-.value {
-    white-space: pre-line;
-    word-wrap: break-word;
-}
-</style>
 <template>
     <div class="vn-label-value">
-        <div v-if="$props.label || $slots.label" class="label">
-            <slot name="label">
-                <span>{{ $props.label }}</span>
-            </slot>
-        </div>
-        <div class="value">
-            <slot name="value">
-                <span :title="$props.value">
-                    {{ $props.dash ? dashIfEmpty($props.value) : $props.value }}
-                </span>
-            </slot>
-        </div>
-        <div class="info" v-if="$props.info">
-            <QIcon name="info" class="cursor-pointer" size="xs" color="grey">
-                <QTooltip class="bg-dark text-white shadow-4" :offset="[10, 10]">
-                    {{ $props.info }}
-                </QTooltip>
-            </QIcon>
-        </div>
-        <div class="copy" v-if="$props.copy && $props.value" @click="copyValueText()">
-            <QIcon name="Content_Copy" color="primary">
-                <QTooltip>{{ t('globals.copyClipboard') }}</QTooltip>
-            </QIcon>
-        </div>
+        <QCheckbox
+            v-if="typeof value === 'boolean'"
+            v-model="val"
+            :label="label"
+            disable
+            dense
+        />
+        <template v-else>
+            <div v-if="label || $slots.label" class="label">
+                <slot name="label">
+                    <span>{{ label }}</span>
+                </slot>
+            </div>
+            <div class="value">
+                <slot name="value">
+                    <span :title="value">
+                        {{ dash ? dashIfEmpty(value) : value }}
+                    </span>
+                </slot>
+            </div>
+            <div class="info" v-if="info">
+                <QIcon name="info" class="cursor-pointer" size="xs" color="grey">
+                    <QTooltip class="bg-dark text-white shadow-4" :offset="[10, 10]">
+                        {{ info }}
+                    </QTooltip>
+                </QIcon>
+            </div>
+            <div class="copy" v-if="copy && value" @click="copyValueText()">
+                <QIcon name="Content_Copy" color="primary">
+                    <QTooltip>{{ t('globals.copyClipboard') }}</QTooltip>
+                </QIcon>
+            </div>
+        </template>
     </div>
 </template>
-
 <style lang="scss" scoped>
-.vn-label-value:hover .copy {
-    visibility: visible;
-    cursor: pointer;
+.vn-label-value {
+    &:hover .copy {
+        visibility: visible;
+        cursor: pointer;
+    }
+
+    .label,
+    .value {
+        white-space: pre-line;
+        word-wrap: break-word;
+    }
+    .copy {
+        visibility: hidden;
+    }
+
+    .info {
+        margin-left: 5px;
+    }
 }
-.copy {
-    visibility: hidden;
-}
-.info {
-    margin-left: 5px;
+
+:deep(.q-checkbox.disabled) {
+    opacity: 1 !important;
 }
 </style>
diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue
index 9a2c06b0c..8e426b471 100644
--- a/src/components/ui/VnPaginate.vue
+++ b/src/components/ui/VnPaginate.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, watch } from 'vue';
+import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useArrayData } from 'composables/useArrayData';
 
@@ -95,6 +95,8 @@ onMounted(async () => {
     mounted.value = true;
 });
 
+onBeforeUnmount(() => arrayData.reset());
+
 watch(
     () => props.data,
     () => {
@@ -118,8 +120,7 @@ const addFilter = async (filter, params) => {
 
 async function fetch(params) {
     useArrayData(props.dataKey, params);
-    store.filter.skip = 0;
-    store.skip = 0;
+    arrayData.reset(['filter.skip', 'skip']);
     await arrayData.fetch({ append: false });
     if (!store.hasMoreData) {
         isLoading.value = false;
diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue
index 4e048e238..0c7a8a3f6 100644
--- a/src/components/ui/VnSearchbar.vue
+++ b/src/components/ui/VnSearchbar.vue
@@ -103,7 +103,7 @@ async function search() {
     const staticParams = Object.entries(store.userParams).filter(
         ([key, value]) => value && (props.staticParams || []).includes(key)
     );
-    store.skip = 0;
+    arrayData.reset(['skip', 'page']);
 
     if (props.makeFetch)
         await arrayData.applyFilter({
diff --git a/src/components/ui/VnSubToolbar.vue b/src/components/ui/VnSubToolbar.vue
index 8c86c056a..df6fcbcb7 100644
--- a/src/components/ui/VnSubToolbar.vue
+++ b/src/components/ui/VnSubToolbar.vue
@@ -1,6 +1,7 @@
 <script setup>
-import { onMounted, onUnmounted, ref } from 'vue';
+import { onMounted, onBeforeUnmount, ref, nextTick } from 'vue';
 import { useStateStore } from 'stores/useStateStore';
+
 const stateStore = useStateStore();
 const actions = ref(null);
 const data = ref(null);
@@ -24,9 +25,7 @@ onMounted(() => {
     if (data.value) observer.observe(data.value, opts);
 });
 
-onUnmounted(() => {
-    stateStore.toggleSubToolbar();
-});
+onBeforeUnmount(() => stateStore.toggleSubToolbar());
 </script>
 
 <template>
diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js
index ff87842e8..0fcbbbb48 100644
--- a/src/composables/useArrayData.js
+++ b/src/composables/useArrayData.js
@@ -1,4 +1,4 @@
-import { onMounted, ref, computed } from 'vue';
+import { onMounted, computed } from 'vue';
 import { useRouter, useRoute } from 'vue-router';
 import axios from 'axios';
 import { useArrayDataStore } from 'stores/useArrayDataStore';
@@ -16,11 +16,9 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
     const router = useRouter();
     let canceller = null;
 
-    const page = ref(1);
-
     onMounted(() => {
         setOptions();
-        store.skip = 0;
+        arrayDataStore.reset(['skip']);
 
         const query = route.query;
         const searchUrl = store.searchUrl;
@@ -29,7 +27,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
             const filter = params?.filter;
             delete params.filter;
             store.userParams = { ...params, ...store.userParams };
-            store.userFilter = { ...JSON.parse(filter), ...store.userFilter };
+            store.userFilter = { ...JSON.parse(filter ?? '{}'), ...store.userFilter };
         }
     });
 
@@ -87,13 +85,17 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         }
 
         Object.assign(filter, store.userFilter, exprFilter);
-        Object.assign(store.filter, { ...filter, skip: store.skip });
-        const params = {
-            filter: JSON.stringify(store.filter),
-        };
+        let where;
+        if (filter?.where || store.filter?.where)
+            where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
+        Object.assign(filter, store.filter);
+        filter.where = where;
+        const params = { filter };
 
         Object.assign(params, userParams);
+        params.filter.skip = store.skip;
 
+        params.filter = JSON.stringify(params.filter);
         store.currentFilter = params;
         store.isLoading = true;
         const response = await axios.get(store.url, {
@@ -129,6 +131,10 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         delete store[option];
     }
 
+    function reset(opts = []) {
+        if (arrayDataStore.get(key)) arrayDataStore.reset(key, opts);
+    }
+
     function cancelRequest() {
         if (canceller) {
             canceller.abort();
@@ -146,22 +152,20 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
     }
 
     async function addFilter({ filter, params }) {
-        if (filter) store.userFilter = Object.assign(store.userFilter, filter);
+        if (filter) store.filter = filter;
 
         let userParams = { ...store.userParams, ...params };
         userParams = sanitizerParams(userParams, store?.exprBuilder);
 
         store.userParams = userParams;
-        store.skip = 0;
-        store.filter.skip = 0;
-        page.value = 1;
+        arrayDataStore.reset(['skip', 'filter.skip', 'page']);
 
         await fetch({ append: false });
         return { filter, params };
     }
 
     async function addFilterWhere(where) {
-        const storedFilter = { ...store.userFilter };
+        const storedFilter = { ...store.filter };
         if (!storedFilter?.where) storedFilter.where = {};
         where = { ...storedFilter.where, ...where };
         await addFilter({ filter: { where } });
@@ -187,8 +191,8 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
     async function loadMore() {
         if (!store.hasMoreData) return;
 
-        store.skip = store.limit * page.value;
-        page.value += 1;
+        store.skip = store.limit * store.page;
+        store.page += 1;
 
         await fetch({ append: true });
     }
@@ -244,5 +248,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         updateStateParams,
         isLoading,
         deleteOption,
+        reset,
     };
 }
diff --git a/src/composables/useRole.js b/src/composables/useRole.js
index 95b585283..d1a6d6ef3 100644
--- a/src/composables/useRole.js
+++ b/src/composables/useRole.js
@@ -27,8 +27,12 @@ export function useRole() {
 
         return false;
     }
+    function isEmployee() {
+        return hasAny(['employee']);
+    }
 
     return {
+        isEmployee,
         fetch,
         hasAny,
         state,
diff --git a/src/css/app.scss b/src/css/app.scss
index f6c873e90..27ed65534 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -5,6 +5,7 @@
 body.body--light {
     --font-color: black;
     --vn-section-color: #e0e0e0;
+    --vn-section-hover-color: #b9b9b9;
     --vn-page-color: #ffffff;
     --vn-text-color: var(--font-color);
     --vn-label-color: #5f5f5f;
@@ -19,6 +20,7 @@ body.body--light {
 body.body--dark {
     --vn-page-color: #222;
     --vn-section-color: #3d3d3d;
+    --vn-section-hover-color: #747474;
     --vn-text-color: white;
     --vn-label-color: #a8a8a8;
     --vn-accent-color: #424242;
@@ -71,8 +73,9 @@ select:-webkit-autofill {
 .bg-vn-section-color {
     background-color: var(--vn-section-color);
 }
-.bg-hover {
-    background-color: #666666;
+
+.bg-vn-hover {
+    background-color: var(--vn-section-hover-color);
 }
 
 .color-vn-label {
@@ -152,6 +155,15 @@ select:-webkit-autofill {
     color: var(--vn-label-color);
 }
 
+.disabled {
+    & .q-checkbox__label {
+        color: var(--vn-text-color);
+    }
+    & .q-checkbox__inner {
+        color: var(--vn-label-color);
+    }
+}
+
 .q-chip,
 .q-notification__message,
 .q-notification__icon {
@@ -174,8 +186,6 @@ select:-webkit-autofill {
     justify-content: center;
 }
 
-/* q-notification row items-stretch q-notification--standard bg-negative text-white */
-
 .q-card,
 .q-table,
 .q-table__bottom,
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index fbab06966..75b07801a 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -90,6 +90,7 @@ globals:
     send: Send
     code: Code
     pageTitles:
+        logIn: Login
         summary: Summary
         basicData: Basic data
         log: Logs
@@ -100,13 +101,143 @@ globals:
         modes: Modes
         zones: Zones
         zonesList: Zones
-        deliveryList: Delivery days
-        upcomingList: Upcoming deliveries
+        deliveryDays: Delivery days
+        upcomingDeliveries: Upcoming deliveries
         role: Role
         alias: Alias
         aliasUsers: Users
         subRoles: Subroles
         inheritedRoles: Inherited Roles
+        customers: Customers
+        list: List
+        webPayments: Web Payments
+        extendedList: Extended list
+        notifications: Notifications
+        defaulter: Defaulter
+        customerCreate: New customer
+        fiscalData: Fiscal data
+        billingData: Billing data
+        consignees: Consignees
+        notes: Notes
+        credits: Credits
+        greuges: Greuges
+        balance: Balance
+        recoveries: Recoveries
+        webAccess: Web access
+        sms: Sms
+        creditManagement: Credit management
+        creditContracts: Credit contracts
+        creditOpinion: Credit opinion
+        others: Others
+        samples: Samples
+        consumption: Consumption
+        mandates: Mandates
+        contacts: Contacts
+        webPayment: Web payment
+        fileManagement: File management
+        unpaid: Unpaid
+        entries: Entries
+        buys: Buys
+        dms: File management
+        entryCreate: New entry
+        latestBuys: Latest buys
+        tickets: Tickets
+        ticketCreate: New Tickets
+        boxing: Boxing
+        sale: Sale
+        claims: Claims
+        claimCreate: New claim
+        lines: Lines
+        photos: Photos
+        development: Development
+        action: Action
+        invoiceOuts: Invoice out
+        negativeBases: Negative Bases
+        globalInvoicing: Global invoicing
+        invoiceOutCreate: Create invoice out
+        shelving: Shelving
+        shelvingList: Shelving List
+        shelvingCreate: New shelving
+        invoiceIns: Invoices In
+        invoiceInCreate: Create invoice in
+        vat: VAT
+        dueDay: Due day
+        intrastat: Intrastat
+        corrective: Corrective
+        order: Orders
+        orderList: List
+        orderCreate: New order
+        catalog: Catalog
+        volume: Volume
+        workers: Workers
+        workerCreate: New worker
+        department: Department
+        pda: PDA
+        pbx: Private Branch Exchange
+        calendar: Calendar
+        timeControl: Time control
+        locker: Locker
+        wagons: Wagons
+        wagonsList: Wagons List
+        wagonCreate: Create wagon
+        wagonEdit: Edit wagon
+        typesList: Types List
+        typeCreate: Create type
+        typeEdit: Edit type
+        wagonCounter: Trolley counter
+        roadmap: Roadmap
+        stops: Stops
+        routes: Routes
+        cmrsList: CMRs list
+        RouteList: List
+        routeCreate: New route
+        RouteRoadmap: Roadmaps
+        RouteRoadmapCreate: Create roadmap
+        autonomous: Autonomous
+        suppliers: Suppliers
+        supplier: Supplier
+        labeler: Labeler
+        supplierCreate: New supplier
+        accounts: Accounts
+        addresses: Addresses
+        agencyTerm: Agency agreement
+        travel: Travels
+        extraCommunity: Extra community
+        travelCreate: New travel
+        history: Log
+        thermographs: Thermograph
+        items: Items
+        diary: Diary
+        tags: Tags
+        create: Create
+        buyRequest: Buy requests
+        fixedPrice: Fixed prices
+        wasteBreakdown: Waste breakdown
+        itemCreate: New item
+        barcode: Barcodes
+        tax: Tax
+        botanical: Botanical
+        itemTypeCreate: New item type
+        family: Item Type
+        lastEntries: Last entries
+        itemType: Item type
+        monitors: Monitors
+        dashboard: Dashboard
+        users: Users
+        createTicket: Create ticket
+        ticketAdvance: Advance tickets
+        futureTickets: Future tickets
+        purchaseRequest: Purchase request
+        weeklyTickets: Weekly tickets
+        formation: Formation
+        locations: Locations
+        warehouses: Warehouses
+        roles: Roles
+        connections: Connections
+        acls: ACLs
+        mailForwarding: Mail forwarding
+        mailAlias: Mail alias
+        privileges: Privileges
     created: Created
     worker: Worker
     now: Now
@@ -114,6 +245,7 @@ globals:
     new: New
     comment: Comment
     observations: Observations
+    goToModuleIndex: Go to module index
 errors:
     statusUnauthorized: Access denied
     statusInternalServerError: An internal server error has ocurred
@@ -132,8 +264,6 @@ login:
     loginError: Invalid username or password
     fieldRequired: This field is required
     twoFactorRequired: Two-factor verification required
-    pageTitles:
-        logIn: Login
 twoFactor:
     code: Code
     validate: Validate
@@ -148,40 +278,8 @@ verifyEmail:
         verifyEmail: Email verification
 dashboard:
     pageTitles:
-        dashboard: Dashboard
+
 customer:
-    pageTitles:
-        customers: Customers
-        list: List
-        webPayments: Web Payments
-        extendedList: Extended list
-        notifications: Notifications
-        defaulter: Defaulter
-        customerCreate: New customer
-        summary: Summary
-        basicData: Basic data
-        fiscalData: Fiscal data
-        billingData: Billing data
-        consignees: Consignees
-        notes: Notes
-        credits: Credits
-        greuges: Greuges
-        balance: Balance
-        recoveries: Recoveries
-        webAccess: Web access
-        log: Log
-        sms: Sms
-        creditManagement: Credit management
-        creditContracts: Credit contracts
-        creditOpinion: Credit opinion
-        others: Others
-        samples: Samples
-        consumption: Consumption
-        mandates: Mandates
-        contacts: Contacts
-        webPayment: Web payment
-        fileManagement: File management
-        unpaid: Unpaid
     list:
         phone: Phone
         email: Email
@@ -311,17 +409,6 @@ customer:
             hasCoreVnl: VNL core received
             hasSepaVnl: VNL B2B received
 entry:
-    pageTitles:
-        entries: Entries
-        list: List
-        summary: Summary
-        basicData: Basic data
-        buys: Buys
-        notes: Notes
-        dms: File management
-        log: Log
-        entryCreate: New entry
-        latestBuys: Latest buys
     list:
         newEntry: New entry
         landed: Landed
@@ -330,6 +417,18 @@ entry:
         booked: Booked
         confirmed: Confirmed
         ordered: Ordered
+        tableVisibleColumns:
+            id: Id
+            reference: Reference
+            created: Creation
+            supplierFk: Supplier
+            isBooked: Booked
+            isConfirmed: Confirmed
+            isOrdered: Ordered
+            companyFk: Company
+            travelFk: Travel
+            isExcludedFromAvailable: Inventory
+            isRaid: Raid
     summary:
         commission: Commission
         currency: Currency
@@ -405,34 +504,37 @@ entry:
         landed: Landed
         warehouseOut: Warehouse Out
     latestBuys:
-        picture: Picture
-        itemFk: Item ID
-        packing: Packing
-        grouping: Grouping
-        quantity: Quantity
-        size: Size
-        tags: Tags
-        type: Type
-        intrastat: Intrastat
-        origin: Origin
-        weightByPiece: Weight/Piece
-        isActive: Active
-        family: Family
-        entryFk: Entry
-        buyingValue: Buying value
-        freightValue: Freight value
-        comissionValue: Commission value
-        description: Description
-        packageValue: Package value
-        isIgnored: Is ignored
-        price2: Grouping
-        price3: Packing
-        minPrice: Min
-        ektFk: Ekt
-        weight: Weight
-        packagingFk: Package
-        packingOut: Package out
-        landing: Landing
+        tableVisibleColumns:
+            image: Picture
+            itemFk: Item ID
+            packing: Packing
+            grouping: Grouping
+            quantity: Quantity
+            size: Size
+            tags: Tags
+            type: Type
+            intrastat: Intrastat
+            origin: Origin
+            weightByPiece: Weight/Piece
+            isActive: Active
+            family: Family
+            entryFk: Entry
+            buyingValue: Buying value
+            freightValue: Freight value
+            comissionValue: Commission value
+            description: Description
+            packageValue: Package value
+            isIgnored: Is ignored
+            price2: Grouping
+            price3: Packing
+            minPrice: Min
+            ektFk: Ekt
+            weight: Weight
+            packagingFk: Package
+            packingOut: Package out
+            landing: Landing
+            isExcludedFromAvailable: Es inventory
+            isRaid: Raid
 ticket:
     pageTitles:
         tickets: Tickets
@@ -444,10 +546,14 @@ ticket:
         sms: Sms
         notes: Notes
         sale: Sale
+        volume: Volume
+        observation: Notes
         ticketAdvance: Advance tickets
         futureTickets: Future tickets
         purchaseRequest: Purchase request
         weeklyTickets: Weekly tickets
+        services: Service
+        tracking: Tracking
     list:
         nickname: Nickname
         state: State
@@ -522,18 +628,6 @@ ticket:
         warehouse: Warehouse
         agency: Agency
 claim:
-    pageTitles:
-        claims: Claims
-        list: List
-        claimCreate: New claim
-        summary: Summary
-        basicData: Basic Data
-        lines: Lines
-        photos: Photos
-        development: Development
-        log: Audit logs
-        notes: Notes
-        action: Action
     list:
         customer: Customer
         assignedTo: Assigned
@@ -597,14 +691,6 @@ claim:
         noData: 'There are no images/videos, click here or drag and drop the file'
         dragDrop: Drag and drop it here
 invoiceOut:
-    pageTitles:
-        invoiceOuts: Invoice out
-        list: List
-        negativeBases: Negative Bases
-        globalInvoicing: Global invoicing
-        invoiceOutCreate: Create invoice out
-        summary: Summary
-        basicData: Basic Data
     list:
         ref: Reference
         issued: Issued
@@ -672,13 +758,6 @@ invoiceOut:
         errors:
             downloadCsvFailed: CSV download failed
 shelving:
-    pageTitles:
-        shelving: Shelving
-        shelvingList: Shelving List
-        shelvingCreate: New shelving
-        summary: Summary
-        basicData: Basic Data
-        log: Logs
     list:
         parking: Parking
         priority: Priority
@@ -705,17 +784,6 @@ parking:
         info: You can search by parking code
         label: Search parking...
 invoiceIn:
-    pageTitles:
-        invoiceIns: Invoices In
-        list: List
-        invoiceInCreate: Create invoice in
-        summary: Summary
-        basicData: Basic data
-        vat: VAT
-        dueDay: Due day
-        intrastat: Intrastat
-        corrective: Corrective
-        log: Logs
     list:
         ref: Reference
         supplier: Supplier
@@ -766,15 +834,6 @@ invoiceIn:
         stems: Stems
         country: Country
 order:
-    pageTitles:
-        order: Orders
-        orderList: List
-        orderCreate: New order
-        summary: Summary
-        basicData: Basic Data
-        catalog: Catalog
-        volume: Volume
-        lines: Lines
     field:
         salesPersonFk: Sales Person
         clientFk: Client
@@ -850,7 +909,6 @@ worker:
         timeControl: Time control
         locker: Locker
         balance: Balance
-        formation: Formation
     list:
         name: Name
         email: Email
@@ -939,15 +997,6 @@ worker:
             credit: Have
             concept: Concept
 wagon:
-    pageTitles:
-        wagons: Wagons
-        wagonsList: Wagons List
-        wagonCreate: Create wagon
-        wagonEdit: Edit wagon
-        typesList: Types List
-        typeCreate: Create type
-        typeEdit: Edit type
-        wagonCounter: Trolley counter
     type:
         name: Name
         submit: Submit
@@ -976,20 +1025,9 @@ wagon:
         minHeightBetweenTrays: 'The minimum height between trays is '
         maxWagonHeight: 'The maximum height of the wagon is '
         uncompleteTrays: There are incomplete trays
-route/roadmap:
-    pageTitles:
-        roadmap: Roadmap
-        summary: Summary
-        basicData: Basic Data
-        stops: Stops
-roadmap:
-    pageTitles:
-        roadmap: Roadmap
-        summary: Summary
-        basicData: Basic Data
-        stops: Stops
 route:
     pageTitles:
+        agency: Agency List
         routes: Routes
         cmrsList: CMRs list
         RouteList: List
@@ -1028,28 +1066,20 @@ route:
         volume: Volume
         finished: Finished
 supplier:
-    pageTitles:
-        suppliers: Suppliers
-        supplier: Supplier
-        list: List
-        supplierCreate: New supplier
-        summary: Summary
-        basicData: Basic data
-        fiscalData: Fiscal data
-        billingData: Billing data
-        log: Log
-        accounts: Accounts
-        contacts: Contacts
-        addresses: Addresses
-        consumption: Consumption
-        agencyTerm: Agency agreement
-        dms: File management
     list:
         payMethod: Pay method
         payDeadline: Pay deadline
         payDay: Pay day
         account: Account
         newSupplier: New supplier
+        tableVisibleColumns:
+            id: Id
+            name: Name
+            nif: NIF/CIF
+            nickname: Alias
+            account: Account
+            payMethod: Pay Method
+            payDay: Pay Day
     summary:
         responsible: Responsible
         notes: Notes
@@ -1135,15 +1165,16 @@ supplier:
         date: Date
         reference: Reference
 travel:
-    pageTitles:
-        travel: Travels
-        list: List
-        summary: Summary
-        extraCommunity: Extra community
-        travelCreate: New travel
-        basicData: Basic data
-        history: Log
-        thermographs: Thermograph
+    travelList:
+        tableVisibleColumns:
+            id: Id
+            ref: Reference
+            agency: Agency
+            shipped: Shipped
+            landed: Landed
+            warehouseIn: Warehouse in
+            warehouseOut: Warehouse out
+            totalEntries: Total entries
     summary:
         confirmed: Confirmed
         entryId: Entry Id
@@ -1190,24 +1221,6 @@ travel:
         travelFileDescription: 'Travel id { travelId }'
         file: File
 item:
-    pageTitles:
-        items: Items
-        list: List
-        diary: Diary
-        tags: Tags
-        create: Create
-        buyRequest: Buy requests
-        fixedPrice: Fixed prices
-        wasteBreakdown: Waste breakdown
-        itemCreate: New item
-        barcode: Barcodes
-        tax: Tax
-        log: Log
-        botanical: Botanical
-        shelving: Shelving
-        itemTypeCreate: New item type
-        family: Item Type
-        lastEntries: Last entries
     descriptor:
         item: Item
         buyer: Buyer
@@ -1293,22 +1306,6 @@ item:
         minSalesQuantity: 'Cantidad mínima de venta'
         genus: 'Genus'
         specie: 'Specie'
-item/itemType:
-    pageTitles:
-        itemType: Item type
-        basicData: Basic data
-        summary: Summary
-monitor:
-    pageTitles:
-        monitors: Monitors
-        list: List
-zone:
-    pageTitles:
-        zones: Zones
-        zonesList: Zones
-        deliveryList: Delivery days
-        upcomingList: Upcoming deliveries
-
 components:
     topbar: {}
     itemsFilterPanel:
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index fec78d5e6..452e387c9 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -90,6 +90,7 @@ globals:
     send: Enviar
     code: Código
     pageTitles:
+        logIn: Inicio de sesión
         summary: Resumen
         basicData: Datos básicos
         log: Historial
@@ -100,14 +101,144 @@ globals:
         modes: Modos
         zones: Zonas
         zonesList: Zonas
-        deliveryList: Días de entrega
-        upcomingList: Próximos repartos
+        deliveryDays: Días de entrega
+        upcomingDeliveries: Próximos repartos
         role: Role
         alias: Alias
         aliasUsers: Usuarios
         subRoles: Subroles
         inheritedRoles: Roles heredados
+        customers: Clientes
+        customerCreate: Nuevo cliente
+        list: Listado
+        webPayments: Pagos Web
+        extendedList: Listado extendido
+        notifications: Notificaciones
+        defaulter: Morosos
+        createCustomer: Crear cliente
+        fiscalData: Datos fiscales
+        billingData: Forma de pago
+        consignees: Consignatarios
+        notes: Notas
+        credits: Créditos
+        greuges: Greuges
+        balance: Balance
+        recoveries: Recobros
+        webAccess: Acceso web
+        sms: Sms
+        creditManagement: Gestión de crédito
+        creditContracts: Contratos de crédito
+        creditOpinion: Opinión de crédito
+        others: Otros
+        samples: Plantillas
+        consumption: Consumo
+        mandates: Mandatos
+        contacts: Contactos
+        webPayment: Pago web
+        fileManagement: Gestión documental
+        unpaid: Impago
+        entries: Entradas
+        buys: Compras
+        dms: Gestión documental
+        entryCreate: Nueva entrada
+        latestBuys: Últimas compras
+        tickets: Tickets
+        ticketCreate: Nuevo ticket
+        boxing: Encajado
+        sale: Lineas del pedido
+        claims: Reclamaciones
+        claimCreate: Crear reclamación
+        lines: Líneas
+        development: Trazabilidad
+        photos: Fotos
+        action: Acción
+        invoiceOuts: Fact. emitidas
+        negativeBases: Bases Negativas
+        globalInvoicing: Facturación global
+        invoiceOutCreate: Crear fact. emitida
+        order: Cesta
+        orderList: Listado
+        orderCreate: Nueva orden
+        catalog: Catálogo
+        volume: Volumen
+        shelving: Carros
+        shelvingList: Listado de carros
+        shelvingCreate: Nuevo carro
+        invoiceIns: Fact. recibidas
+        invoiceInCreate: Crear fact. recibida
+        vat: IVA
+        labeler: Etiquetas
+        dueDay: Vencimiento
+        intrastat: Intrastat
+        corrective: Rectificativa
         workers: Trabajadores
+        workerCreate: Nuevo trabajador
+        department: Departamentos
+        pda: PDA
+        pbx: Centralita
+        calendar: Calendario
+        timeControl: Control de horario
+        locker: Taquilla
+        wagons: Vagones
+        wagonsList: Listado vagones
+        wagonCreate: Crear tipo
+        wagonEdit: Editar tipo
+        typesList: Listado tipos
+        typeCreate: Crear tipo
+        typeEdit: Editar tipo
+        wagonCounter: Contador de carros
+        roadmap: Troncales
+        stops: Paradas
+        routes: Rutas
+        cmrsList: Listado de CMRs
+        RouteList: Listado
+        routeCreate: Nueva ruta
+        RouteRoadmap: Troncales
+        RouteRoadmapCreate: Crear troncal
+        autonomous: Autónomos
+        suppliers: Proveedores
+        supplier: Proveedor
+        supplierCreate: Nuevo proveedor
+        accounts: Cuentas
+        addresses: Direcciones
+        agencyTerm: Acuerdo agencia
+        travel: Envíos
+        create: Crear
+        extraCommunity: Extra comunitarios
+        travelCreate: Nuevo envío
+        history: Historial
+        thermographs: Termógrafos
+        items: Artículos
+        diary: Histórico
+        tags: Etiquetas
+        fixedPrice: Precios fijados
+        buyRequest: Peticiones de compra
+        wasteBreakdown: Deglose de mermas
+        itemCreate: Nuevo artículo
+        tax: 'IVA'
+        botanical: 'Botánico'
+        barcode: 'Código de barras'
+        itemTypeCreate: Nueva familia
+        family: Familia
+        lastEntries: Últimas entradas
+        itemType: Familia
+        monitors: Monitores
+        dashboard: Tablón
+        users: Usuarios
+        createTicket: Crear ticket
+        ticketAdvance: Adelantar tickets
+        futureTickets: Tickets a futuro
+        purchaseRequest: Petición de compra
+        weeklyTickets: Tickets programados
+        formation: Formación
+        locations: Ubicaciones
+        warehouses: Almacenes
+        roles: Roles
+        connections: Conexiones
+        acls: ACLs
+        mailForwarding: Reenvío de correo
+        mailAlias: Alias de correo
+        privileges: Privilegios
     created: Fecha creación
     worker: Trabajador
     now: Ahora
@@ -115,6 +246,7 @@ globals:
     new: Nuevo
     comment: Comentario
     observations: Observaciones
+    goToModuleIndex: Ir al índice del módulo
 errors:
     statusUnauthorized: Acceso denegado
     statusInternalServerError: Ha ocurrido un error interno del servidor
@@ -133,8 +265,6 @@ login:
     loginError: Nombre de usuario o contraseña incorrectos
     fieldRequired: Este campo es obligatorio
     twoFactorRequired: Verificación de doble factor requerida
-    pageTitles:
-        logIn: Inicio de sesión
 twoFactor:
     code: Código
     validate: Validar
@@ -147,41 +277,8 @@ verifyEmail:
         verifyEmail: Verificación de correo
 dashboard:
     pageTitles:
-        dashboard: Tablón
+
 customer:
-    pageTitles:
-        customers: Clientes
-        customerCreate: Nuevo cliente
-        list: Listado
-        webPayments: Pagos Web
-        extendedList: Listado extendido
-        notifications: Notificaciones
-        defaulter: Morosos
-        createCustomer: Crear cliente
-        summary: Resumen
-        basicData: Datos básicos
-        fiscalData: Datos fiscales
-        billingData: Forma de pago
-        consignees: Consignatarios
-        notes: Notas
-        credits: Créditos
-        greuges: Greuges
-        balance: Balance
-        recoveries: Recobros
-        webAccess: Acceso web
-        log: Historial
-        sms: Sms
-        creditManagement: Gestión de crédito
-        creditContracts: Contratos de crédito
-        creditOpinion: Opinión de crédito
-        others: Otros
-        samples: Plantillas
-        consumption: Consumo
-        mandates: Mandatos
-        contacts: Contactos
-        webPayment: Pago web
-        fileManagement: Gestión documental
-        unpaid: Impago
     list:
         phone: Teléfono
         email: Email
@@ -310,17 +407,6 @@ customer:
             hasCoreVnl: Recibido core VNL
             hasSepaVnl: Recibido B2B VNL
 entry:
-    pageTitles:
-        entries: Entradas
-        list: Listado
-        summary: Resumen
-        basicData: Datos básicos
-        buys: Compras
-        notes: Notas
-        dms: Gestión documental
-        log: Historial
-        entryCreate: Nueva entrada
-        latestBuys: Últimas compras
     list:
         newEntry: Nueva entrada
         landed: F. entrega
@@ -329,6 +415,18 @@ entry:
         booked: Asentado
         confirmed: Confirmado
         ordered: Pedida
+        tableVisibleColumns:
+            id: Id
+            reference: Referencia
+            created: Creación
+            supplierFk: Proveedor
+            isBooked: Asentado
+            isConfirmed: Confirmado
+            isOrdered: Pedida
+            companyFk: Empresa
+            travelFk: Envio
+            isExcludedFromAvailable: Inventario
+            isRaid: Redada
     summary:
         commission: Comisión
         currency: Moneda
@@ -404,34 +502,37 @@ entry:
         landed: F. entrega
         warehouseOut: Alm. salida
     latestBuys:
-        picture: Foto
-        itemFk: ID Artículo
-        packing: Packing
-        grouping: Grouping
-        quantity: Cantidad
-        size: Medida
-        tags: Etiquetas
-        type: Tipo
-        intrastat: Intrastat
-        origin: Origen
-        weightByPiece: Peso (gramos)/tallo
-        isActive: Activo
-        family: Familia
-        entryFk: Entrada
-        buyingValue: Coste
-        freightValue: Porte
-        comissionValue: Comisión
-        description: Descripción
-        packageValue: Embalaje
-        isIgnored: Ignorado
-        price2: Grouping
-        price3: Packing
-        minPrice: Min
-        ektFk: Ekt
-        weight: Peso
-        packagingFk: Embalaje
-        packingOut: Embalaje envíos
-        landing: Llegada
+        tableVisibleColumns:
+            image: Foto
+            itemFk: Id Artículo
+            packing: packing
+            grouping: Grouping
+            quantity: Cantidad
+            size: Medida
+            tags: Etiquetas
+            type: Tipo
+            intrastat: Intrastat
+            origin: Origen
+            weightByPiece: Peso (gramos)/tallo
+            isActive: Activo
+            family: Familia
+            entryFk: Entrada
+            buyingValue: Coste
+            freightValue: Porte
+            comissionValue: Comisión
+            description: Descripción
+            packageValue: Embalaje
+            isIgnored: Ignorado
+            price2: Grouping
+            price3: Packing
+            minPrice: Min
+            ektFk: Ekt
+            weight: Peso
+            packagingFk: Embalaje
+            packingOut: Embalaje envíos
+            landing: Llegada
+            isExcludedFromAvailable: Es inventario
+            isRaid: Redada
 ticket:
     pageTitles:
         tickets: Tickets
@@ -443,10 +544,14 @@ ticket:
         sms: Sms
         notes: Notas
         sale: Lineas del pedido
+        volume: Volumen
+        observation: Notas
         ticketAdvance: Adelantar tickets
         futureTickets: Tickets a futuro
         purchaseRequest: Petición de compra
         weeklyTickets: Tickets programados
+        services: Servicios
+        tracking: Estados
     list:
         nickname: Alias
         state: Estado
@@ -521,18 +626,6 @@ ticket:
         warehouse: Almacén
         agency: Agencia
 claim:
-    pageTitles:
-        claims: Reclamaciones
-        list: Listado
-        claimCreate: Crear reclamación
-        summary: Resumen
-        basicData: Datos básicos
-        lines: Líneas
-        development: Trazabilidad
-        photos: Fotos
-        log: Historial
-        notes: Notas
-        action: Acción
     list:
         customer: Cliente
         assignedTo: Asignada a
@@ -596,14 +689,6 @@ claim:
         noData: No hay imágenes/videos haz click aquí o arrastra y suelta el archivo
         dragDrop: Arrástralo y sueltalo aquí
 invoiceOut:
-    pageTitles:
-        invoiceOuts: Fact. emitidas
-        list: Listado
-        negativeBases: Bases Negativas
-        globalInvoicing: Facturación global
-        invoiceOutCreate: Crear fact. emitida
-        summary: Resumen
-        basicData: Datos básicos
     list:
         ref: Referencia
         issued: Fecha emisión
@@ -671,15 +756,6 @@ invoiceOut:
         errors:
             downloadCsvFailed: Error al descargar CSV
 order:
-    pageTitles:
-        order: Cesta
-        orderList: Listado
-        orderCreate: Nueva orden
-        summary: Resumen
-        basicData: Datos básicos
-        catalog: Catálogo
-        volume: Volumen
-        lines: Líneas
     field:
         salesPersonFk: Comercial
         clientFk: Cliente
@@ -721,13 +797,6 @@ order:
         price: Precio
         amount: Monto
 shelving:
-    pageTitles:
-        shelving: Carros
-        shelvingList: Listado de carros
-        shelvingCreate: Nuevo carro
-        summary: Resumen
-        basicData: Datos básicos
-        log: Historial
     list:
         parking: Parking
         priority: Prioridad
@@ -753,17 +822,6 @@ parking:
         info: Puedes buscar por código de parking
         label: Buscar parking...
 invoiceIn:
-    pageTitles:
-        invoiceIns: Fact. recibidas
-        list: Listado
-        invoiceInCreate: Crear fact. recibida
-        summary: Resumen
-        basicData: Datos básicos
-        vat: IVA
-        dueDay: Vencimiento
-        intrastat: Intrastat
-        corrective: Rectificativa
-        log: Historial
     list:
         ref: Referencia
         supplier: Proveedor
@@ -846,7 +904,6 @@ worker:
         timeControl: Control de horario
         locker: Taquilla
         balance: Balance
-        formation: Formación
     list:
         name: Nombre
         email: Email
@@ -926,15 +983,6 @@ worker:
             credit: Haber
             concept: Concepto
 wagon:
-    pageTitles:
-        wagons: Vagones
-        wagonsList: Listado vagones
-        wagonCreate: Crear tipo
-        wagonEdit: Editar tipo
-        typesList: Listado tipos
-        typeCreate: Crear tipo
-        typeEdit: Editar tipo
-        wagonCounter: Contador de carros
     type:
         name: Nombre
         submit: Guardar
@@ -963,36 +1011,12 @@ wagon:
         minHeightBetweenTrays: 'La distancia mínima entre bandejas es '
         maxWagonHeight: 'La altura máxima del vagón es '
         uncompleteTrays: Hay bandejas sin completar
-route/roadmap:
-    pageTitles:
-        roadmap: Troncales
-        summary: Resumen
-        basicData: Datos básicos
-        stops: Paradas
-roadmap:
-    pageTitles:
-        roadmap: Troncales
-        summary: Resumen
-        basicData: Datos básicos
-        stops: Paradas
 route:
-    pageTitles:
-        routes: Rutas
-        cmrsList: Listado de CMRs
-        RouteList: Listado
-        routeCreate: Nueva ruta
-        basicData: Datos básicos
-        summary: Resumen
-        RouteRoadmap: Troncales
-        RouteRoadmapCreate: Crear troncal
-        tickets: Tickets
-        log: Historial
-        autonomous: Autónomos
     cmr:
         list:
             results: resultados
             cmrFk: Id CMR
-            hasCmrDms: Adjuntado en gestdoc
+            hasCmrDms: Gestdoc
             'true': Sí
             'false': 'No'
             ticketFk: Id ticket
@@ -1015,28 +1039,20 @@ route:
         volume: Volumen
         finished: Finalizada
 supplier:
-    pageTitles:
-        suppliers: Proveedores
-        supplier: Proveedor
-        list: Listado
-        supplierCreate: Nuevo proveedor
-        summary: Resumen
-        basicData: Datos básicos
-        fiscalData: Datos fiscales
-        billingData: Forma de pago
-        log: Historial
-        accounts: Cuentas
-        contacts: Contactos
-        addresses: Direcciones
-        consumption: Consumo
-        agencyTerm: Acuerdo agencia
-        dms: Gestión documental
     list:
         payMethod: Método de pago
         payDeadline: Plazo de pago
         payDay: Día de pago
         account: Cuenta
         newSupplier: Nuevo proveedor
+        tableVisibleColumns:
+            id: Id
+            name: Nombre
+            nif: NIF/CIF
+            nickname: Alias
+            account: Cuenta
+            payMethod: Método de pago
+            payDay: Dia de pago
     summary:
         responsible: Responsable
         notes: Notas
@@ -1122,16 +1138,16 @@ supplier:
         date: Fecha
         reference: Referencia
 travel:
-    pageTitles:
-        travel: Envíos
-        list: Listado
-        create: Crear
-        summary: Resumen
-        extraCommunity: Extra comunitarios
-        travelCreate: Nuevo envío
-        basicData: Datos básicos
-        history: Historial
-        thermographs: Termógrafos
+    travelList:
+        tableVisibleColumns:
+            id: Id
+            ref: Referencia
+            agency: Agencia
+            shipped: Enviado
+            landed: Llegada
+            warehouseIn: Almacén de salida
+            warehouseOut: Almacén de entrada
+            totalEntries: Total de entradas
     summary:
         confirmed: Confirmado
         entryId: Id entrada
@@ -1178,24 +1194,6 @@ travel:
         travelFileDescription: 'Id envío { travelId }'
         file: Fichero
 item:
-    pageTitles:
-        items: Artículos
-        list: Listado
-        diary: Histórico
-        tags: Etiquetas
-        fixedPrice: Precios fijados
-        buyRequest: Peticiones de compra
-        wasteBreakdown: Deglose de mermas
-        itemCreate: Nuevo artículo
-        basicData: 'Datos básicos'
-        tax: 'IVA'
-        botanical: 'Botánico'
-        barcode: 'Código de barras'
-        log: Historial
-        shelving: Carros
-        itemTypeCreate: Nueva familia
-        family: Familia
-        lastEntries: Últimas entradas
     descriptor:
         item: Artículo
         buyer: Comprador
@@ -1281,27 +1279,6 @@ item:
         achieved: 'Conseguido'
         concept: 'Concepto'
         state: 'Estado'
-item/itemType:
-    pageTitles:
-        itemType: Familia
-        basicData: Datos básicos
-        summary: Resumen
-zone:
-    pageTitles:
-        zones: Zonas
-        list: Zonas
-        deliveryList: Días de entrega
-        upcomingList: Próximos repartos
-role:
-    pageTitles:
-        zones: Zonas
-        list: Zonas
-        deliveryList: Días de entrega
-        upcomingList: Próximos repartos
-monitor:
-    pageTitles:
-        monitors: Monitores
-        list: Listado
 components:
     topbar: {}
     itemsFilterPanel:
diff --git a/src/pages/Account/Card/AccountDescriptor.vue b/src/pages/Account/Card/AccountDescriptor.vue
index ddc7c077f..d43266172 100644
--- a/src/pages/Account/Card/AccountDescriptor.vue
+++ b/src/pages/Account/Card/AccountDescriptor.vue
@@ -49,20 +49,6 @@ const hasAccount = ref(false);
         :title="data.title"
         :subtitle="data.subtitle"
     >
-        <template #header-extra-action>
-            <QBtn
-                round
-                flat
-                size="md"
-                color="white"
-                icon="face"
-                :to="{ name: 'AccountList' }"
-            >
-                <QTooltip>
-                    {{ t('Go to module index') }}
-                </QTooltip>
-            </QBtn>
-        </template>
         <template #menu>
             <AccountDescriptorMenu :has-account="hasAccount" />
         </template>
diff --git a/src/pages/Account/Role/Card/RoleDescriptor.vue b/src/pages/Account/Role/Card/RoleDescriptor.vue
index 89712b0b9..91d733714 100644
--- a/src/pages/Account/Role/Card/RoleDescriptor.vue
+++ b/src/pages/Account/Role/Card/RoleDescriptor.vue
@@ -15,6 +15,10 @@ const $props = defineProps({
         required: false,
         default: null,
     },
+    summary: {
+        type: Object,
+        default: null,
+    },
 });
 
 const route = useRoute();
@@ -60,14 +64,14 @@ const removeRole = () => {
 
 <template>
     <CardDescriptor
-        ref="descriptor"
-        :url="`VnRoles`"
+        :url="`VnRoles/${entityId}`"
         :filter="filter"
         module="Role"
         @on-fetch="setData"
         data-key="accountData"
         :title="data.title"
         :subtitle="data.subtitle"
+        :summary="$props.summary"
     >
         <template #menu>
             <QItem v-ripple clickable @click="removeRole()">
diff --git a/src/pages/Account/Role/Card/RoleDescriptorProxy.vue b/src/pages/Account/Role/Card/RoleDescriptorProxy.vue
new file mode 100644
index 000000000..9714a3ae6
--- /dev/null
+++ b/src/pages/Account/Role/Card/RoleDescriptorProxy.vue
@@ -0,0 +1,17 @@
+<script setup>
+import RoleDescriptor from './RoleDescriptor.vue';
+import RoleSummary from './RoleSummary.vue';
+
+const $props = defineProps({
+    id: {
+        type: Number,
+        required: true,
+    },
+});
+</script>
+
+<template>
+    <QPopupProxy>
+        <RoleDescriptor v-if="$props.id" :id="$props.id" :summary="RoleSummary" />
+    </QPopupProxy>
+</template>
diff --git a/src/pages/Account/Role/Card/RoleSummary.vue b/src/pages/Account/Role/Card/RoleSummary.vue
index d404fa2f0..76c72e947 100644
--- a/src/pages/Account/Role/Card/RoleSummary.vue
+++ b/src/pages/Account/Role/Card/RoleSummary.vue
@@ -30,6 +30,7 @@ const filter = {
         :url="`VnRoles`"
         :filter="filter"
         @on-fetch="(data) => (role = data)"
+        data-key="RoleSummary"
     >
         <template #header> {{ role.id }} - {{ role.name }} </template>
         <template #body>
diff --git a/src/pages/Agency/AgencyList.vue b/src/pages/Agency/AgencyList.vue
deleted file mode 100644
index ec6506ba0..000000000
--- a/src/pages/Agency/AgencyList.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-<script setup>
-import VnPaginate from 'src/components/ui/VnPaginate.vue';
-import CardList from 'src/components/ui/CardList.vue';
-import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
-import { useRouter } from 'vue-router';
-import { useI18n } from 'vue-i18n';
-
-const { t } = useI18n();
-const router = useRouter();
-function navigate(id) {
-    router.push({ path: `/agency/${id}` });
-}
-function exprBuilder(param, value) {
-    if (!value) return;
-    if (param !== 'search') return;
-
-    if (!isNaN(value)) return { id: value };
-
-    return { name: { like: `%${value}%` } };
-}
-</script>
-<template>
-    <VnSearchbar
-        :info="t('You can search by name')"
-        :label="t('Search agency')"
-        data-key="AgencyList"
-        url="Agencies"
-    />
-    <QPage class="column items-center q-pa-md">
-        <div class="vn-card-list">
-            <VnPaginate
-                data-key="AgencyList"
-                url="Agencies"
-                order="name"
-                :expr-builder="exprBuilder"
-            >
-                <template #body="{ rows }">
-                    <CardList
-                        :id="row.id"
-                        :key="row.id"
-                        :title="row.name"
-                        @click="navigate(row.id)"
-                        v-for="row of rows"
-                    >
-                        <template #list-items>
-                            <QCheckbox
-                                :label="t('isOwn')"
-                                v-model="row.isOwn"
-                                :disable="true"
-                            />
-                            <QCheckbox
-                                :label="t('isAnyVolumeAllowed')"
-                                v-model="row.isAnyVolumeAllowed"
-                                :disable="true"
-                            />
-                        </template>
-                    </CardList>
-                </template>
-            </VnPaginate>
-        </div>
-    </QPage>
-</template>
-<i18n>
-    es: 
-        isOwn: Tiene propietario
-        isAnyVolumeAllowed: Permite cualquier volumen
-        Search agency: Buscar agencia
-        You can search by name: Puedes buscar por nombre
-    en:
-        isOwn: Has owner
-        isAnyVolumeAllowed: Allows any volume
-</i18n>
diff --git a/src/pages/Claim/Card/ClaimDescriptor.vue b/src/pages/Claim/Card/ClaimDescriptor.vue
index 5336c4427..ecf16f4c6 100644
--- a/src/pages/Claim/Card/ClaimDescriptor.vue
+++ b/src/pages/Claim/Card/ClaimDescriptor.vue
@@ -56,8 +56,7 @@ onMounted(async () => {
         :url="`Claims/${entityId}`"
         :filter="filter"
         module="Claim"
-        :title="data.title"
-        :subtitle="data.subtitle"
+        title="client.name"
         @on-fetch="setData"
         data-key="Claim"
     >
diff --git a/src/pages/Claim/Card/ClaimSummary.vue b/src/pages/Claim/Card/ClaimSummary.vue
index 1a2d3c251..55d59822d 100644
--- a/src/pages/Claim/Card/ClaimSummary.vue
+++ b/src/pages/Claim/Card/ClaimSummary.vue
@@ -224,7 +224,7 @@ async function changeState(value) {
             <QCard class="vn-one">
                 <VnTitle
                     :url="`#/claim/${entityId}/basic-data`"
-                    :text="t('claim.pageTitles.basicData')"
+                    :text="t('globals.pageTitles.basicData')"
                 />
                 <VnLv
                     :label="t('claim.summary.created')"
diff --git a/src/pages/Customer/Card/CustomerBasicData.vue b/src/pages/Customer/Card/CustomerBasicData.vue
index 805795522..6f37544e8 100644
--- a/src/pages/Customer/Card/CustomerBasicData.vue
+++ b/src/pages/Customer/Card/CustomerBasicData.vue
@@ -69,7 +69,7 @@ const filterOptions = {
         <template #form="{ data, validate, filter }">
             <VnRow class="row q-gutter-md q-mb-md">
                 <VnInput
-                    :label="t('Comercial name')"
+                    :label="t('globals.name')"
                     :rules="validate('client.socialName')"
                     autofocus
                     clearable
diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue
index 2d3b17bc9..5e688076a 100644
--- a/src/pages/Customer/Card/CustomerDescriptor.vue
+++ b/src/pages/Customer/Card/CustomerDescriptor.vue
@@ -45,20 +45,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.name, entity
         :summary="$props.summary"
         data-key="customerData"
     >
-        <template #header-extra-action>
-            <QBtn
-                round
-                flat
-                size="sm"
-                icon="vn:Person"
-                color="white"
-                :to="{ name: 'CustomerList' }"
-            >
-                <QTooltip>
-                    {{ t('Go to module index') }}
-                </QTooltip>
-            </QBtn>
-        </template>
         <template #menu="{ entity }">
             <CustomerDescriptorMenu :customer="entity" />
         </template>
diff --git a/src/pages/Customer/Card/CustomerGreuges.vue b/src/pages/Customer/Card/CustomerGreuges.vue
index 0dcb3a3a9..8cca2ef23 100644
--- a/src/pages/Customer/Card/CustomerGreuges.vue
+++ b/src/pages/Customer/Card/CustomerGreuges.vue
@@ -13,7 +13,7 @@ const { t } = useI18n();
 const route = useRoute();
 const stateStore = computed(() => useStateStore());
 const rows = ref([]);
-const totalAmount = ref(0);
+const totalAmount = ref();
 
 const filter = {
     include: [
@@ -75,7 +75,7 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        field: (value) => value.user.name,
+        field: (value) => value?.user?.name,
         label: t('Created by'),
         name: 'createdBy',
     },
@@ -87,7 +87,7 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        field: (value) => value.greugeType.name,
+        field: (value) => value?.greugeType?.name,
         label: t('Type'),
         name: 'type',
     },
@@ -108,26 +108,9 @@ const setRows = (data) => {
 
 <template>
     <FetchData :filter="filter" @on-fetch="setRows" auto-load url="greuges" />
-    <template v-if="stateStore.isHeaderMounted()">
-        <Teleport to="#actions-append">
-            <div class="row q-gutter-x-sm">
-                <QBtn
-                    flat
-                    @click="stateStore.toggleRightDrawer()"
-                    round
-                    dense
-                    icon="menu"
-                >
-                    <QTooltip bottom anchor="bottom right">
-                        {{ t('globals.collapseMenu') }}
-                    </QTooltip>
-                </QBtn>
-            </div>
-        </Teleport>
-    </template>
     <QDrawer v-model="stateStore.rightDrawer" side="right" :width="300" show-if-above>
         <QCard class="full-width q-pa-sm">
-            <h6 class="flex justify-end q-my-lg q-pr-lg" v-if="totalAmount">
+            <h6 class="flex justify-end q-my-lg q-pr-lg" v-if="totalAmount !== undefined">
                 <span class="color-vn-label q-mr-md">{{ t('Total') }}:</span>
                 {{ toCurrency(totalAmount) }}
             </h6>
diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue
index 1190f22fe..86de5217e 100644
--- a/src/pages/Customer/Card/CustomerSummary.vue
+++ b/src/pages/Customer/Card/CustomerSummary.vue
@@ -73,7 +73,7 @@ const creditWarning = computed(() => {
                     :text="t('customer.summary.basicData')"
                 />
                 <VnLv :label="t('customer.summary.customerId')" :value="entity.id" />
-                <VnLv :label="t('customer.summary.name')" :value="entity.name" />
+                <VnLv :label="t('globals.name')" :value="entity.name" />
                 <VnLv :label="t('customer.summary.contact')" :value="entity.contact" />
                 <VnLv :value="entity.phone">
                     <template #label>
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index ccd53e8b2..58aaf2bf0 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -38,7 +38,7 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        label: t('customer.extendedList.tableVisibleColumns.name'),
+        label: t('globals.name'),
         name: 'name',
         isTitle: true,
         create: true,
@@ -65,6 +65,8 @@ const columns = computed(() => [
             url: 'Workers/activeWithInheritedRole',
             fields: ['id', 'name'],
             where: { role: 'salesPerson' },
+            optionFilter: 'firstName',
+            useLike: false,
         },
         create: true,
         columnField: {
@@ -406,6 +408,7 @@ function handleLocation(data, location) {
         default-mode="table"
         redirect="customer"
         auto-load
+        :disable-option="{ card: true }"
     >
         <template #more-create-dialog="{ data }">
             <VnLocation
diff --git a/src/pages/Customer/Defaulter/CustomerDefaulter.vue b/src/pages/Customer/Defaulter/CustomerDefaulter.vue
index 06732b944..693b016fb 100644
--- a/src/pages/Customer/Defaulter/CustomerDefaulter.vue
+++ b/src/pages/Customer/Defaulter/CustomerDefaulter.vue
@@ -91,7 +91,6 @@ const tableColumnComponents = {
         props: (prop) => ({
             disable: true,
             'model-value': prop.value,
-            class: 'disabled-checkbox',
         }),
         event: () => {},
     },
diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue
index 3c925ead6..a55ad67cd 100644
--- a/src/pages/Entry/Card/EntryDescriptor.vue
+++ b/src/pages/Entry/Card/EntryDescriptor.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, watch } from 'vue';
+import { ref, computed, watch, onMounted } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
@@ -10,6 +10,7 @@ import useCardDescription from 'src/composables/useCardDescription';
 import { useState } from 'src/composables/useState';
 import { toDate } from 'src/filters';
 import { usePrintService } from 'composables/usePrintService';
+import { getUrl } from 'src/composables/getUrl';
 
 const $props = defineProps({
     id: {
@@ -17,10 +18,6 @@ const $props = defineProps({
         required: false,
         default: null,
     },
-    summary: {
-        type: Object,
-        default: null,
-    },
 });
 
 const route = useRoute();
@@ -28,6 +25,7 @@ const { t } = useI18n();
 const { openReport } = usePrintService();
 const state = useState();
 const entryDescriptorRef = ref(null);
+const url = ref();
 
 const entryFilter = {
     include: [
@@ -69,6 +67,9 @@ const entryFilter = {
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+onMounted(async () => {
+    url.value = await getUrl('');
+});
 
 const data = ref(useCardDescription());
 const setData = (entity) =>
@@ -114,6 +115,7 @@ watch;
         :subtitle="data.subtitle"
         @on-fetch="setData"
         data-key="entry"
+        :summary="$attrs"
     >
         <template #menu="{ entity }">
             <QItem v-ripple clickable @click="showEntryReport(entity)">
diff --git a/src/pages/Entry/Card/EntryDescriptorProxy.vue b/src/pages/Entry/Card/EntryDescriptorProxy.vue
index e1c05f1ac..17b542ec1 100644
--- a/src/pages/Entry/Card/EntryDescriptorProxy.vue
+++ b/src/pages/Entry/Card/EntryDescriptorProxy.vue
@@ -1,5 +1,6 @@
 <script setup>
 import EntryDescriptor from './EntryDescriptor.vue';
+import EntrySummary from './EntrySummary.vue';
 
 const $props = defineProps({
     id: {
@@ -11,6 +12,6 @@ const $props = defineProps({
 
 <template>
     <QPopupProxy>
-        <EntryDescriptor v-if="$props.id" :id="$props.id" />
+        <EntryDescriptor v-if="$props.id" :id="$props.id" :summary="EntrySummary" />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index d08b7eed2..7b92b29d4 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -11,8 +11,6 @@ import { toDate, toCurrency } from 'src/filters';
 import { getUrl } from 'src/composables/getUrl';
 import axios from 'axios';
 
-onUpdated(() => summaryRef.value.fetch());
-
 const route = useRoute();
 const { t } = useI18n();
 
diff --git a/src/pages/Entry/EntryBuysTableDialog.vue b/src/pages/Entry/EntryBuysTableDialog.vue
new file mode 100644
index 000000000..c2b04c291
--- /dev/null
+++ b/src/pages/Entry/EntryBuysTableDialog.vue
@@ -0,0 +1,120 @@
+<script setup>
+import { computed } from 'vue';
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import { QBtn } from 'quasar';
+
+import VnPaginate from 'src/components/ui/VnPaginate.vue';
+import { usePrintService } from 'composables/usePrintService';
+const { openReport } = usePrintService();
+
+const route = useRoute();
+const { t } = useI18n();
+const $props = defineProps({
+    id: {
+        type: String,
+        required: false,
+        default: null,
+    },
+});
+const entityId = computed(() => $props.id || route.params.id);
+
+const entriesTableColumns = computed(() => [
+    {
+        align: 'left',
+        name: 'itemFk',
+        field: 'itemFk',
+        label: t('globals.id'),
+    },
+    {
+        align: 'left',
+        name: 'item',
+        label: t('entry.summary.item'),
+        field: (row) => row.item.name,
+    },
+    {
+        align: 'left',
+        name: 'packagingFk',
+        label: t('entry.summary.package'),
+        field: 'packagingFk',
+    },
+    {
+        align: 'left',
+        name: 'stickers',
+        label: t('entry.summary.stickers'),
+        field: 'stickers',
+    },
+    {
+        align: 'left',
+        name: 'packing',
+        label: t('entry.summary.packing'),
+        field: 'packing',
+    },
+    {
+        align: 'left',
+        name: 'grouping',
+        label: t('entry.summary.grouping'),
+        field: 'grouping',
+    },
+]);
+</script>
+
+<template>
+    <QDialog ref="dialogRef">
+        <QCard style="min-width: 800px">
+            <QCardSection class="row items-center q-pb-none">
+                <QAvatar
+                    :icon="icon"
+                    color="primary"
+                    text-color="white"
+                    size="xl"
+                    v-if="icon"
+                />
+                <span class="text-h6 text-grey">{{ title }}</span>
+                <QSpace />
+                <QBtn icon="close" :disable="isLoading" flat round dense v-close-popup />
+            </QCardSection>
+            <QCardActions align="right">
+                <QBtn
+                    :label="t('Print buys')"
+                    color="primary"
+                    icon="print"
+                    :loading="isLoading"
+                    @click="openReport(`Entries/${entityId}/buy-label`)"
+                    unelevated
+                    autofocus
+                />
+            </QCardActions>
+            <QCardSection class="row items-center">
+                <VnPaginate
+                    ref="entryBuysPaginateRef"
+                    :limit="0"
+                    data-key="EntryBuys"
+                    :url="`Entries/${entityId}/getBuys`"
+                    auto-load
+                >
+                    <template #body="{ rows }">
+                        <QTable
+                            :rows="rows"
+                            :columns="entriesTableColumns"
+                            row-key="id"
+                            flat
+                            dense
+                            class="q-ml-lg"
+                            :grid="$q.screen.lt.md"
+                            :no-data-label="t('globals.noResults')"
+                        >
+                            <template #body="props">
+                                <QTr>
+                                    <QTd v-for="col in props.cols" :key="col.name">
+                                        {{ col.value }}
+                                    </QTd>
+                                </QTr>
+                            </template>
+                        </QTable>
+                    </template>
+                </VnPaginate>
+            </QCardSection>
+        </QCard>
+    </QDialog>
+</template>
diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue
index 5da3309d8..dca32c08d 100644
--- a/src/pages/Entry/EntryLatestBuys.vue
+++ b/src/pages/Entry/EntryLatestBuys.vue
@@ -1,759 +1,200 @@
 <script setup>
 import { onMounted, ref, computed, reactive, onUnmounted } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useRouter } from 'vue-router';
-
-import FetchData from 'components/FetchData.vue';
-import FetchedTags from 'components/ui/FetchedTags.vue';
-import EntryDescriptorProxy from './Card/EntryDescriptorProxy.vue';
-import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
-import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import EntryLatestBuysFilter from './EntryLatestBuysFilter.vue';
-import ItemDescriptorProxy from '../Item/Card/ItemDescriptorProxy.vue';
-import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
-
-import { useStateStore } from 'stores/useStateStore';
-import { toDate, toCurrency } from 'src/filters';
-// import { useSession } from 'composables/useSession';
-import { dashIfEmpty } from 'src/filters';
-import { useArrayData } from 'composables/useArrayData';
 import RightMenu from 'src/components/common/RightMenu.vue';
-import VnImg from 'src/components/ui/VnImg.vue';
-
-const router = useRouter();
-// const { getTokenMultimedia } = useSession();
-// const token = getTokenMultimedia();
+import VnTable from 'components/VnTable/VnTable.vue';
+import EntryLatestBuysFilter from './EntryLatestBuysFilter.vue';
+import { useStateStore } from 'stores/useStateStore';
 const stateStore = useStateStore();
 const { t } = useI18n();
+import { toDate } from 'src/filters';
+import VnImg from 'src/components/ui/VnImg.vue';
+import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 
-const rowsFetchDataRef = ref(null);
-const itemTypesOptions = ref([]);
-const originsOptions = ref([]);
-const itemFamiliesOptions = ref([]);
-const intrastatOptions = ref([]);
-const packagingsOptions = ref([]);
-const editTableCellDialogRef = ref(null);
-const visibleColumns = ref([]);
-const allColumnNames = ref([]);
-
-const exprBuilder = (param, value) => {
-    switch (param) {
-        case 'id':
-        case 'size':
-        case 'weightByPiece':
-        case 'isActive':
-        case 'family':
-        case 'minPrice':
-        case 'packingOut':
-            return { [`i.${param}`]: value };
-        case 'name':
-        case 'description':
-            return { [`i.${param}`]: { like: `%${value}%` } };
-        case 'code':
-            return { 'it.code': value };
-        case 'intrastat':
-            return { 'intr.description': value };
-        case 'origin':
-            return { 'ori.code': value };
-        case 'landing':
-            return { [`lb.${param}`]: value };
-        case 'packing':
-        case 'grouping':
-        case 'quantity':
-        case 'entryFk':
-        case 'buyingValue':
-        case 'freightValue':
-        case 'comissionValue':
-        case 'packageValue':
-        case 'isIgnored':
-        case 'price2':
-        case 'price3':
-        case 'ektFk':
-        case 'weight':
-        case 'packagingFk':
-            return { [`b.${param}`]: value };
-    }
-};
-
-const params = reactive({});
-const arrayData = useArrayData('EntryLatestBuys', {
-    url: 'Buys/latestBuysFilter',
-    order: ['itemFk DESC'],
-    exprBuilder: exprBuilder,
-});
-const store = arrayData.store;
-const rows = computed(() => store.data);
-const rowsSelected = ref([]);
-
-const getInputEvents = (col) => {
-    return col.columnFilter.type === 'select'
-        ? { 'update:modelValue': () => applyColumnFilter(col) }
-        : {
-              'keyup.enter': () => applyColumnFilter(col),
-          };
-};
-
-const columns = computed(() => [
+const columns = [
     {
-        label: t('entry.latestBuys.picture'),
-        name: 'picture',
-        align: 'left',
+        align: 'center',
+        label: t('entry.latestBuys.tableVisibleColumns.image'),
+        name: 'image',
+        columnField: {
+            component: VnImg,
+            attrs: (id) => {
+                return {
+                    id,
+                    width: '50px',
+                };
+            },
+        },
+        columnFilter: false,
     },
     {
-        label: t('entry.latestBuys.itemFk'),
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.itemFk'),
         name: 'itemFk',
-        field: 'itemFk',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
+        isTitle: true,
     },
     {
-        label: t('entry.latestBuys.packing'),
-        field: 'packing',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.packing'),
         name: 'packing',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => dashIfEmpty(val),
     },
     {
-        label: t('entry.latestBuys.grouping'),
-        field: 'grouping',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.grouping'),
         name: 'grouping',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => dashIfEmpty(val),
     },
     {
-        label: t('entry.latestBuys.quantity'),
-        field: 'quantity',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.quantity'),
         name: 'quantity',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.description'),
-        field: 'description',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.description'),
         name: 'description',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => dashIfEmpty(val),
     },
     {
-        label: t('entry.latestBuys.size'),
-        field: 'size',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.size'),
         name: 'size',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.tags'),
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.tags'),
         name: 'tags',
-        align: 'left',
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.type'),
-        field: 'code',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.type'),
         name: 'type',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                options: itemTypesOptions.value,
-                'option-value': 'code',
-                'option-label': 'code',
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.intrastat'),
-        field: 'intrastat',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.intrastat'),
         name: 'intrastat',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                options: intrastatOptions.value,
-                'option-value': 'description',
-                'option-label': 'description',
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.origin'),
-        field: 'origin',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.origin'),
         name: 'origin',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                options: originsOptions.value,
-                'option-value': 'code',
-                'option-label': 'code',
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.weightByPiece'),
-        field: 'weightByPiece',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.weightByPiece'),
         name: 'weightByPiece',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-
-        format: (val) => dashIfEmpty(val),
     },
     {
-        label: t('entry.latestBuys.isActive'),
-        field: 'isActive',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.isActive'),
         name: 'isActive',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.family'),
-        field: 'family',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.family'),
         name: 'family',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                options: itemFamiliesOptions.value,
-                'option-value': 'code',
-                'option-label': 'code',
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.entryFk'),
-        field: 'entryFk',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.entryFk'),
         name: 'entryFk',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.buyingValue'),
-        field: 'buyingValue',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.buyingValue'),
         name: 'buyingValue',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => toCurrency(val),
     },
     {
-        label: t('entry.latestBuys.freightValue'),
-        field: 'freightValue',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.freightValue'),
         name: 'freightValue',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => toCurrency(val),
     },
     {
-        label: t('entry.latestBuys.comissionValue'),
-        field: 'comissionValue',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.comissionValue'),
         name: 'comissionValue',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => toCurrency(val),
     },
     {
-        label: t('entry.latestBuys.packageValue'),
-        field: 'packageValue',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.packageValue'),
         name: 'packageValue',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => toCurrency(val),
     },
     {
-        label: t('entry.latestBuys.isIgnored'),
-        field: 'isIgnored',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.isIgnored'),
         name: 'isIgnored',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.price2'),
-        field: 'price2',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.price2'),
         name: 'price2',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-
-        format: (val) => toCurrency(val),
     },
     {
-        label: t('entry.latestBuys.price3'),
-        field: 'price3',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.price3'),
         name: 'price3',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => toCurrency(val),
     },
     {
-        label: t('entry.latestBuys.minPrice'),
-        field: 'minPrice',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.minPrice'),
         name: 'minPrice',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => toCurrency(val),
     },
     {
-        label: t('entry.latestBuys.ektFk'),
-        field: 'ektFk',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.ektFk'),
         name: 'ektFk',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => dashIfEmpty(val),
     },
     {
-        label: t('entry.latestBuys.weight'),
-        field: 'weight',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.weight'),
         name: 'weight',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.packagingFk'),
-        field: 'packagingFk',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.packagingFk'),
         name: 'packagingFk',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                options: packagingsOptions.value,
-                'option-value': 'id',
-                'option-label': 'id',
-                dense: true,
-            },
-        },
     },
     {
-        label: t('entry.latestBuys.packingOut'),
-        field: 'packingOut',
+        align: 'left',
+        label: t('entry.latestBuys.tableVisibleColumns.packingOut'),
         name: 'packingOut',
-        align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => dashIfEmpty(val),
     },
     {
-        label: t('entry.latestBuys.landing'),
-        field: 'landing',
-        name: 'landing',
         align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
+        label: t('entry.latestBuys.tableVisibleColumns.landing'),
+        name: 'landing',
+        component: 'date',
+        columnField: {
+            component: null,
         },
-        format: (val) => toDate(val),
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landing)),
     },
-]);
-
-const editTableCellFormFieldsOptions = [
-    { field: 'packing', label: t('entry.latestBuys.packing') },
-    { field: 'grouping', label: t('entry.latestBuys.grouping') },
-    { field: 'packageValue', label: t('entry.latestBuys.packageValue') },
-    { field: 'weight', label: t('entry.latestBuys.weight') },
-    { field: 'description', label: t('globals.description') },
-    { field: 'size', label: t('entry.latestBuys.size') },
-    { field: 'weightByPiece', label: t('entry.latestBuys.weightByPiece') },
-    { field: 'packingOut', label: t('entry.latestBuys.packingOut') },
-    { field: 'landing', label: t('entry.latestBuys.landing') },
 ];
 
-const openEditTableCellDialog = () => {
-    editTableCellDialogRef.value.show();
-};
-
-const onEditCellDataSaved = async () => {
-    rowsSelected.value = [];
-    await rowsFetchDataRef.value.fetch();
-};
-
-const redirectToEntryBuys = (entryFk) => {
-    router.push({ name: 'EntryBuys', params: { id: entryFk } });
-};
-
-const applyColumnFilter = async (col) => {
-    try {
-        params[col.field] = col.columnFilter.filterValue;
-        await arrayData.addFilter({ params });
-    } catch (err) {
-        console.error('Error applying column filter', err);
-    }
-};
-
 onMounted(async () => {
     stateStore.rightDrawer = true;
-    const filteredColumns = columns.value.filter((col) => col.name !== 'picture');
-    allColumnNames.value = filteredColumns.map((col) => col.name);
-    await arrayData.fetch({ append: false });
 });
 
 onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
-    <FetchData
-        url="ItemTypes"
-        :filter="{ fields: ['code'], order: 'code ASC', limit: 30 }"
-        auto-load
-        @on-fetch="(data) => (itemTypesOptions = data)"
-    />
-    <FetchData
-        url="Origins"
-        :filter="{ fields: ['code'], order: 'code ASC', limit: 30 }"
-        auto-load
-        @on-fetch="(data) => (originsOptions = data)"
-    />
-    <FetchData
-        url="ItemFamilies"
-        :filter="{ fields: ['code'], order: 'code ASC', limit: 30 }"
-        auto-load
-        @on-fetch="(data) => (itemFamiliesOptions = data)"
-    />
-    <FetchData
-        url="Packagings"
-        :filter="{ fields: ['id'], order: 'id ASC', limit: 30 }"
-        auto-load
-        @on-fetch="(data) => (packagingsOptions = data)"
-    />
-    <FetchData
-        url="Intrastats"
-        :filter="{ fields: ['description'], order: 'description ASC', limit: 30 }"
-        auto-load
-        @on-fetch="(data) => (intrastatOptions = data)"
-    />
-    <VnSubToolbar>
-        <template #st-data>
-            <TableVisibleColumns
-                :all-columns="allColumnNames"
-                table-code="latestBuys"
-                labels-traductions-path="entry.latestBuys"
-                @on-config-saved="visibleColumns = ['picture', ...$event]"
-            />
-        </template>
-    </VnSubToolbar>
     <RightMenu>
         <template #right-panel>
-            <EntryLatestBuysFilter data-key="EntryLatestBuys" />
+            <EntryLatestBuysFilter data-key="LatestBuys" />
         </template>
     </RightMenu>
-    <Teleport to="#actions-append">
-        <div class="row q-gutter-x-sm">
-            <QBtn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
-                <QTooltip bottom anchor="bottom right">
-                    {{ t('globals.collapseMenu') }}
-                </QTooltip>
-            </QBtn>
-        </div>
-    </Teleport>
-    <QPage class="column items-center q-pa-md">
-        <QTable
-            :rows="rows"
-            :columns="columns"
-            selection="multiple"
-            row-key="id"
-            class="full-width q-mt-md"
-            :visible-columns="visibleColumns"
-            v-model:selected="rowsSelected"
-            :no-data-label="t('globals.noResults')"
-            @row-click="(_, row) => redirectToEntryBuys(row.entryFk)"
-        >
-            <template #top-row="{ cols }">
-                <QTr>
-                    <QTd />
-                    <QTd
-                        v-for="(col, index) in cols"
-                        :key="index"
-                        style="max-width: 100px"
-                    >
-                        <component
-                            :is="col.columnFilter.component"
-                            v-if="col.name !== 'picture'"
-                            v-model="col.columnFilter.filterValue"
-                            v-bind="col.columnFilter.attrs"
-                            v-on="col.columnFilter.event(col)"
-                            dense
-                        />
-                    </QTd>
-                </QTr>
-            </template>
-            <template #body-cell-picture="{ row }">
-                <QTd>
-                    <VnImg :id="row.itemFk" size="50x50" class="image" />
-                </QTd>
-            </template>
-            <template #body-cell-itemFk="{ row }">
-                <QTd @click.stop>
-                    <QBtn flat color="primary">
-                        {{ row.itemFk }}
-                    </QBtn>
-                    <ItemDescriptorProxy :id="row.itemFk" />
-                </QTd>
-            </template>
-            <template #body-cell-tags="{ row }">
-                <QTd>
-                    <FetchedTags :item="row" :max-length="6" />
-                </QTd>
-            </template>
-            <template #body-cell-entryFk="{ row }">
-                <QTd @click.stop>
-                    <QBtn flat color="primary">
-                        <EntryDescriptorProxy :id="row.entryFk" />
-                        {{ row.entryFk }}
-                    </QBtn>
-                </QTd>
-            </template>
-            <template #body-cell-isIgnored="{ row }">
-                <QTd>
-                    <QIcon
-                        :name="row.isIgnored ? `check` : `close`"
-                        :color="row.isIgnored ? `positive` : `negative`"
-                        size="sm"
-                    />
-                </QTd>
-            </template>
-            <template #body-cell-isActive="{ row }">
-                <QTd>
-                    <QIcon
-                        :name="row.isActive ? `check` : `close`"
-                        :color="row.isActive ? `positive` : `negative`"
-                        size="sm"
-                    />
-                </QTd>
-            </template>
-        </QTable>
-        <QPageSticky v-if="rowsSelected.length > 0" :offset="[20, 20]">
-            <QBtn @click="openEditTableCellDialog()" color="primary" fab icon="edit" />
-            <QTooltip>
-                {{ t('Edit buy(s)') }}
-            </QTooltip>
-        </QPageSticky>
-        <QDialog ref="editTableCellDialogRef">
-            <EditTableCellValueForm
-                edit-url="Buys/editLatestBuys"
-                :rows="rowsSelected"
-                :fields-options="editTableCellFormFieldsOptions"
-                @on-data-saved="onEditCellDataSaved()"
-            />
-        </QDialog>
-    </QPage>
+    <VnSubToolbar />
+    <VnTable
+        ref="tableRef"
+        data-key="LatestBuys"
+        url="Buys/latestBuysFilter"
+        order="id DESC"
+        :columns="columns"
+        redirect="entry"
+        default-mode="table"
+        auto-load
+        :right-search="false"
+    />
 </template>
 
 <i18n>
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index e5d37900c..fe719db6e 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -1,31 +1,178 @@
 <script setup>
-import { onMounted } from 'vue';
+import { onMounted, ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
-import VnPaginate from 'src/components/ui/VnPaginate.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
-import CardList from 'src/components/ui/CardList.vue';
-import EntrySummary from './Card/EntrySummary.vue';
+import { useRoute } from 'vue-router';
 import EntryFilter from './EntryFilter.vue';
 import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
 import { useStateStore } from 'stores/useStateStore';
-import { toDate } from 'src/filters/index';
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
+import VnTable from 'components/VnTable/VnTable.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
+import { toDate } from 'src/filters';
 
 const stateStore = useStateStore();
-const router = useRouter();
 const { t } = useI18n();
-const { viewSummary } = useSummaryDialog();
+const route = useRoute();
+const entityId = computed(() => route.params.id);
+const tableRef = ref();
 
-function navigate(id) {
-    router.push({ path: `/entry/${id}` });
-}
-
-const redirectToCreateView = () => {
-    router.push({ name: 'EntryCreate' });
+const entryFilter = {
+    include: [
+        {
+            relation: 'suppliers',
+            scope: {
+                fields: ['id', 'name'],
+            },
+        },
+        {
+            relation: 'travels',
+            scope: {
+                fields: ['id', 'ref'],
+            },
+        },
+        {
+            relation: 'companies',
+            scope: {
+                fields: ['id', 'code'],
+            },
+        },
+    ],
 };
 
+const columns = computed(() => [
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.id'),
+        name: 'id',
+        isTitle: true,
+        cardVisible: true,
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.reference'),
+        name: 'reference',
+        isTitle: true,
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+        create: true,
+        cardVisible: true,
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.created'),
+        name: 'created',
+        create: true,
+        cardVisible: true,
+        component: 'date',
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.created)),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.supplierFk'),
+        name: 'supplierFk',
+        create: true,
+        cardVisible: true,
+        component: 'select',
+        attrs: {
+            url: 'suppliers',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.isBooked'),
+        name: 'isBooked',
+        cardVisible: true,
+        create: true,
+        component: 'checkbox',
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.isConfirmed'),
+        name: 'isConfirmed',
+        cardVisible: true,
+        create: true,
+        component: 'checkbox',
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.isOrdered'),
+        name: 'isOrdered',
+        cardVisible: true,
+        create: true,
+        component: 'checkbox',
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.companyFk'),
+        name: 'companyFk',
+        component: 'select',
+        attrs: {
+            url: 'companies',
+            fields: ['id', 'code'],
+            optionLabel: 'code',
+            optionValue: 'id',
+        },
+        columnField: {
+            component: null,
+        },
+        create: true,
+
+        format: (row, dashIfEmpty) => dashIfEmpty(row.companyCode),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.travelFk'),
+        name: 'travelFk',
+        component: 'select',
+        attrs: {
+            url: 'travels',
+            fields: ['id', 'ref'],
+            optionLabel: 'ref',
+            optionValue: 'id',
+        },
+        columnField: {
+            component: null,
+        },
+        create: true,
+        format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
+        name: 'isExcludedFromAvailable',
+        chip: {
+            color: null,
+            condition: (value) => value,
+            icon: 'vn:inventory',
+        },
+        columnFilter: {
+            inWhere: true,
+        },
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.isRaid'),
+        name: 'isRaid',
+        chip: {
+            color: null,
+            condition: (value) => value,
+            icon: 'vn:net',
+        },
+        columnFilter: {
+            inWhere: true,
+        },
+    },
+]);
 onMounted(async () => {
     stateStore.rightDrawer = true;
 });
@@ -42,83 +189,24 @@ onMounted(async () => {
             <EntryFilter data-key="EntryList" />
         </template>
     </RightMenu>
-    <QPage class="column items-center q-pa-md">
-        <div class="vn-card-list">
-            <VnPaginate
-                data-key="EntryList"
-                url="Entries/filter"
-                :order="['landed DESC', 'id DESC']"
-                auto-load
-            >
-                <template #body="{ rows }">
-                    <CardList
-                        v-for="row of rows"
-                        :key="row.id"
-                        :title="row.reference"
-                        @click="navigate(row.id)"
-                        :id="row.id"
-                        :has-info-icons="!!row.isExcludedFromAvailable || !!row.isRaid"
-                    >
-                        <template #info-icons>
-                            <QIcon
-                                v-if="row.isExcludedFromAvailable"
-                                name="vn:inventory"
-                                color="primary"
-                                size="xs"
-                            >
-                                <QTooltip>{{ t('Inventory entry') }}</QTooltip>
-                            </QIcon>
-                            <QIcon
-                                v-if="row.isRaid"
-                                name="vn:net"
-                                color="primary"
-                                size="xs"
-                            >
-                                <QTooltip>{{ t('Virtual entry') }}</QTooltip>
-                            </QIcon>
-                        </template>
-                        <template #list-items>
-                            <VnLv :label="t('landed')" :value="toDate(row.landed)" />
-                            <VnLv
-                                :label="t('entry.list.booked')"
-                                :value="!!row.isBooked"
-                            />
-                            <VnLv
-                                :label="t('entry.list.invoiceNumber')"
-                                :value="row.invoiceNumber"
-                            />
-                            <VnLv
-                                :label="t('entry.list.confirmed')"
-                                :value="!!row.isConfirmed"
-                            />
-                            <VnLv
-                                :label="t('entry.list.supplier')"
-                                :value="row.supplierName"
-                            />
-                            <VnLv
-                                :label="t('entry.list.ordered')"
-                                :value="!!row.isOrdered"
-                            />
-                        </template>
-                        <template #actions>
-                            <QBtn
-                                :label="t('components.smartCard.openSummary')"
-                                @click.stop="viewSummary(row.id, EntrySummary)"
-                                color="primary"
-                                type="submit"
-                            />
-                        </template>
-                    </CardList>
-                </template>
-            </VnPaginate>
-        </div>
-    </QPage>
-    <QPageSticky :offset="[20, 20]">
-        <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" />
-        <QTooltip>
-            {{ t('entry.list.newEntry') }}
-        </QTooltip>
-    </QPageSticky>
+    <VnTable
+        ref="tableRef"
+        data-key="EntryList"
+        url="Entries/filter"
+        :filter="entryFilter"
+        :create="{
+            urlCreate: 'Entries',
+            title: 'Create entry',
+            onDataSaved: ({ id }) => tableRef.redirect(id),
+            formInitialData: {},
+        }"
+        order="id DESC"
+        :columns="columns"
+        redirect="entry"
+        default-mode="table"
+        auto-load
+        :right-search="false"
+    />
 </template>
 
 <i18n>
diff --git a/src/pages/Entry/MyEntries.vue b/src/pages/Entry/MyEntries.vue
new file mode 100644
index 000000000..58a69f70c
--- /dev/null
+++ b/src/pages/Entry/MyEntries.vue
@@ -0,0 +1,106 @@
+<script setup>
+import { computed, onMounted } from 'vue';
+import { useI18n } from 'vue-i18n';
+import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
+import { useStateStore } from 'stores/useStateStore';
+import { toDate } from 'src/filters/index';
+import { useQuasar } from 'quasar';
+import EntryBuysTableDialog from './EntryBuysTableDialog.vue';
+import VnTable from 'components/VnTable/VnTable.vue';
+
+const stateStore = useStateStore();
+const { t } = useI18n();
+const quasar = useQuasar();
+
+onMounted(async () => {
+    stateStore.rightDrawer = true;
+});
+
+const columns = computed(() => [
+    {
+        align: 'left',
+        name: 'id',
+        label: t('customer.extendedList.tableVisibleColumns.id'),
+        chip: {
+            condition: () => true,
+        },
+        isId: true,
+        isTitle: false,
+    },
+    {
+        align: 'left',
+        label: t('shipped'),
+        name: 'shipped',
+        isTitle: false,
+        create: true,
+        cardVisible: true,
+        format: ({ shipped }) => toDate(shipped),
+    },
+    {
+        align: 'left',
+        label: t('landed'),
+        name: 'landed',
+        isTitle: false,
+        create: true,
+        cardVisible: false,
+        format: ({ landed }) => toDate(landed),
+    },
+    {
+        align: 'left',
+        label: t('globals.wareHouseIn'),
+        name: 'warehouseInName',
+        isTitle: false,
+        cardVisible: true,
+        create: false,
+    },
+    {
+        align: 'right',
+        name: 'tableActions',
+        computed,
+        actions: [
+            {
+                title: t('printBuys'),
+                icon: 'print',
+                action: (row) => printBuys(row.id),
+            },
+        ],
+    },
+]);
+
+const printBuys = (rowId) => {
+    quasar.dialog({
+        component: EntryBuysTableDialog,
+        componentProps: {
+            id: rowId,
+        },
+    });
+};
+</script>
+<template>
+    <VnSearchbar
+        data-key="EntryList"
+        url="Entries/filter"
+        :label="t('Search entries')"
+        :info="t('You can search by entry reference')"
+    />
+    <QPage class="column items-center q-pa-md">
+        <div class="vn-card-list">
+            <VnTable
+                ref="myEntriesRef"
+                data-key="myEntriesList"
+                url="Entries/filter"
+                :order="['landed DESC', 'id DESC']"
+                :columns="columns"
+                default-mode="card"
+                auto-load
+            >
+            </VnTable>
+        </div>
+    </QPage>
+</template>
+
+<i18n>
+es:
+    Search entries: Buscar entradas
+    You can search by entry reference: Puedes buscar por referencia de la entrada
+</i18n>
diff --git a/src/pages/Entry/locale/en.yml b/src/pages/Entry/locale/en.yml
index 9a476c80c..677c3c055 100644
--- a/src/pages/Entry/locale/en.yml
+++ b/src/pages/Entry/locale/en.yml
@@ -8,3 +8,4 @@ entryFilter:
         reference: Reference
 landed: Landed
 shipped: Shipped
+printBuys: Print buys
diff --git a/src/pages/Entry/locale/es.yml b/src/pages/Entry/locale/es.yml
index fba6c5460..10b77c2ee 100644
--- a/src/pages/Entry/locale/es.yml
+++ b/src/pages/Entry/locale/es.yml
@@ -1,5 +1,6 @@
 Search entries: Buscar entradas
 You can search by entry reference: Puedes buscar por referencia de la entrada
+
 entryList:
     list:
         inventoryEntry: Es inventario
@@ -11,3 +12,4 @@ entryFilter:
 
 landed: F. llegada
 shipped: F. salida
+Print buys: Imprimir etiquetas
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue
index a36656c1d..e9ca762ed 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue
@@ -1,5 +1,6 @@
 <script setup>
-import InvoiceInDescriptor from "pages/InvoiceIn/Card/InvoiceInDescriptor.vue";
+import InvoiceInDescriptor from 'pages/InvoiceIn/Card/InvoiceInDescriptor.vue';
+import InvoiceInSummary from './InvoiceInSummary.vue';
 
 const $props = defineProps({
     id: {
@@ -10,6 +11,10 @@ const $props = defineProps({
 </script>
 <template>
     <QPopupProxy>
-        <InvoiceInDescriptor v-if="$props.id" :id="$props.id" />
+        <InvoiceInDescriptor
+            v-if="$props.id"
+            :id="$props.id"
+            :summary="InvoiceInSummary"
+        />
     </QPopupProxy>
 </template>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index 428e7a7a1..cdf012b2a 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -209,7 +209,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnTitle
                         :url="getLink('basic-data')"
-                        :text="t('invoiceIn.pageTitles.basicData')"
+                        :text="t('globals.pageTitles.basicData')"
                     />
                 </QCardSection>
                 <VnLv
@@ -240,7 +240,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnTitle
                         :url="getLink('basic-data')"
-                        :text="t('invoiceIn.pageTitles.basicData')"
+                        :text="t('globals.pageTitles.basicData')"
                     />
                 </QCardSection>
                 <VnLv
@@ -265,7 +265,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnTitle
                         :url="getLink('basic-data')"
-                        :text="t('invoiceIn.pageTitles.basicData')"
+                        :text="t('globals.pageTitles.basicData')"
                     />
                 </QCardSection>
                 <VnLv
@@ -289,7 +289,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnTitle
                         :url="getLink('basic-data')"
-                        :text="t('invoiceIn.pageTitles.basicData')"
+                        :text="t('globals.pageTitles.basicData')"
                     />
                 </QCardSection>
                 <QCardSection class="q-pa-none">
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
index e96c74689..84a79661e 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
@@ -150,21 +150,19 @@ const downloadCSV = async () => {
         >
             <template #body-cell-clientId="{ row }">
                 <QTd>
-                    <QBtn flat dense color="blue"> {{ row.clientId }}</QBtn>
+                    <QBtn flat dense class="link"> {{ row.clientId }}</QBtn>
                     <CustomerDescriptorProxy :id="row.clientId" />
                 </QTd>
             </template>
             <template #body-cell-ticketId="{ row }">
                 <QTd>
-                    <QBtn flat dense color="blue"> {{ row.ticketFk }}</QBtn>
+                    <QBtn flat dense class="link"> {{ row.ticketFk }}</QBtn>
                     <TicketDescriptorProxy :id="row.ticketFk" />
                 </QTd>
             </template>
             <template #body-cell-worker="{ row }">
                 <QTd>
-                    <QBtn class="no-uppercase" flat dense color="blue">{{
-                        row.workerName
-                    }}</QBtn>
+                    <QBtn class="no-uppercase link" flat dense>{{ row.workerName }}</QBtn>
                     <WorkerDescriptorProxy :id="row.comercialId" />
                 </QTd>
             </template>
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
index 66b9257a0..9eeac8355 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
@@ -20,6 +20,7 @@ const props = defineProps({
         :data-key="props.dataKey"
         :search-button="true"
         :unremovable-params="['from', 'to']"
+        :hidden-tags="['from', 'to']"
     >
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue
index 9071cc6eb..a3ae99da6 100644
--- a/src/pages/Item/Card/ItemLastEntries.vue
+++ b/src/pages/Item/Card/ItemLastEntries.vue
@@ -200,16 +200,10 @@ onUnmounted(() => (stateStore.rightDrawer = false));
             <VnInputDate
                 :label="t('lastEntries.since')"
                 dense
-                emit-date-format
                 v-model="from"
                 class="q-mr-lg"
             />
-            <VnInputDate
-                :label="t('lastEntries.to')"
-                dense
-                emit-date-format
-                v-model="to"
-            />
+            <VnInputDate :label="t('lastEntries.to')" dense v-model="to" />
         </div>
         <QSpace />
         <div id="st-actions"></div>
diff --git a/src/pages/Item/ItemRequestFilter.vue b/src/pages/Item/ItemRequestFilter.vue
index 2c056acc6..2fbe849d1 100644
--- a/src/pages/Item/ItemRequestFilter.vue
+++ b/src/pages/Item/ItemRequestFilter.vue
@@ -192,7 +192,6 @@ const decrement = (paramsObj, key) => {
                             v-model="params.from"
                             @update:model-value="searchFn()"
                             is-outlined
-                            emit-date-format
                         />
                     </QItemSection>
                 </QItem>
@@ -203,7 +202,6 @@ const decrement = (paramsObj, key) => {
                             v-model="params.to"
                             @update:model-value="searchFn()"
                             is-outlined
-                            emit-date-format
                         />
                     </QItemSection>
                 </QItem>
diff --git a/src/pages/ItemType/Card/ItemTypeDescriptor.vue b/src/pages/ItemType/Card/ItemTypeDescriptor.vue
index e565a791b..cd12fc238 100644
--- a/src/pages/ItemType/Card/ItemTypeDescriptor.vue
+++ b/src/pages/ItemType/Card/ItemTypeDescriptor.vue
@@ -51,20 +51,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity
         @on-fetch="setData"
         data-key="entry"
     >
-        <template #header-extra-action>
-            <QBtn
-                round
-                flat
-                size="sm"
-                icon="vn:item"
-                color="white"
-                :to="{ name: 'ItemTypeList' }"
-            >
-                <QTooltip>
-                    {{ t('Go to module index') }}
-                </QTooltip>
-            </QBtn>
-        </template>
         <template #body="{ entity }">
             <VnLv :label="t('shared.code')" :value="entity.code" />
             <VnLv :label="t('shared.name')" :value="entity.name" />
diff --git a/src/pages/Monitor/SalesClientsTable.vue b/src/pages/Monitor/SalesClientsTable.vue
index 3f2389471..8008b1fda 100644
--- a/src/pages/Monitor/SalesClientsTable.vue
+++ b/src/pages/Monitor/SalesClientsTable.vue
@@ -169,7 +169,6 @@ const columns = computed(() => [
                         <VnInputDate
                             :label="t('salesClientsTable.from')"
                             dense
-                            emit-date-format
                             v-model="from"
                             class="q-mr-lg"
                             style="width: 150px"
@@ -177,7 +176,6 @@ const columns = computed(() => [
                         <VnInputDate
                             :label="t('salesClientsTable.to')"
                             dense
-                            emit-date-format
                             v-model="to"
                             style="width: 150px"
                         />
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index fd5300122..c354ec94b 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -37,6 +37,10 @@ const selectedOrder = ref(null);
 const selectedOrderField = ref(null);
 const moreFields = ref([]);
 const moreFieldsOrder = ref([]);
+const selectedTag = ref(null);
+const tagValues = ref([{}]);
+const tagOptions = ref([]);
+
 const createValue = (val, done) => {
     if (val.length > 2) {
         if (!tagOptions.value.includes(val)) {
@@ -95,10 +99,6 @@ function exprBuilder(param, value) {
     }
 }
 
-const selectedTag = ref(null);
-const tagValues = ref([{}]);
-const tagOptions = ref([]);
-
 const applyTagFilter = (params, search) => {
     if (!tagValues.value?.length) {
         params.tagGroups = null;
@@ -139,39 +139,23 @@ const onOrderChange = (value, params) => {
 };
 
 const onOrderFieldChange = (value, params) => {
-    const tagObj = JSON.parse(params.orderBy); // esto donde va
-    const fields = {
-        Relevancy: (value) => value + ' DESC, name',
-        ColorAndPrice: 'showOrder, price',
-        Name: 'name',
-        Price: 'price',
-    };
-    let tagField = fields[value];
-    if (!tagField) return;
-
-    if (typeof tagField === 'function') tagField = tagField(value);
-    tagObj.field = tagField;
-    params.orderBy = JSON.stringify(tagObj);
+    const tagObj = JSON.parse(params.orderBy);
     switch (value) {
         case 'Relevancy':
-            tagObj.field = value + ' DESC, name';
+            tagObj.name = value + ' DESC, name';
             params.orderBy = JSON.stringify(tagObj);
-            console.log('params: ', params);
             break;
         case 'ColorAndPrice':
-            tagObj.field = 'showOrder, price';
+            tagObj.name = 'showOrder, price';
             params.orderBy = JSON.stringify(tagObj);
-            console.log('params: ', params);
             break;
         case 'Name':
-            tagObj.field = 'name';
+            tagObj.name = 'name';
             params.orderBy = JSON.stringify(tagObj);
-            console.log('params: ', params);
             break;
         case 'Price':
-            tagObj.field = 'price';
+            tagObj.name = 'price';
             params.orderBy = JSON.stringify(tagObj);
-            console.log('params: ', params);
             break;
     }
 };
@@ -312,6 +296,7 @@ const useLang = (values) => {
                         v-model="selectedOrder"
                         :options="moreFields"
                         option-label="label"
+                        option-value="way"
                         dense
                         outlined
                         rounded
diff --git a/src/pages/Order/Card/OrderCatalogItem.vue b/src/pages/Order/Card/OrderCatalogItem.vue
index 34e22915d..8fa0bb5b9 100644
--- a/src/pages/Order/Card/OrderCatalogItem.vue
+++ b/src/pages/Order/Card/OrderCatalogItem.vue
@@ -27,7 +27,7 @@ const dialog = ref(null);
     <div class="container order-catalog-item overflow-hidden">
         <QCard class="card shadow-6">
             <div class="img-wrapper">
-                <VnImg :id="item.id" class="image" />
+                <VnImg :id="item.id" zoom-size="lg" class="image" />
                 <div v-if="item.hex" class="item-color-container">
                     <div
                         class="item-color"
diff --git a/src/pages/Order/Card/OrderForm.vue b/src/pages/Order/Card/OrderForm.vue
index 20b29cd9c..98bcf4d3a 100644
--- a/src/pages/Order/Card/OrderForm.vue
+++ b/src/pages/Order/Card/OrderForm.vue
@@ -122,8 +122,6 @@ const orderFilter = {
 const onClientChange = async (clientId) => {
     try {
         const { data } = await axios.get(`Clients/${clientId}`);
-        console.log('info cliente: ', data);
-
         await fetchAddressList(data.defaultAddressFk);
     } catch (error) {
         console.error('Error al cambiar el cliente:', error);
diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue
index d82dbaa17..7961b250e 100644
--- a/src/pages/Order/Card/OrderSummary.vue
+++ b/src/pages/Order/Card/OrderSummary.vue
@@ -7,6 +7,8 @@ import VnLv from 'components/ui/VnLv.vue';
 import CardSummary from 'components/ui/CardSummary.vue';
 import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
 import FetchedTags from 'components/ui/FetchedTags.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
+import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
 
 const { t } = useI18n();
 const route = useRoute();
@@ -62,6 +64,10 @@ const detailsColumns = ref([
             </template>
             <template #body="{ entity }">
                 <QCard class="vn-one">
+                    <VnTitle
+                        :url="`#/order/${entity.id}/basic-data`"
+                        :text="t('globals.pageTitles.basicData')"
+                    />
                     <VnLv label="ID" :value="entity.id" />
                     <VnLv :label="t('order.summary.nickname')" dash>
                         <template #value>
@@ -81,6 +87,10 @@ const detailsColumns = ref([
                     />
                 </QCard>
                 <QCard class="vn-one">
+                    <VnTitle
+                        :url="`#/order/${entity.id}/basic-data`"
+                        :text="t('globals.pageTitles.basicData')"
+                    />
                     <VnLv
                         :label="t('order.summary.created')"
                         :value="toDateHourMinSec(entity?.created)"
@@ -116,14 +126,13 @@ const detailsColumns = ref([
                     />
                 </QCard>
                 <QCard class="vn-one">
-                    <p class="header">
-                        {{ t('order.summary.notes') }}
-                    </p>
+                    <VnTitle :text="t('globals.pageTitles.notes')" />
                     <p v-if="entity?.note" class="no-margin">
                         {{ entity?.note }}
                     </p>
                 </QCard>
                 <QCard class="vn-one">
+                    <VnTitle :text="t('order.summary.total')" />
                     <VnLv>
                         <template #label>
                             <span class="text-h6">{{ t('order.summary.subtotal') }}</span>
@@ -152,9 +161,7 @@ const detailsColumns = ref([
                     </VnLv>
                 </QCard>
                 <QCard>
-                    <p class="header">
-                        {{ t('order.summary.details') }}
-                    </p>
+                    <VnTitle :text="t('order.summary.details')" />
                     <QTable :columns="detailsColumns" :rows="entity?.rows" flat>
                         <template #header="props">
                             <QTr :props="props">
@@ -168,7 +175,10 @@ const detailsColumns = ref([
                         <template #body="props">
                             <QTr :props="props">
                                 <QTd key="item" :props="props" class="item">
-                                    {{ props.row.item?.id }}
+                                    <span class="link">
+                                        {{ props.row.item?.id }}
+                                        <ItemDescriptorProxy :id="props.row.item?.id" />
+                                    </span>
                                 </QTd>
                                 <QTd key="description" :props="props" class="description">
                                     <div class="name">
diff --git a/src/pages/Order/OrderCatalog.vue b/src/pages/Order/OrderCatalog.vue
index 1d97663d0..081a2cd2f 100644
--- a/src/pages/Order/OrderCatalog.vue
+++ b/src/pages/Order/OrderCatalog.vue
@@ -70,6 +70,7 @@ function extractValueTags(items) {
                 :user-params="catalogParams"
                 auto-load
                 @on-fetch="extractTags"
+                :update-router="false"
             >
                 <template #body="{ rows }">
                     <div class="catalog-list">
diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue
index 247a8e3b2..0e6e11482 100644
--- a/src/pages/Order/OrderList.vue
+++ b/src/pages/Order/OrderList.vue
@@ -9,7 +9,7 @@ import WorkerDescriptorProxy from 'pages/Worker/Card/WorkerDescriptorProxy.vue';
 import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
 import VnPaginate from 'components/ui/VnPaginate.vue';
 import VnLv from 'components/ui/VnLv.vue';
-import OrderSearchbar from 'pages/Order/Card/OrderSearchbar.vue';
+import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
 import OrderFilter from 'pages/Order/Card/OrderFilter.vue';
 import OrderSummary from 'pages/Order/Card/OrderSummary.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
@@ -28,7 +28,11 @@ function navigate(id) {
 }
 </script>
 <template>
-    <OrderSearchbar />
+    <VnSearchbar
+        data-key="OrderList"
+        :label="t('Search order')"
+        :info="t('You can search orders by reference')"
+    />
     <RightMenu>
         <template #right-panel>
             <OrderFilter data-key="OrderList" />
diff --git a/src/pages/Parking/Card/ParkingDescriptor.vue b/src/pages/Parking/Card/ParkingDescriptor.vue
index b5c8820ed..b57bfb0cc 100644
--- a/src/pages/Parking/Card/ParkingDescriptor.vue
+++ b/src/pages/Parking/Card/ParkingDescriptor.vue
@@ -2,7 +2,6 @@
 import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
-import { useArrayData } from 'src/composables/useArrayData';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'components/ui/VnLv.vue';
 
@@ -17,8 +16,7 @@ const props = defineProps({
 const { t } = useI18n();
 const route = useRoute();
 const entityId = computed(() => props.id || route.params.id);
-const { store } = useArrayData('Parking');
-const parking = computed(() => store.data);
+
 const filter = {
     fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'],
     include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }],
@@ -29,15 +27,13 @@ const filter = {
         module="Parking"
         data-key="Parking"
         :url="`Parkings/${entityId}`"
-        :title="parking?.code"
-        :subtitle="parking?.id"
+        title="code"
         :filter="filter"
-        @on-fetch="(data) => (parking = data)"
     >
-        <template #body>
-            <VnLv :label="t('globals.code')" :value="parking.code" />
-            <VnLv :label="t('parking.pickingOrder')" :value="parking.pickingOrder" />
-            <VnLv :label="t('parking.sector')" :value="parking.sector?.description" />
+        <template #body="{ entity }">
+            <VnLv :label="t('globals.code')" :value="entity.code" />
+            <VnLv :label="t('parking.pickingOrder')" :value="entity.pickingOrder" />
+            <VnLv :label="t('parking.sector')" :value="entity.sector?.description" />
         </template>
     </CardDescriptor>
 </template>
diff --git a/src/pages/Parking/Card/ParkingSummary.vue b/src/pages/Parking/Card/ParkingSummary.vue
index 7406856b9..95620ebfd 100644
--- a/src/pages/Parking/Card/ParkingSummary.vue
+++ b/src/pages/Parking/Card/ParkingSummary.vue
@@ -1,10 +1,9 @@
 <script setup>
-import { ref, computed } from 'vue';
+import { computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'components/ui/VnLv.vue';
-import { useArrayData } from 'src/composables/useArrayData';
 
 const $props = defineProps({
     id: {
@@ -15,9 +14,7 @@ const $props = defineProps({
 const router = useRoute();
 const { t } = useI18n();
 const entityId = computed(() => $props.id || router.params.id);
-const { store } = useArrayData('Parking');
 
-const parking = ref(store.data);
 const filter = {
     fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'],
     include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }],
@@ -26,14 +23,9 @@ const filter = {
 
 <template>
     <div class="q-pa-md">
-        <CardSummary
-            :url="`Parkings/${entityId}`"
-            :filter="filter"
-            @on-fetch="(data) => (parking = data)"
-            data-key="Parking"
-        >
-            <template #header>{{ parking.code }}</template>
-            <template #body>
+        <CardSummary :url="`Parkings/${entityId}`" data-key="Parking" :filter="filter">
+            <template #header="{ entity }">{{ entity.code }}</template>
+            <template #body="{ entity }">
                 <QCard class="vn-one">
                     <QCardSection class="q-pa-none">
                         <a
@@ -44,17 +36,17 @@ const filter = {
                             <QIcon name="open_in_new" />
                         </a>
                     </QCardSection>
-                    <VnLv :label="t('globals.code')" :value="parking.code" />
+                    <VnLv :label="t('globals.code')" :value="entity.code" />
                     <VnLv
                         :label="t('parking.pickingOrder')"
-                        :value="parking.pickingOrder"
+                        :value="entity.pickingOrder"
                     />
                     <VnLv
                         :label="t('parking.sector')"
-                        :value="parking.sector?.description"
+                        :value="entity.sector?.description"
                     />
-                    <VnLv :label="t('parking.row')" :value="parking.row" />
-                    <VnLv :label="t('parking.column')" :value="parking.column" />
+                    <VnLv :label="t('parking.row')" :value="entity.row" />
+                    <VnLv :label="t('parking.column')" :value="entity.column" />
                 </QCard>
             </template>
         </CardSummary>
diff --git a/src/pages/Route/Agency/AgencyList.vue b/src/pages/Route/Agency/AgencyList.vue
new file mode 100644
index 000000000..eb301c9ba
--- /dev/null
+++ b/src/pages/Route/Agency/AgencyList.vue
@@ -0,0 +1,92 @@
+<script setup>
+import { computed } from 'vue';
+import { useRouter } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
+import VnTable from 'components/VnTable/VnTable.vue';
+
+const { t } = useI18n();
+const router = useRouter();
+function navigate(id) {
+    router.push({ path: `/agency/${id}` });
+}
+const exprBuilder = (param, value) => {
+    if (!value) return;
+    if (param !== 'search') return;
+    if (!isNaN(value)) return { id: value };
+
+    return { name: { like: `%${value}%` } };
+};
+
+const columns = computed(() => [
+    {
+        align: 'left',
+        name: 'id',
+        label: 'Id',
+        chip: {
+            condition: () => true,
+        },
+        isId: true,
+    },
+    {
+        align: 'left',
+        label: t('globals.name'),
+        name: 'name',
+        isTitle: true,
+    },
+    {
+        align: 'left',
+        label: t('isOwn'),
+        name: 'isOwn',
+        component: 'checkbox',
+        cardVisible: true,
+    },
+    {
+        align: 'left',
+        label: t('isAnyVolumeAllowed'),
+        name: 'isAnyVolumeAllowed',
+        component: 'checkbox',
+        cardVisible: true,
+        disable: true,
+    },
+    {
+        align: 'right',
+        label: '',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('Client ticket list'),
+                icon: 'preview',
+                action: (row) => navigate(row.id),
+            },
+        ],
+    },
+]);
+</script>
+<template>
+    <VnSearchbar
+        :info="t('You can search by name')"
+        :label="t('Search agency')"
+        data-key="AgencyList"
+        :expr-builder="exprBuilder"
+    />
+    <VnTable
+        ref="tableRef"
+        data-key="AgencyList"
+        url="Agencies"
+        order="name"
+        :columns="columns"
+        :right-search="false"
+        :use-model="true"
+    />
+</template>
+<i18n>
+    es: 
+        isOwn: Tiene propietario
+        isAnyVolumeAllowed: Permite cualquier volumen
+        Search agency: Buscar agencia
+        You can search by name: Puedes buscar por nombre
+    en:
+        isOwn: Has owner
+        isAnyVolumeAllowed: Allows any volume
+</i18n>
diff --git a/src/pages/Agency/Card/AgencyBasicData.vue b/src/pages/Route/Agency/Card/AgencyBasicData.vue
similarity index 100%
rename from src/pages/Agency/Card/AgencyBasicData.vue
rename to src/pages/Route/Agency/Card/AgencyBasicData.vue
diff --git a/src/pages/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue
similarity index 82%
rename from src/pages/Agency/Card/AgencyCard.vue
rename to src/pages/Route/Agency/Card/AgencyCard.vue
index 6b2296df3..e1eebabf7 100644
--- a/src/pages/Agency/Card/AgencyCard.vue
+++ b/src/pages/Route/Agency/Card/AgencyCard.vue
@@ -1,5 +1,5 @@
 <script setup>
-import AgencyDescriptor from 'pages/Agency/Card/AgencyDescriptor.vue';
+import AgencyDescriptor from 'pages/Route/Agency/Card/AgencyDescriptor.vue';
 import VnCard from 'components/common/VnCard.vue';
 </script>
 <template>
diff --git a/src/pages/Agency/Card/AgencyDescriptor.vue b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
similarity index 100%
rename from src/pages/Agency/Card/AgencyDescriptor.vue
rename to src/pages/Route/Agency/Card/AgencyDescriptor.vue
diff --git a/src/pages/Agency/Card/AgencyLog.vue b/src/pages/Route/Agency/Card/AgencyLog.vue
similarity index 100%
rename from src/pages/Agency/Card/AgencyLog.vue
rename to src/pages/Route/Agency/Card/AgencyLog.vue
diff --git a/src/pages/Agency/Card/AgencyModes.vue b/src/pages/Route/Agency/Card/AgencyModes.vue
similarity index 100%
rename from src/pages/Agency/Card/AgencyModes.vue
rename to src/pages/Route/Agency/Card/AgencyModes.vue
diff --git a/src/pages/Agency/Card/AgencySummary.vue b/src/pages/Route/Agency/Card/AgencySummary.vue
similarity index 81%
rename from src/pages/Agency/Card/AgencySummary.vue
rename to src/pages/Route/Agency/Card/AgencySummary.vue
index f9a1c5ea0..71a6d1066 100644
--- a/src/pages/Agency/Card/AgencySummary.vue
+++ b/src/pages/Route/Agency/Card/AgencySummary.vue
@@ -18,12 +18,10 @@ const entityId = computed(() => $props.id || useRoute().params.id);
             <template #header="{ entity: agency }">{{ agency.name }}</template>
             <template #body="{ entity: agency }">
                 <QCard class="vn-one">
-                    <QCardSection class="q-pa-none">
-                        <VnTitle
-                            :url="`#/agency/${entityId}/basic-data`"
-                            :text="t('globals.pageTitles.basicData')"
-                        />
-                    </QCardSection>
+                    <VnTitle
+                        :url="`#/agency/${entityId}/basic-data`"
+                        :text="t('globals.pageTitles.basicData')"
+                    />
                     <VnLv :label="t('globals.name')" :value="agency.name" />
                     <QCheckbox
                         :label="t('agency.isOwn')"
diff --git a/src/pages/Agency/Card/AgencyWorkcenter.vue b/src/pages/Route/Agency/Card/AgencyWorkcenter.vue
similarity index 100%
rename from src/pages/Agency/Card/AgencyWorkcenter.vue
rename to src/pages/Route/Agency/Card/AgencyWorkcenter.vue
diff --git a/src/pages/Agency/locale/en.yml b/src/pages/Route/Agency/locale/en.yml
similarity index 100%
rename from src/pages/Agency/locale/en.yml
rename to src/pages/Route/Agency/locale/en.yml
diff --git a/src/pages/Agency/locale/es.yml b/src/pages/Route/Agency/locale/es.yml
similarity index 100%
rename from src/pages/Agency/locale/es.yml
rename to src/pages/Route/Agency/locale/es.yml
diff --git a/src/pages/Route/Card/RouteDescriptor.vue b/src/pages/Route/Card/RouteDescriptor.vue
index 218764277..2fa0e77e0 100644
--- a/src/pages/Route/Card/RouteDescriptor.vue
+++ b/src/pages/Route/Card/RouteDescriptor.vue
@@ -74,8 +74,9 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity
         :filter="filter"
         :title="data.title"
         :subtitle="data.subtitle"
-        data-key="Routes"
+        data-key="routeData"
         @on-fetch="setData"
+        :summary="$attrs"
     >
         <template #body="{ entity }">
             <VnLv :label="t('Date')" :value="toDate(entity?.created)" />
diff --git a/src/pages/Route/Card/RouteDescriptorProxy.vue b/src/pages/Route/Card/RouteDescriptorProxy.vue
index 541f9716a..1ff39a51e 100644
--- a/src/pages/Route/Card/RouteDescriptorProxy.vue
+++ b/src/pages/Route/Card/RouteDescriptorProxy.vue
@@ -1,5 +1,6 @@
 <script setup>
 import RouteDescriptor from 'pages/Route/Card/RouteDescriptor.vue';
+import RouteSummary from './RouteSummary.vue';
 
 const $props = defineProps({
     id: {
@@ -10,6 +11,6 @@ const $props = defineProps({
 </script>
 <template>
     <QPopupProxy>
-        <RouteDescriptor v-if="$props.id" :id="$props.id" />
+        <RouteDescriptor v-if="$props.id" :id="$props.id" :summary="RouteSummary" />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Route/Card/RouteSearchbar.vue b/src/pages/Route/Card/RouteSearchbar.vue
index 924280580..0e5c1643d 100644
--- a/src/pages/Route/Card/RouteSearchbar.vue
+++ b/src/pages/Route/Card/RouteSearchbar.vue
@@ -9,7 +9,6 @@ const { t } = useI18n();
         data-key="RouteList"
         :label="t('Search route')"
         :info="t('You can search by route reference')"
-        custom-route-redirect-name="RouteList"
     />
 </template>
 
diff --git a/src/pages/Route/Cmr/CmrFilter.vue b/src/pages/Route/Cmr/CmrFilter.vue
index 32040ddd6..bea58b2d8 100644
--- a/src/pages/Route/Cmr/CmrFilter.vue
+++ b/src/pages/Route/Cmr/CmrFilter.vue
@@ -154,7 +154,7 @@ const warehouses = ref();
     es:
         params:
             cmrFk: Id cmr
-            hasCmrDms: Adjuntado en gestdoc
+            hasCmrDms: Gestdoc
             ticketFk: Id ticket
             country: País
             clientFk: Id cliente
diff --git a/src/pages/Route/Cmr/CmrList.vue b/src/pages/Route/Cmr/CmrList.vue
index 327b37ac5..74a070cbf 100644
--- a/src/pages/Route/Cmr/CmrList.vue
+++ b/src/pages/Route/Cmr/CmrList.vue
@@ -12,6 +12,8 @@ import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy
 import RightMenu from 'src/components/common/RightMenu.vue';
 import { useStateStore } from 'src/stores/useStateStore';
 
+import VnTable from 'components/VnTable/VnTable.vue';
+
 const { t } = useI18n();
 const { getTokenMultimedia } = useSession();
 const token = getTokenMultimedia();
@@ -107,88 +109,15 @@ function downloadPdfs() {
 }
 </script>
 <template>
-    <RightMenu>
-        <template #right-panel>
-            <CmrFilter data-key="CmrList" />
-        </template>
-    </RightMenu>
-    <div class="column items-center">
-        <div class="list">
-            <VnPaginate data-key="CmrList" :url="`Routes/cmrs`" order="cmrFk DESC">
-                <template #body="{ rows }">
-                    <QTable
-                        :columns="columns"
-                        :rows="rows"
-                        :dense="$q.screen.lt.md"
-                        row-key="cmrFk"
-                        selection="multiple"
-                        v-model:selected="selected"
-                        :grid="$q.screen.lt.md"
-                        auto-load
-                    >
-                        <template #top>
-                            <div style="width: 100%; display: table">
-                                <div style="float: right; color: lightgray">
-                                    {{ `${rows.length} ${t('route.cmr.list.results')}` }}
-                                </div>
-                            </div>
-                        </template>
-                        <template #body-cell-hasCmrDms="{ value }">
-                            <QTd align="center">
-                                <QBadge
-                                    text-color="black"
-                                    :id="value ? 'true' : 'false'"
-                                    :label="
-                                        value
-                                            ? t('route.cmr.list.true')
-                                            : t('route.cmr.list.false')
-                                    "
-                                />
-                            </QTd>
-                        </template>
-                        <template #body-cell-ticketFk="{ value }">
-                            <QTd align="right" class="text-primary">
-                                <span class="text-primary link">{{ value }}</span>
-                                <TicketDescriptorProxy :id="value" />
-                            </QTd>
-                        </template>
-                        <template #body-cell-clientFk="{ value }">
-                            <QTd align="right" class="text-primary">
-                                <span class="text-primary link">{{ value }}</span>
-                                <CustomerDescriptorProxy :id="value" />
-                            </QTd>
-                        </template>
-                        <template #body-cell-warehouseFk="{ value }">
-                            <QTd align="center">
-                                {{ warehouses.find(({ id }) => id === value)?.name }}
-                            </QTd>
-                        </template>
-                        <template #body-cell-icons="{ value }">
-                            <QTd align="center">
-                                <a :href="getCmrUrl(value)" target="_blank">
-                                    <QIcon
-                                        name="visibility"
-                                        color="primary"
-                                        size="md"
-                                        class="q-mr-sm q-ml-sm"
-                                    />
-                                    <QTooltip>
-                                        {{ t('route.cmr.list.viewCmr') }}
-                                    </QTooltip>
-                                </a>
-                            </QTd>
-                        </template>
-                    </QTable>
-                </template>
-            </VnPaginate>
-        </div>
-        <QPageSticky :offset="[20, 20]">
-            <QBtn @click="downloadPdfs" fab icon="cloud_download" color="primary" />
-            <QTooltip>
-                {{ t('route.cmr.list.downloadCmrs') }}
-            </QTooltip>
-        </QPageSticky>
-    </div>
+    <VnTable
+        ref="tableRef"
+        data-key="CmrList"
+        url="Routes/cmrs"
+        order="cmrFk DESC"
+        :columns="columns"
+        :right-search="true"
+        :use-model="true"
+    />
 </template>
 <style lang="scss" scoped>
 .list {
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index de60d164e..e116fd823 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -1,29 +1,32 @@
 <script setup>
-import { useI18n } from 'vue-i18n';
-import { computed, onMounted, ref } from 'vue';
+import { useArrayData } from 'composables/useArrayData';
 import { dashIfEmpty, toHour } from 'src/filters';
+import { computed, onMounted, ref } from 'vue';
+import { useI18n } from 'vue-i18n';
 import { useValidator } from 'composables/useValidator';
 import { useSession } from 'composables/useSession';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import { useArrayData } from 'composables/useArrayData';
 import { useQuasar } from 'quasar';
 
 import axios from 'axios';
 import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
 import FetchData from 'components/FetchData.vue';
-import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
-import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
-import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
 import RouteListTicketsDialog from 'pages/Route/Card/RouteListTicketsDialog.vue';
+import { useRouter } from 'vue-router';
+import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
+import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
+import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
 
 import VnPaginate from 'components/ui/VnPaginate.vue';
-import VnSelect from 'components/common/VnSelect.vue';
-import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInput from 'components/common/VnInput.vue';
 import VnInputTime from 'components/common/VnInputTime.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
+import VnSelect from 'components/common/VnSelect.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
+import VnInputDate from 'components/common/VnInputDate.vue';
+import VnLv from 'src/components/ui/VnLv.vue';
+import VnTable from 'components/VnTable/VnTable.vue';
+import { useStateStore } from 'src/stores/useStateStore';
 
 const { t } = useI18n();
 const { validate } = useValidator();
@@ -40,90 +43,100 @@ const allColumnNames = ref([]);
 const confirmationDialog = ref(false);
 const startingDate = ref(null);
 const refreshKey = ref(0);
-
+const router = useRouter();
+const stateStore = useStateStore();
 const columns = computed(() => [
     {
-        name: 'Id',
-        label: t('Id'),
-        field: (row) => row.id,
-        sortable: true,
-        align: 'center',
+        align: 'left',
+        name: 'id',
+        label: 'Id',
+        chip: {
+            condition: () => true,
+        },
+        isId: true,
+        columnFilter: {
+            name: 'search',
+        },
     },
     {
+        align: 'left',
         name: 'worker',
         label: t('Worker'),
-        field: (row) => row.workerUserName,
-        sortable: true,
-        align: 'left',
+        create: true,
+        component: 'select',
+        attrs: {
+            url: 'payrollComponents',
+            fields: ['id', 'name'],
+        },
+        cardVisible: true,
     },
     {
         name: 'agency',
         label: t('Agency'),
-        field: (row) => row.agencyName,
-        sortable: true,
         align: 'left',
+        isTitle: true,
+        cardVisible: true,
+        create: true,
     },
     {
         name: 'vehicle',
         label: t('Vehicle'),
-        field: (row) => row.vehiclePlateNumber,
-        sortable: true,
         align: 'left',
+        cardVisible: true,
+        create: true,
     },
     {
         name: 'date',
         label: t('Date'),
-        field: (row) => row.created,
-        sortable: true,
         align: 'left',
+        cardVisible: true,
+        create: true,
     },
     {
         name: 'volume',
         label: 'm³',
-        field: (row) => dashIfEmpty(row.m3),
-        sortable: true,
         align: 'center',
+        cardVisible: true,
     },
     {
         name: 'description',
         label: t('Description'),
-        field: (row) => row.description,
-        sortable: true,
         align: 'left',
+        isTitle: true,
+        create: true,
     },
     {
         name: 'started',
         label: t('hourStarted'),
-        field: (row) => toHour(row.started),
-        sortable: true,
         align: 'left',
     },
     {
         name: 'finished',
         label: t('hourFinished'),
-        field: (row) => toHour(row.finished),
-        sortable: true,
         align: 'left',
     },
     {
         name: 'isServed',
         label: t('Served'),
-        field: (row) => Boolean(row.isOk),
-        sortable: true,
         align: 'left',
     },
     {
-        name: 'actions',
-        label: '',
-        sortable: false,
         align: 'right',
+        label: 'asdasd',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('Client ticket list'),
+                icon: 'preview',
+                action: (row) => navigate(row.id),
+            },
+        ],
     },
 ]);
 
-const arrayData = useArrayData('EntryLatestBuys', {
-    url: 'Buys/latestBuysFilter',
-    order: ['itemFk DESC'],
-});
+function navigate(id) {
+    router.push({ path: `/route/${id}` });
+}
 
 const updateRoute = async (route) => {
     try {
@@ -181,20 +194,10 @@ const openTicketsDialog = (id) => {
         })
         .onOk(() => refreshKey.value++);
 };
-
-onMounted(async () => {
-    allColumnNames.value = columns.value.map((col) => col.name);
-    await arrayData.fetch({ append: false });
-});
 </script>
 
 <template>
     <RouteSearchbar />
-    <RightMenu>
-        <template #right-panel>
-            <RouteFilter data-key="RouteList" />
-        </template>
-    </RightMenu>
     <QDialog v-model="confirmationDialog">
         <QCard style="min-width: 350px">
             <QCardSection>
@@ -227,256 +230,53 @@ onMounted(async () => {
     />
     <FetchData url="AgencyModes" @on-fetch="(data) => (agencyList = data)" auto-load />
     <FetchData url="Vehicles" @on-fetch="(data) => (vehicleList = data)" auto-load />
-    <QPage class="column items-center">
-        <VnSubToolbar>
-            <template #st-data>
-                <TableVisibleColumns
-                    class="LeftIcon"
-                    :all-columns="allColumnNames"
-                    table-code="routesList"
-                    labels-traductions-path="route.columnLabels"
-                    @on-config-saved="visibleColumns = [...$event]"
-                />
-            </template>
-            <template #st-actions>
-                <QBtn
-                    icon="vn:clone"
-                    color="primary"
-                    class="q-mr-sm"
-                    :disable="!selectedRows?.length"
-                    @click="confirmationDialog = true"
-                >
-                    <QTooltip>{{ t('Clone Selected Routes') }}</QTooltip>
-                </QBtn>
-                <QBtn
-                    icon="cloud_download"
-                    color="primary"
-                    class="q-mr-sm"
-                    :disable="!selectedRows?.length"
-                    @click="showRouteReport"
-                >
-                    <QTooltip>{{ t('Download selected routes as PDF') }}</QTooltip>
-                </QBtn>
-                <QBtn
-                    icon="check"
-                    color="primary"
-                    class="q-mr-sm"
-                    :disable="!selectedRows?.length"
-                    @click="markAsServed()"
-                >
-                    <QTooltip>{{ t('Mark as served') }}</QTooltip>
-                </QBtn>
-            </template>
-        </VnSubToolbar>
-        <div class="route-list">
-            <VnPaginate
-                :key="refreshKey"
-                data-key="RouteList"
-                url="Routes/filter"
-                :order="['created ASC', 'started ASC', 'id ASC']"
-                :limit="20"
+    <VnSubToolbar />
+    <VnTable
+        ref="tableRef"
+        data-key="RouteList"
+        url="Routes/filter"
+        :columns="columns"
+        :right-search="true"
+        default-mode="table"
+        :is-editable="true"
+        :create="{
+            urlCreate: 'Routes',
+            title: t('Create route'),
+            onDataSaved: () => tableRef.reload(),
+        }"
+        save-url="routes"
+        :disable-option="{ card: true }"
+    >
+        <template #moreBeforeActions>
+            <QBtn
+                icon="vn:clone"
+                color="primary"
+                class="q-mr-sm"
+                :disable="!selectedRows?.length"
+                @click="confirmationDialog = true"
             >
-                <template #body="{ rows }">
-                    <div class="q-pa-md route-table">
-                        <QTable
-                            v-model:selected="selectedRows"
-                            :columns="columns"
-                            :rows="rows"
-                            flat
-                            row-key="id"
-                            selection="multiple"
-                            :rows-per-page-options="[0]"
-                            :visible-columns="visibleColumns"
-                            hide-pagination
-                            :no-data-label="t('globals.noResults')"
-                            style="max-height: 82vh"
-                        >
-                            <template #body-cell-worker="{ row }">
-                                <QTd class="table-input-cell">
-                                    <VnSelect
-                                        :label="t('Worker')"
-                                        v-model="row.workerFk"
-                                        :options="workers"
-                                        option-value="id"
-                                        option-label="nickname"
-                                        hide-selected
-                                        dense
-                                        :emit-value="false"
-                                        :rules="validate('Route.workerFk')"
-                                        :is-clearable="false"
-                                        @update:model-value="updateRoute(row)"
-                                    >
-                                        <template #option="{ opt, itemProps }">
-                                            <QItem
-                                                v-bind="itemProps"
-                                                class="q-pa-xs row items-center"
-                                            >
-                                                <QItemSection
-                                                    class="col-9 justify-center"
-                                                >
-                                                    <span>{{ opt.name }}</span>
-                                                    <span class="text-grey">{{
-                                                        opt.nickname
-                                                    }}</span>
-                                                </QItemSection>
-                                            </QItem>
-                                        </template>
-                                    </VnSelect>
-                                </QTd>
-                            </template>
-                            <template #body-cell-agency="{ row }">
-                                <QTd class="table-input-cell">
-                                    <VnSelect
-                                        :label="t('Agency')"
-                                        v-model="row.agencyModeFk"
-                                        :options="agencyList"
-                                        option-value="id"
-                                        option-label="name"
-                                        hide-selected
-                                        dense
-                                        :emit-value="false"
-                                        :rules="validate('route.agencyFk')"
-                                        :is-clearable="false"
-                                        @update:model-value="updateRoute(row)"
-                                    />
-                                </QTd>
-                            </template>
-                            <template #body-cell-vehicle="{ row }">
-                                <QTd class="table-input-cell small-column">
-                                    <VnSelect
-                                        :label="t('Vehicle')"
-                                        v-model="row.vehicleFk"
-                                        :options="vehicleList"
-                                        option-value="id"
-                                        option-label="numberPlate"
-                                        hide-selected
-                                        dense
-                                        :emit-value="false"
-                                        :rules="validate('route.vehicleFk')"
-                                        :is-clearable="false"
-                                        @update:model-value="updateRoute(row)"
-                                    />
-                                </QTd>
-                            </template>
-                            <template #body-cell-date="{ row }">
-                                <QTd class="table-input-cell small-column">
-                                    <VnInputDate
-                                        v-model="row.created"
-                                        hide-bottom-space
-                                        dense
-                                        :label="t('Date')"
-                                        :rules="validate('route.created')"
-                                        :is-clearable="false"
-                                        @update:model-value="updateRoute(row)"
-                                    />
-                                </QTd>
-                            </template>
-                            <template #body-cell-description="{ row }">
-                                <QTd class="table-input-cell">
-                                    <VnInput
-                                        v-model="row.description"
-                                        :label="t('Description')"
-                                        :rules="validate('route.description')"
-                                        :is-clearable="false"
-                                        dense
-                                        @update:model-value="updateRoute(row)"
-                                    />
-                                </QTd>
-                            </template>
-                            <template #body-cell-started="{ row }">
-                                <QTd class="table-input-cell small-column">
-                                    <VnInputTime
-                                        v-model="row.started"
-                                        :label="t('hourStarted')"
-                                        :rules="validate('route.started')"
-                                        :is-clearable="false"
-                                        hide-bottom-space
-                                        dense
-                                        @update:model-value="updateRoute(row)"
-                                    />
-                                </QTd>
-                            </template>
-                            <template #body-cell-finished="{ row }">
-                                <QTd class="table-input-cell small-column">
-                                    <VnInputTime
-                                        v-model="row.finished"
-                                        autofocus
-                                        :label="t('hourFinished')"
-                                        :rules="validate('route.finished')"
-                                        :is-clearable="false"
-                                        hide-bottom-space
-                                        dense
-                                        @update:model-value="updateRoute(row)"
-                                    />
-                                </QTd>
-                            </template>
-                            <template #body-cell-isServed="props">
-                                <QTd class="table-input-cell small-column">
-                                    <QCheckbox v-model="props.value" disable>
-                                        <QTooltip>
-                                            {{
-                                                props.value
-                                                    ? t('Route is closed')
-                                                    : t('Route is not served')
-                                            }}
-                                        </QTooltip>
-                                    </QCheckbox>
-                                </QTd>
-                            </template>
-                            <template #body-cell-actions="props">
-                                <QTd :props="props">
-                                    <div class="flex items-center no-wrap table-actions">
-                                        <QIcon
-                                            name="vn:ticketAdd"
-                                            size="sm"
-                                            color="primary"
-                                            class="cursor-pointer"
-                                            @click="openTicketsDialog(props?.row?.id)"
-                                        >
-                                            <QTooltip>{{ t('Add ticket') }}</QTooltip>
-                                        </QIcon>
-                                        <QIcon
-                                            name="preview"
-                                            size="sm"
-                                            color="primary"
-                                            @click="
-                                                viewSummary(props?.row?.id, RouteSummary)
-                                            "
-                                            class="cursor-pointer"
-                                        >
-                                            <QTooltip>{{ t('Preview') }}</QTooltip>
-                                        </QIcon>
-                                        <RouterLink
-                                            :to="{
-                                                name: 'RouteSummary',
-                                                params: { id: props?.row?.id },
-                                            }"
-                                        >
-                                            <QIcon
-                                                name="vn:eye"
-                                                size="xs"
-                                                color="primary"
-                                            >
-                                                <QTooltip>{{ t('Summary') }}</QTooltip>
-                                            </QIcon>
-                                        </RouterLink>
-                                    </div>
-                                </QTd>
-                            </template>
-                        </QTable>
-                    </div>
-                </template>
-            </VnPaginate>
-        </div>
-        <QPageSticky :offset="[20, 20]">
-            <RouterLink :to="{ name: 'RouteCreate' }">
-                <QBtn fab icon="add" color="primary" />
-                <QTooltip>
-                    {{ t('newRoute') }}
-                </QTooltip>
-            </RouterLink>
-        </QPageSticky>
-    </QPage>
+                <QTooltip>{{ t('Clone Selected Routes') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                icon="cloud_download"
+                color="primary"
+                class="q-mr-sm"
+                :disable="!selectedRows?.length"
+                @click="showRouteReport"
+            >
+                <QTooltip>{{ t('Download selected routes as PDF') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                icon="check"
+                color="primary"
+                class="q-mr-sm"
+                :disable="!selectedRows?.length"
+                @click="markAsServed()"
+            >
+                <QTooltip>{{ t('Mark as served') }}</QTooltip>
+            </QBtn>
+        </template>
+    </VnTable>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/pages/Route/RouteMain.vue b/src/pages/Route/RouteMain.vue
index bbf19068e..aace646fb 100644
--- a/src/pages/Route/RouteMain.vue
+++ b/src/pages/Route/RouteMain.vue
@@ -2,7 +2,7 @@
 import { useStateStore } from 'stores/useStateStore';
 import LeftMenu from 'src/components/LeftMenu.vue';
 import { onMounted } from 'vue';
-
+import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 const stateStore = useStateStore();
 onMounted(() => (stateStore.leftDrawer = false));
 </script>
diff --git a/src/pages/Shelving/Card/ShelvingDescriptor.vue b/src/pages/Shelving/Card/ShelvingDescriptor.vue
index 6beca6d88..52b4896ad 100644
--- a/src/pages/Shelving/Card/ShelvingDescriptor.vue
+++ b/src/pages/Shelving/Card/ShelvingDescriptor.vue
@@ -51,6 +51,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity
         :subtitle="data.subtitle"
         data-key="Shelvings"
         @on-fetch="setData"
+        :summary="$attrs"
     >
         <template #body="{ entity }">
             <VnLv :label="t('shelving.summary.code')" :value="entity.code" />
diff --git a/src/pages/Shelving/Card/ShelvingDescriptorProxy.vue b/src/pages/Shelving/Card/ShelvingDescriptorProxy.vue
index 8023271b0..9561b77db 100644
--- a/src/pages/Shelving/Card/ShelvingDescriptorProxy.vue
+++ b/src/pages/Shelving/Card/ShelvingDescriptorProxy.vue
@@ -1,5 +1,6 @@
 <script setup>
-import ShelvingDescriptor from "pages/Shelving/Card/ShelvingDescriptor.vue";
+import ShelvingDescriptor from 'pages/Shelving/Card/ShelvingDescriptor.vue';
+import ShelvingSummary from './ShelvingSummary.vue';
 
 const $props = defineProps({
     id: {
@@ -10,6 +11,6 @@ const $props = defineProps({
 </script>
 <template>
     <QPopupProxy>
-        <ShelvingDescriptor v-if="$props.id" :id="$props.id" />
+        <ShelvingDescriptor v-if="$props.id" :id="$props.id" :summary="ShelvingSummary" />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Shelving/Card/ShelvingSummary.vue b/src/pages/Shelving/Card/ShelvingSummary.vue
index 08d05626e..94175b0c1 100644
--- a/src/pages/Shelving/Card/ShelvingSummary.vue
+++ b/src/pages/Shelving/Card/ShelvingSummary.vue
@@ -51,7 +51,7 @@ const filter = {
                         class="header header-link"
                         :to="{ name: 'ShelvingBasicData', params: { id: entityId } }"
                     >
-                        {{ t('shelving.pageTitles.basicData') }}
+                        {{ t('globals.pageTitles.basicData') }}
                         <QIcon name="open_in_new" />
                     </RouterLink>
                     <VnLv :label="t('shelving.summary.code')" :value="entity.code" />
diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue
index 4ef76c2f8..a31a3bc8d 100644
--- a/src/pages/Supplier/Card/SupplierDescriptor.vue
+++ b/src/pages/Supplier/Card/SupplierDescriptor.vue
@@ -112,22 +112,6 @@ const getEntryQueryParams = (supplier) => {
         data-key="supplier"
         :summary="$props.summary"
     >
-        <template #header-extra-action>
-            <QBtn
-                round
-                flat
-                dense
-                size="md"
-                icon="vn:supplier"
-                color="white"
-                class="link"
-                :to="{ name: 'SupplierList' }"
-            >
-                <QTooltip>
-                    {{ t('Go to module index') }}
-                </QTooltip>
-            </QBtn>
-        </template>
         <template #body="{ entity }">
             <VnLv :label="t('supplier.summary.taxNumber')" :value="entity.nif" />
             <VnLv label="Alias" :value="entity.nickname" />
diff --git a/src/pages/Supplier/Card/SupplierSummary.vue b/src/pages/Supplier/Card/SupplierSummary.vue
index d007ad08f..9337724b0 100644
--- a/src/pages/Supplier/Card/SupplierSummary.vue
+++ b/src/pages/Supplier/Card/SupplierSummary.vue
@@ -9,8 +9,6 @@ import { dashIfEmpty } from 'src/filters';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import VnTitle from 'src/components/common/VnTitle.vue';
 
-onUpdated(() => summaryRef.value.fetch());
-
 const route = useRoute();
 const roleState = useRole();
 const { t } = useI18n();
diff --git a/src/pages/Supplier/SupplierList.vue b/src/pages/Supplier/SupplierList.vue
index d53781a38..ce7d234c8 100644
--- a/src/pages/Supplier/SupplierList.vue
+++ b/src/pages/Supplier/SupplierList.vue
@@ -1,26 +1,81 @@
 <script setup>
+import { computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useRouter } from 'vue-router';
-import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
-import VnPaginate from 'src/components/ui/VnPaginate.vue';
-import CardList from 'src/components/ui/CardList.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
-import SupplierSummary from './Card/SupplierSummary.vue';
+import VnTable from 'components/VnTable/VnTable.vue';
+import VnSearchbar from 'components/ui/VnSearchbar.vue';
+import RightMenu from 'components/common/RightMenu.vue';
 import SupplierListFilter from './SupplierListFilter.vue';
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import RightMenu from 'src/components/common/RightMenu.vue';
 
-const router = useRouter();
 const { t } = useI18n();
-const { viewSummary } = useSummaryDialog();
+const tableRef = ref();
 
-function navigate(id) {
-    router.push({ path: `/supplier/${id}` });
-}
-
-const redirectToCreateView = () => {
-    router.push({ name: 'SupplierCreate' });
-};
+const columns = computed(() => [
+    {
+        align: 'left',
+        label: t('supplier.list.tableVisibleColumns.id'),
+        name: 'id',
+        isTitle: true,
+    },
+    {
+        align: 'left',
+        label: t('supplier.list.tableVisibleColumns.name'),
+        name: 'socialName',
+        create: true,
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+    },
+    {
+        align: 'left',
+        label: t('supplier.list.tableVisibleColumns.nif'),
+        name: 'nif',
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+    },
+    {
+        align: 'left',
+        label: t('supplier.list.tableVisibleColumns.nickname'),
+        name: 'alias',
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+    },
+    {
+        align: 'left',
+        label: t('supplier.list.tableVisibleColumns.account'),
+        name: 'account',
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+    },
+    {
+        align: 'left',
+        label: t('supplier.list.tableVisibleColumns.payMethod'),
+        name: 'payMethod',
+        component: 'select',
+        attrs: {
+            url: 'payMethods',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+    },
+    {
+        align: 'left',
+        label: t('supplier.list.tableVisibleColumns.payDay'),
+        name: 'payDat',
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+    },
+]);
 </script>
 
 <template>
@@ -30,56 +85,25 @@ const redirectToCreateView = () => {
             <SupplierListFilter data-key="SuppliersList" />
         </template>
     </RightMenu>
-    <QPage class="column items-center q-pa-md">
-        <div class="vn-card-list">
-            <VnPaginate data-key="SuppliersList" url="Suppliers/filter">
-                <template #body="{ rows }">
-                    <CardList
-                        v-for="row of rows"
-                        :key="row.id"
-                        :title="row.socialName"
-                        :id="row.id"
-                        @click="navigate(row.id)"
-                    >
-                        <template #list-items>
-                            <VnLv label="NIF/CIF" :value="row.nif" />
-                            <VnLv label="Alias" :value="row.alias" />
-                            <VnLv
-                                :label="t('supplier.list.payMethod')"
-                                :value="row.payMethod"
-                            />
-                            <VnLv
-                                :label="t('supplier.list.payDeadline')"
-                                :title-label="t('invoiceOut.list.created')"
-                                :value="row.payDem"
-                            />
-                            <VnLv
-                                :label="t('supplier.list.payDay')"
-                                :value="row.payDay"
-                            />
-                            <VnLv
-                                :label="t('supplier.list.account')"
-                                :value="row.account"
-                            />
-                        </template>
-                        <template #actions>
-                            <QBtn
-                                :label="t('components.smartCard.openSummary')"
-                                @click.stop="viewSummary(row.id, SupplierSummary)"
-                                color="primary"
-                            />
-                        </template>
-                    </CardList>
-                </template>
-            </VnPaginate>
-        </div>
-        <QPageSticky :offset="[20, 20]">
-            <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" />
-            <QTooltip>
-                {{ t('supplier.list.newSupplier') }}
-            </QTooltip>
-        </QPageSticky>
-    </QPage>
+    <VnTable
+        ref="tableRef"
+        data-key="SuppliersList"
+        url="Suppliers/filter"
+        save-url="Suppliers/crud"
+        redirect="supplier"
+        :create="{
+            urlCreate: 'Suppliers/newSupplier',
+            title: t('Create Supplier'),
+            onDataSaved: ({ id }) => tableRef.redirect(id),
+            formInitialData: {},
+        }"
+        order="id ASC"
+        :columns="columns"
+        default-mode="table"
+        auto-load
+        :right-search="false"
+        :use-model="true"
+    />
 </template>
 
 <i18n>
diff --git a/src/pages/Ticket/Card/TicketCreateServiceType.vue b/src/pages/Ticket/Card/TicketCreateServiceType.vue
new file mode 100644
index 000000000..d392ec206
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketCreateServiceType.vue
@@ -0,0 +1,49 @@
+<script setup>
+import { reactive, ref, onMounted, nextTick } from 'vue';
+import { useI18n } from 'vue-i18n';
+import VnInput from 'src/components/common/VnInput.vue';
+
+import VnRow from 'components/ui/VnRow.vue';
+import FormModelPopup from 'components/FormModelPopup.vue';
+
+const { t } = useI18n();
+const emit = defineEmits(['onDataSaved']);
+
+const nameInputRef = ref(null);
+const serviceFormData = reactive({});
+
+const onDataSaved = (formData, requestResponse) => {
+    emit('onDataSaved', formData, requestResponse);
+};
+
+onMounted(async () => {
+    await nextTick();
+    nameInputRef.value.focus();
+});
+</script>
+
+<template>
+    <FormModelPopup
+        url-create="TicketServiceTypes"
+        model="TicketServiceType"
+        :title="t('New service type')"
+        :form-initial-data="serviceFormData"
+        @on-data-saved="onDataSaved"
+    >
+        <template #form-inputs="{ data }">
+            <VnRow class="row q-gutter-md q-mb-md">
+                <VnInput
+                    ref="nameInputRef"
+                    :label="t('service.description')"
+                    v-model="data.name"
+                    :required="true"
+                />
+            </VnRow>
+        </template>
+    </FormModelPopup>
+</template>
+
+<i18n>
+es:
+    New service type: Nuevo tipo de servicio
+</i18n>
diff --git a/src/pages/Ticket/Card/TicketCreateTracking.vue b/src/pages/Ticket/Card/TicketCreateTracking.vue
new file mode 100644
index 000000000..399663571
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketCreateTracking.vue
@@ -0,0 +1,86 @@
+<script setup>
+import { ref } from 'vue';
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+
+import FormModelPopup from 'components/FormModelPopup.vue';
+import VnRow from 'components/ui/VnRow.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import FetchData from 'components/FetchData.vue';
+
+import { useState } from 'src/composables/useState';
+
+const emit = defineEmits(['onRequestCreated']);
+
+const route = useRoute();
+const { t } = useI18n();
+const state = useState();
+const user = state.getUser();
+const stateFetchDataRef = ref(null);
+
+const statesOptions = ref([]);
+const workersOptions = ref([]);
+
+const onStateFkChange = (formData) => (formData.userFk = user.value.id);
+</script>
+<template>
+    <FetchData
+        ref="stateFetchDataRef"
+        url="States"
+        auto-load
+        @on-fetch="(data) => (statesOptions = data)"
+    />
+    <FetchData
+        url="Workers/search"
+        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
+        auto-load
+        @on-fetch="(data) => (workersOptions = data)"
+    />
+    <FormModelPopup
+        :title="t('Create tracking')"
+        url-create="Tickets/state"
+        model="CreateTicketTracking"
+        :form-initial-data="{ ticketFk: route.params.id }"
+        @on-data-saved="() => emit('onRequestCreated')"
+    >
+        <template #form-inputs="{ data }">
+            <VnRow class="row q-gutter-md q-mb-md">
+                <VnSelect
+                    v-model="data.stateFk"
+                    :label="t('tracking.state')"
+                    :options="statesOptions"
+                    @update:model-value="onStateFkChange(data)"
+                    hide-selected
+                    option-label="name"
+                    option-value="id"
+                />
+                <VnSelect
+                    :label="t('tracking.worker')"
+                    v-model="data.userFk"
+                    :options="workersOptions"
+                    hide-selected
+                    option-label="name"
+                    option-value="id"
+                >
+                    <template #option="{ opt, itemProps }">
+                        <QItem v-bind="itemProps">
+                            <QItemSection>
+                                <QItemLabel>
+                                    {{ opt.name }}
+                                </QItemLabel>
+                                <QItemLabel caption>
+                                    {{ opt.nickname }}, {{ opt.code }}
+                                </QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template></VnSelect
+                >
+            </VnRow>
+        </template>
+    </FormModelPopup>
+</template>
+
+<i18n>
+    es:
+        Create tracking: Crear estado
+</i18n>
diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue
index dfbcfc106..b753d0b4c 100644
--- a/src/pages/Ticket/Card/TicketDescriptor.vue
+++ b/src/pages/Ticket/Card/TicketDescriptor.vue
@@ -70,8 +70,6 @@ const filter = {
 };
 
 const data = ref(useCardDescription());
-const setData = (entity) =>
-    (data.value = useCardDescription(entity.client.name, entity.id));
 </script>
 
 <template>
@@ -82,7 +80,6 @@ const setData = (entity) =>
         :title="data.title"
         :subtitle="data.subtitle"
         data-key="ticketData"
-        @on-fetch="setData"
     >
         <template #menu="{ entity }">
             <TicketDescriptorMenu :ticket="entity" />
@@ -92,7 +89,7 @@ const setData = (entity) =>
                 <template #value>
                     <span class="link">
                         {{ entity.clientFk }}
-                        <CustomerDescriptorProxy :id="entity.client.id" />
+                        <CustomerDescriptorProxy :id="entity.client?.id" />
                     </span>
                 </template>
             </VnLv>
@@ -109,8 +106,8 @@ const setData = (entity) =>
             <VnLv :label="t('ticket.summary.salesPerson')">
                 <template #value>
                     <VnUserLink
-                        :name="entity.client.salesPersonUser?.name"
-                        :worker-id="entity.client.salesPersonFk"
+                        :name="entity.client?.salesPersonUser?.name"
+                        :worker-id="entity.client?.salesPersonFk"
                     />
                 </template>
             </VnLv>
@@ -153,4 +150,5 @@ const setData = (entity) =>
 <i18n>
 es:
     This ticket is deleted: Este ticket está eliminado
+    Go to module index: Ir al índice del modulo
 </i18n>
diff --git a/src/pages/Ticket/Card/TicketDescriptorProxy.vue b/src/pages/Ticket/Card/TicketDescriptorProxy.vue
index 7799b9ee6..583ba35e7 100644
--- a/src/pages/Ticket/Card/TicketDescriptorProxy.vue
+++ b/src/pages/Ticket/Card/TicketDescriptorProxy.vue
@@ -1,5 +1,6 @@
 <script setup>
 import TicketDescriptor from './TicketDescriptor.vue';
+import TicketSummary from './TicketSummary.vue';
 
 const $props = defineProps({
     id: {
@@ -10,6 +11,6 @@ const $props = defineProps({
 </script>
 <template>
     <QPopupProxy>
-        <TicketDescriptor v-if="$props.id" :id="$props.id" />
+        <TicketDescriptor v-if="$props.id" :id="$props.id" :summary="TicketSummary" />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Ticket/Card/TicketNotes.vue b/src/pages/Ticket/Card/TicketNotes.vue
new file mode 100644
index 000000000..cfc0c2431
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketNotes.vue
@@ -0,0 +1,106 @@
+<script setup>
+import { ref, watch, computed, reactive } from 'vue';
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+
+import CrudModel from 'components/CrudModel.vue';
+import VnRow from 'components/ui/VnRow.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import FetchData from 'components/FetchData.vue';
+
+import { useArrayData } from 'src/composables/useArrayData';
+
+const route = useRoute();
+const { t } = useI18n();
+const ticketNotesCrudRef = ref(null);
+const observationTypes = ref([]);
+const arrayData = useArrayData('TicketNotes');
+const { store } = arrayData;
+
+const crudModelFilter = reactive({
+    where: { ticketFk: route.params.id },
+    fields: ['id', 'ticketFk', 'observationTypeFk', 'description'],
+});
+
+const crudModelRequiredData = computed(() => ({ ticketFk: route.params.id }));
+
+watch(
+    () => route.params.id,
+    async () => {
+        crudModelFilter.where.ticketFk = route.params.id;
+        store.filter = crudModelFilter;
+        await ticketNotesCrudRef.value.reload();
+    }
+);
+</script>
+
+<template>
+    <FetchData
+        @on-fetch="(data) => (observationTypes = data)"
+        auto-load
+        url="ObservationTypes"
+    />
+    <div class="flex justify-center">
+        <CrudModel
+            ref="ticketNotesCrudRef"
+            data-key="TicketNotes"
+            url="TicketObservations"
+            model="TicketNotes"
+            :filter="crudModelFilter"
+            :data-required="crudModelRequiredData"
+            :default-remove="false"
+            auto-load
+            style="max-width: 800px"
+        >
+            <template #body="{ rows }">
+                <QCard class="q-px-lg q-py-md">
+                    <div
+                        v-for="(row, index) in rows"
+                        :key="index"
+                        class="q-mb-md row items-center q-gutter-x-md"
+                    >
+                        <VnSelect
+                            :label="t('ticketNotes.observationType')"
+                            :options="observationTypes"
+                            hide-selected
+                            option-label="description"
+                            option-value="id"
+                            v-model="row.observationTypeFk"
+                            :disable="!!row.id"
+                        />
+                        <VnInput
+                            :label="t('ticketNotes.description')"
+                            v-model="row.description"
+                            class="col"
+                        />
+                        <QIcon
+                            name="delete"
+                            size="sm"
+                            class="cursor-pointer"
+                            color="primary"
+                            @click="ticketNotesCrudRef.remove([row])"
+                        >
+                            <QTooltip>
+                                {{ t('ticketNotes.removeNote') }}
+                            </QTooltip>
+                        </QIcon>
+                    </div>
+                    <VnRow v-if="observationTypes.length > rows.length">
+                        <QIcon
+                            name="add_circle"
+                            class="fill-icon-on-hover q-ml-md"
+                            size="sm"
+                            color="primary"
+                            @click="ticketNotesCrudRef.insert()"
+                        >
+                            <QTooltip>
+                                {{ t('ticketNotes.addNote') }}
+                            </QTooltip>
+                        </QIcon>
+                    </VnRow>
+                </QCard>
+            </template>
+        </CrudModel>
+    </div>
+</template>
diff --git a/src/pages/Ticket/Card/TicketService.vue b/src/pages/Ticket/Card/TicketService.vue
new file mode 100644
index 000000000..4cc8207ef
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketService.vue
@@ -0,0 +1,190 @@
+<script setup>
+import { ref, watch, computed, onMounted } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+
+import CrudModel from 'components/CrudModel.vue';
+import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
+import FetchData from 'components/FetchData.vue';
+import TicketCreateServiceType from './TicketCreateServiceType.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+
+import { useArrayData } from 'src/composables/useArrayData';
+import useNotify from 'src/composables/useNotify.js';
+import axios from 'axios';
+
+const route = useRoute();
+const router = useRouter();
+const { t } = useI18n();
+const ticketServiceTypeFetchRef = ref(null);
+const ticketServiceCrudRef = ref(null);
+const ticketServiceOptions = ref([]);
+const arrayData = useArrayData('TicketNotes');
+const { store } = arrayData;
+const { notify } = useNotify();
+
+const selected = ref([]);
+const defaultTaxClass = ref(null);
+
+const crudModelFilter = computed(() => ({
+    where: { ticketFk: route.params.id },
+}));
+
+const crudModelRequiredData = computed(() => ({
+    ticketFk: route.params.id,
+    taxClassFk: defaultTaxClass.value?.id,
+}));
+
+watch(
+    () => route.params.id,
+    async () => {
+        store.filter = crudModelFilter.value;
+        await ticketServiceCrudRef.value.reload();
+    }
+);
+
+onMounted(async () => await getDefaultTaxClass());
+
+const createRefund = async () => {
+    try {
+        if (!selected.value.length) return;
+
+        const params = {
+            servicesIds: selected.value.map((s) => +s.ticketFk),
+            withWarehouse: false,
+            negative: true,
+        };
+        const { data } = await axios.post('Sales/clone', params);
+        const [refundTicket] = data;
+        notify(
+            t('service.createRefundSuccess', {
+                ticketId: refundTicket.id,
+            }),
+            'positive'
+        );
+        router.push({ name: 'TicketSale', params: { id: refundTicket.id } });
+    } catch (error) {
+        console.error(error);
+    }
+};
+
+const getDefaultTaxClass = async () => {
+    try {
+        let filter = {
+            where: { code: 'G' },
+        };
+        const { data } = await axios.get('TaxClasses/findOne', {
+            params: { filter: JSON.stringify(filter) },
+        });
+        defaultTaxClass.value = data;
+        console.log('defaultTaxClass', defaultTaxClass.value);
+    } catch (error) {
+        console.error(error);
+    }
+};
+
+const columns = computed(() => [
+    {
+        name: 'description',
+        label: t('service.description'),
+        field: (row) => row.ticketServiceTypeFk,
+        sortable: true,
+        align: 'left',
+    },
+    {
+        name: 'quantity',
+        label: t('service.quantity'),
+        field: (row) => row.quantity,
+        sortable: true,
+        align: 'left',
+    },
+    {
+        name: 'price',
+        label: t('service.price'),
+        field: (row) => row.price,
+        sortable: true,
+        align: 'left',
+    },
+]);
+</script>
+
+<template>
+    <FetchData
+        ref="ticketServiceTypeFetchRef"
+        @on-fetch="(data) => (ticketServiceOptions = data)"
+        auto-load
+        url="TicketServiceTypes"
+    />
+    <CrudModel
+        ref="ticketServiceCrudRef"
+        data-key="TicketService"
+        url="TicketServices"
+        model="TicketService"
+        :filter="crudModelFilter"
+        :data-required="crudModelRequiredData"
+        auto-load
+        v-model:selected="selected"
+    >
+        <template #moreBeforeActions>
+            <QBtn
+                color="primary"
+                :label="t('service.pay')"
+                :disabled="!selected.length"
+                @click.stop="createRefund()"
+            />
+        </template>
+        <template #body="{ rows }">
+            <QTable
+                :columns="columns"
+                :rows="rows"
+                row-key="$index"
+                selection="multiple"
+                v-model:selected="selected"
+                table-header-class="text-left"
+            >
+                <template #body-cell-description="{ row, col }">
+                    <QTd auto-width>
+                        <VnSelectDialog
+                            :label="col.label"
+                            v-model="row.ticketServiceTypeFk"
+                            :options="ticketServiceOptions"
+                            option-label="name"
+                            option-value="id"
+                            hide-selected
+                        >
+                            <template #form>
+                                <TicketCreateServiceType
+                                    @on-data-saved="ticketServiceTypeFetchRef.fetch()"
+                                />
+                            </template>
+                        </VnSelectDialog>
+                    </QTd>
+                </template>
+                <template #body-cell-quantity="{ row, col }">
+                    <QTd auto-width>
+                        <VnInput
+                            :label="col.label"
+                            v-model.number="row.quantity"
+                            type="number"
+                            min="0"
+                            :info="t('service.quantityInfo')"
+                        />
+                    </QTd>
+                </template>
+                <template #body-cell-price="{ row, col }">
+                    <QTd auto-width>
+                        <VnInput
+                            :label="col.label"
+                            v-model.number="row.price"
+                            type="number"
+                            min="0"
+                        />
+                    </QTd>
+                </template>
+            </QTable>
+        </template>
+    </CrudModel>
+    <QPageSticky position="bottom-right" :offset="[25, 25]">
+        <QBtn fab color="primary" icon="add" @click="ticketServiceCrudRef.insert()" />
+    </QPageSticky>
+</template>
diff --git a/src/pages/Ticket/Card/TicketTracking.vue b/src/pages/Ticket/Card/TicketTracking.vue
new file mode 100644
index 000000000..2ddb278fa
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketTracking.vue
@@ -0,0 +1,121 @@
+<script setup>
+import { ref, computed, watch, reactive } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useRoute } from 'vue-router';
+
+import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import TicketCreateTracking from './TicketCreateTracking.vue';
+import VnPaginate from 'components/ui/VnPaginate.vue';
+
+import { toDateTimeFormat } from 'src/filters/date.js';
+
+const route = useRoute();
+const { t } = useI18n();
+const createTrackingDialogRef = ref(null);
+const paginateRef = ref(null);
+
+watch(
+    () => route.params.id,
+    async (val) => {
+        paginateFilter.where.ticketFk = val;
+        paginateRef.value.fetch();
+    }
+);
+
+const paginateFilter = reactive({
+    include: [
+        {
+            relation: 'user',
+            scope: {
+                fields: ['id', 'name'],
+                include: {
+                    relation: 'worker',
+                    scope: {
+                        fields: ['id'],
+                    },
+                },
+            },
+        },
+        {
+            relation: 'state',
+            scope: {
+                fields: ['name'],
+            },
+        },
+    ],
+
+    order: ['created DESC'],
+    where: {
+        ticketFk: route.params.id,
+    },
+});
+
+const columns = computed(() => [
+    {
+        label: t('tracking.state'),
+        name: 'state',
+        field: 'state',
+        align: 'left',
+        format: (val) => val.name,
+    },
+    {
+        label: t('tracking.worker'),
+        name: 'worker',
+        align: 'left',
+    },
+    {
+        label: t('tracking.created'),
+        name: 'created',
+        field: 'created',
+        align: 'left',
+        format: (val) => toDateTimeFormat(val),
+    },
+]);
+
+const openCreateModal = () => createTrackingDialogRef.value.show();
+</script>
+
+<template>
+    <QPage class="column items-center q-pa-md">
+        <VnPaginate
+            ref="paginateRef"
+            data-key="TicketTracking"
+            :filter="paginateFilter"
+            url="TicketTrackings"
+            auto-load
+        >
+            <template #body="{ rows }">
+                <QTable
+                    :rows="rows"
+                    :columns="columns"
+                    row-key="id"
+                    :pagination="{ rowsPerPage: 0 }"
+                    class="full-width q-mt-md"
+                    :no-data-label="t('globals.noResults')"
+                >
+                    <template #body-cell-worker="{ row }">
+                        <QTd @click.stop>
+                            <QBtn flat color="primary">
+                                {{ row.user?.name }}
+                                <WorkerDescriptorProxy :id="row.user?.worker?.id" />
+                            </QBtn>
+                        </QTd>
+                    </template>
+                </QTable>
+            </template>
+        </VnPaginate>
+        <QDialog
+            ref="createTrackingDialogRef"
+            transition-show="scale"
+            transition-hide="scale"
+        >
+            <TicketCreateTracking @on-request-created="paginateRef.fetch()" />
+        </QDialog>
+        <QPageSticky :offset="[20, 20]">
+            <QBtn @click="openCreateModal()" color="primary" fab icon="add" />
+            <QTooltip class="text-no-wrap">
+                {{ t('tracking.addState') }}
+            </QTooltip>
+        </QPageSticky>
+    </QPage>
+</template>
diff --git a/src/pages/Ticket/Card/TicketVolume.vue b/src/pages/Ticket/Card/TicketVolume.vue
new file mode 100644
index 000000000..93da31e53
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketVolume.vue
@@ -0,0 +1,153 @@
+<script setup>
+import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useRoute } from 'vue-router';
+
+import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
+import FetchedTags from 'components/ui/FetchedTags.vue';
+import RightMenu from 'src/components/common/RightMenu.vue';
+import FetchData from 'components/FetchData.vue';
+
+import { useStateStore } from 'stores/useStateStore';
+import { dashIfEmpty } from 'src/filters';
+import axios from 'axios';
+
+const route = useRoute();
+const stateStore = useStateStore();
+const { t } = useI18n();
+const salesRef = ref(null);
+
+watch(
+    () => route.params.id,
+    async () => {
+        await nextTick();
+        salesRef.value?.fetch();
+    }
+);
+
+const salesFilter = computed(() => ({
+    include: { relation: 'item' },
+    order: 'concept',
+    where: { ticketFk: route.params.id },
+    limit: 20,
+}));
+
+const sales = ref([]);
+const packingTypeVolume = ref([]);
+const rows = computed(() => sales.value);
+
+const columns = computed(() => [
+    {
+        label: t('volume.item'),
+        name: 'item',
+        align: 'left',
+    },
+    {
+        label: t('volume.description'),
+        name: 'description',
+        align: 'left',
+    },
+    {
+        label: t('volume.packingType'),
+        name: 'quantity',
+        field: (row) => row.item.itemPackingTypeFk,
+        align: 'left',
+        format: (val) => dashIfEmpty(val),
+    },
+    {
+        label: t('volume.quantity'),
+        name: 'quantity',
+        field: 'quantity',
+        align: 'left',
+    },
+    {
+        label: t('volume.volumeQuantity'),
+        name: 'quantity',
+        field: (row) => row.saleVolume?.volume,
+        align: 'left',
+    },
+]);
+
+const applyVolumes = async (salesData) => {
+    try {
+        if (!salesData.length) return;
+
+        sales.value = salesData;
+        const ticket = sales.value[0].ticketFk;
+        const { data } = await axios.get(`Tickets/${ticket}/getVolume`);
+        const volumes = new Map(data.saleVolume.map((volume) => [volume.saleFk, volume]));
+
+        sales.value.forEach((sale) => {
+            sale.saleVolume = volumes.get(sale.id);
+        });
+
+        packingTypeVolume.value = data.packingTypeVolume;
+    } catch (error) {
+        console.error(error);
+    }
+};
+
+onMounted(() => {
+    stateStore.rightDrawer = true;
+});
+
+onUnmounted(() => (stateStore.rightDrawer = false));
+</script>
+
+<template>
+    <FetchData
+        ref="salesRef"
+        url="sales"
+        :filter="salesFilter"
+        @on-fetch="(data) => applyVolumes(data)"
+        auto-load
+    />
+    <RightMenu v-if="packingTypeVolume.length">
+        <template #right-panel>
+            <QCard
+                v-for="(packingType, index) in packingTypeVolume"
+                :key="index"
+                class="q-pa-md q-mb-md q-ma-md color-vn-text"
+                bordered
+                flat
+                style="border-color: black"
+            >
+                <QCardSection class="column items-center" horizontal>
+                    <span>
+                        {{ t('volume.type') }}:
+                        {{ dashIfEmpty(packingType.description) }}
+                    </span>
+                </QCardSection>
+                <QCardSection class="column items-center" horizontal>
+                    <span> {{ t('volume.volume') }}: {{ packingType.volume }} </span>
+                </QCardSection>
+            </QCard>
+        </template>
+    </RightMenu>
+    <QTable
+        :rows="rows"
+        :columns="columns"
+        row-key="id"
+        :pagination="{ rowsPerPage: 0 }"
+        class="full-width q-mt-md"
+        :no-data-label="t('globals.noResults')"
+    >
+        <template #body-cell-item="{ row }">
+            <QTd>
+                <QBtn flat color="primary">
+                    {{ row.itemFk }}
+                    <ItemDescriptorProxy :id="row.itemFk" />
+                </QBtn>
+            </QTd>
+        </template>
+        <template #body-cell-description="{ row }">
+            <QTd>
+                <div class="column">
+                    <span>{{ row.item.name }}</span>
+                    <span class="color-vn-label">{{ row.item.subName }}</span>
+                    <FetchedTags :item="row.item" :max-length="6" />
+                </div>
+            </QTd>
+        </template>
+    </QTable>
+</template>
diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue
index 7b74117bb..63ac48393 100644
--- a/src/pages/Ticket/TicketFilter.vue
+++ b/src/pages/Ticket/TicketFilter.vue
@@ -17,15 +17,6 @@ const props = defineProps({
     },
 });
 
-const from = Date.vnNew();
-const to = Date.vnNew();
-to.setDate(to.getDate() + 1);
-
-const defaultParams = {
-    from: toDateString(from),
-    to: toDateString(to),
-};
-
 const workers = ref();
 const provinces = ref();
 const states = ref();
@@ -44,11 +35,7 @@ const warehouses = ref();
         @on-fetch="(data) => (workers = data)"
         auto-load
     />
-    <VnFilterPanel
-        :data-key="props.dataKey"
-        :params="defaultParams"
-        :search-button="true"
-    >
+    <VnFilterPanel :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
                 <strong>{{ t(`params.${tag.label}`) }}: </strong>
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index c065cf6bf..16d7aac5d 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -26,8 +26,8 @@ const to = Date.vnNew();
 to.setDate(to.getDate() + 1);
 
 const userParams = {
-    from: toDateString(from),
-    to: toDateString(to),
+    from: from.toISOString(),
+    to: to.toISOString(),
 };
 
 function navigate(id) {
diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml
index 2c648e7f2..39aed4af7 100644
--- a/src/pages/Ticket/locale/en.yml
+++ b/src/pages/Ticket/locale/en.yml
@@ -1,3 +1,19 @@
+card:
+    search: Search tickets
+    searchInfo: You can search by ticket id or alias
+volume:
+    item: Item
+    description: Description
+    packingType: Packing Type
+    quantity: Quantity
+    volumeQuantity: m³ per quantity
+    type: Type
+    volume: Volume
+ticketNotes:
+    observationType: Observation type
+    description: Description
+    removeNote: Remove note
+    addNote: Add note
 ticketSale:
     id: Id
     visible: Visible
@@ -113,9 +129,6 @@ basicData:
     negativesConfirmMessage: Negatives are going to be generated, are you sure you want to advance all the lines?
     chooseAnOption: Choose an option
     unroutedTicket: The ticket has been unrouted
-card:
-    search: Search tickets
-    searchInfo: You can search by ticket id or alias
 purchaseRequest:
     id: Id
     description: Description
@@ -136,3 +149,18 @@ weeklyTickets:
     salesperson: Salesperson
     search: Search weekly tickets
     searchInfo: Search weekly tickets by id or client id
+service:
+    pay: Pay
+    description: Description
+    quantity: Quantity
+    price: Price
+    removeService: Remove service
+    newService: New service type
+    addService: Add service
+    quantityInfo: To create services with negative amounts mark the service on the source ticket and press the pay button.
+    createRefundSuccess: 'The following refund ticket have been created: { ticketId }'
+tracking:
+    state: State
+    worker: Worker
+    created: Created
+    addState: Add state
diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml
index 3ce4c0545..d5b50efc5 100644
--- a/src/pages/Ticket/locale/es.yml
+++ b/src/pages/Ticket/locale/es.yml
@@ -1,6 +1,34 @@
+service:
+    pay: Abonar
+    description: Descripción
+    quantity: Cantidad
+    price: Precio
+    removeService: Quitar servicio
+    newService: Nuevo tipo de servicio
+    addService: Añadir servicio
+    quantityInfo: Para crear sevicios con cantidades negativas marcar servicio en el ticket origen y apretar el boton abonar.
+    createRefundSuccess: 'Se ha creado siguiente ticket de abono: { ticketId }'
+tracking:
+    state: Estado
+    worker: Trabajador
+    created: Fecha creación
+    addState: Añadir estado
 card:
     search: Buscar tickets
     searchInfo: Buscar tickets por identificador o alias
+volume:
+    item: Artículo
+    description: Descripción
+    packingType: Encajado
+    quantity: Cantidad
+    volumeQuantity: m³ por cantidad
+    type: Tipo
+    volume: Volumen
+ticketNotes:
+    observationType: Tipo de observación
+    description: Descripción
+    removeNote: Quitar nota
+    addNote: Añadir nota
 purchaseRequest:
     Id: Id
     description: Descripción
@@ -112,8 +140,6 @@ futureTickets:
     moveTicketSuccess: Tickets movidos correctamente
     searchInfo: Buscar tickets por fecha
     futureTicket: Tickets a futuro
-Search ticket: Buscar tickets
-You can search by ticket id or alias: Puedes buscar por id o alias del ticket
 ticketSale:
     id: Id
     visible: Visible
@@ -138,3 +164,5 @@ ticketSale:
     shipped: F. Envío
     agency: Agencia
     address: Consignatario
+Search ticket: Buscar tickets
+You can search by ticket id or alias: Puedes buscar por id o alias del ticket
diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue
index bf7e6d57a..a3c1430e9 100644
--- a/src/pages/Travel/Card/TravelCard.vue
+++ b/src/pages/Travel/Card/TravelCard.vue
@@ -33,8 +33,12 @@ const filter = {
 <template>
     <VnCard
         data-key="Travel"
-        :filter="filter"
         base-url="Travels"
+        search-data-key="TravelList"
+        searchbar-label="Search travel"
+        searchbar-info="You can search by travel id or name"
+        search-url="Travels"
+        :filter="filter"
         :descriptor="TravelDescriptor"
     />
 </template>
diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue
index 6d3707828..b74761b37 100644
--- a/src/pages/Travel/Card/TravelDescriptor.vue
+++ b/src/pages/Travel/Card/TravelDescriptor.vue
@@ -1,10 +1,11 @@
 <script setup>
-import { computed } from 'vue';
+import { computed, ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
+import useCardDescription from 'src/composables/useCardDescription';
 import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
 
 import { toDate } from 'src/filters';
@@ -51,32 +52,22 @@ const filter = {
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+
+const data = ref(useCardDescription());
+const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.id));
 </script>
 
 <template>
     <CardDescriptor
         module="Travel"
         :url="`Travels/${entityId}`"
-        title="ref"
+        :title="data.title"
+        :subtitle="data.subtitle"
         :filter="filter"
-        data-key="Travel"
+        data-key="travelData"
+        :summary="$attrs"
+        @on-fetch="setData"
     >
-        <template #header-extra-action>
-            <QBtn
-                round
-                flat
-                dense
-                size="md"
-                icon="local_airport"
-                color="white"
-                class="link"
-                :to="{ name: 'TravelList' }"
-            >
-                <QTooltip>
-                    {{ t('Go to module index') }}
-                </QTooltip>
-            </QBtn>
-        </template>
         <template #menu="{ entity }">
             <TravelDescriptorMenuItems :travel="entity" />
         </template>
diff --git a/src/pages/Travel/Card/TravelDescriptorProxy.vue b/src/pages/Travel/Card/TravelDescriptorProxy.vue
index ab5c42d7e..eddadb382 100644
--- a/src/pages/Travel/Card/TravelDescriptorProxy.vue
+++ b/src/pages/Travel/Card/TravelDescriptorProxy.vue
@@ -1,5 +1,6 @@
 <script setup>
 import TravelDescriptor from './TravelDescriptor.vue';
+import TravelSummary from './TravelSummary.vue';
 
 const $props = defineProps({
     id: {
@@ -11,6 +12,6 @@ const $props = defineProps({
 
 <template>
     <QPopupProxy>
-        <TravelDescriptor v-if="$props.id" :id="$props.id" />
+        <TravelDescriptor v-if="$props.id" :id="$props.id" :summary="TravelSummary" />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index 88ddee9a2..af9aa5f7f 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -12,8 +12,6 @@ import FetchData from 'src/components/FetchData.vue';
 import { toDate, toCurrency } from 'src/filters';
 import axios from 'axios';
 
-onUpdated(() => summaryRef.value.fetch());
-
 const $props = defineProps({
     id: {
         type: Number,
@@ -49,7 +47,7 @@ const entriesTableColumns = computed(() => {
             showValue: false,
         },
         {
-            label: t('supplier.pageTitles.supplier'),
+            label: t('globals.pageTitles.supplier'),
             field: 'supplierName',
             name: 'supplierName',
             align: 'left',
@@ -248,7 +246,7 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnTitle
                         :url="getLink('basic-data')"
-                        :text="t('travel.pageTitles.basicData')"
+                        :text="t('globals.pageTitles.basicData')"
                     />
                 </QCardSection>
                 <VnLv :label="t('globals.shipped')" :value="toDate(travel.shipped)" />
@@ -266,7 +264,7 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnTitle
                         :url="getLink('basic-data')"
-                        :text="t('travel.pageTitles.basicData')"
+                        :text="t('globals.pageTitles.basicData')"
                     />
                 </QCardSection>
                 <VnLv :label="t('globals.landed')" :value="toDate(travel.landed)" />
@@ -284,7 +282,7 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnTitle
                         :url="getLink('basic-data')"
-                        :text="t('travel.pageTitles.basicData')"
+                        :text="t('globals.pageTitles.basicData')"
                     />
                 </QCardSection>
                 <VnLv :label="t('globals.agency')" :value="travel.agency?.name" />
diff --git a/src/pages/Travel/ExtraCommunity.vue b/src/pages/Travel/ExtraCommunity.vue
index 98648512f..4dc7eb052 100644
--- a/src/pages/Travel/ExtraCommunity.vue
+++ b/src/pages/Travel/ExtraCommunity.vue
@@ -140,7 +140,7 @@ const columns = computed(() => [
         sortable: true,
     },
     {
-        label: t('supplier.pageTitles.supplier'),
+        label: t('globals.pageTitles.supplier'),
         field: 'cargoSupplierNickname',
         name: 'cargoSupplierNickname',
         align: 'left',
diff --git a/src/pages/Travel/ExtraCommunityFilter.vue b/src/pages/Travel/ExtraCommunityFilter.vue
index 7fe628180..c51151451 100644
--- a/src/pages/Travel/ExtraCommunityFilter.vue
+++ b/src/pages/Travel/ExtraCommunityFilter.vue
@@ -7,6 +7,7 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
+import axios from 'axios';
 
 const { t } = useI18n();
 const props = defineProps({
@@ -20,6 +21,7 @@ const warehousesOptions = ref([]);
 const continentsOptions = ref([]);
 const agenciesOptions = ref([]);
 const suppliersOptions = ref([]);
+const warehousesByContinent = ref({});
 
 const add = (paramsObj, key) => {
     if (paramsObj[key] === undefined) {
@@ -34,6 +36,28 @@ const decrement = (paramsObj, key) => {
 
     paramsObj[key]--;
 };
+
+const warehouses = async () => {
+    const warehousesResponse = await axios.get('Warehouses');
+    const countriesResponse = await axios.get('Countries');
+    const continentsResponse = await axios.get('Continents');
+
+    const countryContinentMap = countriesResponse.data.reduce((acc, country) => {
+        acc[country.id] = country.continentFk;
+        return acc;
+    }, {});
+
+    continentsResponse.data.forEach((continent) => {
+        const countriesInContinent = Object.keys(countryContinentMap).filter(
+            (countryId) => countryContinentMap[countryId] === continent.id.toString()
+        );
+
+        warehousesByContinent.value[continent.code] = warehousesResponse.data.filter(
+            (warehouse) => countriesInContinent.includes(warehouse.countryFk.toString())
+        );
+    });
+};
+warehouses();
 </script>
 
 <template>
@@ -116,7 +140,6 @@ const decrement = (paramsObj, key) => {
                     <VnSelect
                         :label="t('params.agencyModeFk')"
                         v-model="params.agencyModeFk"
-                        @update:model-value="searchFn()"
                         :options="agenciesOptions"
                         option-value="agencyFk"
                         option-label="name"
@@ -147,12 +170,26 @@ const decrement = (paramsObj, key) => {
                     />
                 </QItemSection>
             </QItem>
-            <QItem>
+            <QItem v-if="warehousesByContinent[params.continent]">
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.warehouseOutFk')"
+                        v-model="params.warehouseOutFk"
+                        :options="warehousesByContinent[params.continent]"
+                        option-value="id"
+                        option-label="name"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem v-else>
                 <QItemSection>
                     <VnSelect
                         :label="t('params.warehouseOutFk')"
                         v-model="params.warehouseOutFk"
-                        @update:model-value="searchFn()"
                         :options="warehousesOptions"
                         option-value="id"
                         option-label="name"
@@ -168,7 +205,6 @@ const decrement = (paramsObj, key) => {
                     <VnSelect
                         :label="t('params.warehouseInFk')"
                         v-model="params.warehouseInFk"
-                        @update:model-value="searchFn()"
                         :options="warehousesOptions"
                         option-value="id"
                         option-label="name"
@@ -182,9 +218,8 @@ const decrement = (paramsObj, key) => {
             <QItem>
                 <QItemSection>
                     <VnSelect
-                        :label="t('supplier.pageTitles.supplier')"
+                        :label="t('globals.pageTitles.supplier')"
                         v-model="params.cargoSupplierFk"
-                        @update:model-value="searchFn()"
                         :options="suppliersOptions"
                         option-value="id"
                         option-label="name"
@@ -200,7 +235,6 @@ const decrement = (paramsObj, key) => {
                     <VnSelect
                         :label="t('params.continent')"
                         v-model="params.continent"
-                        @update:model-value="searchFn()"
                         :options="continentsOptions"
                         option-value="code"
                         option-label="name"
diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue
index e6696b26f..12a5fafa5 100644
--- a/src/pages/Travel/TravelList.vue
+++ b/src/pages/Travel/TravelList.vue
@@ -2,31 +2,27 @@
 import { onMounted, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
-import VnPaginate from 'src/components/ui/VnPaginate.vue';
-import CardList from 'src/components/ui/CardList.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
-import TravelSummary from './Card/TravelSummary.vue';
-import TravelFilter from './TravelFilter.vue';
-import FetchData from 'components/FetchData.vue';
-import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
-
+import { useRoute } from 'vue-router';
 import { useStateStore } from 'stores/useStateStore';
-import { toDate } from 'src/filters/index';
+import VnTable from 'components/VnTable/VnTable.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
-import RightMenu from 'src/components/common/RightMenu.vue';
-
+import { computed } from 'vue';
+import TravelSummary from './Card/TravelSummary.vue';
+import VnSearchbar from 'components/ui/VnSearchbar.vue';
+import { dashIfEmpty, toDate } from 'src/filters';
+const { viewSummary } = useSummaryDialog();
 const router = useRouter();
 const { t } = useI18n();
 const stateStore = useStateStore();
-const { viewSummary } = useSummaryDialog();
-
-const warehouses = ref([]);
-
-const navigateToTravelId = (id) => {
-    router.push({ path: `/travel/${id}` });
-};
-
+const route = useRoute();
+const tableRef = ref();
+const $props = defineProps({
+    id: {
+        type: Number,
+        default: 0,
+    },
+});
+const entityId = computed(() => $props.id || route.params.id);
 const cloneTravel = (travelData) => {
     const stringifiedTravelData = JSON.stringify(travelData);
     redirectToCreateView(stringifiedTravelData);
@@ -40,125 +36,170 @@ const redirectCreateEntryView = (travelData) => {
     router.push({ name: 'EntryCreate', query: { travelFk: travelData.id } });
 };
 
-const getWarehouseName = (id) => {
-    return warehouses.value.find((warehouse) => warehouse.id === id).name;
-};
-
 onMounted(async () => {
     stateStore.rightDrawer = true;
 });
+
+const columns = computed(() => [
+    {
+        align: 'left',
+        name: 'id',
+        label: t('travel.travelList.tableVisibleColumns.id'),
+        isId: true,
+        field: 'id',
+        cardVisible: true,
+    },
+    {
+        align: 'left',
+        name: 'ref',
+        label: t('travel.travelList.tableVisibleColumns.ref'),
+        field: 'ref',
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+    },
+    {
+        align: 'left',
+        name: 'agencyModeFk',
+        label: t('travel.travelList.tableVisibleColumns.agency'),
+        field: 'agencyModeFk',
+        component: 'select',
+        attrs: {
+            url: 'agencyModes',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+    },
+    {
+        align: 'left',
+        name: 'shipped',
+        label: t('travel.travelList.tableVisibleColumns.shipped'),
+        field: 'shipped',
+        component: 'date',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.shipped)),
+    },
+    {
+        align: 'left',
+        name: 'landed',
+        label: t('travel.travelList.tableVisibleColumns.landed'),
+        field: 'landed',
+        component: 'date',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)),
+    },
+    {
+        align: 'left',
+        name: 'warehouseInFk',
+        label: t('travel.travelList.tableVisibleColumns.warehouseIn'),
+        field: 'warehouseInFk',
+        component: 'select',
+        attrs: {
+            url: 'warehouses',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+    },
+    {
+        align: 'left',
+        name: 'warehouseOutFk',
+        label: t('travel.travelList.tableVisibleColumns.warehouseOut'),
+        field: 'warehouseOutFk',
+        component: 'select',
+        attrs: {
+            url: 'warehouses',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+    },
+    {
+        align: 'left',
+        name: 'totalEntries',
+        label: t('travel.travelList.tableVisibleColumns.totalEntries'),
+        field: 'totalEntries',
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+    },
+    {
+        align: 'right',
+        label: '',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('Clone'),
+                icon: 'vn:clone',
+                action: cloneTravel,
+                isPrimary: true,
+            },
+            {
+                title: t('Add entry'),
+                icon: 'contact_support',
+                action: redirectCreateEntryView,
+            },
+            {
+                title: t('View Summary'),
+                icon: 'preview',
+                action: (row) => viewSummary(row.id, TravelSummary),
+            },
+        ],
+    },
+]);
 </script>
 
 <template>
-    <FetchData
-        url="Warehouses"
-        :filter="{ fields: ['id', 'name'] }"
-        order="name"
-        @on-fetch="(data) => (warehouses = data)"
-        auto-load
+    <VnSearchbar
+        :info="t('You can search by travel id or name')"
+        :label="t('Search travel')"
+        data-key="TravelList"
+    />
+    <VnTable
+        ref="tableRef"
+        data-key="TravelList"
+        url="Travels/filter"
+        :create="{
+            urlCreate: 'Travels',
+            title: t('Create Travels'),
+            onDataSaved: ({ id }) => tableRef.redirect(id),
+            formInitialData: {
+                editorFk: entityId,
+            },
+        }"
+        order="landed DESC"
+        :columns="columns"
+        default-mode="table"
+        auto-load
+        redirect="travel"
+        :right-search="false"
+        :is-editable="false"
+        :use-model="true"
     />
-    <VnSearchbar data-key="TravelList" :limit="20" :label="t('searchByIdOrReference')" />
-    <RightMenu>
-        <template #right-panel>
-            <TravelFilter data-key="TravelList" />
-        </template>
-    </RightMenu>
-    <QPage class="column items-center q-pa-md">
-        <div class="vn-card-list">
-            <VnPaginate
-                data-key="TravelList"
-                url="Travels/filter"
-                auto-load
-                order="shipped DESC, landed DESC"
-            >
-                <template #body="{ rows }">
-                    <CardList
-                        v-for="row of rows"
-                        :key="row.id"
-                        :title="row.ref"
-                        :id="row.id"
-                        @click="navigateToTravelId(row.id)"
-                    >
-                        <template #list-items>
-                            <VnLv
-                                :label="t('globals.agency')"
-                                :value="row.agencyModeName"
-                            />
-                            <VnLv
-                                v-if="warehouses.length > 0"
-                                :label="t('globals.wareHouseOut')"
-                                :value="getWarehouseName(row.warehouseOutFk)"
-                            />
-                            <VnLv :label="t('globals.shipped')">
-                                <template #value>
-                                    <QBadge
-                                        text-color="black"
-                                        v-if="getDateQBadgeColor(row.shipped)"
-                                        :color="getDateQBadgeColor(row.shipped)"
-                                        class="q-ma-none"
-                                        dense
-                                        style="font-size: 14px"
-                                    >
-                                        {{ toDate(row.shipped) }}
-                                    </QBadge>
-                                    <span v-else>{{ toDate(row.shipped) }}</span>
-                                </template>
-                            </VnLv>
-                            <VnLv :label="t('globals.landed')">
-                                <template #value>
-                                    <QBadge
-                                        text-color="black"
-                                        v-if="getDateQBadgeColor(row.landed)"
-                                        :color="getDateQBadgeColor(row.landed)"
-                                        class="q-ma-none"
-                                        dense
-                                        style="font-size: 14px"
-                                    >
-                                        {{ toDate(row.landed) }}
-                                    </QBadge>
-                                    <span v-else>{{ toDate(row.landed) }}</span>
-                                </template>
-                            </VnLv>
-                            <VnLv
-                                v-if="warehouses.length > 0"
-                                :label="t('globals.wareHouseIn')"
-                                :value="getWarehouseName(row.warehouseInFk)"
-                            />
-                            <VnLv
-                                :label="t('globals.totalEntries')"
-                                :value="row.totalEntries"
-                            />
-                        </template>
-                        <template #actions>
-                            <QBtn
-                                :label="t('components.smartCard.clone')"
-                                @click.stop="cloneTravel(row)"
-                                outline
-                            />
-                            <QBtn
-                                :label="t('addEntry')"
-                                @click.stop="redirectCreateEntryView(row)"
-                                outline
-                                style="margin-top: 15px"
-                            />
-                            <QBtn
-                                :label="t('components.smartCard.openSummary')"
-                                @click.stop="viewSummary(row.id, TravelSummary)"
-                                color="primary"
-                                style="margin-top: 15px"
-                            />
-                        </template>
-                    </CardList>
-                </template>
-            </VnPaginate>
-        </div>
-        <QPageSticky :offset="[20, 20]">
-            <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" />
-            <QTooltip>
-                {{ t('supplier.list.newSupplier') }}
-            </QTooltip>
-        </QPageSticky>
-    </QPage>
 </template>
 
 <i18n>
@@ -169,4 +210,6 @@ en:
 es:
     addEntry: Añadir entrada
     searchByIdOrReference: Buscar por ID o por referencia
+    You can search by travel id or name: Buscar por envio por id o nombre
+    Search travel: Buscar envio
 </i18n>
diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue
index 6739b3356..82a698878 100644
--- a/src/pages/Worker/Card/WorkerDescriptor.vue
+++ b/src/pages/Worker/Card/WorkerDescriptor.vue
@@ -17,10 +17,6 @@ const $props = defineProps({
         required: false,
         default: null,
     },
-    summary: {
-        type: Object,
-        default: null,
-    },
 });
 
 const route = useRoute();
@@ -115,7 +111,7 @@ const refetch = async () => await cardDescriptorRef.value.getData();
         :filter="filter"
         :title="data.title"
         :subtitle="data.subtitle"
-        :summary="$props.summary"
+        :summary="$attrs"
         @on-fetch="
             (data) => {
                 worker = data;
diff --git a/src/pages/Worker/Card/WorkerNotificationsManager.vue b/src/pages/Worker/Card/WorkerNotificationsManager.vue
index 8699392e0..731e073cd 100644
--- a/src/pages/Worker/Card/WorkerNotificationsManager.vue
+++ b/src/pages/Worker/Card/WorkerNotificationsManager.vue
@@ -56,7 +56,6 @@ const swapEntry = (from, to, key) => {
 };
 
 function setNotifications(data) {
-    console.log('data: ', data);
     active.value = new Map(data.active);
     available.value = new Map(data.available);
 }
diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue
index 319592fe9..d8bee4714 100644
--- a/src/pages/Worker/Card/WorkerSummary.vue
+++ b/src/pages/Worker/Card/WorkerSummary.vue
@@ -9,6 +9,7 @@ import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import VnTitle from 'src/components/common/VnTitle.vue';
+import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -161,7 +162,14 @@ const filter = {
                 <VnTitle :text="t('worker.summary.userData')" />
                 <VnLv :label="t('worker.summary.userId')" :value="worker.user.id" />
                 <VnLv :label="t('worker.card.name')" :value="worker.user.nickname" />
-                <VnLv :label="t('worker.summary.role')" :value="worker.user.role.name" />
+                <VnLv :label="t('worker.summary.role')">
+                    <template #value>
+                        <span class="link">
+                            {{ worker.user.role.name }}
+                            <RoleDescriptorProxy :id="worker.user.role.id" />
+                        </span>
+                    </template>
+                </VnLv>
                 <VnLv :value="worker?.sip?.extension">
                     <template #label>
                         {{ t('worker.summary.sipExtension') }}
diff --git a/src/pages/Zone/Card/ZoneBasicData.vue b/src/pages/Zone/Card/ZoneBasicData.vue
index 7a2c505fa..9f2195766 100644
--- a/src/pages/Zone/Card/ZoneBasicData.vue
+++ b/src/pages/Zone/Card/ZoneBasicData.vue
@@ -74,7 +74,7 @@ const agencyOptions = ref([]);
                     type="number"
                     min="0"
                 />
-                <VnInputTime v-model="data.hour" :label="t('Closing')" clearable />
+                <VnInputTime v-model="data.hour" :label="t('Closing')" />
             </VnRow>
 
             <VnRow class="row q-gutter-md q-mb-md">
diff --git a/src/pages/Zone/Card/ZoneDescriptor.vue b/src/pages/Zone/Card/ZoneDescriptor.vue
index b3a55bbe0..602fefde3 100644
--- a/src/pages/Zone/Card/ZoneDescriptor.vue
+++ b/src/pages/Zone/Card/ZoneDescriptor.vue
@@ -38,7 +38,6 @@ const entityId = computed(() => {
 });
 
 const data = ref(useCardDescription());
-
 const setData = (entity) => {
     data.value = useCardDescription(entity.ref, entity.id);
 };
@@ -53,23 +52,8 @@ const setData = (entity) => {
         :filter="filter"
         @on-fetch="setData"
         data-key="zoneData"
+        :summary="$attrs"
     >
-        <template #header-extra-action>
-            <QBtn
-                round
-                flat
-                dense
-                size="md"
-                icon="vn:zone"
-                color="white"
-                class="link"
-                :to="{ name: 'ZoneList' }"
-            >
-                <QTooltip>
-                    {{ t('Summary') }}
-                </QTooltip>
-            </QBtn>
-        </template>
         <template #menu="{ entity }">
             <ZoneDescriptorMenuItems :zone="entity" />
         </template>
@@ -82,3 +66,8 @@ const setData = (entity) => {
         </template>
     </CardDescriptor>
 </template>
+
+<i18n>
+es:
+    Go to module index: Ir al índice del módulo
+</i18n>
diff --git a/src/pages/Zone/Card/ZoneDescriptorProxy.vue b/src/pages/Zone/Card/ZoneDescriptorProxy.vue
index 15c5fb0e5..27102ac07 100644
--- a/src/pages/Zone/Card/ZoneDescriptorProxy.vue
+++ b/src/pages/Zone/Card/ZoneDescriptorProxy.vue
@@ -1,5 +1,6 @@
 <script setup>
 import ZoneDescriptor from './ZoneDescriptor.vue';
+import ZoneSummary from './ZoneSummary.vue';
 
 const $props = defineProps({
     id: {
@@ -11,6 +12,6 @@ const $props = defineProps({
 
 <template>
     <QPopupProxy>
-        <ZoneDescriptor v-if="$props.id" :id="$props.id" />
+        <ZoneDescriptor v-if="$props.id" :id="$props.id" :summary="ZoneSummary" />
     </QPopupProxy>
 </template>
diff --git a/src/router/index.js b/src/router/index.js
index 41ff4c1da..faa3ab5d4 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -11,7 +11,6 @@ import { useState } from 'src/composables/useState';
 import { useSession } from 'src/composables/useSession';
 import { useRole } from 'src/composables/useRole';
 import { useUserConfig } from 'src/composables/useUserConfig';
-import { toLowerCamel } from 'src/filters';
 import { useTokenConfig } from 'src/composables/useTokenConfig';
 import { useAcl } from 'src/composables/useAcl';
 
@@ -79,13 +78,11 @@ export default route(function (/* { store, ssrContext } */) {
         let title = t(`login.title`);
 
         const matches = to.matched;
-        let moduleName;
         if (matches && matches.length > 1) {
             const module = matches[1];
             const moduleTitle = module.meta && module.meta.title;
-            moduleName = toLowerCamel(module.name);
             if (moduleTitle) {
-                title = t(`${moduleName}.pageTitles.${moduleTitle}`);
+                title = t(`globals.pageTitles.${moduleTitle}`);
             }
         }
 
@@ -94,7 +91,7 @@ export default route(function (/* { store, ssrContext } */) {
         if (childPageTitle && matches.length > 2) {
             if (title != '') title += ': ';
 
-            const moduleLocale = `${moduleName}.pageTitles.${childPageTitle}`;
+            const moduleLocale = `globals.pageTitles.${childPageTitle}`;
             const pageTitle = te(moduleLocale)
                 ? t(moduleLocale)
                 : t(`globals.pageTitles.${childPageTitle}`);
diff --git a/src/router/modules/agency.js b/src/router/modules/agency.js
index 6f281e21d..c714865fa 100644
--- a/src/router/modules/agency.js
+++ b/src/router/modules/agency.js
@@ -18,7 +18,7 @@ export default {
         {
             path: '/agency/:id',
             name: 'AgencyCard',
-            component: () => import('src/pages/Agency/Card/AgencyCard.vue'),
+            component: () => import('src/pages/Route/Agency/Card/AgencyCard.vue'),
             redirect: { name: 'AgencySummary' },
             children: [
                 {
@@ -28,7 +28,8 @@ export default {
                         title: 'summary',
                         icon: 'view_list',
                     },
-                    component: () => import('src/pages/Agency/Card/AgencySummary.vue'),
+                    component: () =>
+                        import('src/pages/Route/Agency/Card/AgencySummary.vue'),
                 },
                 {
                     name: 'AgencyBasicData',
@@ -37,7 +38,8 @@ export default {
                         title: 'basicData',
                         icon: 'vn:settings',
                     },
-                    component: () => import('pages/Agency/Card/AgencyBasicData.vue'),
+                    component: () =>
+                        import('pages/Route/Agency/Card/AgencyBasicData.vue'),
                 },
                 {
                     path: 'workCenter',
@@ -52,7 +54,9 @@ export default {
                                 title: 'workCenters',
                             },
                             component: () =>
-                                import('src/pages/Agency/Card/AgencyWorkcenter.vue'),
+                                import(
+                                    'src/pages/Route/Agency/Card/AgencyWorkcenter.vue'
+                                ),
                         },
                     ],
                 },
@@ -69,7 +73,7 @@ export default {
                                 title: 'modes',
                             },
                             component: () =>
-                                import('src/pages/Agency/Card/AgencyModes.vue'),
+                                import('src/pages/Route/Agency/Card/AgencyModes.vue'),
                         },
                     ],
                 },
@@ -80,7 +84,7 @@ export default {
                         title: 'log',
                         icon: 'history',
                     },
-                    component: () => import('src/pages/Agency/Card/AgencyLog.vue'),
+                    component: () => import('src/pages/Route/Agency/Card/AgencyLog.vue'),
                 },
             ],
         },
diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js
index 67fc41824..4f5f05231 100644
--- a/src/router/modules/entry.js
+++ b/src/router/modules/entry.js
@@ -11,7 +11,7 @@ export default {
     component: RouterView,
     redirect: { name: 'EntryMain' },
     menus: {
-        main: ['EntryList', 'EntryLatestBuys'],
+        main: ['EntryList', 'MyEntries', 'EntryLatestBuys'],
         card: ['EntryBasicData', 'EntryBuys', 'EntryNotes', 'EntryDms', 'EntryLog'],
     },
     children: [
@@ -30,6 +30,15 @@ export default {
                     },
                     component: () => import('src/pages/Entry/EntryList.vue'),
                 },
+                {
+                    path: 'my',
+                    name: 'MyEntries',
+                    meta: {
+                        title: 'labeler',
+                        icon: 'sell',
+                    },
+                    component: () => import('src/pages/Entry/MyEntries.vue'),
+                },
                 {
                     path: 'create',
                     name: 'EntryCreate',
diff --git a/src/router/modules/item.js b/src/router/modules/item.js
index 6e8659747..06fe680eb 100644
--- a/src/router/modules/item.js
+++ b/src/router/modules/item.js
@@ -201,15 +201,6 @@ export default {
                     },
                     component: () => import('src/pages/Item/Card/ItemLog.vue'),
                 },
-                {
-                    path: 'botanical',
-                    name: 'ItemBotanical',
-                    meta: {
-                        title: 'botanical',
-                        icon: 'vn:botanical',
-                    },
-                    component: () => import('src/pages/Item/Card/ItemBotanical.vue'),
-                },
             ],
         },
     ],
diff --git a/src/router/modules/route.js b/src/router/modules/route.js
index 8e08d7222..72f423ae3 100644
--- a/src/router/modules/route.js
+++ b/src/router/modules/route.js
@@ -86,7 +86,8 @@ export default {
                                 title: 'agencyList',
                                 icon: 'view_list',
                             },
-                            component: () => import('src/pages/Agency/AgencyList.vue'),
+                            component: () =>
+                                import('src/pages/Route/Agency/AgencyList.vue'),
                         },
                     ],
                 },
diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js
index 81ca405ee..1e635470b 100644
--- a/src/router/modules/ticket.js
+++ b/src/router/modules/ticket.js
@@ -19,6 +19,10 @@ export default {
             'TicketSale',
             'TicketLog',
             'TicketPurchaseRequest',
+            'TicketService',
+            'TicketTracking',
+            'TicketVolume',
+            'TicketNotes',
         ],
     },
     children: [
@@ -29,8 +33,8 @@ export default {
             redirect: { name: 'TicketList' },
             children: [
                 {
-                    name: 'TicketList',
                     path: 'list',
+                    name: 'TicketList',
                     meta: {
                         title: 'list',
                         icon: 'view_list',
@@ -38,8 +42,8 @@ export default {
                     component: () => import('src/pages/Ticket/TicketList.vue'),
                 },
                 {
-                    name: 'TicketCreate',
                     path: 'create',
+                    name: 'TicketCreate',
                     meta: {
                         title: 'createTicket',
                         icon: 'vn:ticketAdd',
@@ -48,8 +52,8 @@ export default {
                     component: () => import('src/pages/Ticket/TicketCreate.vue'),
                 },
                 {
-                    name: 'TicketWeekly',
                     path: 'weekly',
+                    name: 'TicketWeekly',
                     meta: {
                         title: 'weeklyTickets',
                         icon: 'access_time',
@@ -57,8 +61,8 @@ export default {
                     component: () => import('src/pages/Ticket/TicketWeekly.vue'),
                 },
                 {
-                    name: 'TicketFuture',
                     path: 'future',
+                    name: 'TicketFuture',
                     meta: {
                         title: 'futureTickets',
                         icon: 'keyboard_double_arrow_right',
@@ -66,8 +70,8 @@ export default {
                     component: () => import('src/pages/Ticket/TicketFuture.vue'),
                 },
                 {
-                    name: 'TicketAdvance',
                     path: 'advance',
+                    name: 'TicketAdvance',
                     meta: {
                         title: 'ticketAdvance',
                         icon: 'keyboard_double_arrow_left',
@@ -83,8 +87,8 @@ export default {
             redirect: { name: 'TicketSummary' },
             children: [
                 {
-                    name: 'TicketSummary',
                     path: 'summary',
+                    name: 'TicketSummary',
                     meta: {
                         title: 'summary',
                         icon: 'launch',
@@ -92,8 +96,8 @@ export default {
                     component: () => import('src/pages/Ticket/Card/TicketSummary.vue'),
                 },
                 {
-                    name: 'TicketBasicData',
                     path: 'basic-data',
+                    name: 'TicketBasicData',
                     meta: {
                         title: 'basicData',
                         icon: 'vn:settings',
@@ -102,8 +106,8 @@ export default {
                         import('src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue'),
                 },
                 {
-                    name: 'TicketSale',
                     path: 'sale',
+                    name: 'TicketSale',
                     meta: {
                         title: 'sale',
                         icon: 'vn:lines',
@@ -120,6 +124,15 @@ export default {
                     component: () =>
                         import('src/pages/Ticket/Card/TicketPurchaseRequest.vue'),
                 },
+                {
+                    path: 'tracking',
+                    name: 'TicketTracking',
+                    meta: {
+                        title: 'tracking',
+                        icon: 'vn:eye',
+                    },
+                    component: () => import('src/pages/Ticket/Card/TicketTracking.vue'),
+                },
                 {
                     path: 'log',
                     name: 'TicketLog',
@@ -147,6 +160,34 @@ export default {
                     },
                     component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
                 },
+
+                {
+                    path: 'service',
+                    name: 'TicketService',
+                    meta: {
+                        title: 'services',
+                        icon: 'vn:services',
+                    },
+                    component: () => import('src/pages/Ticket/Card/TicketService.vue'),
+                },
+                {
+                    path: 'volume',
+                    name: 'TicketVolume',
+                    meta: {
+                        title: 'volume',
+                        icon: 'vn:volume',
+                    },
+                    component: () => import('src/pages/Ticket/Card/TicketVolume.vue'),
+                },
+                {
+                    path: 'observation',
+                    name: 'TicketNotes',
+                    meta: {
+                        title: 'notes',
+                        icon: 'vn:notes',
+                    },
+                    component: () => import('src/pages/Ticket/Card/TicketNotes.vue'),
+                },
             ],
         },
     ],
diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js
index ebe32f8d0..ea029bc12 100644
--- a/src/stores/useArrayDataStore.js
+++ b/src/stores/useArrayDataStore.js
@@ -3,36 +3,56 @@ import { defineStore } from 'pinia';
 
 export const useArrayDataStore = defineStore('arrayDataStore', () => {
     const state = ref({});
+    const defaultOpts = {
+        filter: {},
+        userFilter: {},
+        userParams: {},
+        url: '',
+        limit: 10,
+        skip: 0,
+        order: '',
+        isLoading: false,
+        userParamsChanged: false,
+        exprBuilder: null,
+        searchUrl: 'params',
+        navigate: null,
+        page: 1,
+    };
 
     function get(key) {
         return state.value[key];
     }
 
     function set(key) {
-        state.value[key] = {
-            filter: {},
-            userFilter: {},
-            userParams: {},
-            url: '',
-            limit: 10,
-            skip: 0,
-            order: '',
-            data: ref(),
-            isLoading: false,
-            userParamsChanged: false,
-            exprBuilder: null,
-            searchUrl: 'params',
-            navigate: null,
-        };
+        state.value[key] = getDefaultState();
     }
 
     function clear(key) {
         delete state.value[key];
     }
 
+    function reset(key, opts = []) {
+        if (!opts.length) state.value[key] = getDefaultState();
+        else
+            opts.forEach((opt) => {
+                if (opt.includes('.')) {
+                    const [parent, child] = opt.split('.');
+                    state.value[key][parent][child] = defaultOpts[child];
+                } else if (Object.hasOwn(state.value[key], opt))
+                    state.value[key][opt] = defaultOpts[opt];
+            });
+    }
+
+    function getDefaultState() {
+        return Object.assign(JSON.parse(JSON.stringify(defaultOpts)), {
+            data: ref(),
+        });
+    }
+
     return {
         get,
         set,
         clear,
+        reset,
     };
 });
diff --git a/src/stores/useNavigationStore.js b/src/stores/useNavigationStore.js
index 4dd5ed2ae..51f266800 100644
--- a/src/stores/useNavigationStore.js
+++ b/src/stores/useNavigationStore.js
@@ -60,7 +60,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
             menuChildren = menuChildren.map(({ name, title, icon }) => ({
                 name,
                 icon,
-                title: `${module}.pageTitles.${title}`,
+                title: `globals.pageTitles.${title}`,
             }));
 
         if (meta && meta.roles && role.hasAny(meta.roles) === false) return;
@@ -70,7 +70,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
             children: menuChildren,
         };
         if (meta) {
-            item.title = `${module}.pageTitles.${meta.title}`;
+            item.title = `globals.pageTitles.${meta.title}`;
             item.icon = meta.icon;
         }
 
diff --git a/test/cypress/integration/entry/entryDms.spec.js b/test/cypress/integration/entry/entryDms.spec.js
index 5f9fae3dd..ed4a3d79c 100644
--- a/test/cypress/integration/entry/entryDms.spec.js
+++ b/test/cypress/integration/entry/entryDms.spec.js
@@ -1,4 +1,4 @@
-describe('WagonTypeCreate', () => {
+describe('EntryDms', () => {
     const entryId = 1;
 
     beforeEach(() => {
diff --git a/test/cypress/integration/entry/myEntry.spec.js b/test/cypress/integration/entry/myEntry.spec.js
new file mode 100644
index 000000000..fc80c93f8
--- /dev/null
+++ b/test/cypress/integration/entry/myEntry.spec.js
@@ -0,0 +1,20 @@
+// describe('WagonTypeCreate', () => {
+//     beforeEach(() => {
+//         cy.viewport(1920, 1080);
+//         cy.login('customer');
+//         cy.visit(`/#/entry/my`, {
+//             onBeforeLoad(win) {
+//                 cy.stub(win, 'open');
+//             },
+//         });
+//         cy.waitForElement('.q-page', 6000);
+//     });
+
+//     it('should create edit and remove new dms', () => {
+//         cy.get(
+//             '[to="/null/2"] > .q-card > .column > .q-btn > .q-btn__content > .q-icon'
+//         ).click();
+//         cy.get('.q-card__actions > .q-btn').click();
+//         cy.window().its('open').should('be.called');
+//     });
+// });
diff --git a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
index ca0b309e9..a2e9998bb 100644
--- a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
@@ -1,8 +1,7 @@
 describe('InvoiceInDescriptor', () => {
     const dialogBtns = '.q-card__actions button';
     const firstDescritorOpt = '.q-menu > .q-list > :nth-child(1) > .q-item__section';
-    const isBookedField =
-        '.q-card:nth-child(3) .vn-label-value:nth-child(5) > .value > span';
+    const isBookedField = '.q-card:nth-child(3) .vn-label-value:nth-child(5) .q-checkbox';
 
     it('should booking and unbooking the invoice properly', () => {
         cy.viewport(1280, 720);
@@ -12,10 +11,10 @@ describe('InvoiceInDescriptor', () => {
         cy.openActionsDescriptor();
         cy.get(firstDescritorOpt).click();
         cy.get(dialogBtns).eq(1).click();
-        cy.get(isBookedField).should('have.attr', 'title', 'true');
+        cy.get(isBookedField).should('have.attr', 'aria-checked', 'true');
 
         cy.get(firstDescritorOpt).click();
         cy.get(dialogBtns).eq(1).click();
-        cy.get(isBookedField).should('have.attr', 'title', 'false');
+        cy.get(isBookedField).should('have.attr', 'aria-checked', 'false');
     });
 });
diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
index 5e2a5aa4c..b2fa10d52 100644
--- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
@@ -5,12 +5,11 @@ describe('InvoiceInList', () => {
         ':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content';
     const firstDetailBtn = '.q-card:nth-child(1) .q-btn:nth-child(2)';
     const summaryHeaders = '.summaryBody .header-link';
-    const screen = '.q-page-container > .q-drawer-container > .fullscreen';
 
     beforeEach(() => {
+        cy.viewport(1920, 1080);
         cy.login('developer');
         cy.visit(`/#/invoice-in/list`);
-        cy.get(screen).click();
     });
 
     it('should redirect on clicking a invoice', () => {
diff --git a/test/cypress/integration/parking/parkingList.spec.js b/test/cypress/integration/parking/parkingList.spec.js
index 3ac46f8cd..b78a660d1 100644
--- a/test/cypress/integration/parking/parkingList.spec.js
+++ b/test/cypress/integration/parking/parkingList.spec.js
@@ -8,9 +8,9 @@ describe('ParkingList', () => {
     const summaryHeader = '.summaryBody .header';
 
     beforeEach(() => {
+        cy.viewport(1920, 1080);
         cy.login('developer');
         cy.visit(`/#/parking/list`);
-        cy.closeSideMenu();
     });
 
     it('should redirect on clicking a parking', () => {
diff --git a/test/cypress/integration/agency/agencyWorkCenter.spec.js b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
similarity index 72%
rename from test/cypress/integration/agency/agencyWorkCenter.spec.js
rename to test/cypress/integration/route/agency/agencyWorkCenter.spec.js
index 8349260ee..6d33dbc39 100644
--- a/test/cypress/integration/agency/agencyWorkCenter.spec.js
+++ b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
@@ -2,13 +2,10 @@ describe('AgencyWorkCenter', () => {
     beforeEach(() => {
         cy.viewport(1920, 1080);
         cy.login('developer');
-        cy.visit(`/#/agency`);
+        cy.visit(`/#/agency/11/workCenter`);
     });
 
     it('assign workCenter', () => {
-        cy.visit(`/#/agency`);
-        cy.get(':nth-child(1) > :nth-child(1) > .card-list-body > .list-items').click();
-        cy.get('[href="#/agency/11/workCenter"] > .q-item__section--main').click();
         cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
         cy.get(
             '.vn-row > .q-field > .q-field__inner > .q-field__control > .q-field__control-container'
@@ -17,8 +14,6 @@ describe('AgencyWorkCenter', () => {
     });
 
     it('delete workCenter', () => {
-        cy.get(':nth-child(1) > :nth-child(1) > .card-list-body > .list-items').click();
-        cy.get('[href="#/agency/11/workCenter"] > .q-item__section--main').click();
         cy.get('.q-item__section--side > .q-btn > .q-btn__content > .q-icon').click();
         cy.get('.q-notification__message').should(
             'have.text',
@@ -27,9 +22,6 @@ describe('AgencyWorkCenter', () => {
     });
 
     it('error on duplicate workCenter', () => {
-        cy.visit(`/#/agency`);
-        cy.get(':nth-child(1) > :nth-child(1) > .card-list-body > .list-items').click();
-        cy.get('[href="#/agency/11/workCenter"] > .q-item__section--main').click();
         cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
         cy.get(
             '.vn-row > .q-field > .q-field__inner > .q-field__control > .q-field__control-container'
diff --git a/test/cypress/integration/vnBreadcrumbs.spec.js b/test/cypress/integration/vnComponent/vnBreadcrumbs.spec.js
similarity index 100%
rename from test/cypress/integration/vnBreadcrumbs.spec.js
rename to test/cypress/integration/vnComponent/vnBreadcrumbs.spec.js
diff --git a/test/cypress/integration/VnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js
similarity index 100%
rename from test/cypress/integration/VnLocation.spec.js
rename to test/cypress/integration/vnComponent/vnLocation.spec.js
diff --git a/test/cypress/integration/vnLog.spec.js b/test/cypress/integration/vnComponent/vnLog.spec.js
similarity index 100%
rename from test/cypress/integration/vnLog.spec.js
rename to test/cypress/integration/vnComponent/vnLog.spec.js
diff --git a/test/cypress/integration/vnSearchBar.spec.js b/test/cypress/integration/vnComponent/vnSearchBar.spec.js
similarity index 65%
rename from test/cypress/integration/vnSearchBar.spec.js
rename to test/cypress/integration/vnComponent/vnSearchBar.spec.js
index f1f3a9e82..580199bc3 100644
--- a/test/cypress/integration/vnSearchBar.spec.js
+++ b/test/cypress/integration/vnComponent/vnSearchBar.spec.js
@@ -3,13 +3,10 @@ describe('VnSearchBar', () => {
     const employeeId = ' #1';
     const salesPersonId = ' #18';
     const idGap = '.q-item > .q-item__label';
-    const cardList = '.vn-card-list';
-
-    let url;
+    const vnTableRow = '.q-virtual-scroll__content';
     beforeEach(() => {
         cy.login('developer');
         cy.visit('#/customer/list');
-        cy.url().then((currentUrl) => (url = currentUrl));
     });
 
     it('should redirect to customer summary page', () => {
@@ -19,12 +16,12 @@ describe('VnSearchBar', () => {
 
     it('should stay on the list page if there are several results or none', () => {
         cy.writeSearchbar('salesA{enter}');
-        checkCardListAndUrl(2);
+        checkTableLength(2);
 
         cy.clearSearchbar();
 
         cy.writeSearchbar('0{enter}');
-        checkCardListAndUrl(0);
+        checkTableLength(0);
     });
 
     const searchAndCheck = (searchTerm, expectedText) => {
@@ -33,10 +30,7 @@ describe('VnSearchBar', () => {
         cy.get(idGap).should('have.text', expectedText);
     };
 
-    const checkCardListAndUrl = (expectedLength) => {
-        cy.get(cardList).then(($cardList) => {
-            expect($cardList.find('.q-card').length).to.equal(expectedLength);
-            cy.url().then((currentUrl) => expect(currentUrl).to.contain(url));
-        });
+    const checkTableLength = (expectedLength) => {
+        cy.get(vnTableRow).find('tr').should('have.length', expectedLength);
     };
 });
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 055cb8021..38a23f71c 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -50,8 +50,8 @@ Cypress.Commands.add('login', (user) => {
     });
 });
 
-Cypress.Commands.add('waitForElement', (element) => {
-    cy.get(element, { timeout: 5000 }).should('be.visible');
+Cypress.Commands.add('waitForElement', (element, timeout = 5000) => {
+    cy.get(element, { timeout }).should('be.visible');
 });
 
 Cypress.Commands.add('getValue', (selector) => {
@@ -221,10 +221,6 @@ Cypress.Commands.add('openLeftMenu', (element) => {
     if (element) cy.waitForElement(element);
     cy.get('.q-toolbar > .q-btn--round.q-btn--dense > .q-btn__content > .q-icon').click();
 });
-Cypress.Commands.add('closeSideMenu', (element) => {
-    if (element) cy.waitForElement(element);
-    cy.get('.fullscreen.q-drawer__backdrop:not(.hidden)').click();
-});
 
 Cypress.Commands.add('clearSearchbar', (element) => {
     if (element) cy.waitForElement(element);
@@ -243,6 +239,5 @@ Cypress.Commands.add('validateContent', (selector, expectedValue) => {
 });
 
 Cypress.Commands.add('openActionsDescriptor', () => {
-    cy.get('.descriptor > .header > .q-btn').click();
+    cy.get('.header > :nth-child(3) > .q-btn__content > .q-icon').click();
 });
-// registerCommands();
diff --git a/test/vitest/__tests__/components/Leftmenu.spec.js b/test/vitest/__tests__/components/Leftmenu.spec.js
index ea1c51f8d..10d9d66fb 100644
--- a/test/vitest/__tests__/components/Leftmenu.spec.js
+++ b/test/vitest/__tests__/components/Leftmenu.spec.js
@@ -78,13 +78,13 @@ describe('Leftmenu', () => {
             {
                 children: null,
                 name: 'CustomerList',
-                title: 'customer.pageTitles.list',
+                title: 'globals.pageTitles.list',
                 icon: 'view_list',
             },
             {
                 children: null,
                 name: 'CustomerCreate',
-                title: 'customer.pageTitles.createCustomer',
+                title: 'globals.pageTitles.createCustomer',
                 icon: 'vn:addperson',
             },
         ];