feat: Add infinite loader, option for increasing page size (#8525)

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
Pranav Raj S
2023-12-10 20:09:17 -08:00
committed by GitHub
parent 27239ae14a
commit 8dfe193461
3 changed files with 72 additions and 37 deletions

View File

@@ -160,6 +160,6 @@ class ConversationFinder
:taggings, :inbox, { assignee: { avatar_attachment: [:blob] } }, { contact: { avatar_attachment: [:blob] } }, :team, :contact_inbox :taggings, :inbox, { assignee: { avatar_attachment: [:blob] } }, { contact: { avatar_attachment: [:blob] } }, :team, :contact_inbox
) )
sort_by = SORT_OPTIONS[params[:sort_by]] || SORT_OPTIONS['latest'] sort_by = SORT_OPTIONS[params[:sort_by]] || SORT_OPTIONS['latest']
@conversations.send(sort_by).page(current_page) @conversations.send(sort_by).page(current_page).per(ENV.fetch('CONVERSATION_RESULTS_PER_PAGE', '25').to_i)
end end
end end

View File

@@ -126,11 +126,10 @@
@assign-team="onAssignTeamsForBulk" @assign-team="onAssignTeamsForBulk"
/> />
<div <div
ref="activeConversation" ref="conversationList"
class="conversations-list flex-1" class="conversations-list flex-1"
:class="{ 'overflow-hidden': isContextMenuOpen }" :class="{ 'overflow-hidden': isContextMenuOpen }"
> >
<div>
<conversation-card <conversation-card
v-for="chat in conversationList" v-for="chat in conversationList"
:key="chat.id" :key="chat.id"
@@ -151,24 +150,17 @@
@mark-as-unread="markAsUnread" @mark-as-unread="markAsUnread"
@assign-priority="assignPriority" @assign-priority="assignPriority"
/> />
</div>
<div v-if="chatListLoading" class="text-center"> <div v-if="chatListLoading" class="text-center">
<span class="spinner mt-4 mb-4" /> <span class="spinner mt-4 mb-4" />
</div> </div>
<woot-button
v-if="!hasCurrentPageEndReached && !chatListLoading"
variant="clear"
size="expanded"
class="load-more--button"
@click="loadMoreConversations"
>
{{ $t('CHAT_LIST.LOAD_MORE_CONVERSATIONS') }}
</woot-button>
<p v-if="showEndOfListMessage" class="text-center text-muted p-4"> <p v-if="showEndOfListMessage" class="text-center text-muted p-4">
{{ $t('CHAT_LIST.EOF') }} {{ $t('CHAT_LIST.EOF') }}
</p> </p>
<intersection-observer
v-if="!showEndOfListMessage && !chatListLoading"
:options="infiniteLoaderOptions"
@observed="loadMoreConversations"
/>
</div> </div>
<woot-modal <woot-modal
:show.sync="showAdvancedFilters" :show.sync="showAdvancedFilters"
@@ -222,6 +214,7 @@ import {
isOnUnattendedView, isOnUnattendedView,
} from '../store/modules/conversations/helpers/actionHelpers'; } from '../store/modules/conversations/helpers/actionHelpers';
import { CONVERSATION_EVENTS } from '../helper/AnalyticsHelper/events'; import { CONVERSATION_EVENTS } from '../helper/AnalyticsHelper/events';
import IntersectionObserver from './IntersectionObserver.vue';
export default { export default {
components: { components: {
@@ -232,6 +225,7 @@ export default {
DeleteCustomViews, DeleteCustomViews,
ConversationBulkActions, ConversationBulkActions,
ConversationBasicFilter, ConversationBasicFilter,
IntersectionObserver,
}, },
mixins: [ mixins: [
timeMixin, timeMixin,
@@ -291,6 +285,10 @@ export default {
selectedInboxes: [], selectedInboxes: [],
isContextMenuOpen: false, isContextMenuOpen: false,
appliedFilter: [], appliedFilter: [],
infiniteLoaderOptions: {
root: this.$refs.conversationList,
rootMargin: '100px 0px 100px 0px',
},
}; };
}, },
computed: { computed: {
@@ -635,10 +633,10 @@ export default {
); );
}, },
getKeyboardListenerParams() { getKeyboardListenerParams() {
const allConversations = this.$refs.activeConversation.querySelectorAll( const allConversations = this.$refs.conversationList.querySelectorAll(
'div.conversations-list div.conversation' 'div.conversations-list div.conversation'
); );
const activeConversation = this.$refs.activeConversation.querySelector( const activeConversation = this.$refs.conversationList.querySelector(
'div.conversations-list div.conversation.active' 'div.conversations-list div.conversation.active'
); );
const activeConversationIndex = [...allConversations].indexOf( const activeConversationIndex = [...allConversations].indexOf(
@@ -697,6 +695,9 @@ export default {
.then(() => this.$emit('conversation-load')); .then(() => this.$emit('conversation-load'));
}, },
loadMoreConversations() { loadMoreConversations() {
if (this.hasCurrentPageEndReached || this.chatListLoading) {
return;
}
if (!this.hasAppliedFiltersOrActiveFolders) { if (!this.hasAppliedFiltersOrActiveFolders) {
this.fetchConversations(); this.fetchConversations();
} }

View File

@@ -0,0 +1,34 @@
<template>
<div ref="observedElement" class="h-6 w-full" />
</template>
<script>
export default {
props: {
options: {
type: Object,
default: () => ({ root: document, rootMargin: '100px 0 100px 0)' }),
},
},
mounted() {
this.intersectionObserver = null;
this.registerInfiniteLoader();
},
beforeDestroy() {
this.unobserveInfiniteLoadObserver();
},
methods: {
registerInfiniteLoader() {
this.intersectionObserver = new IntersectionObserver(entries => {
if (entries && entries[0].isIntersecting) {
this.$emit('observed');
}
}, this.options);
this.intersectionObserver.observe(this.$refs.observedElement);
},
unobserveInfiniteLoadObserver() {
this.intersectionObserver.unobserve(this.$refs.observedElement);
},
},
};
</script>