diff --git a/app/assets/javascripts/protocols/external_protocols_tab.js b/app/assets/javascripts/protocols/external_protocols_tab.js index 5f42bd52c..dd8654590 100644 --- a/app/assets/javascripts/protocols/external_protocols_tab.js +++ b/app/assets/javascripts/protocols/external_protocols_tab.js @@ -53,6 +53,14 @@ function setDefaultViewState() { $('.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 function applySearchCallback() { var timeout; @@ -75,20 +83,30 @@ function applySearchCallback() { // Bind ajax calls on the form $('form.protocols-search-bar').off('ajax:success').off('ajax:error') - .bind('ajax:success', function(evt, data, status, xhr) { - if (data.html) { + .bind('ajax:success', function(evt, data) { + 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(); $('.empty-text').hide(); $('.list-wrapper').show(); $('.list-wrapper').html(data.html); - applyClickCallbackOnProtocolCards(); - initLoadProtocolModalPreview(); } else { 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(); console.log(xhr.responseText); diff --git a/app/assets/stylesheets/protocol_management.scss b/app/assets/stylesheets/protocol_management.scss index cfe41640f..ea738745d 100644 --- a/app/assets/stylesheets/protocol_management.scss +++ b/app/assets/stylesheets/protocol_management.scss @@ -196,6 +196,11 @@ padding-right: 0; } + .show-more-protocols-btn { + margin-bottom: 5px; + margin-top: 5px; + } + } .protocol-preview-panel { diff --git a/app/controllers/external_protocols_controller.rb b/app/controllers/external_protocols_controller.rb index b458ce3da..751ae2373 100644 --- a/app/controllers/external_protocols_controller.rb +++ b/app/controllers/external_protocols_controller.rb @@ -15,7 +15,8 @@ class ExternalProtocolsController < ApplicationController html: render_to_string( partial: 'protocol_importers/list_of_protocol_cards.html.erb', locals: { protocols: service_call.protocols_list, show_import_button: show_import_button } - ) + ), + page_id: service_call.protocols_list[:pagination][:current_page] } else render json: { errors: service_call.errors }, status: 400 diff --git a/app/services/protocol_importers/search_protocols_service.rb b/app/services/protocol_importers/search_protocols_service.rb index 6a0c25be3..9d6eec776 100644 --- a/app/services/protocol_importers/search_protocols_service.rb +++ b/app/services/protocol_importers/search_protocols_service.rb @@ -41,9 +41,7 @@ module ProtocolImporters @errors[:invalid_params][:key] = 'Key cannot be empty' if @query_params[:key].blank? # 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' - end + @errors[:invalid_params][:page_id] = 'Page needs to be positive' if @query_params[:page_id]&.to_i&.negative? # try if endpints exists @errors[:invalid_params][:source_endpoint] = 'Wrong source endpoint' unless endpoint_name&.is_a?(String) diff --git a/app/utilities/protocol_importers/protocols_io/v3/api_client.rb b/app/utilities/protocol_importers/protocols_io/v3/api_client.rb index c8986e3a0..c496e0801 100644 --- a/app/utilities/protocol_importers/protocols_io/v3/api_client.rb +++ b/app/utilities/protocol_importers/protocols_io/v3/api_client.rb @@ -46,10 +46,11 @@ module ProtocolImporters response = with_handle_network_errors do sort_mappings = CONSTANTS[:sort_mappings] query = CONSTANTS.dig(:endpoints, :protocols, :default_query_params) + .stringify_keys .merge(query_params.except(:sort_by)) 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 self.class.get('/protocols', query: query) @@ -95,7 +96,7 @@ module ProtocolImporters when 1219 raise ProtocolImporters::ProtocolsIO::V3::UnauthorizedError.new(:token_expires), error_message 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 diff --git a/app/utilities/protocol_importers/protocols_io/v3/protocol_normalizer.rb b/app/utilities/protocol_importers/protocols_io/v3/protocol_normalizer.rb index e38adc8d5..ec02fd5eb 100644 --- a/app/utilities/protocol_importers/protocols_io/v3/protocol_normalizer.rb +++ b/app/utilities/protocol_importers/protocols_io/v3/protocol_normalizer.rb @@ -73,6 +73,7 @@ module ProtocolImporters def normalize_list(client_data) # client_data is HttpParty ApiReponse object protocols_hash = client_data.parsed_response.with_indifferent_access[:items] + pagination = client_data.parsed_response.with_indifferent_access[:pagination] normalized_data = {} normalized_data[:protocols] = protocols_hash.map do |e| @@ -87,6 +88,14 @@ module ProtocolImporters uri: e[:uri] } end + + # Parse pagination + normalized_data[:pagination] = { + current_page: pagination[:current_page], + total_pages: pagination[:total_pages], + page_size: pagination[:page_size] + } + normalized_data rescue StandardError => e raise ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message diff --git a/app/views/protocol_importers/_list_of_protocol_cards.html.erb b/app/views/protocol_importers/_list_of_protocol_cards.html.erb index 0831753dc..aaaf539be 100644 --- a/app/views/protocol_importers/_list_of_protocol_cards.html.erb +++ b/app/views/protocol_importers/_list_of_protocol_cards.html.erb @@ -2,3 +2,12 @@ <%= render partial: 'protocol_importers/protocol_card', locals: { protocol: protocol, show_import_button: show_import_button } %> <% end %> + +<% if protocols[:pagination][:current_page] + 1 <= protocols[:pagination][:total_pages] %> +
+ +
+<% end %> diff --git a/app/views/protocols/index/_external_protocols_tab.html.erb b/app/views/protocols/index/_external_protocols_tab.html.erb index 20044e4e2..2ddf66f45 100644 --- a/app/views/protocols/index/_external_protocols_tab.html.erb +++ b/app/views/protocols/index/_external_protocols_tab.html.erb @@ -10,6 +10,7 @@ class: 'protocolsio-logo' %> <%= t('protocols.index.external_protocols.protocolsio_title') %> <%= hidden_field_tag 'protocol_source', 'protocolsio/v3' %> + <%= hidden_field_tag 'page_id', 1, id: 'page-id' %>
diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb index 67f6045f1..b7b6e41a4 100644 --- a/config/initializers/constants.rb +++ b/config/initializers/constants.rb @@ -226,7 +226,7 @@ class Constants key: '', order_field: :activity, order_dir: :desc, - page_size: 10, + page_size: 50, page_id: 1, fields: 'id,title,authors,created_on,uri,stats' } diff --git a/config/locales/protocols/en.yml b/config/locales/protocols/en.yml index 3ac2c6280..8990f1198 100644 --- a/config/locales/protocols/en.yml +++ b/config/locales/protocols/en.yml @@ -5,6 +5,8 @@ en: card: views_and_steps: '%{nr_of_views} views • %{nr_of_steps} steps' import_button_text: 'Import...' + show_more_button: + title: 'Show more protocols' templates: amount: title: 'Amount'