<script setup>
import { ref, onUnmounted, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { date } from 'quasar';
import { useStateStore } from 'stores/useStateStore';
import { toRelativeDate } from 'src/filters';
import { useColor } from 'src/composables/useColor';
import { useCapitalize } from 'src/composables/useCapitalize';
import { useValidator } from 'src/composables/useValidator';
import VnAvatar from '../ui/VnAvatar.vue';
import VnJsonValue from '../common/VnJsonValue.vue';
import FetchData from '../FetchData.vue';
import VnSelect from './VnSelect.vue';
import VnUserLink from '../ui/VnUserLink.vue';
import VnPaginate from '../ui/VnPaginate.vue';

const stateStore = useStateStore();
const validationsStore = useValidator();
const { models } = validationsStore;
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
const props = defineProps({
    model: {
        type: String,
        default: null,
    },
    url: {
        type: String,
        default: null,
    },
    mapper: {
        type: Function,
        default: null,
    },
});

const filter = {
    fields: [
        'id',
        'originFk',
        'userFk',
        'action',
        'changedModel',
        'oldInstance',
        'newInstance',
        'creationDate',
        'changedModel',
        'changedModelId',
        'changedModelValue',
        'description',
        'summaryId',
    ],
    include: [
        {
            relation: 'user',
            scope: {
                fields: ['nickname', 'name', 'image'],
                include: {
                    relation: 'worker',
                    scope: {
                        fields: ['id'],
                    },
                },
            },
        },
    ],
    where: { and: [{ originFk: route.params.id }] },
};

const paginate = ref();
const actions = ref();
const changeInput = ref();
const searchInput = ref();
const userRadio = ref();
const userSelect = ref();
const dateFrom = ref();
const dateFromDialog = 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,
    },
});

let validations = models;
let pointRecord = ref(null);
let byRecord = ref(false);
const logTree = ref([]);

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
);

function castJsonValue(value) {
    return typeof value === 'string' && validDate.test(value) ? new Date(value) : value;
}

