<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } 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 VnSelectFilter from './VnSelectFilter.vue';
import VnUserLink from '../ui/VnUserLink.vue';

const stateStore = useStateStore();
const validationsStore = useValidator();
const { models } = validationsStore;
const route = useRoute();
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',
    ],
    include: [
        {
            relation: 'user',
            scope: {
                fields: ['nickname', 'name', 'image'],
                include: {
                    relation: 'worker',
                    scope: {
                        fields: ['id'],
                    },
                },
            },
        },
    ],
};

const workers = 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);

        // 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() {
    filter.where = { and: [{ originFk: route.params.id }] };
    const { data } = await getLogs(filter);
    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);
    }

    const { data } = await getLogs(filter);

    logTree.value = getLogTree(data);
}

async function getLogs(filter) {
    return axios.get(props.url ?? `${props.model}Logs`, {
        params: { filter: JSON.stringify(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();
}

setLogTree();
</script>
<template>
    <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) => {
                    return {
                        locale: useCapitalize(validations[item.changedModel].locale.name),
                        value: item.changedModel,
                    };
                }))
        "
        auto-load
    />
    <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"
                                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"
                            >
                                {{ 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 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>
    <Teleport v-if="stateStore.isHeaderMounted()" to="#actions-append">
        <div class="row q-gutter-x-sm">
            <QBtn
                flat
                @click.stop="stateStore.toggleRightDrawer()"
                round
                dense
                icon="menu"
            >
                <QTooltip bottom anchor="bottom right">
                    {{ t('globals.collapseMenu') }}
                </QTooltip>
            </QBtn>
        </div>
    </Teleport>
    <QDrawer v-model="stateStore.rightDrawer" show-if-above side="right" :width="300">
        <QScrollArea class="fit text-grey-8">
            <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>
                    <VnSelectFilter
                        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="!workers">
                        <QSkeleton type="QInput" class="full-width" />
                    </QItemSection>
                    <QItemSection v-if="workers && userRadio !== null">
                        <VnSelectFilter
                            class="full-width"
                            :label="t('globals.user')"
                            v-model="userSelect"
                            option-label="name"
                            option-value="id"
                            :options="workers"
                            @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>
                        </VnSelectFilter>
                    </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>
        </QScrollArea>
    </QDrawer>
    <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
        hasToPickUp: Has to pick Up
        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á
        hasToPickUp: Se debe recoger
        dmsFk: ID documento
        text: Descripción
        claimStateFk: Estado de la reclamación
        workerFk: Trabajador
        clientFk: Cliente
        responsibility: Responsabilidad
        packages: Bultos
</i18n>
