diff --git a/package.json b/package.json
index b713c906a..8568d507d 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
         "lint": "eslint --ext .js,.vue ./",
         "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
         "test:e2e": "cypress open",
-        "test:e2e:ci": "cypress run --browser chromium",
+        "test:e2e:ci": "cypress run --browser chrome",
         "test": "echo \"See package.json => scripts for available tests.\" && exit 0",
         "test:unit": "vitest",
         "test:unit:ci": "vitest run"
diff --git a/src/components/FetchData.vue b/src/components/FetchData.vue
index 251d7502a..f0d908972 100644
--- a/src/components/FetchData.vue
+++ b/src/components/FetchData.vue
@@ -46,7 +46,7 @@ async function fetch() {
         if ($props.limit) filter.limit = $props.limit;
 
         const { data } = await axios.get($props.url, {
-            params: { filter },
+            params: { filter: JSON.stringify(filter) },
         });
 
         emit('onFetch', data);
diff --git a/src/components/common/VnJsonValue.vue b/src/components/common/VnJsonValue.vue
new file mode 100644
index 000000000..a2e858d0d
--- /dev/null
+++ b/src/components/common/VnJsonValue.vue
@@ -0,0 +1,88 @@
+<script setup>
+import { watch } from 'vue';
+import { toDateString } from 'src/filters';
+
+const props = defineProps({
+    value: { type: [String, Number, Boolean, Object], default: undefined },
+});
+
+const maxStrLen = 512;
+let t = '';
+let cssClass = '';
+let type;
+const updateValue = () => {
+    type = typeof props.value;
+
+    if (props.value == null) {
+        t = '∅';
+        cssClass = 'json-null';
+    } else {
+        cssClass = `json-${type}`;
+        switch (type) {
+            case 'number':
+                if (Number.isInteger(props.value)) {
+                    t = props.value.toString();
+                } else {
+                    t = (
+                        Math.round((props.value + Number.EPSILON) * 1000) / 1000
+                    ).toString();
+                }
+                break;
+            case 'boolean':
+                t = props.value ? '✓' : '✗';
+                cssClass = `json-${props.value ? 'true' : 'false'}`;
+                break;
+            case 'string':
+                t =
+                    props.value.length <= maxStrLen
+                        ? props.value
+                        : props.value.substring(0, maxStrLen) + '...';
+                break;
+            case 'object':
+                if (props.value instanceof Date) {
+                    t = toDateString(props.value);
+                } else {
+                    t = props.value.toString();
+                }
+                break;
+            default:
+                t = props.value.toString();
+        }
+    }
+};
+
+watch(() => props.value, updateValue);
+
+updateValue();
+</script>
+
+<template>
+    <span
+        :title="type === 'string' && props.value.length > maxStrLen ? props.value : ''"
+        :class="{ [cssClass]: t !== '' }"
+    >
+        {{ t }}
+    </span>
+</template>
+
+<style scoped>
+.json-string {
+    color: #d172cc;
+}
+.json-object {
+    color: #d1a572;
+}
+.json-number {
+    color: #85d0ff;
+}
+.json-true {
+    color: #7dc489;
+}
+.json-false {
+    color: #c74949;
+}
+.json-null {
+    color: #cd7c7c;
+    font-style: italic;
+}
+</style>
diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue
index 1213c8bbc..7e3cfc408 100644
--- a/src/components/common/VnLog.vue
+++ b/src/components/common/VnLog.vue
@@ -1,128 +1,641 @@
 <script setup>
+import { ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
-import { useSession } from 'src/composables/useSession';
+import axios from 'axios';
 import { useStateStore } from 'stores/useStateStore';
-import VnPaginate from 'src/components/ui/VnPaginate.vue';
-import VnLogFilter from 'src/components/common/VnLogFilter.vue';
-
-import { toDate } from 'src/filters';
+import { useValidationsStore } from 'src/stores/useValidationsStore';
+import { toRelativeDate, toDateString, toDateHour } from 'src/filters';
+import { useColor } from 'src/composables/useColor';
+import { useFirstUpper } from 'src/composables/useFirstUpper';
+import { useIso8601 } from 'src/composables/useIso8601';
+import VnAvatar from '../ui/VnAvatar.vue';
+import VnJsonValue from '../common/VnJsonValue.vue';
+import FetchData from '../FetchData.vue';
+import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 
 const stateStore = useStateStore();
 const route = useRoute();
-const session = useSession();
-const token = session.getToken();
 const { t } = useI18n();
-
+const validationsStore = useValidationsStore();
 const props = defineProps({
     model: {
         type: String,
         default: null,
     },
 });
+const filter = {
+    fields: [
+        'id',
+        'originFk',
+        'userFk',
+        'action',
+        'changedModel',
+        'oldInstance',
+        'newInstance',
+        'creationDate',
+        'changedModel',
+        'changedModelId',
+        'changedModelValue',
+        'description',
+    ],
+    include: [
+        {
+            relation: 'user',
+            scope: {
+                fields: ['nickname', 'name', 'image'],
+                include: {
+                    relation: 'worker',
+                    scope: {
+                        fields: ['id'],
+                    },
+                },
+            },
+        },
+    ],
+};
 
-const columns = [
-    {
-        name: 'property',
-        label: 'Property',
-        field: (row) => t(`properties.${row.property}`),
-        align: 'left',
-    },
-    {
-        name: 'before',
-        label: 'Before',
-        field: (row) => formatValue(row.before),
-    },
-    {
-        name: 'after',
-        label: 'After',
-        field: (row) => formatValue(row.after),
-    },
+const workers = ref();
+const actions = ref();
+const changeInput = ref();
+const searchInput = ref();
+const userRadio = ref();
+const userSelect = ref();
+const date = ref();
+const dateDialog = ref(false);
+const dateTo = ref();
+const dateToDialog = ref(false);
+const selectedFilters = ref({});
+const userTypes = [
+    { label: 'All', value: undefined },
+    { label: 'User', value: { neq: null } },
+    { label: 'System', value: null },
 ];
+const checkboxOptions = ref({
+    insert: {
+        label: 'Creates',
+        selected: false,
+    },
+    update: {
+        label: 'Edits',
+        selected: false,
+    },
+    delete: {
+        label: 'Deletes',
+        selected: false,
+    },
+    select: {
+        label: 'Accesses',
+        selected: false,
+    },
+});
 
-function formatValue(value) {
-    if (typeof value === 'boolean') {
-        return value ? t('Yes') : t('No');
-    }
+let validations;
+let pointRecord = ref(null);
+let byRecord = ref(false);
+const logTree = ref([]);
 
-    if (isNaN(value) && !isNaN(Date.parse(value))) {
-        return toDate(value);
-    }
+const actionsText = {
+    insert: 'Creates',
+    update: 'Edits',
+    delete: 'Deletes',
+    select: 'Accesses',
+};
+const actionsClass = {
+    insert: 'success',
+    update: 'warning',
+    delete: 'alert',
+    select: 'notice',
+};
+const actionsIcon = {
+    insert: 'add',
+    update: 'edit',
+    delete: 'remove',
+    select: 'visibility',
+};
+const validDate = new RegExp(
+    /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])/.source +
+        /T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/.source
+);
 
-    if (value === undefined) {
-        return t('Nothing');
-    }
+const filteredActions = ref([]);
+const filteredWorkers = ref([]);
 
-    return `"${value}"`;
+function castJsonValue(value) {
+    return typeof value === 'string' && validDate.test(value) ? new Date(value) : value;
 }
 
-function actionColor(action) {
-    if (action === 'insert') return 'positive';
-    if (action === 'update') return 'positive';
-    if (action === 'delete') return 'negative';
+function parseProps(propNames, locale, vals, olds) {
+    const props = [];
+
+    for (const prop of propNames) {
+        if (prop.endsWith('$')) continue;
+        props.push({
+            name: prop,
+            nameI18n: useFirstUpper(locale.columns?.[prop]) || prop,
+            val: getVal(vals, prop),
+            old: olds && getVal(olds, prop),
+        });
+    }
+    props.sort((a, b) => a.nameI18n.localeCompare(b.nameI18n));
+
+    function getVal(vals, prop) {
+        let val;
+        let id;
+        const showProp = `${prop}$`;
+
+        if (vals[showProp] != null) {
+            val = vals[showProp];
+            id = vals[prop];
+        } else val = vals[prop];
+
+        return { val: castJsonValue(val), id };
+    }
+
+    return props;
 }
+
+function getLogs(data) {
+    const logs = [];
+    let originLog = null;
+    let userLog = null;
+    let modelLog = null;
+    let prevLog, prevUser, prevModel;
+    let nLogs;
+
+    data.forEach((log) => {
+        const locale = validationsStore.validations[log.changedModel]?.locale || {};
+
+        // Origin
+        if (!prevLog || prevLog.originFk != log.originFk) {
+            logs.push((originLog = { originFk: log.originFk, logs: [] }));
+            prevLog = log;
+        }
+        // User
+        if (prevUser != log.userFk) {
+            originLog.logs.push(
+                (userLog = {
+                    user: log.user,
+                    userFk: log.userFk,
+                    logs: [],
+                })
+            );
+            prevUser = log.userFk;
+        }
+        // Model
+        if (
+            !prevModel ||
+            prevModel.changedModelId != log.changedModelId ||
+            prevModel.changedModel != log.changedModel ||
+            nLogs >= 6
+        ) {
+            userLog.logs.push(
+                (modelLog = {
+                    model: log.changedModel,
+                    modelI18n: useFirstUpper(locale.name) || log.changedModel,
+                    id: log.changedModelId,
+                    showValue: log.changedModelValue,
+                    logs: [],
+                })
+            );
+            prevModel = {
+                changedModelId: log.changedModelId,
+                changedModel: log.changedModel,
+            };
+            nLogs = 0;
+        }
+        nLogs++;
+        modelLog.logs.push(log);
+
+        // Changes
+        const notDelete = log.action != 'delete';
+        const olds = (notDelete ? log.oldInstance : null) || {};
+        const vals = (notDelete ? log.newInstance : log.oldInstance) || {};
+
+        let propNames = Object.keys(olds).concat(Object.keys(vals));
+        propNames = [...new Set(propNames)];
+
+        log.props = parseProps(propNames, locale, vals, olds);
+    });
+    return logs;
+}
+
+async function openPointRecord(id, modelLog) {
+    pointRecord.value = null;
+    const { data } = await axios.get(`${props.model}Logs/${id}/pitInstance`);
+    const propNames = Object.keys(data);
+    const locale = validationsStore.validations[modelLog.model]?.locale || {};
+    pointRecord.value = parseProps(propNames, locale, data);
+}
+async function setLogTree() {
+    if (!validations) {
+        validations = await validationsStore.fetchModels();
+    }
+    filter.where = { and: [{ originFk: route.params.id }] };
+    const { data } = await axios.get(`${props.model}Logs`, {
+        params: { filter: JSON.stringify(filter) },
+    });
+    logTree.value = getLogs(data);
+}
+
+function filterByRecord(modelLog) {
+    byRecord.value = true;
+    const { id, model } = modelLog;
+
+    searchInput.value = id;
+    selectedFilters.value.changedModelId = id;
+    selectedFilters.value.changedModel = model;
+    applyFilter();
+}
+
+async function applyFilter() {
+    filter.where = { and: [] };
+    if (
+        !selectedFilters.value.changedModel ||
+        (!selectedFilters.value.changedModelValue &&
+            !selectedFilters.value.changedModelId)
+    )
+        byRecord.value = false;
+
+    if (!byRecord.value) filter.where.and.push({ originFk: route.params.id });
+
+    if (Object.keys(selectedFilters.value).length) {
+        filter.where.and.push(selectedFilters.value);
+    }
+
+    const { data } = await axios.get(`${props.model}Logs`, {
+        params: { filter: JSON.stringify(filter) },
+    });
+
+    logTree.value = getLogs(data);
+}
+
+function setDate(type) {
+    const from = date.value
+        ? useIso8601(date.value.split('-').reverse().join('-'))
+        : undefined;
+    const to = dateTo.value
+        ? useIso8601(`${dateTo.value.split('-').reverse().join('-')} 21:59:59.999`)
+        : useIso8601(`${date.value.split('-').reverse().join('-')} 21:59:59.999`);
+
+    switch (type) {
+        case 'from':
+            return { between: [from, to] };
+        case 'to': {
+            if (date.value) {
+                return {
+                    between: [from, to],
+                };
+            } else {
+                return { lte: to };
+            }
+        }
+    }
+}
+
+function selectFilter(type, dateType) {
+    const filter = {};
+    const actions = { inq: [] };
+    let reload = true;
+
+    if (type === 'search') {
+        if (/^\s*[0-9]+\s*$/.test(searchInput.value) || props.byRecord) {
+            selectedFilters.value.changedModelId = searchInput.value.trim();
+        } else if (!searchInput.value) {
+            selectedFilters.value.changedModelId = undefined;
+            selectedFilters.value.changedModelValue = undefined;
+        } else {
+            selectedFilters.value.changedModelValue = { like: `%${searchInput.value}%` };
+        }
+    }
+    if (type === 'action' && selectedFilters.value.changedModel === null) {
+        selectedFilters.value.changedModel = undefined;
+        reload = false;
+    }
+    if (type === 'userRadio') {
+        selectedFilters.value.userFk = userRadio.value;
+    }
+    if (type === 'change') {
+        if (changeInput.value)
+            selectedFilters.value.or = [
+                { oldJson: { like: `%${changeInput.value}%` } },
+                { newJson: { like: `%${changeInput.value}%` } },
+                { description: { like: `%${changeInput.value}%` } },
+            ];
+        else selectedFilters.value.or = undefined;
+    }
+    if (type === 'userSelect') {
+        selectedFilters.value.userFk =
+            userSelect.value !== null ? userSelect.value : undefined;
+    }
+    if (type === 'date') {
+        if (!date.value && !dateTo.value) {
+            selectedFilters.value.creationDate = undefined;
+        } else if (dateType === 'to') {
+            selectedFilters.value.creationDate = setDate('to');
+        } else if (dateType === 'from') {
+            selectedFilters.value.creationDate = setDate('from');
+        }
+    }
+
+    Object.keys(checkboxOptions.value).forEach((key) => {
+        if (checkboxOptions.value[key].selected) actions.inq.push(key);
+    });
+    selectedFilters.value.action = actions.inq.length ? actions : undefined;
+
+    Object.keys(selectedFilters.value).forEach((key) => {
+        if (selectedFilters.value[key]) filter[key] = selectedFilters.value[key];
+    });
+
+    if (reload) applyFilter(filter);
+}
+
+async function clearFilter() {
+    selectedFilters.value = {};
+    byRecord.value = false;
+    userSelect.value = undefined;
+    searchInput.value = undefined;
+    changeInput.value = undefined;
+    date.value = undefined;
+    dateTo.value = undefined;
+    Object.keys(checkboxOptions.value).forEach(
+        (opt) => (checkboxOptions.value[opt].selected = false)
+    );
+    await applyFilter();
+}
+
+function filterFn(val, update, abortFn, type) {
+    if (!val) {
+        update(() => {
+            if (type === 'actions') filteredActions.value = actions.value;
+            if (type === 'workers') filteredWorkers.value = workers.value;
+        });
+        return;
+    }
+
+    update(() => {
+        const needle = val.toLowerCase();
+        if (type === 'actions')
+            filteredActions.value = actions.value.filter((item) =>
+                item.toLowerCase().includes(needle)
+            );
+        if (type === 'workers') {
+            if (isNaN(needle))
+                filteredWorkers.value = workers.value.filter(
+                    (item) =>
+                        item.name.toLowerCase().includes(needle) ||
+                        item.nickname.toLowerCase().includes(needle)
+                );
+            else
+                filteredWorkers.value = workers.value.filter((item) => item.id == needle);
+        }
+    });
+}
+
+setLogTree();
 </script>
 <template>
-    <div class="column items-center">
-        <QTimeline class="q-pa-md">
-            <QTimelineEntry heading tag="h4"> {{ t('Audit logs') }} </QTimelineEntry>
-            <VnPaginate
-                :data-key="`${props.model}Logs`"
-                :url="`${props.model}s/${route.params.id}/logs`"
-                order="id DESC"
-                :offset="100"
-                :limit="5"
-                auto-load
-            >
-                <template #body="{ rows }">
-                    <template v-for="log of rows" :key="log.id">
-                        <QTimelineEntry
-                            :avatar="`/api/Images/user/160x160/${log.userFk}/download?access_token=${token}`"
-                        >
-                            <template #subtitle>
-                                {{ log.userName }} -
-                                {{
-                                    toDate(log.created, {
-                                        dateStyle: 'medium',
-                                        timeStyle: 'short',
-                                    })
-                                }}
-                            </template>
-                            <template #title>
-                                <QChip :color="actionColor(log.action)">
-                                    {{ t(`actions.${log.action}`) }}
-                                </QChip>
-                                {{ t(`models.${log.model}`) }}
-                            </template>
-                            <QTable
-                                :rows="log.changes"
-                                :columns="columns"
-                                row-key="property"
-                                hide-pagination
+    <FetchData
+        :url="`${props.model}Logs/${route.params.id}/editors`"
+        :filter="{
+            fields: ['id', 'nickname', 'name', 'image'],
+            order: 'nickname',
+            limit: 30,
+        }"
+        @on-fetch="(data) => (workers = data)"
+        auto-load
+    />
+    <FetchData
+        :url="`${props.model}Logs/${route.params.id}/models`"
+        :filter="{ order: ['changedModel'] }"
+        @on-fetch="(data) => (actions = data.map((item) => item.changedModel))"
+        auto-load
+    />
+    <div
+        class="column items-center logs origin-log"
+        v-for="(originLog, originLogIndex) in logTree"
+        :key="originLogIndex"
+    >
+        <QItem class="origin-info items-center q-my-md" v-if="logTree.length > 1">
+            <h6 class="origin-id">
+                {{ originLog.modelI18n }}
+                #{{ originLog.originFk }}
+            </h6>
+            <div class="line"></div>
+        </QItem>
+        <div
+            class="user-log q-mb-sm row"
+            v-for="(userLog, userIndex) in originLog.logs"
+            :key="userIndex"
+        >
+            <div class="timeline">
+                <div class="user-avatar">
+                    <VnAvatar
+                        class="cursor-pointer"
+                        :worker="userLog.user.id"
+                        :title="userLog.user.nickname"
+                    />
+                    <WorkerDescriptorProxy
+                        v-if="userLog.user.image"
+                        :id="userLog.user.id"
+                    />
+                </div>
+                <div class="arrow bg-panel" v-if="byRecord"></div>
+                <div class="line"></div>
+            </div>
+            <QList class="user-changes" v-if="userLog">
+                <QItem
+                    class="model-log column q-px-none q-py-xs"
+                    v-for="(modelLog, modelLogIndex) in userLog.logs"
+                    :key="modelLogIndex"
+                >
+                    <QItemSection>
+                        <QItemLabel class="model-info q-mb-xs" v-if="!byRecord">
+                            <QChip
                                 dense
-                                flat
+                                size="md"
+                                class="model-name q-mr-xs text-white"
+                                v-if="
+                                    !(modelLog.changedModel && modelLog.changedModelId) &&
+                                    modelLog.model
+                                "
+                                :style="{
+                                    backgroundColor: useColor(modelLog.model),
+                                }"
+                                :title="modelLog.model"
                             >
-                                <template #header="propsLabel">
-                                    <QTr :props="propsLabel">
-                                        <QTh
-                                            v-for="col in propsLabel.cols"
-                                            :key="col.name"
-                                            :props="propsLabel"
+                                {{ t(modelLog.modelI18n) }}
+                            </QChip>
+                            <span class="model-id" v-if="modelLog.id"
+                                >#{{ modelLog.id }}</span
+                            >
+                            <span class="model-value" :title="modelLog.showValue">
+                                {{ modelLog.showValue }}
+                            </span>
+                            <QBtn
+                                flat
+                                round
+                                color="grey"
+                                class="q-mr-xs q-ml-auto"
+                                size="sm"
+                                icon="filter_alt"
+                                :title="t('recordChanges')"
+                                @click.stop="filterByRecord(modelLog)"
+                            />
+                        </QItemLabel>
+                    </QItemSection>
+                    <QItemSection>
+                        <QCard
+                            class="changes-log q-py-none"
+                            v-for="(log, logIndex) in modelLog.logs"
+                            :key="logIndex"
+                        >
+                            <QCardSection class="change-info q-pa-none">
+                                <QItem
+                                    class="q-px-sm q-py-xs justify-between items-center"
+                                >
+                                    <div
+                                        class="date text-grey text-caption q-mr-sm"
+                                        :title="
+                                            toDateHour(log.creationDate) ??
+                                            `date:'dd/MM/yyyy HH:mm:ss'`
+                                        "
+                                    >
+                                        {{ toRelativeDate(log.creationDate) }}
+                                    </div>
+                                    <div>
+                                        <QBtn
+                                            color="grey"
+                                            class="pit"
+                                            icon="preview"
+                                            flat
+                                            round
+                                            :title="t('pointRecord')"
+                                            padding="xs"
+                                            v-if="log.action != 'insert'"
+                                            @click.stop="
+                                                openPointRecord(log.id, modelLog)
+                                            "
                                         >
-                                            {{ t(col.label) }}
-                                        </QTh>
-                                    </QTr>
-                                </template>
-                            </QTable>
-                        </QTimelineEntry>
-                    </template>
-                </template>
-            </VnPaginate>
-        </QTimeline>
+                                            <QPopupProxy>
+                                                <QCard v-if="pointRecord">
+                                                    <div
+                                                        class="header q-px-sm q-py-xs q-ma-none text-white text-bold bg-primary"
+                                                    >
+                                                        {{ modelLog.modelI18n }}
+                                                        <span v-if="modelLog.id"
+                                                            >#{{ modelLog.id }}</span
+                                                        >
+                                                    </div>
+                                                    <QCardSection
+                                                        class="change-detail q-pa-sm"
+                                                    >
+                                                        <QItem
+                                                            v-for="(
+                                                                value, index
+                                                            ) in pointRecord"
+                                                            :key="index"
+                                                            class="q-pa-none"
+                                                        >
+                                                            <span
+                                                                class="json-field q-mr-xs text-grey"
+                                                                :title="value.name"
+                                                            >
+                                                                {{ value.nameI18n }}:
+                                                            </span>
+                                                            <VnJsonValue
+                                                                :value="value.val.val"
+                                                            />
+                                                        </QItem>
+                                                    </QCardSection>
+                                                </QCard>
+                                            </QPopupProxy>
+                                        </QBtn>
+                                        <QIcon
+                                            class="action q-ml-xs"
+                                            :class="actionsClass[log.action]"
+                                            :name="actionsIcon[log.action]"
+                                            :title="
+                                                t(`actions.${actionsText[log.action]}`)
+                                            "
+                                        />
+                                    </div>
+                                </QItem>
+                            </QCardSection>
+                            <QCardSection
+                                class="change-detail q-px-sm q-py-xs"
+                                :class="{ expanded: log.expand }"
+                                v-if="log.props.length || log.description"
+                            >
+                                <QIcon
+                                    class="cursor-pointer q-mr-md"
+                                    color="grey"
+                                    name="expand_more"
+                                    :title="t('globals.details')"
+                                    size="sm"
+                                    @click="log.expand = !log.expand"
+                                />
+                                <QList v-if="log.props.length" class="attributes">
+                                    <QItem v-if="!log.expand" class="q-pa-none text-grey">
+                                        <span
+                                            v-for="(prop, propIndex) in log.props"
+                                            :key="propIndex"
+                                            class="basic-json"
+                                        >
+                                            <span class="json-field" :title="prop.name">
+                                                {{ prop.nameI18n }}:
+                                            </span>
+                                            <VnJsonValue :value="prop.val.val" />
+                                            <span v-if="propIndex < log.props.length - 1">
+                                                ,
+                                            </span>
+                                        </span>
+                                    </QItem>
+                                    <QItem
+                                        v-if="log.expand"
+                                        class="expanded-json column q-pa-none"
+                                    >
+                                        <div
+                                            v-for="(prop, prop2Index) in log.props"
+                                            :key="prop2Index"
+                                            class="q-pa-none text-grey"
+                                        >
+                                            <span class="json-field" :title="prop.name">
+                                                {{ prop.nameI18n }}:
+                                            </span>
+                                            <VnJsonValue :value="prop.val.val" />
+                                            <span v-if="prop.val.id" class="id-value">
+                                                #{{ prop.val.id }}
+                                            </span>
+                                            <span v-if="log.action == 'update'">
+                                                ←
+                                                <VnJsonValue :value="prop.old.val" />
+                                                <span v-if="prop.old.id" class="id-value">
+                                                    #{{ prop.old.id }}
+                                                </span>
+                                            </span>
+                                        </div>
+                                    </QItem>
+                                </QList>
+                                <span v-if="!log.props.length" class="description">
+                                    {{ log.description }}
+                                </span>
+                            </QCardSection>
+                        </QCard>
+                    </QItemSection>
+                </QItem>
+            </QList>
+        </div>
     </div>
     <Teleport v-if="stateStore.isHeaderMounted()" to="#actions-append">
         <div class="row q-gutter-x-sm">
