mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 23:16:15 +08:00
Merge pull request #1897 from jbargu/jg_sci_3646
[SCI-3646] Add paging functionality to external protocols
This commit is contained in:
commit
ae7da78bff
|
@ -53,6 +53,14 @@ function setDefaultViewState() {
|
||||||
$('.list-wrapper').hide();
|
$('.list-wrapper').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle clicks on Load more protocols button
|
||||||
|
function applyClickCallbackOnShowMoreProtocols() {
|
||||||
|
$('.show-more-protocols-btn button').off('click').on('click', function() {
|
||||||
|
$('form.protocols-search-bar #page-id').val($(this).data('next-page-id'));
|
||||||
|
$('form.protocols-search-bar').submit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Apply AJAX callbacks onto the search box
|
// Apply AJAX callbacks onto the search box
|
||||||
function applySearchCallback() {
|
function applySearchCallback() {
|
||||||
var timeout;
|
var timeout;
|
||||||
|
@ -75,20 +83,31 @@ function applySearchCallback() {
|
||||||
|
|
||||||
// Bind ajax calls on the form
|
// Bind ajax calls on the form
|
||||||
$('form.protocols-search-bar').off('ajax:success').off('ajax:error')
|
$('form.protocols-search-bar').off('ajax:success').off('ajax:error')
|
||||||
.bind('ajax:success', function(evt, data, status, xhr) {
|
.bind('ajax:success', function(evt, data) {
|
||||||
if (data.html) {
|
if (data.page_id > 1) {
|
||||||
|
// Remove old load more button since we will append a new one
|
||||||
|
$('.show-more-protocols-btn').remove();
|
||||||
|
$('.list-wrapper').append(data.html);
|
||||||
|
} else if (data.html) {
|
||||||
resetPreviewPanel();
|
resetPreviewPanel();
|
||||||
$('.empty-text').hide();
|
$('.empty-text').hide();
|
||||||
$('.list-wrapper').show();
|
$('.list-wrapper').show();
|
||||||
|
|
||||||
$('.list-wrapper').html(data.html);
|
$('.list-wrapper').html(data.html);
|
||||||
applyClickCallbackOnProtocolCards();
|
$('.list-wrapper').scrollTo(0);
|
||||||
initLoadProtocolModalPreview();
|
|
||||||
} else {
|
} else {
|
||||||
setDefaultViewState();
|
setDefaultViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset page id after every request
|
||||||
|
$('form.protocols-search-bar #page-id').val(1);
|
||||||
|
|
||||||
|
// Apply all callbacks on new elements
|
||||||
|
applyClickCallbackOnProtocolCards();
|
||||||
|
applyClickCallbackOnShowMoreProtocols();
|
||||||
|
initLoadProtocolModalPreview();
|
||||||
})
|
})
|
||||||
.bind("ajax:error", function(evt, xhr, status, error) {
|
.bind('ajax:error', function(evt, xhr) {
|
||||||
setDefaultViewState();
|
setDefaultViewState();
|
||||||
|
|
||||||
console.log(xhr.responseText);
|
console.log(xhr.responseText);
|
||||||
|
|
|
@ -196,6 +196,11 @@
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.show-more-protocols-btn {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.protocol-preview-panel {
|
.protocol-preview-panel {
|
||||||
|
|
|
@ -15,7 +15,8 @@ class ExternalProtocolsController < ApplicationController
|
||||||
html: render_to_string(
|
html: render_to_string(
|
||||||
partial: 'protocol_importers/list_of_protocol_cards.html.erb',
|
partial: 'protocol_importers/list_of_protocol_cards.html.erb',
|
||||||
locals: { protocols: service_call.protocols_list, show_import_button: show_import_button }
|
locals: { protocols: service_call.protocols_list, show_import_button: show_import_button }
|
||||||
)
|
),
|
||||||
|
page_id: service_call.protocols_list[:pagination][:current_page]
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
render json: { errors: service_call.errors }, status: 400
|
render json: { errors: service_call.errors }, status: 400
|
||||||
|
|
|
@ -41,9 +41,7 @@ module ProtocolImporters
|
||||||
@errors[:invalid_params][:key] = 'Key cannot be empty' if @query_params[:key].blank?
|
@errors[:invalid_params][:key] = 'Key cannot be empty' if @query_params[:key].blank?
|
||||||
|
|
||||||
# try if page id is ok
|
# try if page id is ok
|
||||||
if @query_params[:page_id] && !@query_params[:page_id].to_i.positive?
|
@errors[:invalid_params][:page_id] = 'Page needs to be positive' if @query_params[:page_id]&.to_i&.negative?
|
||||||
@errors[:invalid_params][:page_id] = 'Page needs to be positive'
|
|
||||||
end
|
|
||||||
|
|
||||||
# try if endpints exists
|
# try if endpints exists
|
||||||
@errors[:invalid_params][:source_endpoint] = 'Wrong source endpoint' unless endpoint_name&.is_a?(String)
|
@errors[:invalid_params][:source_endpoint] = 'Wrong source endpoint' unless endpoint_name&.is_a?(String)
|
||||||
|
|
|
@ -46,10 +46,11 @@ module ProtocolImporters
|
||||||
response = with_handle_network_errors do
|
response = with_handle_network_errors do
|
||||||
sort_mappings = CONSTANTS[:sort_mappings]
|
sort_mappings = CONSTANTS[:sort_mappings]
|
||||||
query = CONSTANTS.dig(:endpoints, :protocols, :default_query_params)
|
query = CONSTANTS.dig(:endpoints, :protocols, :default_query_params)
|
||||||
|
.stringify_keys
|
||||||
.merge(query_params.except(:sort_by))
|
.merge(query_params.except(:sort_by))
|
||||||
|
|
||||||
if sort_mappings[query_params[:sort_by]&.to_sym]
|
if sort_mappings[query_params[:sort_by]&.to_sym]
|
||||||
query = query.merge(sort_mappings[query_params[:sort_by].to_sym])
|
query = query.merge(sort_mappings[query_params[:sort_by].to_sym].stringify_keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.class.get('/protocols', query: query)
|
self.class.get('/protocols', query: query)
|
||||||
|
@ -95,7 +96,7 @@ module ProtocolImporters
|
||||||
when 1219
|
when 1219
|
||||||
raise ProtocolImporters::ProtocolsIO::V3::UnauthorizedError.new(:token_expires), error_message
|
raise ProtocolImporters::ProtocolsIO::V3::UnauthorizedError.new(:token_expires), error_message
|
||||||
else
|
else
|
||||||
raise ProtocolImporters::ProtocolsIO::V3::Error.new(e.class), error_message
|
raise ProtocolImporters::ProtocolsIO::V3::Error.new(:api_response_error), response.parsed_response
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,6 +73,7 @@ module ProtocolImporters
|
||||||
def normalize_list(client_data)
|
def normalize_list(client_data)
|
||||||
# client_data is HttpParty ApiReponse object
|
# client_data is HttpParty ApiReponse object
|
||||||
protocols_hash = client_data.parsed_response.with_indifferent_access[:items]
|
protocols_hash = client_data.parsed_response.with_indifferent_access[:items]
|
||||||
|
pagination = client_data.parsed_response.with_indifferent_access[:pagination]
|
||||||
|
|
||||||
normalized_data = {}
|
normalized_data = {}
|
||||||
normalized_data[:protocols] = protocols_hash.map do |e|
|
normalized_data[:protocols] = protocols_hash.map do |e|
|
||||||
|
@ -87,6 +88,14 @@ module ProtocolImporters
|
||||||
uri: e[:uri]
|
uri: e[:uri]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Parse pagination
|
||||||
|
normalized_data[:pagination] = {
|
||||||
|
current_page: pagination[:current_page],
|
||||||
|
total_pages: pagination[:total_pages],
|
||||||
|
page_size: pagination[:page_size]
|
||||||
|
}
|
||||||
|
|
||||||
normalized_data
|
normalized_data
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
raise ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message
|
raise ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message
|
||||||
|
|
|
@ -2,3 +2,12 @@
|
||||||
<%= render partial: 'protocol_importers/protocol_card',
|
<%= render partial: 'protocol_importers/protocol_card',
|
||||||
locals: { protocol: protocol, show_import_button: show_import_button } %>
|
locals: { protocol: protocol, show_import_button: show_import_button } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<% if protocols[:pagination][:current_page] + 1 <= protocols[:pagination][:total_pages] %>
|
||||||
|
<div class='show-more-protocols-btn text-center'>
|
||||||
|
<button class='btn btn-default'
|
||||||
|
data-next-page-id='<%= protocols[:pagination][:current_page] + 1 %>'>
|
||||||
|
<%= t('protocol_importers.show_more_button.title') %>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
class: 'protocolsio-logo' %>
|
class: 'protocolsio-logo' %>
|
||||||
<span class='protocolsio-title'><%= t('protocols.index.external_protocols.protocolsio_title') %></span>
|
<span class='protocolsio-title'><%= t('protocols.index.external_protocols.protocolsio_title') %></span>
|
||||||
<%= hidden_field_tag 'protocol_source', 'protocolsio/v3' %>
|
<%= hidden_field_tag 'protocol_source', 'protocolsio/v3' %>
|
||||||
|
<%= hidden_field_tag 'page_id', 1, id: 'page-id' %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='input-group'>
|
<div class='input-group'>
|
||||||
|
|
|
@ -231,7 +231,7 @@ class Constants
|
||||||
key: '',
|
key: '',
|
||||||
order_field: :activity,
|
order_field: :activity,
|
||||||
order_dir: :desc,
|
order_dir: :desc,
|
||||||
page_size: 10,
|
page_size: 50,
|
||||||
page_id: 1,
|
page_id: 1,
|
||||||
fields: 'id,title,authors,created_on,uri,stats'
|
fields: 'id,title,authors,created_on,uri,stats'
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ en:
|
||||||
card:
|
card:
|
||||||
views_and_steps: '%{nr_of_views} views • %{nr_of_steps} steps'
|
views_and_steps: '%{nr_of_views} views • %{nr_of_steps} steps'
|
||||||
import_button_text: 'Import...'
|
import_button_text: 'Import...'
|
||||||
|
show_more_button:
|
||||||
|
title: 'Show more protocols'
|
||||||
templates:
|
templates:
|
||||||
amount:
|
amount:
|
||||||
title: 'Amount'
|
title: 'Amount'
|
||||||
|
|
|
@ -15,8 +15,8 @@ describe ExternalProtocolsController, type: :controller do
|
||||||
team_id: team.id,
|
team_id: team.id,
|
||||||
key: 'search_string',
|
key: 'search_string',
|
||||||
protocol_source: 'protocolsio/v3',
|
protocol_source: 'protocolsio/v3',
|
||||||
page_id: 1,
|
page_id: 2,
|
||||||
page_size: 10,
|
page_size: 50,
|
||||||
order_field: 'activity',
|
order_field: 'activity',
|
||||||
order_dir: 'desc'
|
order_dir: 'desc'
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,21 @@ describe ExternalProtocolsController, type: :controller do
|
||||||
|
|
||||||
let(:action) { get :index, params: params }
|
let(:action) { get :index, params: params }
|
||||||
|
|
||||||
|
let(:valid_search_response) do
|
||||||
|
{
|
||||||
|
protocols: [],
|
||||||
|
pagination: {
|
||||||
|
current_page: 2,
|
||||||
|
total_pages: 6,
|
||||||
|
page_size: 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
service = double('success_service')
|
service = double('success_service')
|
||||||
allow(service).to(receive(:succeed?)).and_return(true)
|
allow(service).to(receive(:succeed?)).and_return(true)
|
||||||
allow(service).to(receive(:protocols_list)).and_return({})
|
allow(service).to(receive(:protocols_list)).and_return(valid_search_response)
|
||||||
|
|
||||||
allow_any_instance_of(ProtocolImporters::SearchProtocolsService).to(receive(:call)).and_return(service)
|
allow_any_instance_of(ProtocolImporters::SearchProtocolsService).to(receive(:call)).and_return(service)
|
||||||
end
|
end
|
||||||
|
@ -42,6 +53,11 @@ describe ExternalProtocolsController, type: :controller do
|
||||||
action
|
action
|
||||||
expect(JSON.parse(response.body)).to have_key('html')
|
expect(JSON.parse(response.body)).to have_key('html')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'contains page_id in the response' do
|
||||||
|
action
|
||||||
|
expect(JSON.parse(response.body)['page_id']).to eq 2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET show' do
|
describe 'GET show' do
|
||||||
|
|
|
@ -100,5 +100,10 @@
|
||||||
"nr_of_views": 33,
|
"nr_of_views": 33,
|
||||||
"uri": "SN-Maintenance-Medium-for-Synechococcus-c9hz35"
|
"uri": "SN-Maintenance-Medium-for-Synechococcus-c9hz35"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"pagination": {
|
||||||
|
"current_page": 1,
|
||||||
|
"total_pages": 6,
|
||||||
|
"page_size": 10
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ describe ProtocolImporters::SearchProtocolsService do
|
||||||
.and_return(normalized_list))
|
.and_return(normalized_list))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an error when params are invalid' do
|
it 'returns normalized list' do
|
||||||
expect(service_call.protocols_list).to be == normalized_list
|
expect(service_call.protocols_list).to be == normalized_list
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue