HOTFIX: OrderCatalog scroll To Item #1026
|
@ -67,7 +67,7 @@ const dialog = ref(null);
|
||||||
<QTooltip>{{ t('globals.add') }}</QTooltip>
|
<QTooltip>{{ t('globals.add') }}</QTooltip>
|
||||||
<QPopupProxy ref="dialog">
|
<QPopupProxy ref="dialog">
|
||||||
<OrderCatalogItemDialog
|
<OrderCatalogItemDialog
|
||||||
:prices="item.prices"
|
:item="item"
|
||||||
@added="() => dialog.hide()"
|
@added="() => dialog.hide()"
|
||||||
/>
|
/>
|
||||||
</QPopupProxy>
|
</QPopupProxy>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { onMounted, onUnmounted, ref, computed, watch } from 'vue';
|
import { onMounted, onUnmounted, ref, computed, watch, provide, nextTick } from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||||
|
@ -18,6 +18,7 @@ const dataKey = 'OrderCatalogList';
|
||||||
const arrayData = useArrayData(dataKey);
|
const arrayData = useArrayData(dataKey);
|
||||||
const store = arrayData.store;
|
const store = arrayData.store;
|
||||||
const tags = ref([]);
|
const tags = ref([]);
|
||||||
|
const itemRefs = ref({});
|
||||||
|
|
||||||
let catalogParams = {
|
let catalogParams = {
|
||||||
orderFk: route.params.id,
|
orderFk: route.params.id,
|
||||||
|
@ -76,6 +77,19 @@ watch(
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
const onItemSaved = (updatedItem) => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
scrollToItem(updatedItem.items[0].itemFk);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollToItem = async (id) => {
|
||||||
|
|||||||
|
const element = itemRefs.value[id]?.$el;
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
provide('onItemSaved', onItemSaved);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -115,6 +129,7 @@ watch(
|
||||||
<CatalogItem
|
<CatalogItem
|
||||||
v-for="row in rows"
|
v-for="row in rows"
|
||||||
:key="row.id"
|
:key="row.id"
|
||||||
|
:ref="(el) => (itemRefs[row.id] = el)"
|
||||||
:item="row"
|
:item="row"
|
||||||
is-catalog
|
is-catalog
|
||||||
class="fill-icon"
|
class="fill-icon"
|
||||||
|
|
|
@ -1,41 +1,53 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import toCurrency from '../../../filters/toCurrency';
|
import toCurrency from 'src/filters/toCurrency';
|
||||||
import { ref } from 'vue';
|
import { inject, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import useNotify from 'composables/useNotify';
|
import useNotify from 'composables/useNotify';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const emit = defineEmits(['added']);
|
const emit = defineEmits(['added']);
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
prices: {
|
item: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const onItemSaved = inject('onItemSaved');
|
||||||
const fields = ref((props.prices || []).map((item) => ({ ...item, quantity: 0 })));
|
const prices = ref((props.item.prices || []).map((item) => ({ ...item, quantity: 0 })));
|
||||||
const descriptorData = useArrayData('orderData');
|
const descriptorData = useArrayData('orderData');
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const addToOrder = async () => {
|
const addToOrder = async () => {
|
||||||
if (isLoading.value) return;
|
if (isLoading.value) return;
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
const items = (fields.value || []).filter((item) => Number(item.quantity) > 0);
|
const items = (prices.value || []).filter((item) => Number(item.quantity) > 0);
|
||||||
await axios.post('/OrderRows/addToOrder', {
|
await axios.post('/OrderRows/addToOrder', {
|
||||||
items,
|
items,
|
||||||
orderFk: Number(route.params.id),
|
orderFk: Number(route.params.id),
|
||||||
});
|
});
|
||||||
notify(t('globals.dataSaved'), 'positive');
|
notify(t('globals.dataSaved'), 'positive');
|
||||||
emit('added');
|
await descriptorData.fetch({});
|
||||||
descriptorData.fetch({});
|
onItemSaved({ ...props, items, saved: true });
|
||||||
|
emit('added', items);
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
};
|
};
|
||||||
const canAddToOrder = () => {
|
const canAddToOrder = () => {
|
||||||
return (fields.value || []).some((item) => Number(item.quantity) > 0);
|
let canAddToOrder = (prices.value || []).some((price) => Number(price.quantity) > 0);
|
||||||
|
if (canAddToOrder) {
|
||||||
|
const excedQuantity = prices.value.reduce(
|
||||||
|
(acc, { quantity }) => acc + quantity,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (excedQuantity > props.item.available) {
|
||||||
|
canAddToOrder = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return canAddToOrder;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -44,30 +56,33 @@ const canAddToOrder = () => {
|
||||||
<QForm @submit="addToOrder">
|
<QForm @submit="addToOrder">
|
||||||
<QMarkupTable class="shadow-0">
|
<QMarkupTable class="shadow-0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="item in fields" :key="item.warehouse">
|
<tr v-for="price in prices" :key="price.warehouse">
|
||||||
<td class="text-bold q-pr-md td" style="width: 35%">
|
<td class="text-bold q-pr-md td" style="width: 35%">
|
||||||
{{ item.warehouse }}
|
{{ price.warehouse }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right" style="width: 35%">
|
<td class="text-right" style="width: 35%">
|
||||||
<span
|
<span
|
||||||
class="link"
|
class="link"
|
||||||
@click="
|
@click.shift="
|
||||||
() => {
|
() => {
|
||||||
item.quantity += item.grouping;
|
price.quantity -= price.grouping;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@click.exact="
|
||||||
|
() => {
|
||||||
|
price.quantity += price.grouping;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ item.grouping }}
|
{{ price.grouping }}
|
||||||
</span>
|
</span>
|
||||||
x {{ toCurrency(item.price) }}
|
x {{ toCurrency(price.price) }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<QInput
|
<VnInputNumber
|
||||||
v-model.number="item.quantity"
|
v-model.number="price.quantity"
|
||||||
type="number"
|
:step="price.grouping"
|
||||||
:step="item.grouping"
|
|
||||||
min="0"
|
min="0"
|
||||||
dense
|
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in New Issue
Y si lo tuviese que cargar tardase 101ms ya no iria?
Le puse el nextTick para que el DOM terminase de montarse pero no terminaba de funcionar
Con el setTimeout conseguí el efecto deseado
Iría de todas maneras porque el timeout no depende de la petición anterior
https://chatgpt.com/c/675000bd-53e8-8011-8a7a-0481f274180d
Resuelto con requestAnimationFrame
He usado un console.error y solo se muestra 1 vez