-            <QBtn flat @click="stateStore.toggleRightDrawer()" round dense icon="menu">
+            <QBtn
+                flat
+                @click.stop="stateStore.toggleRightDrawer()"
+                round
+                dense
+                icon="menu"
+            >
                 <QTooltip bottom anchor="bottom right">
                     {{ t('globals.collapseMenu') }}
                 </QTooltip>
@@ -131,28 +644,414 @@ function actionColor(action) {
     </Teleport>
     <QDrawer v-model="stateStore.rightDrawer" show-if-above side="right" :width="300">
         <QScrollArea class="fit text-grey-8">
-            <VnLogFilter :data-key="`${props.model}Logs`" />
+            <QList dense>
+                <QSeparator />
+                <QItem class="q-mt-sm">
+                    <QInput
+                        :label="t('globals.search')"
+                        v-model="searchInput"
+                        class="full-width"
+                        clearable
+                        clear-icon="close"
+                        @keyup.enter="() => selectFilter('search')"
+                        @focusout="() => selectFilter('search')"
+                        @clear="() => selectFilter('search')"
+                    >
+                        <template #append>
+                            <QIcon name="info" class="cursor-pointer">
+                                <QTooltip>{{ t('tooltips.search') }}</QTooltip>
+                            </QIcon>
+                        </template>
+                    </QInput>
+                </QItem>
+                <QItem class="q-mt-sm">
+                    <QSelect
+                        class="full-width"
+                        v-model="selectedFilters.changedModel"
+                        @update:model-value="selectFilter('action')"
+                        :options="filteredActions"
+                        :label="t('globals.entity')"
+                        use-input
+                        clearable
+                        clear-icon="close"
+                        @filter="
+                            (val, update, abortFn) =>
+                                filterFn(val, update, abortFn, 'actions')
+                        "
+                        @clear="() => selectFilter('action')"
+                    >
+                        <template #option="{ opt, index, itemProps }">
+                            <QItem :index="index" v-bind="itemProps">
+                                {{ t(`models.${opt}`) }}
+                            </QItem>
+                        </template>
+                        <template #selected-item="{ opt }">
+                            {{ t(opt) }}
+                        </template>
+                    </QSelect>
+                </QItem>
+                <QItem class="q-mt-sm">
+                    <QOptionGroup
+                        size="sm"
+                        v-model="userRadio"
+                        :options="userTypes"
+                        color="primary"
+                        @update:model-value="selectFilter('userRadio')"
+                        right-label
+                    >
+                        <template #label="{ label }">
+                            {{ t(`Users.${label}`) }}
+                        </template>
+                    </QOptionGroup>
+                </QItem>
+                <QItem class="q-mt-sm">
+                    <QItemSection v-if="!workers">
+                        <QSkeleton type="QInput" class="full-width" />
+                    </QItemSection>
+                    <QItemSection v-if="workers">
+                        <QSelect
+                            :label="t('globals.user')"
+                            v-model="userSelect"
+                            @update:model-value="selectFilter('userSelect')"
+                            :options="filteredWorkers"
+                            option-value="id"
+                            option-label="name"
+                            emit-value
+                            map-options
+                            use-input
+                            clearable
+                            clear-icon="close"
+                            @filter="
+                                (val, update, abortFn) =>
+                                    filterFn(val, update, abortFn, 'workers')
+                            "
+                        >
+                            <template #option="{ opt, itemProps }">
+                                <QItem
+                                    v-bind="itemProps"
+                                    class="q-pa-xs row items-center"
+                                >
+                                    <QItemSection class="col-3 items-center">
+                                        <VnAvatar :worker="opt.id" />
+                                    </QItemSection>
+                                    <QItemSection class="col-9 justify-center">
+                                        <span>{{ opt.name }}</span>
+                                        <span class="text-grey">{{ opt.nickname }}</span>
+                                    </QItemSection>
+                                </QItem>
+                            </template>
+                        </QSelect>
+                    </QItemSection>
+                </QItem>
+                <QItem class="q-mt-sm">
+                    <QInput
+                        :label="t('globals.changes')"
+                        v-model="changeInput"
+                        class="full-width"
+                        clearable
+                        clear-icon="close"
+                        @keyup.enter="selectFilter('change')"
+                        @focusout="selectFilter('change')"
+                        @clear="selectFilter('change')"
+                    >
+                        <template #append>
+                            <QIcon name="info" class="cursor-pointer">
+                                <QTooltip max-width="250px">{{
+                                    t('tooltips.changes')
+                                }}</QTooltip>
+                            </QIcon>
+                        </template>
+                    </QInput>
+                </QItem>
+                <QItem
+                    :class="index == 'create' ? 'q-mt-md' : 'q-mt-xs'"
+                    v-for="(checkboxOption, index) in checkboxOptions"
+                    :key="index"
+                >
+                    <QCheckbox
+                        size="sm"
+                        v-model="checkboxOption.selected"
+                        :label="t(`actions.${checkboxOption.label}`)"
+                        @update:model-value="selectFilter"
+                    />
+                </QItem>
+                <QItem class="q-mt-sm">
+                    <QInput
+                        class="full-width"
+                        :label="t('globals.date')"
+                        @click="dateDialog = true"
+                        @focus="(evt) => evt.target.blur()"
+                        @clear="selectFilter('date', 'to')"
+                        v-model="date"
+                        clearable
+                        clear-icon="close"
+                    />
+                </QItem>
+                <QItem class="q-mt-sm">
+                    <QInput
+                        class="full-width"
+                        :label="t('to')"
+                        @click="dateToDialog = true"
+                        @focus="(evt) => evt.target.blur()"
+                        @clear="selectFilter('date', 'from')"
+                        v-model="dateTo"
+                        clearable
+                        clear-icon="close"
+                    />
+                </QItem>
+            </QList>
         </QScrollArea>
     </QDrawer>
+    <QDialog v-model="dateDialog">
+        <QDate
+            :years-in-month-view="false"
+            v-model="date"
+            dense
+            flat
+            minimal
+            @update:model-value="
+                (value) => {
+                    dateDialog = false;
+                    const formatDate = toDateString(new Date(value));
+                    date = formatDate.split('-').reverse().join('-');
+                    selectFilter('date', 'from');
+                }
+            "
+        />
+    </QDialog>
+    <QDialog v-model="dateToDialog">
+        <QDate
+            v-model="dateTo"
+            dense
+            flat
+            minimal
+            @update:model-value="
+                (value) => {
+                    dateToDialog = false;
+                    const formatDate = toDateString(new Date(value));
+                    dateTo = formatDate.split('-').reverse().join('-');
+                    selectFilter('date', 'to');
+                }
+            "
+        />
+    </QDialog>
+    <QPageSticky position="bottom-right" :offset="[25, 25]">
+        <QBtn
+            v-if="Object.values(selectedFilters).some((filter) => filter !== undefined)"
+            color="primary"
+            icon="filter_alt_off"
+            size="md"
+            round
+            @click="clearFilter"
+        />
+    </QPageSticky>
 </template>
-
+<style lang="scss">
+.q-timeline__subtitle {
+    opacity: 1 !important;
+}
+.logs {
+    .vn-label-value {
+        .label {
+            margin-right: 5px;
+            color: var(--vn-label);
+        }
+    }
+    .q-avatar {
+        font-size: 38px;
+    }
+}
+</style>
 <style lang="scss" scoped>
-.q-timeline {
-    width: 100%;
-    max-width: 80em;
+.q-card {
+    background-color: var(--vn-gray);
+}
+.q-item {
+    min-height: 0px;
+}
+
+.origin-log {
+    &:first-child > .origin-info {
+        margin-top: 0;
+    }
+    & > .origin-info {
+        gap: 6px;
+
+        & > .origin-id {
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+            margin: 0;
+        }
+        & > .line {
+            flex-grow: 1;
+            background-color: $primary;
+            height: 2px;
+        }
+    }
+}
+.user-log {
+    width: 40em;
+
+    & > .timeline {
+        position: relative;
+        padding-right: 5px;
+        width: 50px;
+        min-width: 38px;
+        & > .arrow {
+            height: 8px;
+            width: 8px;
+            position: absolute;
+            transform: rotateY(0deg) rotate(45deg);
+            top: 15px;
+            right: -4px;
+            z-index: 1;
+        }
+        & > .user-avatar {
+            padding: 8px 0;
+            margin-top: -8px;
+            position: sticky;
+            top: 64px;
+        }
+        & > .line {
+            position: absolute;
+            background-color: $primary;
+            width: 2px;
+            left: 23px;
+            z-index: -1;
+            top: 0;
+            bottom: -8px;
+        }
+    }
+    &:last-child > .timeline > .line {
+        display: none;
+    }
+    & > .user-changes {
+        flex-grow: 1;
+        overflow: hidden;
+    }
+}
+.model-log {
+    .model-info {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        .model-value {
+            font-style: italic;
+        }
+        .model-id {
+            color: var(--vn-label);
+            font-size: 0.9rem;
+        }
+        .q-btn {
+            float: right;
+        }
+    }
+}
+.changes-log {
+    overflow: hidden;
+
+    &:last-child {
+        margin-bottom: 0;
+    }
+    .change-info {
+        overflow: hidden;
+        background-color: var(--vn-header);
+        & > .date {
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+        }
+        & > div {
+            white-space: nowrap;
+            .action {
+                color: black;
+                border-radius: 50%;
+                padding: 3px;
+                font-size: 18px;
+
+                &.notice {
+                    background-color: $info;
+                }
+                &.success {
+                    background-color: $positive;
+                }
+                &.warning {
+                    background-color: $warning;
+                }
+                &.alert {
+                    background-color: $negative;
+                }
+            }
+        }
+    }
+    & > .change-detail {
+        background-color: var(--vn-gray);
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        box-sizing: border-box;
+        & > .q-icon {
+            float: right;
+            transition-property: transform, background-color;
+            transition-duration: 150ms;
+            margin: 0;
+        }
+        &.expanded {
+            text-overflow: initial;
+            white-space: initial;
+
+            & > .q-icon {
+                transform: rotate(180deg);
+            }
+        }
+        & > .no-changes {
+            font-style: italic;
+        }
+    }
+}
+.q-menu {
+    display: block;
+
+    & > .loading {
+        display: flex;
+        justify-content: center;
+    }
+    & > .q-card {
+        min-width: 180px;
+        max-width: 400px;
+
+        & > .header {
+            color: $dark;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+        }
+    }
 }
 </style>
 <i18n>
 en:
+    to: To
+    pointRecord: View record at this point in time
+    recordChanges: show all record changes
+    tooltips:
+        search: Search by id or concept
+        changes: Search by changes
     actions:
-        insert: Creates
-        update: Updates
-        delete: Deletes
+        Creates: Creates
+        Edits: Edits
+        Deletes: Deletes
+        Accesses: Accesses
     models:
-        Claim: Claim
-        ClaimDms: Document
-        ClaimBeginning: Claimed Sales
-        ClaimObservation: Observation
+        Claim: Reclamación
+        ClaimDms: Documento
+        ClaimBeginning: Comienzo
+        ClaimObservation: Observación
+    Users:
+        User: Usuario
+        All: Todo
+        System: Sistema
     properties:
         id: ID
         claimFk: Claim ID
@@ -172,6 +1071,12 @@ en:
         responsibility: Responsibility
         packages: Packages
 es:
+    to: Hasta
+    pointRecord: Ver el registro en este punto
+    recordChanges: Mostrar todos los cambios realizados en el registro
+    tooltips:
+        search: Buscar por identificador o concepto
+        changes: Buscar por cambios. Los atributos deben buscarse por su nombre interno, para obtenerlo situar el cursor sobre el atributo.
     Audit logs: Registros de auditoría
     Property: Propiedad
     Before: Antes
@@ -179,14 +1084,14 @@ es:
     Yes: Si
     Nothing: Nada
     actions:
-        insert: Crea
-        update: Actualiza
-        delete: Elimina
-    models:
-        Claim: Reclamación
-        ClaimDms: Documento
-        ClaimBeginning: Línea reclamada
-        ClaimObservation: Observación
+        Creates: Crea
+        Edits: Modifica
+        Deletes: Elimina
+        Accesses: Accede
+    Users:
+        User: Usuario
+        All: Todo
+        System: Sistema
     properties:
         id: ID
         claimFk: ID reclamación
diff --git a/src/composables/useColor.js b/src/composables/useColor.js
new file mode 100644
index 000000000..b325e985f
--- /dev/null
+++ b/src/composables/useColor.js
@@ -0,0 +1,35 @@
+export function djb2a(string) {
+    let hash = 5381;
+    for (let i = 0; i < string.length; i++)
+        hash = ((hash << 5) + hash) ^ string.charCodeAt(i);
+    return hash >>> 0;
+}
+
+export function useColor(value) {
+    return '#' + colors[djb2a(value || '') % colors.length];
+}
+
+const colors = [
+    'b5b941', // Yellow
+    'ae9681', // Peach
+    'd78767', // Salmon
+    'cc7000', // Orange bright
+    'e2553d', // Coral
+    '8B0000', // Red dark
+    'de4362', // Red crimson
+    'FF1493', // Ping intense
+    'be39a2', // Pink light
+    'b754cf', // Purple middle
+    'a87ba8', // Pink
+    '8a69cd', // Blue lavender
+    'ab20ab', // Purple dark
+    '00b5b8', // Turquoise
+    '1fa8a1', // Green ocean
+    '5681cf', // Blue steel
+    '3399fe', // Blue sky
+    '6d9c3e', // Green chartreuse
+    '51bb51', // Green lime
+    '518b8b', // Gray board
+    '7e7e7e', // Gray
+    '5d5d5d', // Gray dark
+];
diff --git a/src/composables/useFirstUpper.js b/src/composables/useFirstUpper.js
new file mode 100644
index 000000000..36378c05f
--- /dev/null
+++ b/src/composables/useFirstUpper.js
@@ -0,0 +1,3 @@
+export function useFirstUpper(str) {
+    return str && str.charAt(0).toUpperCase() + str.substr(1);
+}
diff --git a/src/composables/useIso8601.js b/src/composables/useIso8601.js
new file mode 100644
index 000000000..848e60de8
--- /dev/null
+++ b/src/composables/useIso8601.js
@@ -0,0 +1,18 @@
+export function useIso8601(dateString) {
+    // Crear un objeto Date a partir de la cadena de texto
+    const date = new Date(dateString);
+
+    // Obtener los componentes de fecha y hora
+    const year = date.getUTCFullYear();
+    const month = String(date.getUTCMonth() + 1).padStart(2, '0');
+    const day = String(date.getUTCDate()).padStart(2, '0');
+    const hours = String(date.getUTCHours()).padStart(2, '0');
+    const minutes = String(date.getUTCMinutes()).padStart(2, '0');
+    const seconds = String(date.getUTCSeconds()).padStart(2, '0');
+    const milliseconds = String(date.getUTCMilliseconds()).padStart(3, '0');
+
+    // Formatear la cadena en el formato ISO 8601
+    const formattedDate = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}Z`;
+
+    return formattedDate;
+}
diff --git a/src/css/app.scss b/src/css/app.scss
index 3c8cc50b6..9ed51c1c7 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -14,6 +14,10 @@ a {
     color: $orange-4;
 }
 
+.rounded--full {
+    border-radius: 50%;
+}
+
 // Removes chrome autofill background
 input:-webkit-autofill,
 select:-webkit-autofill {
@@ -32,10 +36,12 @@ body.body--light {
     --vn-text: #000000;
     --vn-gray: #f5f5f5;
     --vn-label: #5f5f5f;
+    --vn-header: #e9e9e9;
 }
 
 body.body--dark {
     --vn-text: #ffffff;
     --vn-gray: #313131;
     --vn-label: #a8a8a8;
+    --vn-header: #212121;
 }
diff --git a/src/filters/index.js b/src/filters/index.js
index 158ce1009..b0c441641 100644
--- a/src/filters/index.js
+++ b/src/filters/index.js
@@ -2,6 +2,7 @@ import toLowerCase from './toLowerCase';
 import toDate from './toDate';
 import toDateString from './toDateString';
 import toDateHour from './toDateHour';
+import toRelativeDate from './toRelativeDate';
 import toCurrency from './toCurrency';
 import toPercentage from './toPercentage';
 import toLowerCamel from './toLowerCamel';
@@ -13,6 +14,7 @@ export {
     toDate,
     toDateString,
     toDateHour,
+    toRelativeDate,
     toCurrency,
     toPercentage,
     dashIfEmpty,
diff --git a/src/filters/toRelativeDate.js b/src/filters/toRelativeDate.js
new file mode 100644
index 000000000..76e67dbea
--- /dev/null
+++ b/src/filters/toRelativeDate.js
@@ -0,0 +1,32 @@
+import { useI18n } from 'vue-i18n';
+
+export default function formatDate(dateVal) {
+    const { t } = useI18n();
+    const today = new Date();
+    if (dateVal == null) return '';
+
+    const date = new Date(dateVal);
+    const dateZeroTime = new Date(dateVal);
+    dateZeroTime.setHours(0, 0, 0, 0);
+    const diff = Math.trunc(
+        (today.getTime() - dateZeroTime.getTime()) / (1000 * 3600 * 24)
+    );
+    let format;
+    if (diff === 0) format = t('globals.today');
+    else if (diff === 1) format = t('globals.yesterday');
+    else if (diff > 1 && diff < 7) {
+        const options = { weekday: 'short' };
+        format = date.toLocaleDateString(t('globals.dateFormat'), options);
+    } else if (today.getFullYear() === date.getFullYear()) {
+        const options = { day: 'numeric', month: 'short' };
+        format = date.toLocaleDateString(t('globals.dateFormat'), options);
+    } else {
+        const options = { year: 'numeric', month: '2-digit', day: '2-digit' };
+        format = date.toLocaleDateString(t('globals.dateFormat'), options);
+    }
+
+    // Formatear la hora en HH:mm
+    const hours = date.getHours().toString().padStart(2, '0');
+    const minutes = date.getMinutes().toString().padStart(2, '0');
+    return `${format} ${hours}:${minutes}`;
+}
diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js
index d7519ba53..285fb778f 100644
--- a/src/i18n/en/index.js
+++ b/src/i18n/en/index.js
@@ -5,6 +5,9 @@ export default {
             en: 'English',
         },
         language: 'Language',
+        entity: 'Entity',
+        user: 'User',
+        details: 'Details',
         collapseMenu: 'Collapse left menu',
         backToDashboard: 'Return to dashboard',
         notifications: 'Notifications',
@@ -13,8 +16,11 @@ export default {
         pinnedModules: 'Pinned modules',
         darkMode: 'Dark mode',
         logOut: 'Log out',
+        date: 'Date',
         dataSaved: 'Data saved',
         dataDeleted: 'Data deleted',
+        search: 'Search',
+        changes: 'Changes',
         add: 'Add',
         create: 'Create',
         save: 'Save',
@@ -36,6 +42,9 @@ export default {
         summary: {
             basicData: 'Basic data',
         },
+        today: 'Today',
+        yesterday: 'Yesterday',
+        dateFormat: 'en-GB',
     },
     errors: {
         statusUnauthorized: 'Access denied',
diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js
index fc2c80f55..97001eab8 100644
--- a/src/i18n/es/index.js
+++ b/src/i18n/es/index.js
@@ -5,6 +5,9 @@ export default {
             en: 'Inglés',
         },
         language: 'Idioma',
+        entity: 'Entidad',
+        user: 'Usuario',
+        details: 'Detalles',
         collapseMenu: 'Contraer menú lateral',
         backToDashboard: 'Volver al tablón',
         notifications: 'Notificaciones',
@@ -13,8 +16,11 @@ export default {
         pinnedModules: 'Módulos fijados',
         darkMode: 'Modo oscuro',
         logOut: 'Cerrar sesión',
+        date: 'Fecha',
         dataSaved: 'Datos guardados',
         dataDeleted: 'Datos eliminados',
+        search: 'Buscar',
+        changes: 'Cambios',
         add: 'Añadir',
         create: 'Crear',
         save: 'Guardar',
@@ -36,6 +42,9 @@ export default {
         summary: {
             basicData: 'Datos básicos',
         },
+        today: 'Hoy',
+        yesterday: 'Ayer',
+        dateFormat: 'es-ES',
     },
     errors: {
         statusUnauthorized: 'Acceso denegado',
diff --git a/src/stores/useValidationsStore.js b/src/stores/useValidationsStore.js
new file mode 100644
index 000000000..c658a90af
--- /dev/null
+++ b/src/stores/useValidationsStore.js
@@ -0,0 +1,19 @@
+import axios from 'axios';
+import { defineStore } from 'pinia';
+
+export const useValidationsStore = defineStore('validationsStore', {
+    state: () => ({
+        validations: null,
+    }),
+    actions: {
+        async fetchModels() {
+            if (this.validations) return;
+            try {
+                const { data } = await axios.get('Schemas/modelinfo');
+                this.validations = data;
+            } catch (error) {
+                console.error('Error al obtener las validaciones:', error);
+            }
+        },
+    },
+});
diff --git a/test/cypress/integration/ClaimNotes.spec.js b/test/cypress/integration/ClaimNotes.spec.js
index 5b52dd339..9f52c29e4 100644
--- a/test/cypress/integration/ClaimNotes.spec.js
+++ b/test/cypress/integration/ClaimNotes.spec.js
@@ -8,6 +8,7 @@ describe('ClaimNotes', () => {
     it('should add a new note', () => {
         const message = 'This is a new message.';
         cy.get('.q-page-sticky button').click();
+        cy.get('.q-page-sticky > div > button').click();
         cy.get('.q-dialog .q-card__section:nth-child(2)').type(message);
         cy.get('.q-card__actions button:nth-child(2)').click();
         cy.get('.q-card .q-card__section:nth-child(2)')
diff --git a/test/cypress/integration/vnLog.spec.js b/test/cypress/integration/vnLog.spec.js
new file mode 100644
index 000000000..3d6d9b95d
--- /dev/null
+++ b/test/cypress/integration/vnLog.spec.js
@@ -0,0 +1,31 @@
+/// <reference types="cypress" />
+describe('ClaimNotes', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.visit(`/#/claim/${1}/log`);
+    });
+
+    it('should have just one record', () => {
+        cy.get('.model-info .q-btn').eq(1).click();
+        cy.get('.user-log .model-log').its('length').should('eq', 1);
+        cy.get('.q-page-sticky .q-btn').click();
+        cy.get('.user-log .model-log').its('length').should('eq', 4);
+    });
+
+    it('should filter by insert actions', () => {
+        cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get('.q-checkbox__inner').eq(0).click();
+        cy.get('.q-page > .q-drawer-container > .fullscreen').click();
+        cy.get('.model-info .q-chip__content').eq(0).should('have.text', 'Document');
+        cy.get('.model-info .q-chip__content').eq(1).should('have.text', 'Beginning');
+    });
+
+    it('should show the point record', () => {
+        cy.get('.pit').eq(0).click();
+        cy.get('.q-menu .q-card .header').should('have.text', 'Observation #1');
+        cy.get('.q-menu .q-card .json-string').should(
+            'have.text',
+            'Waiting for customer'
+        );
+    });
+});
diff --git a/test/cypress/integration/workerList.spec.js b/test/cypress/integration/workerList.spec.js
index d76958367..8d4dd770d 100644
--- a/test/cypress/integration/workerList.spec.js
+++ b/test/cypress/integration/workerList.spec.js
@@ -8,17 +8,17 @@ describe('WorkerList', () => {
     it('should load workers', () => {
         cy.get('.card-list-body > .list-items > :nth-child(2) > .value > span')
             .eq(0)
-            .should('have.text', 'victorvd');
-        cy.get('.card-list-body > .list-items > :nth-child(2) > .value > span')
-            .eq(1)
             .should('have.text', 'JessicaJones');
         cy.get('.card-list-body > .list-items > :nth-child(2) > .value > span')
-            .eq(2)
+            .eq(1)
             .should('have.text', 'BruceBanner');
+        cy.get('.card-list-body > .list-items > :nth-child(2) > .value > span')
+            .eq(2)
+            .should('have.text', 'CharlesXavier');
     });
 
     it('should open the worker summary', () => {
-        cy.get('.card-list-body .actions .q-btn:nth-child(2)').eq(1).click();
+        cy.get('.card-list-body .actions .q-btn:nth-child(2)').eq(0).click();
         cy.get('.summaryHeader div').should('have.text', '1110 - Jessica Jones');
         cy.get('.summary .header').eq(0).invoke('text').should('include', 'Basic data');
         cy.get('.summary .header').eq(1).should('have.text', 'User data');