function parseProps(propNames, locale, vals, olds) {
    const props = [];

    for (const prop of propNames) {
        if (prop.endsWith('$')) continue;
        props.push({
            name: prop,
            nameI18n: useCapitalize(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 getLogTree(data) {
    const logs = [];
    let originLog = null;
    let userLog = null;
    let modelLog = null;
    let nLogs;

    for (let i = 0; i < data.length; i++) {
        let log = data[i];
        let prevLog = i > 0 ? data[i - 1] : null;
        const locale = validations[log.changedModel]?.locale || {};

        // Origin
        const originChanged = !prevLog || log.originFk != prevLog.originFk;
        if (originChanged) {
            logs.push((originLog = { originFk: log.originFk, logs: [] }));
        }
        // User
        const userChanged = originChanged || log.userFk != prevLog.userFk;
        if (userChanged) {
            originLog.logs.push(
                (userLog = {
                    user: log.user,
                    userFk: log.userFk,
                    logs: [],
                })
            );
        }
        // Model
        const modelChanged =
            userChanged ||
            log.changedModel != prevLog.changedModel ||
            log.changedModelId != prevLog.changedModelId ||
            nLogs >= 6;

        if (modelChanged) {
            userLog.logs.push(
                (modelLog = {
                    model: log.changedModel,
                    modelI18n: useCapitalize(locale.name) || log.changedModel,
                    id: log.changedModelId,
                    showValue: log.changedModelValue,
                    logs: [],
                })
            );
            nLogs = 0;
        }
        nLogs++;
        modelLog.logs.push(log);
        modelLog.summaryId = modelLog.logs[0].summaryId;
        // 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 = validations[modelLog.model]?.locale || {};
    pointRecord.value = parseProps(propNames, locale, data);
}
async function setLogTree(data) {
    logTree.value = getLogTree(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);
    }

    paginate.value.fetch(filter);
}

function setDate(type) {
    let from = dateFrom.value
        ? date.formatDate(dateFrom.value.split('-').reverse().join('-'), 'YYYY-MM-DD')
        : undefined;
    from = date.adjustDate(from, { hour: 0, minute: 0, second: 0, millisecond: 0 }, true);

    let to = dateTo.value
        ? date.formatDate(dateTo.value.split('-').reverse().join('-'), 'YYYY-MM-DD')
        : date.formatDate(dateFrom.value.split('-').reverse().join('-'), 'YYYY-MM-DD');
    to = date.adjustDate(
        to,
        { hour: 21, minute: 59, second: 59, millisecond: 999 },
        true
    );

    switch (type) {
        case 'from':
            return { between: [from, to] };
        case 'to': {
            if (dateFrom.value) {
                return {
                    between: [from, to],
                };
            }
            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;
    }
    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 (!dateFrom.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;
    dateFrom.value = undefined;
    dateTo.value = undefined;
    userRadio.value = undefined;
    Object.keys(checkboxOptions.value).forEach(
        (opt) => (checkboxOptions.value[opt].selected = false)
    );
    await applyFilter();
}

onUnmounted(() => {
    stateStore.rightDrawer = false;
});

watch(
    () => router.currentRoute.value.params.id,
    () => {
        applyFilter();
    }
);
</script>
<template>
    <FetchData
        :url="`${props.model}Logs/${route.params.id}/models`"
        :filter="{ order: ['changedModel'] }"
        @on-fetch="
            (data) =>
                (actions = data.map((item) => {
                    const changedModel = item.changedModel;
                    return {
                        locale: useCapitalize(
                            validations[changedModel]?.locale?.name ?? changedModel
                        ),
                        value: changedModel,
                    };
                }))
        "
        auto-load
    />
    <VnPaginate
        ref="paginate"
        :data-key="`${model}Log`"
        :url="`${model}Logs`"
        :filter="filter"
        :skeleton="false"
        auto-load
        @on-fetch="setLogTree"
        search-url="logs"
    >
        <template #body>
            <div
                class="column items-center logs origin-log q-mt-md"
                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 text-grey">
                        {{ useCapitalize(validations[props.model].locale.name) }}
                        #{{ originLog.originFk }}
                    </h6>
                    <div class="line bg-grey"></div>
                </QItem>
                <div
                    class="user-log q-mb-sm"
                    v-for="(userLog, userIndex) in originLog.logs"
                    :key="userIndex"
                >
                    <div class="timeline">
                        <div class="user-avatar">
                            <VnUserLink :worker-id="userLog?.user?.id">
                                <template #link>
                                    <VnAvatar
                                        :class="{ 'cursor-pointer': userLog?.user?.id }"
                                        :worker-id="userLog?.user?.id"
                                        :title="userLog?.user?.nickname"
                                        :show-letter="!userLog?.user"
                                        size="lg"
                                    />
                                </template>
                            </VnUserLink>
                        </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
                                        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} #${modelLog.id}`"
                                    >
                                        {{ t(modelLog.modelI18n) }}
                                    </QChip>

                                    <span
                                        class="model-id q-mr-xs"
                                        v-if="modelLog.summaryId"
                                        v-text="`#${modelLog.summaryId}`"
                                    />
                                    <span
                                        class="model-value"
                                        :title="modelLog.showValue"
                                        v-text="modelLog.showValue"
                                    />
                                    <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 q-mb-xs"
                                    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="
                                                    date.formatDate(
                                                        log.creationDate,
                                                        'DD/MM/YYYY hh:mm:ss'
                                                    ) ?? `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="none"
                                                    v-if="log.action != 'insert'"
                                                    @click.stop="
                                                        openPointRecord(log.id, modelLog)
                                                    "
                                                >
                                                    <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"
                                        />
                                        <span v-if="log.props.length" class="attributes">
                                            <span
                                                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
                                                        "
                                                        >,&nbsp;
                                                    </span>
                                                </span>
                                            </span>
                                            <span
                                                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>
                                            </span>
                                        </span>
                                        <span
                                            v-if="!log.props.length"
                                            class="description"
                                        >
                                            {{ log.description }}
                                        </span>
                                    </QCardSection>
                                </QCard>
                            </QItemSection>
                        </QItem>
                    </QList>
                </div>
            </div>
        </template>
    </VnPaginate>
    <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
        <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>
                <VnSelect
                    class="full-width"
                    :label="t('globals.entity')"
                    v-model="selectedFilters.changedModel"
                    option-label="locale"
                    option-value="value"
                    :options="actions"
                    @update:model-value="selectFilter('action')"
                    hide-selected
                />
            </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="userRadio !== null">
                    <VnSelect
                        class="full-width"
                        :label="t('globals.user')"
                        v-model="userSelect"
                        option-label="name"
                        option-value="id"
                        :url="`${model}Logs/${$route.params.id}/editors`"
                        :fields="['id', 'nickname', 'name', 'image']"
                        sort-by="nickname"
                        @update:model-value="selectFilter('userSelect')"
                        hide-selected
                    >
                        <template #option="{ opt, itemProps }">
                            <QItem v-bind="itemProps" class="q-pa-xs row items-center">
                                <QItemSection class="col-3 items-center">
                                    <VnAvatar :worker-id="opt.id" />
                                </QItemSection>
                                <QItemSection class="col-9 justify-center">
                                    <span>{{ opt.name }}</span>
                                    <span class="text-grey">{{ opt.nickname }}</span>
                                </QItemSection>
                            </QItem>
                        </template>
                    </VnSelect>
                </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="dateFromDialog = true"
                    @focus="(evt) => evt.target.blur()"
                    @clear="selectFilter('date', 'to')"
                    v-model="dateFrom"
                    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>
    </Teleport>
    <QDialog v-model="dateFromDialog">
        <QDate
            :years-in-month-view="false"
            v-model="dateFrom"
            dense
            flat
            minimal
            @update:model-value="
                (value) => {
                    dateFromDialog = false;
                    dateFrom = date.formatDate(value, 'DD-MM-YYYY');
                    selectFilter('date', 'from');
                }
            "
        />
    </QDialog>
    <QDialog v-model="dateToDialog">
        <QDate
            v-model="dateTo"
            dense
            flat
            minimal
            @update:model-value="
                (value) => {
                    dateToDialog = false;
                    dateTo = date.formatDate(value, 'DD-MM-YYYY');
                    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" scoped>
.q-card {
    background-color: var(--vn-section-color);
}
.q-item {
    min-height: 0px;
}
.q-menu {
    display: block;

    & > .loading {
        display: flex;
        justify-content: center;
    }
    & > .q-card {
        min-width: 180px;
        max-width: 400px;

        & > .header {
            color: var(--vn-section-color);
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
        }
    }
}
.origin-log {
    &:first-child > .origin-info {
        margin-top: 0;
    }
    & > .origin-info {
        margin-top: 28px;
        gap: 6px;

        & > .origin-id {
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            margin: 0;
        }
        & > .line {
            flex-grow: 1;
            height: 2px;
        }
    }
}
.user-log {
    display: flex;
    width: 100%;
    max-width: 40em;
    & > .timeline {
        position: relative;
        padding-right: 1px;
        width: 38px;
        min-width: 38px;
        flex-grow: auto;
        & > .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: 19px;
            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;
        min-height: 22px;
        .model-value {
            font-style: italic;
        }
        .model-id {
            color: var(--vn-label-color);
            font-size: 0.9rem;
        }
        .q-btn {
            visibility: hidden;
            float: right;
        }
    }

    &:hover {
        .model-info {
            .q-btn {
                visibility: visible;
            }
        }
    }
}
.changes-log {
    width: 100%;
    overflow: hidden;

    &:last-child {
        margin-bottom: 0;
    }
    .change-info {
        overflow: hidden;
        background-color: var(--vn-section-color);
        & > .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;
                }
            }
        }
        .q-btn.pit {
            visibility: hidden;
        }
        &:hover .q-btn.pit {
            visibility: visible;
        }
    }
    & > .change-detail {
        position: relative;
        overflow: hidden;
        text-overflow: ellipsis;
        background-color: var(--vn-section-color);
        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;
        }
    }
}
</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:
        Creates: Creates
        Edits: Edits
        Deletes: Deletes
        Accesses: Accesses
    Users:
        User: Usuario
        All: Todo
        System: Sistema
    properties:
        id: ID
        claimFk: Claim ID
        saleFk: Sale ID
        quantity: Quantity
        observation: Observation
        ticketCreated: Created
        created: Created
        isChargedToMana: Charged to mana
        pickup: Type of pickup
        dmsFk: Document ID
        text: Description
        claimStateFk: Claim State
        workerFk: Worker
        clientFk: Customer
        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: Historial
    Property: Propiedad
    Before: Antes
    After: Después
    Yes: Si
    Nothing: Nada
    actions:
        Creates: Crea
        Edits: Modifica
        Deletes: Elimina
        Accesses: Accede
    Users:
        User: Usuario
        All: Todo
        System: Sistema
    properties:
        id: ID
        claimFk: ID reclamación
        saleFk: ID linea de venta
        quantity: Cantidad
        observation: Observación
        ticketCreated: Creado
        created: Creado
        isChargedToMana: Cargado a maná
        pickup: Se debe recoger
        dmsFk: ID documento
        text: Descripción
        claimStateFk: Estado de la reclamación
        workerFk: Trabajador
        clientFk: Cliente
        responsibility: Responsabilidad
        packages: Bultos
</i18n>
