Merge pull request #7928 from aignatov-bio/ai-sci-11111-add-infinite-scroll-to-select-dropdown

Add infinite scroll to select dropdown [SCI-11111]
This commit is contained in:
Martin Artnik 2024-10-07 11:51:12 +02:00 committed by GitHub
commit a2a264e2fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 7 deletions

View file

@ -62,7 +62,13 @@ class RepositoriesController < ApplicationController
end
results = results.active if params[:active].present?
render json: { data: results.order('LOWER(repository_rows.name) asc').map { |r| [r.id, r.name] } }
results = results.order('LOWER(repository_rows.name) asc').page(params[:page])
render json: {
paginated: true,
next_page: results.next_page,
data: results.map { |r| [r.id, r.name] }
}
end
def sidebar

View file

@ -28,7 +28,7 @@
v-else
v-model="query"
:placeholder="placeholderRender"
@keyup="fetchOptions"
@keyup="reloadItems"
@change.stop
class="w-full bg-transparent border-0 outline-none pl-0 placeholder:text-sn-grey" />
</template>
@ -70,7 +70,7 @@
{{ i18n.t('general.select_all') }}
</div>
</div>
<perfect-scrollbar class="p-2.5 flex flex-col max-h-80 relative" :class="{ 'pt-0': withCheckboxes }">
<perfect-scrollbar ref="scrollContainer" class="p-2.5 flex flex-col max-h-80 relative" :class="{ 'pt-0': withCheckboxes }">
<template v-for="(option, i) in filteredOptions" :key="option[0]">
<div
@click.stop="setValue(option[0])"
@ -143,7 +143,8 @@ export default {
query: '',
fixedWidth: true,
focusedOption: null,
skipQueryCallback: false
skipQueryCallback: false,
nextPage: 1
};
},
mixins: [FixedFlyoutMixin],
@ -270,19 +271,31 @@ export default {
this.$nextTick(() => {
this.setPosition();
this.$refs.search?.focus();
this.$refs.scrollContainer.$el.addEventListener('scroll', this.loadNextPage);
});
}
},
urlParams: {
handler(oldVal, newVal) {
if (!this.compareObjects(oldVal, newVal)) {
this.fetchOptions();
this.reloadItems();
}
},
deep: true
}
},
methods: {
reloadItems() {
this.fetchedOptions = [];
this.nextPage = 1;
this.fetchOptions();
},
loadNextPage() {
const container = this.$refs.scrollContainer.$el;
if (this.nextPage && container.scrollTop + container.clientHeight >= container.scrollHeight) {
this.fetchOptions();
}
},
renderLabel(option) {
if (!option) return false;
@ -354,10 +367,15 @@ export default {
},
fetchOptions() {
if (this.optionsUrl) {
const params = { query: this.query, ...this.urlParams };
const params = { query: this.query, page: this.nextPage, ...this.urlParams };
axios.get(this.optionsUrl, { params })
.then((response) => {
this.fetchedOptions = response.data.data;
if (response.data.paginated) {
this.fetchedOptions = [...this.fetchedOptions, ...response.data.data];
this.nextPage = response.data.next_page;
} else {
this.fetchedOptions = response.data.data;
}
this.$nextTick(() => {
this.setPosition();
});