Compare commits

...

9 Commits

6 changed files with 88 additions and 70 deletions

View File

@ -22,7 +22,7 @@ const pinnedModulesRef = ref();
</script> </script>
<template> <template>
<QHeader color="white" elevated> <QHeader color="white" elevated reveal>
<QToolbar class="q-py-sm q-px-md"> <QToolbar class="q-py-sm q-px-md">
<QBtn <QBtn
@click="stateStore.toggleLeftDrawer()" @click="stateStore.toggleLeftDrawer()"

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { onBeforeMount, computed } from 'vue'; import { onBeforeMount, computed, onMounted, ref } from 'vue';
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router'; import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
@ -57,6 +57,10 @@ if (props.baseUrl) {
} }
}); });
} }
const headerHeight = ref(0);
onMounted(() => {
headerHeight.value = document.querySelector('.q-toolbar')?.offsetHeight + 'px';
});
</script> </script>
<template> <template>
<QDrawer <QDrawer
@ -80,11 +84,12 @@ if (props.baseUrl) {
</template> </template>
</RightMenu> </RightMenu>
<QPageContainer> <QPageContainer>
<QPage> <QPage padding :style="{ 'padding-top': headerHeight }">
<VnSubToolbar />
<div :class="[useCardSize(), $attrs.class]"> <div :class="[useCardSize(), $attrs.class]">
<RouterView :key="route.path" /> <RouterView :key="route.path" /></div
</div> ></QPage>
</QPage> <QPageSticky expand position="top">
<VnSubToolbar />
</QPageSticky>
</QPageContainer> </QPageContainer>
</template> </template>

View File

@ -1,7 +1,6 @@
<script setup> <script setup>
import { onMounted, onBeforeUnmount, ref } from 'vue'; import { onMounted, onBeforeUnmount, ref } from 'vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
const stateStore = useStateStore(); const stateStore = useStateStore();
const actions = ref(null); const actions = ref(null);
const data = ref(null); const data = ref(null);
@ -24,14 +23,13 @@ onMounted(() => {
if (actions.value) observer.observe(actions.value, opts); if (actions.value) observer.observe(actions.value, opts);
if (data.value) observer.observe(data.value, opts); if (data.value) observer.observe(data.value, opts);
}); });
onBeforeUnmount(() => stateStore.toggleSubToolbar()); onBeforeUnmount(() => stateStore.toggleSubToolbar());
</script> </script>
<template> <template>
<QToolbar <QToolbar
id="subToolbar" id="subToolbar"
class="justify-end sticky" class="justify-end shadow-10"
v-show="hasContent || $slots['st-actions'] || $slots['st-data']" v-show="hasContent || $slots['st-actions'] || $slots['st-data']"
> >
<slot name="st-data"> <slot name="st-data">
@ -43,9 +41,3 @@ onBeforeUnmount(() => stateStore.toggleSubToolbar());
</slot> </slot>
</QToolbar> </QToolbar>
</template> </template>
<style lang="scss" scoped>
.sticky {
position: sticky;
z-index: 1;
}
</style>

View File

@ -5,7 +5,7 @@ const quasar = useQuasar();
</script> </script>
<template> <template>
<QLayout view="hHh LpR fFf" v-shortcut> <QLayout view="hHh lpR lFr" v-shortcut class="shadow-2">
<Navbar /> <Navbar />
<RouterView></RouterView> <RouterView></RouterView>
<QFooter v-if="quasar.platform.is.mobile"></QFooter> <QFooter v-if="quasar.platform.is.mobile"></QFooter>

View File

@ -185,8 +185,8 @@ const showBalancePdf = ({ id }) => {
@on-fetch="getCurrentBalance" @on-fetch="getCurrentBalance"
></FetchData> ></FetchData>
<VnSubToolbar class="q-mb-md"> <template v-if="stateStore.isHeaderMounted()">
<template #st-data> <Teleport to="#st-data">
<div class="column justify-center q-px-md q-py-sm"> <div class="column justify-center q-px-md q-py-sm">
<span class="text-bold">{{ t('Total by company') }}</span> <span class="text-bold">{{ t('Total by company') }}</span>
<div class="row justify-center"> <div class="row justify-center">
@ -194,8 +194,8 @@ const showBalancePdf = ({ id }) => {
{{ toCurrency(currentBalance[companyId]?.amount) }} {{ toCurrency(currentBalance[companyId]?.amount) }}
</div> </div>
</div> </div>
</template> </Teleport>
<template #st-actions> <Teleport to="#st-actions">
<div> <div>
<VnSelect <VnSelect
:label="t('Company')" :label="t('Company')"
@ -207,8 +207,8 @@ const showBalancePdf = ({ id }) => {
option-value="id" option-value="id"
></VnSelect> ></VnSelect>
</div> </div>
</template> </Teleport>
</VnSubToolbar> </template>
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="CustomerBalance" data-key="CustomerBalance"

View File

@ -36,7 +36,14 @@ const itemBalances = ref([]);
const warehouseFk = ref(null); const warehouseFk = ref(null);
const _showWhatsBeforeInventory = ref(false); const _showWhatsBeforeInventory = ref(false);
const inventoriedDate = ref(null); const inventoriedDate = ref(null);
const loading = ref(true);
const pagination = ref({
rowsPerPage: 20,
sortBy: 'desc',
descending: false,
page: 1,
});
const filterWarehouses = "{ fields: ['id', 'name'], order: 'name ASC' }";
const columns = computed(() => [ const columns = computed(() => [
{ {
name: 'claim', name: 'claim',
@ -104,6 +111,11 @@ const showWhatsBeforeInventory = computed({
else itemsBalanceFilter.where.date = inventoriedDate.value ?? new Date(); else itemsBalanceFilter.where.date = inventoriedDate.value ?? new Date();
}, },
}); });
async function handleOnFetch(data) {
itemBalances.value = data;
if (data.length < 1) return;
await scrollToToday();
}
const fetchItemBalances = async () => await itemBalancesRef.value.fetch(); const fetchItemBalances = async () => await itemBalancesRef.value.fetch();
@ -120,15 +132,12 @@ const scrollToToday = async () => {
await nextTick(); await nextTick();
const today = Date.vnNew(); const today = Date.vnNew();
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
const todayCell = document.querySelector(`td[data-date="${today.toISOString()}"]`); const todayIndex = itemBalances.value.findIndex((item) =>
if (todayCell) { date.isSameDate(today.toISOString(), item.shipped)
todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' }); );
} if (todayIndex > -1)
}; pagination.value.page = Math.ceil(todayIndex / pagination.value.rowsPerPage);
loading.value = false;
const formatDateForAttribute = (dateValue) => {
if (dateValue instanceof Date) return date.formatDate(dateValue, 'YYYY-MM-DD');
return dateValue;
}; };
const originTypeMap = { const originTypeMap = {
@ -166,7 +175,6 @@ onMounted(async () => {
const { data } = await axios.get('Configs/findOne'); const { data } = await axios.get('Configs/findOne');
inventoriedDate.value = data.inventoried; inventoriedDate.value = data.inventoried;
await fetchItemBalances(); await fetchItemBalances();
await scrollToToday();
}); });
onUnmounted(() => (stateStore.rightDrawer = false)); onUnmounted(() => (stateStore.rightDrawer = false));
@ -178,6 +186,9 @@ watch(
itemBalancesRef.value.fetch(); itemBalancesRef.value.fetch();
} }
); );
const pagesNumber = computed(() =>
Math.ceil(itemBalances.value.length / pagination.value.rowsPerPage)
);
</script> </script>
<template> <template>
@ -185,50 +196,51 @@ watch(
ref="itemBalancesRef" ref="itemBalancesRef"
url="Items/getBalance" url="Items/getBalance"
:filter="itemsBalanceFilter" :filter="itemsBalanceFilter"
@on-fetch="(data) => (itemBalances = data)" @on-fetch="handleOnFetch"
/> />
<FetchData <FetchData
url="Warehouses" url="Warehouses"
:filter="{ fields: ['id', 'name'], order: 'name ASC' }" :filter="filterWarehouses"
auto-load auto-load
@on-fetch="(data) => (warehousesOptions = data)" @on-fetch="(data) => (warehousesOptions = data)"
/> />
<QToolbar class="justify-end"> <template v-if="stateStore.isHeaderMounted()">
<div id="st-data" class="row"> <Teleport to="#st-data">
<VnSelect <div class="row">
:label="t('itemDiary.warehouse')" <VnSelect
:options="warehousesOptions" :label="t('itemDiary.warehouse')"
hide-selected :options="warehousesOptions"
option-label="name" hide-selected
option-value="id" option-label="name"
dense option-value="id"
v-model="itemsBalanceFilter.where.warehouseFk" dense
@update:model-value="fetchItemBalances" v-model="itemsBalanceFilter.where.warehouseFk"
class="q-mr-lg" @update:model-value="fetchItemBalances"
/> class="q-mr-lg"
<QCheckbox />
:label="t('itemDiary.showBefore')" <QCheckbox
v-model="showWhatsBeforeInventory" :label="t('itemDiary.showBefore')"
@update:model-value="fetchItemBalances" v-model="showWhatsBeforeInventory"
class="q-mr-lg" @update:model-value="fetchItemBalances"
/> class="q-mr-lg"
<VnInputDate />
v-if="showWhatsBeforeInventory" <VnInputDate
:label="t('itemDiary.since')" v-if="showWhatsBeforeInventory"
dense :label="t('itemDiary.since')"
v-model="itemsBalanceFilter.where.date" dense
@update:model-value="fetchItemBalances" v-model="itemsBalanceFilter.where.date"
/> @update:model-value="fetchItemBalances"
</div> />
<QSpace /> </div>
<div id="st-actions"></div> </Teleport>
</QToolbar> </template>
<QPage class="column items-center q-pa-md"> <QPage>
<QTable <QTable
:loading="loading"
:rows="itemBalances" :rows="itemBalances"
:columns="columns" :columns="columns"
class="full-width q-mt-md" class="full-width"
:no-data-label="t('globals.noResults')" v-model:pagination="pagination"
> >
<template #body-cell-claim="{ row }"> <template #body-cell-claim="{ row }">
<QTd @click.stop> <QTd @click.stop>
@ -247,7 +259,7 @@ watch(
</QTd> </QTd>
</template> </template>
<template #body-cell-date="{ row }"> <template #body-cell-date="{ row }">
<QTd @click.stop :data-date="formatDateForAttribute(row.shipped)"> <QTd @click.stop>
<QBadge <QBadge
v-bind="getBadgeAttrs(row.shipped)" v-bind="getBadgeAttrs(row.shipped)"
class="q-ma-none" class="q-ma-none"
@ -334,6 +346,15 @@ watch(
</QTd> </QTd>
</template> </template>
</QTable> </QTable>
<QFooter elevated style="background-color: var(--vn-section-color)">
<QPagination
v-model="pagination.page"
:max="pagesNumber"
style="justify-content: center"
size="sm"
input
/>
</QFooter>
</QPage> </QPage>
</template> </template>