mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-28 04:01:10 -04:00
refactor and apply scroll to load data in estimates, invoices and payments
This commit is contained in:
@ -23,7 +23,6 @@
|
||||
estimateData.status === 'DRAFT' &&
|
||||
userStore.hasAbilities(abilities.SEND_ESTIMATE)
|
||||
"
|
||||
:disabled="isSendingEmail"
|
||||
:content-loading="isLoadingEstimate"
|
||||
variant="primary"
|
||||
class="text-sm"
|
||||
@ -45,7 +44,7 @@
|
||||
hidden
|
||||
h-full
|
||||
pt-16
|
||||
pb-4
|
||||
pb-[6.4rem]
|
||||
ml-56
|
||||
bg-white
|
||||
xl:ml-64
|
||||
@ -156,18 +155,17 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="estimateStore && estimateStore.estimates"
|
||||
ref="estimateListSection"
|
||||
class="
|
||||
h-full
|
||||
pb-32
|
||||
overflow-y-scroll
|
||||
border-l border-gray-200 border-solid
|
||||
base-scroll
|
||||
"
|
||||
>
|
||||
<div v-for="(estimate, index) in estimateStore.estimates" :key="index">
|
||||
<div v-for="(estimate, index) in estimateList" :key="index">
|
||||
<router-link
|
||||
v-if="estimate && !isLoading"
|
||||
v-if="estimate"
|
||||
:id="'estimate-' + estimate.id"
|
||||
:to="`/admin/estimates/${estimate.id}/view`"
|
||||
:class="[
|
||||
@ -248,11 +246,8 @@
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="flex justify-center p-4 items-center">
|
||||
<LoadingIcon
|
||||
v-if="isLoading"
|
||||
class="h-6 m-1 animate-spin text-primary-400"
|
||||
/>
|
||||
<div v-if="isLoading" class="flex justify-center p-4 items-center">
|
||||
<LoadingIcon class="h-6 m-1 animate-spin text-primary-400" />
|
||||
</div>
|
||||
<p
|
||||
v-if="!estimateStore.estimates.length && !isLoading"
|
||||
@ -283,49 +278,41 @@
|
||||
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { computed, reactive, ref, watch, inject } from 'vue'
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import EstimateDropDown from '@/scripts/admin/components/dropdowns/EstimateIndexDropdown.vue'
|
||||
import { debounce } from 'lodash'
|
||||
|
||||
import { useEstimateStore } from '@/scripts/admin/stores/estimate'
|
||||
import { useModalStore } from '@/scripts/stores/modal'
|
||||
import { useNotificationStore } from '@/scripts/stores/notification'
|
||||
import { useDialogStore } from '@/scripts/stores/dialog'
|
||||
import { useUserStore } from '@/scripts/admin/stores/user'
|
||||
|
||||
import EstimateDropDown from '@/scripts/admin/components/dropdowns/EstimateIndexDropdown.vue'
|
||||
import SendEstimateModal from '@/scripts/admin/components/modal-components/SendEstimateModal.vue'
|
||||
import LoadingIcon from '@/scripts/components/icons/LoadingIcon.vue'
|
||||
|
||||
import abilities from '@/scripts/admin/stub/abilities'
|
||||
|
||||
const modalStore = useModalStore()
|
||||
const estimateStore = useEstimateStore()
|
||||
const notificationStore = useNotificationStore()
|
||||
const dialogStore = useDialogStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const { t } = useI18n()
|
||||
const utils = inject('$utils')
|
||||
const id = ref(null)
|
||||
const count = ref(null)
|
||||
const estimateData = ref(null)
|
||||
const currency = ref(null)
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const status = ref([
|
||||
'DRAFT',
|
||||
'SENT',
|
||||
'VIEWED',
|
||||
'EXPIRED',
|
||||
'ACCEPTED',
|
||||
'REJECTED',
|
||||
])
|
||||
|
||||
const isMarkAsSent = ref(false)
|
||||
const isSendingEmail = ref(false)
|
||||
const isRequestOnGoing = ref(false)
|
||||
const isSearching = ref(false)
|
||||
const isLoading = ref(false)
|
||||
const isLoadingEstimate = ref(false)
|
||||
|
||||
const estimateList = ref(null)
|
||||
const currentPageNumber = ref(1)
|
||||
const lastPageNumber = ref(1)
|
||||
const estimateListSection = ref(null)
|
||||
|
||||
const searchData = reactive({
|
||||
orderBy: null,
|
||||
orderByField: null,
|
||||
@ -374,14 +361,40 @@ function hasActiveUrl(id) {
|
||||
return route.params.id == id
|
||||
}
|
||||
|
||||
async function loadEstimates() {
|
||||
async function loadEstimates(params, isScroll = false) {
|
||||
if (isLoading.value) {
|
||||
return
|
||||
}
|
||||
|
||||
isLoading.value = true
|
||||
await estimateStore.fetchEstimates(route.params.id)
|
||||
let response = await estimateStore.fetchEstimates(params)
|
||||
isLoading.value = false
|
||||
|
||||
setTimeout(() => {
|
||||
scrollToEstimate()
|
||||
}, 500)
|
||||
estimateList.value = estimateList.value ? estimateList.value : []
|
||||
|
||||
estimateList.value = [...estimateList.value, ...response.data.data]
|
||||
|
||||
currentPageNumber.value = params ? params.page : 1
|
||||
lastPageNumber.value = response.data.meta.last_page
|
||||
let isEstimateExist = estimateList.value.find(
|
||||
(est) => est.id == route.params.id
|
||||
)
|
||||
|
||||
if (
|
||||
isScroll == false &&
|
||||
!isEstimateExist &&
|
||||
currentPageNumber.value < lastPageNumber.value
|
||||
) {
|
||||
loadEstimates({ page: ++currentPageNumber.value })
|
||||
}
|
||||
|
||||
if (isEstimateExist) {
|
||||
setTimeout(() => {
|
||||
if (isScroll == false) {
|
||||
scrollToEstimate()
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToEstimate() {
|
||||
@ -389,9 +402,24 @@ function scrollToEstimate() {
|
||||
if (el) {
|
||||
el.scrollIntoView({ behavior: 'smooth' })
|
||||
el.classList.add('shake')
|
||||
addScrollListner()
|
||||
}
|
||||
}
|
||||
|
||||
function addScrollListner() {
|
||||
estimateListSection.value.addEventListener('scroll', (ev) => {
|
||||
if (
|
||||
ev.target.scrollTop > 0 &&
|
||||
ev.target.scrollTop + ev.target.clientHeight >
|
||||
ev.target.scrollHeight - 200
|
||||
) {
|
||||
if (currentPageNumber.value < lastPageNumber.value) {
|
||||
loadEstimates({ page: ++currentPageNumber.value }, true)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function loadEstimate() {
|
||||
isLoadingEstimate.value = true
|
||||
let response = await estimateStore.fetchEstimate(route.params.id)
|
||||
|
||||
Reference in New Issue
Block a user