mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-10 17:36:33 +08:00
Add infinite scroll to results [SCI-9108]
This commit is contained in:
parent
f5235a9b9d
commit
2d76e628be
4 changed files with 61 additions and 25 deletions
|
@ -16,8 +16,17 @@ class ResultsController < ApplicationController
|
|||
apply_sort!
|
||||
apply_filters!
|
||||
|
||||
@results = @results.page(params[:page] || 1)
|
||||
|
||||
render(
|
||||
json: @results,
|
||||
json: {
|
||||
results: @results.map do |r|
|
||||
{
|
||||
attributes: ResultSerializer.new(r, scope: current_user).as_json
|
||||
}
|
||||
end,
|
||||
next_page: @results.next_page
|
||||
},
|
||||
formats: :json
|
||||
)
|
||||
end
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
<div class="result-head-right flex">
|
||||
<input type="file" class="hidden" ref="fileSelector" @change="loadFromComputer" multiple />
|
||||
<div ref="elementsDropdownButton" v-if="urls.update_url" class="dropdown">
|
||||
<button class="btn btn-light dropdown-toggle insert-button" type="button" :id="'resultInsertMenu_' + result.id" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<button class="btn btn-light dropdown-toggle insert-button" type="button" :id="'resultInsertMenu_' + result.attributes.id" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
{{ i18n.t('protocols.steps.insert.button') }}
|
||||
<span class="sn-icon sn-icon-down"></span>
|
||||
</button>
|
||||
<ul ref="elementsDropdown" class="dropdown-menu insert-element-dropdown dropdown-menu-right" :aria-labelledby="'resultInsertMenu_' + result.id">
|
||||
<ul ref="elementsDropdown" class="dropdown-menu insert-element-dropdown dropdown-menu-right" :aria-labelledby="'resultInsertMenu_' + result.attributes.id">
|
||||
<li class="title">
|
||||
<a>
|
||||
{{ i18n.t('protocols.steps.insert.title') }}
|
||||
|
@ -78,7 +78,7 @@
|
|||
<a class="cursor-point er">
|
||||
<span
|
||||
class="new-marvinjs-upload-button text-sn-black text-decoration-none"
|
||||
:data-object-id="result.id"
|
||||
:data-object-id="result.attributes.id"
|
||||
ref="marvinJsButton"
|
||||
:data-marvin-url="result.attributes.marvinjs_context.marvin_js_asset_url"
|
||||
:data-object-type="result.attributes.type"
|
||||
|
@ -97,14 +97,14 @@
|
|||
class="open-comments-sidebar btn icon-btn btn-light"
|
||||
data-turbolinks="false"
|
||||
data-object-type="Result"
|
||||
:data-object-id="result.id">
|
||||
:data-object-id="result.attributes.id">
|
||||
<i class="sn-icon sn-icon-comments"></i>
|
||||
</a>
|
||||
<div ref="actionsDropdownButton" class="dropdown">
|
||||
<button class="btn btn-light icon-btn dropdown-toggle insert-button" type="button" :id="'resultOptionsMenu_' + result.id" data-toggle="dropdown" data-display="static" aria-haspopup="true" aria-expanded="true">
|
||||
<button class="btn btn-light icon-btn dropdown-toggle insert-button" type="button" :id="'resultOptionsMenu_' + result.attributes.id" data-toggle="dropdown" data-display="static" aria-haspopup="true" aria-expanded="true">
|
||||
<i class="sn-icon sn-icon-more-hori"></i>
|
||||
</button>
|
||||
<ul ref="actionsDropdown" class="dropdown-menu dropdown-menu-right insert-element-dropdown" :aria-labelledby="'resultOptionsMenu_' + result.id">
|
||||
<ul ref="actionsDropdown" class="dropdown-menu dropdown-menu-right insert-element-dropdown" :aria-labelledby="'resultOptionsMenu_' + result.attributes.id">
|
||||
<li class="action" @click="openReorderModal">
|
||||
<a class="cursor-pointer">{{ i18n.t('my_modules.results.actions.rearrange') }}</a>
|
||||
</li>
|
||||
|
@ -202,7 +202,7 @@
|
|||
},
|
||||
watch: {
|
||||
resultToReload() {
|
||||
if (this.resultToReload == this.result.id) {
|
||||
if (this.resultToReload == this.result.attributes.id) {
|
||||
this.loadElements();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
class="mb-3"
|
||||
/>
|
||||
<div class="results-list">
|
||||
<Result v-for="result in results" :key="result.id"
|
||||
<Result v-for="result in results" :key="result.attributes.id"
|
||||
:result="result"
|
||||
:resultToReload="resultToReload"
|
||||
@result:elements:loaded="resultToReload = null"
|
||||
@result:move_element="reloadResult"
|
||||
@duplicated="loadResults"
|
||||
@duplicated="resetPageAndReload"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -36,37 +36,60 @@
|
|||
results: [],
|
||||
sort: 'created_at_desc',
|
||||
filters: {},
|
||||
resultToReload: null
|
||||
resultToReload: null,
|
||||
nextPage: 1,
|
||||
loadingPage: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.loadResults, false);
|
||||
this.loadResults();
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('scroll', this.loadResults, false);
|
||||
},
|
||||
methods: {
|
||||
reloadResult(result) {
|
||||
this.resultToReload = result;
|
||||
},
|
||||
resetPageAndReload(){
|
||||
this.nextPage = 1;
|
||||
this.results = [];
|
||||
this.$nextTick(() => {
|
||||
this.loadResults();
|
||||
});
|
||||
},
|
||||
loadResults() {
|
||||
axios.get(
|
||||
`${this.url}`,
|
||||
{
|
||||
params: {
|
||||
sort: this.sort,
|
||||
...this.filters
|
||||
if (this.nextPage == null || this.loadingPage) return;
|
||||
|
||||
if (window.scrollY + window.innerHeight >= document.body.scrollHeight - 20) {
|
||||
this.loadingPage = true;
|
||||
axios.get(
|
||||
`${this.url}`,
|
||||
{
|
||||
params: {
|
||||
sort: this.sort,
|
||||
page: this.nextPage,
|
||||
...this.filters
|
||||
},
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
},
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
},
|
||||
).then((response) => this.results = response.data.data);
|
||||
).then((response) => {
|
||||
this.results = this.results.concat(response.data.results);
|
||||
this.nextPage = response.data.next_page;
|
||||
this.loadingPage = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
setSort(sort) {
|
||||
this.sort = sort;
|
||||
this.loadResults();
|
||||
this.resetPageAndReload();
|
||||
},
|
||||
setFilters(filters) {
|
||||
this.filters = filters;
|
||||
this.loadResults();
|
||||
this.resetPageAndReload();
|
||||
},
|
||||
createResult() {
|
||||
axios.post(
|
||||
|
|
|
@ -19,6 +19,10 @@ class ResultSerializer < ActiveModel::Serializer
|
|||
'Result'
|
||||
end
|
||||
|
||||
def current_user
|
||||
scope
|
||||
end
|
||||
|
||||
def marvinjs_context
|
||||
if marvinjs_enabled
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue