mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-10 07:05:57 +08:00
Add pagination for experiments [SCI-6656]
This commit is contained in:
parent
d96103d714
commit
d091c56e9f
10 changed files with 243 additions and 25 deletions
|
@ -7,7 +7,8 @@
|
|||
// - refresh project users tab after manage user modal is closed
|
||||
// - refactor view handling using library, ex. backbone.js
|
||||
|
||||
/* global HelperModule dropdownSelector Sidebar Turbolinks filterDropdown InfiniteScroll */
|
||||
/* global HelperModule dropdownSelector Sidebar Turbolinks filterDropdown InfiniteScroll GLOBAL_CONSTANTS */
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
var ProjectsIndex = (function() {
|
||||
const PERMISSIONS = ['editable', 'archivable', 'restorable', 'moveable', 'deletable'];
|
||||
|
@ -16,7 +17,7 @@ var ProjectsIndex = (function() {
|
|||
var cardsWrapper = '#cardsWrapper';
|
||||
var editProjectModal = '#edit-modal';
|
||||
var moveToModal = '#move-to-modal';
|
||||
var pageSize = 20;
|
||||
var pageSize = GLOBAL_CONSTANTS.DEFAULT_ELEMENTS_PER_PAGE;
|
||||
|
||||
var exportProjectsModal = null;
|
||||
var exportProjectsModalHeader = null;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* global animateSpinner filterDropdown Sidebar Turbolinks HelperModule */
|
||||
/* global animateSpinner filterDropdown Sidebar Turbolinks HelperModule InfiniteScroll GLOBAL_CONSTANTS */
|
||||
/* eslint-disable no-use-before-define */
|
||||
(function() {
|
||||
const PERMISSIONS = ['editable', 'archivable', 'restorable', 'moveable', 'duplicable'];
|
||||
const pageSize = GLOBAL_CONSTANTS.DEFAULT_ELEMENTS_PER_PAGE;
|
||||
var cardsWrapper = '#cardsWrapper';
|
||||
var experimentsPage = '#projectShowWrapper';
|
||||
|
||||
|
@ -67,23 +69,35 @@
|
|||
});
|
||||
}
|
||||
|
||||
function loadPlaceHolder() {
|
||||
let palceholder = '';
|
||||
$.each(Array(pageSize), function() {
|
||||
palceholder += $('#experimentPlaceholder').html();
|
||||
});
|
||||
$(palceholder).insertAfter($(cardsWrapper).find('.table-header'));
|
||||
}
|
||||
|
||||
function loadCardsView() {
|
||||
var requestParams = {
|
||||
view_mode: $(experimentsPage).data('view-mode'),
|
||||
sort: experimentsCurrentSort,
|
||||
search: experimentsViewSearch,
|
||||
created_on_from: startedOnFromFilter,
|
||||
created_on_to: startedOnToFilter,
|
||||
updated_on_from: modifiedOnFromFilter,
|
||||
updated_on_to: modifiedOnToFilter,
|
||||
archived_on_from: archivedOnFromFilter,
|
||||
archived_on_to: archivedOnToFilter
|
||||
};
|
||||
var viewContainer = $(cardsWrapper);
|
||||
var cardsUrl = viewContainer.data('experiments-cards-url');
|
||||
|
||||
loadPlaceHolder();
|
||||
$.ajax({
|
||||
url: viewContainer.data('experiments-cards-url'),
|
||||
url: cardsUrl,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
view_mode: $(experimentsPage).data('view-mode'),
|
||||
sort: experimentsCurrentSort,
|
||||
search: experimentsViewSearch,
|
||||
created_on_from: startedOnFromFilter,
|
||||
created_on_to: startedOnToFilter,
|
||||
updated_on_from: modifiedOnFromFilter,
|
||||
updated_on_to: modifiedOnToFilter,
|
||||
archived_on_from: archivedOnFromFilter,
|
||||
archived_on_to: archivedOnToFilter
|
||||
},
|
||||
data: requestParams,
|
||||
success: function(data) {
|
||||
viewContainer.find('.card, .no-results-container').remove();
|
||||
viewContainer.removeClass('no-results');
|
||||
|
@ -94,6 +108,20 @@
|
|||
selectedExperiments.length = 0;
|
||||
updateExperimentsToolbar();
|
||||
loadExperimentWorkflowImages();
|
||||
|
||||
InfiniteScroll.init(cardsWrapper, {
|
||||
url: cardsUrl,
|
||||
eventTarget: window,
|
||||
placeholderTemplate: '#experimentPlaceholder',
|
||||
endOfListTemplate: '#experimentEndOfList',
|
||||
pageSize: pageSize,
|
||||
customResponse: (response) => {
|
||||
$(response.cards_html).appendTo(cardsWrapper);
|
||||
},
|
||||
customParams: (params) => {
|
||||
return { ...params, ...requestParams };
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
viewContainer.html('Error loading project list');
|
||||
|
|
|
@ -9,5 +9,6 @@ const GLOBAL_CONSTANTS = {
|
|||
REPOSITORY_LIST_ITEMS_PER_COLUMN: <%= Constants::REPOSITORY_LIST_ITEMS_PER_COLUMN %>,
|
||||
REPOSITORY_CHECKLIST_ITEMS_PER_COLUMN: <%= Constants::REPOSITORY_CHECKLIST_ITEMS_PER_COLUMN %>,
|
||||
REPOSITORY_STOCK_UNIT_ITEMS_PER_COLUMN: <%= Constants::REPOSITORY_STOCK_UNIT_ITEMS_PER_COLUMN %>,
|
||||
HAS_UNSAVED_DATA_CLASS_NAME: 'has-unsaved-data'
|
||||
HAS_UNSAVED_DATA_CLASS_NAME: 'has-unsaved-data',
|
||||
DEFAULT_ELEMENTS_PER_PAGE: <%= Constants::DEFAULT_ELEMENTS_PER_PAGE %>
|
||||
};
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
/* eslint-disable no-use-before-define */
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
var InfiniteScroll = (function() {
|
||||
function getScrollHeight($container) {
|
||||
return $container[0].scrollHeight;
|
||||
}
|
||||
|
||||
function scrollNotVisible($container) {
|
||||
let eventTarget = $($container.data('config').eventTarget || $container);
|
||||
return scrollHitBottom(eventTarget[0]);
|
||||
|
|
|
@ -173,6 +173,78 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.experiment-placeholder {
|
||||
align-items: center;
|
||||
background-color: $color-white;
|
||||
border-radius: $border-radius-default;
|
||||
box-shadow: $flyout-shadow;
|
||||
display: flex;
|
||||
|
||||
.placeholder-body {
|
||||
display: flex;
|
||||
flex-basis: 70%;
|
||||
flex-wrap: wrap;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
margin-left: auto;
|
||||
|
||||
.image-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-element {
|
||||
animation-duration: 2s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: placeholder-pulsing;
|
||||
background-color: $color-alto;
|
||||
border-radius: $border-radius-default;
|
||||
height: 18px;
|
||||
|
||||
&.header,
|
||||
&.footer {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
&.footer {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
&.line-0 {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
&.line-1 {
|
||||
flex-basis: 90%;
|
||||
}
|
||||
|
||||
&.line-2 {
|
||||
flex-basis: 80%;
|
||||
}
|
||||
|
||||
&.image {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
@keyframes placeholder-pulsing {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.list {
|
||||
|
@ -281,6 +353,72 @@
|
|||
background: linear-gradient(to right, $color-transparent, $color-concrete 50%);
|
||||
}
|
||||
}
|
||||
|
||||
&.experiment-placeholder {
|
||||
display: contents;
|
||||
|
||||
.placeholder-body {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.placeholder-element {
|
||||
align-self: flex-start;
|
||||
display: none;
|
||||
margin-top: .5em;
|
||||
padding: .5em 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: block;
|
||||
grid-column: 6;
|
||||
height: 18px;
|
||||
width: 80%;
|
||||
|
||||
}
|
||||
|
||||
.header {
|
||||
display: block;
|
||||
grid-column: 7;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
display: flex;
|
||||
grid-column: 2;
|
||||
margin-left: 0;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
flex-basis: 56px;
|
||||
height: 56px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.image-text {
|
||||
display: block;
|
||||
flex-basis: calc(100% - 80px);
|
||||
margin: 0 10px 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.line-0 {
|
||||
display: block;
|
||||
grid-column: 3;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.line-1 {
|
||||
display: block;
|
||||
grid-column: 4;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.line-2 {
|
||||
display: block;
|
||||
grid-column: 5;
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,6 +427,29 @@
|
|||
margin-left: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.last-page {
|
||||
padding-bottom: 5em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.experiment-list-end-placeholder {
|
||||
align-items: center;
|
||||
background-color: $color-concrete;
|
||||
bottom: 1em;
|
||||
display: flex;
|
||||
height: 3em;
|
||||
left: calc(50% - 150px);
|
||||
margin: 0 auto;
|
||||
padding: 1em;
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
|
||||
> * {
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -624,8 +624,8 @@ li.module-hover {
|
|||
--list-columns-number: 6;
|
||||
|
||||
&.last-page {
|
||||
position: relative;
|
||||
padding-bottom: 5em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.projects-group {
|
||||
|
@ -798,9 +798,9 @@ li.module-hover {
|
|||
display: flex;
|
||||
|
||||
.placeholder-element {
|
||||
animation-name: placeholder-pulsing;
|
||||
animation-duration: 2s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: placeholder-pulsing;
|
||||
background-color: $color-alto;
|
||||
border-radius: $border-radius-default;
|
||||
height: 18px;
|
||||
|
@ -832,9 +832,11 @@ li.module-hover {
|
|||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class ProjectsController < ApplicationController
|
|||
end
|
||||
|
||||
cards = Kaminari.paginate_array(overview_service.project_and_folder_cards)
|
||||
.page(params[:page] || 1).per(20)
|
||||
.page(params[:page] || 1).per(Constants::DEFAULT_ELEMENTS_PER_PAGE)
|
||||
|
||||
render json: {
|
||||
projects_cards_url: projects_cards_url,
|
||||
|
@ -292,10 +292,12 @@ class ProjectsController < ApplicationController
|
|||
|
||||
def experiments_cards
|
||||
overview_service = ExperimentsOverviewService.new(@project, current_user, params)
|
||||
cards = overview_service.experiments.page(params[:page] || 1).per(Constants::DEFAULT_ELEMENTS_PER_PAGE)
|
||||
render json: {
|
||||
next_page: cards.next_page,
|
||||
cards_html: render_to_string(
|
||||
partial: 'projects/show/experiments_list.html.erb',
|
||||
locals: { cards: overview_service.experiments,
|
||||
locals: { cards: cards,
|
||||
filters_included: filters_included? }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ class ExperimentsOverviewService
|
|||
.select('experiments.*')
|
||||
.select('COUNT(DISTINCT active_tasks.id) AS task_count')
|
||||
.select('COUNT(DISTINCT active_completed_tasks.id) AS completed_task_count')
|
||||
.group('experiments.id, user_assignments.id, user_roles.id')
|
||||
.group('experiments.id')
|
||||
end
|
||||
|
||||
def filter_records(records)
|
||||
|
|
|
@ -37,5 +37,29 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<template id="experimentPlaceholder">
|
||||
<div class="experiment-placeholder card">
|
||||
<div class="placeholder-element header"></div>
|
||||
<div class="placeholder-body">
|
||||
<% 3.times do |i| %>
|
||||
<div class="placeholder-element line-<%= i %>"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="placeholder image-container">
|
||||
<div class="placeholder-element image"></div>
|
||||
<div class="placeholder-element image-text"></div>
|
||||
</div>
|
||||
<div class="placeholder-element footer"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="experimentEndOfList">
|
||||
<div class="experiment-list-end-placeholder">
|
||||
<i class="fas fa-flag-checkered"></i>
|
||||
<span><%= t('projects.index.end_of_list_placeholder') %></span>
|
||||
<i class="fas fa-flag-checkered"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<%= javascript_include_tag("projects/show") %>
|
||||
<i data-hook="project-show-js"></i>
|
||||
|
|
|
@ -71,6 +71,8 @@ class Constants
|
|||
RESULTS_PER_PAGE_LIMIT = 10
|
||||
#Experiments more button appears
|
||||
EXPERIMENT_LONG_DESCRIPTION = 80
|
||||
# Infinite scroll default elements per page
|
||||
DEFAULT_ELEMENTS_PER_PAGE = 20
|
||||
|
||||
#=============================================================================
|
||||
# File and data memory size
|
||||
|
|
Loading…
Add table
Reference in a new issue