feat: add row
This commit is contained in:
parent
4a12fd08e0
commit
8a4b3302cf
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, reactive, computed, onUnmounted, watch } from 'vue';
|
import { onMounted, ref, reactive, computed, onUnmounted, watch, nextTick } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
@ -291,8 +291,36 @@ const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => {
|
||||||
console.error('Error editing price', err);
|
console.error('Error editing price', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const lastRow = ref(null);
|
||||||
|
async function saveOnRowChange(_, row) {
|
||||||
|
if (lastRow.value && lastRow.value !== row.id) {
|
||||||
|
console.log('update');
|
||||||
|
// await upsertPrice(row);
|
||||||
|
}
|
||||||
|
lastRow.value = row.id;
|
||||||
|
rowsSelected.value = [row];
|
||||||
|
}
|
||||||
|
const tableRef = ref();
|
||||||
|
function checkLastVisibleRow() {
|
||||||
|
const tableBody = tableRef.value.$el.querySelector('tbody.q-virtual-scroll__content');
|
||||||
|
if (!tableBody) return;
|
||||||
|
const rows = tableBody.querySelectorAll('tr');
|
||||||
|
let lastVisibleRow = null;
|
||||||
|
|
||||||
|
rows.forEach((row, index) => {
|
||||||
|
const rect = row.getBoundingClientRect();
|
||||||
|
if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
|
||||||
|
lastVisibleRow = index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (lastVisibleRow) {
|
||||||
|
console.log('Última fila visible:', lastVisibleRow);
|
||||||
|
return lastVisibleRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
const addRow = () => {
|
const addRow = () => {
|
||||||
|
const lastvisible = checkLastVisibleRow();
|
||||||
if (!fixedPrices.value || fixedPrices.value.length === 0) {
|
if (!fixedPrices.value || fixedPrices.value.length === 0) {
|
||||||
fixedPrices.value = [];
|
fixedPrices.value = [];
|
||||||
|
|
||||||
|
@ -316,10 +344,22 @@ const addRow = () => {
|
||||||
JSON.stringify(fixedPrices.value[fixedPrices.value.length - 1])
|
JSON.stringify(fixedPrices.value[fixedPrices.value.length - 1])
|
||||||
);
|
);
|
||||||
delete lastItemCopy.id;
|
delete lastItemCopy.id;
|
||||||
fixedPricesOriginalData.value.push(lastItemCopy);
|
fixedPricesOriginalData.value.splice(lastvisible, 0, lastItemCopy);
|
||||||
fixedPrices.value.push(lastItemCopy);
|
fixedPrices.value.unshift(lastItemCopy);
|
||||||
|
nextTick(() => {
|
||||||
|
highlightNewRow(lastvisible);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
function highlightNewRow(index) {
|
||||||
|
const tableBody = tableRef.value.$el.querySelector('tbody.q-virtual-scroll__content');
|
||||||
|
const row = tableBody.querySelectorAll('tr')[index];
|
||||||
|
if (row) {
|
||||||
|
row.classList.add('highlight');
|
||||||
|
setTimeout(() => {
|
||||||
|
row.classList.remove('highlight');
|
||||||
|
}, 3000); // Duración de la animación en milisegundos
|
||||||
|
}
|
||||||
|
}
|
||||||
const openEditTableCellDialog = () => {
|
const openEditTableCellDialog = () => {
|
||||||
editTableCellDialogRef.value.show();
|
editTableCellDialogRef.value.show();
|
||||||
};
|
};
|
||||||
|
@ -359,6 +399,10 @@ const removePrice = async (id, rowIndex) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function onScroll({ to, ref }) {
|
||||||
|
console.log(to, ref);
|
||||||
|
}
|
||||||
|
|
||||||
const updateMinPrice = async (value, props) => {
|
const updateMinPrice = async (value, props) => {
|
||||||
// El checkbox hasMinPrice se encuentra en la misma columna que el input hasMinPrice
|
// El checkbox hasMinPrice se encuentra en la misma columna que el input hasMinPrice
|
||||||
// Por lo tanto le mandamos otro objeto con las mismas propiedades pero con el campo 'field' cambiado
|
// Por lo tanto le mandamos otro objeto con las mismas propiedades pero con el campo 'field' cambiado
|
||||||
|
@ -395,7 +439,11 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
</template>
|
</template>
|
||||||
</RightMenu>
|
</RightMenu>
|
||||||
<QPage class="column items-center q-pa-md">
|
<QPage class="column items-center q-pa-md">
|
||||||
|
{{ rowsSelected }}
|
||||||
<QTable
|
<QTable
|
||||||
|
ref="tableRef"
|
||||||
|
@virtual-scroll="onScroll"
|
||||||
|
virtual-scroll
|
||||||
dense
|
dense
|
||||||
:rows="fixedPrices"
|
:rows="fixedPrices"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
@ -405,6 +453,8 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
:pagination="{ rowsPerPage: 0 }"
|
||||||
class="full-width q-mt-md"
|
class="full-width q-mt-md"
|
||||||
:no-data-label="t('globals.noResults')"
|
:no-data-label="t('globals.noResults')"
|
||||||
|
@row-click="saveOnRowChange"
|
||||||
|
:virtual-scroll-item-size="48"
|
||||||
>
|
>
|
||||||
<template #top-row="{ cols }">
|
<template #top-row="{ cols }">
|
||||||
<QTr>
|
<QTr>
|
||||||
|
@ -427,7 +477,19 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
</template>
|
</template>
|
||||||
<template #header="props">
|
<template #header="props">
|
||||||
<QTr :props="props" class="bg">
|
<QTr :props="props" class="bg">
|
||||||
<QTh />
|
<QTh>
|
||||||
|
<QIcon
|
||||||
|
@click.stop="addRow()"
|
||||||
|
class="fill-icon-on-hover"
|
||||||
|
color="primary"
|
||||||
|
name="add_circle"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Add fixed price') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</QTh>
|
||||||
<QTh
|
<QTh
|
||||||
v-for="col in props.cols"
|
v-for="col in props.cols"
|
||||||
:key="col.name"
|
:key="col.name"
|
||||||
|
@ -530,6 +592,16 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
style="max-width: 125px"
|
style="max-width: 125px"
|
||||||
:show-event="false"
|
:show-event="false"
|
||||||
v-model="props.row.started"
|
v-model="props.row.started"
|
||||||
|
v-on="getRowUpdateInputEvents(props, false, 'date')"
|
||||||
|
:options="(date) => date > props.row.ended"
|
||||||
|
v-bind="
|
||||||
|
isBigger(props.row.started)
|
||||||
|
? {
|
||||||
|
'bg-color': 'warning',
|
||||||
|
'is-outlined': true,
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
@ -539,7 +611,16 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
style="max-width: 125px"
|
style="max-width: 125px"
|
||||||
:show-event="false"
|
:show-event="false"
|
||||||
v-model="props.row.ended"
|
v-model="props.row.ended"
|
||||||
:options="(date) => date > props.row.ended"
|
:options="isLower(props.row.started)"
|
||||||
|
v-on="getRowUpdateInputEvents(props, false, 'date')"
|
||||||
|
v-bind="
|
||||||
|
isLower(props.row.started)
|
||||||
|
? {
|
||||||
|
'bg-color': 'warning',
|
||||||
|
'is-outlined': true,
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
@ -598,6 +679,12 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
{{ t('Edit fixed price(s)') }}
|
{{ t('Edit fixed price(s)') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
|
<QPageSticky :offset="[20, -20]">
|
||||||
|
<QBtn @click="addRow()" color="primary" fab icon="add" />
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('Add') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QPageSticky>
|
||||||
<QPageSticky v-if="rowsSelected.length" :offset="[20, 20]">
|
<QPageSticky v-if="rowsSelected.length" :offset="[20, 20]">
|
||||||
<QBtn @click="openEditTableCellDialog()" color="primary" fab icon="edit" />
|
<QBtn @click="openEditTableCellDialog()" color="primary" fab icon="edit" />
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -623,6 +710,40 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
||||||
.q-field__append {
|
.q-field__append {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
/* height or max-height is important */
|
||||||
|
|
||||||
|
.q-table__top,
|
||||||
|
.q-table__bottom,
|
||||||
|
tbody tr:first-child td {
|
||||||
|
/* bg color is important for th; just specify one */
|
||||||
|
background-color: #00b4ff;
|
||||||
|
}
|
||||||
|
thead tr th {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
thead tr:first-child th {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is when the loading indicator appears */
|
||||||
|
|
||||||
|
/* prevent scrolling behind sticky top row on focus */
|
||||||
|
tbody
|
||||||
|
/* height of all previous header rows */ {
|
||||||
|
scroll-margin-top: 148px;
|
||||||
|
}
|
||||||
|
tbody tr.highlight .q-td {
|
||||||
|
animation: highlight-animation 4s ease-in-out;
|
||||||
|
}
|
||||||
|
@keyframes highlight-animation {
|
||||||
|
0% {
|
||||||
|
background-color: $primary-light;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
|
Loading…
Reference in New Issue