Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permit configurable replacement of search tracking with client session storage #2954

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
157 changes: 136 additions & 21 deletions app/assets/javascripts/blacklight/blacklight.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/assets/javascripts/blacklight/blacklight.js.map

Large diffs are not rendered by default.

@@ -0,0 +1,4 @@
<div id="appliedParams" class="clearfix constraints-container">
<%= render 'start_over' %>
<%= link_to t('blacklight.back_to_search'), search_action_path(only_path: true), class: 'btn btn-outline-secondary back-to-catalog', aria: { live: "off", disabled: true }, hidden: true %>
</div>
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Blacklight
module SearchContext
class ClientAppliedParamsComponent < Blacklight::Component
delegate :search_action_path, to: :helpers
def render?
controller.params[:counter]
end
end
end
end
@@ -0,0 +1,10 @@
<div class='pagination-search-widgets'>

<div class="page-links" data-page-links-url="<%= page_links_url %>" aria-live="polite">
<%= link_to_previous_document %> |

<%= item_page_entry_info %> |

<%= link_to_next_document %>
</div>
</div>
@@ -0,0 +1,55 @@
# frozen_string_literal: true

module Blacklight
module SearchContext
class ClientItemPaginationComponent < Blacklight::Component
delegate :search_action_path, to: :helpers

def initialize(search_context:, **_args)
@counter = search_context&.fetch(:counter, nil)
end

def render?
@counter.present?
end

def page_links_url
search_action_path action: 'page_links', counter: @counter
end

##
# Displays "showing X of Y items" message.
#
# @return [String]
def item_page_entry_info
# rubocop:disable Rails/OutputSafety
t('blacklight.search.entry_pagination_info.other', current: "<span class=\"pagination-counter-delimited\"></span>",
total: "<span class=\"pagination-total-delimited\"></span>",
count: "<span class=\"pagination-total-raw\"></span>").html_safe
# rubocop:enable Rails/OutputSafety
end

# Displays a stub link for previous document to be activated by client script
# @return [String]
def link_to_previous_document
# rubocop:disable Rails/OutputSafety
link_opts = { class: ['previous'], rel: 'prev', aria: { disabled: true } }
content_tag :a, link_opts do
tag.span raw(t('views.pagination.previous')), class: 'previous'
end
# rubocop:enable Rails/OutputSafety
end

# Displays a stub link for next document to be activated by client script
# @return [String]
def link_to_next_document
# rubocop:disable Rails/OutputSafety
link_opts = { class: ['next'], rel: 'next', aria: { disabled: true } }
content_tag :a, link_opts do
tag.span raw(t('views.pagination.next')), class: 'next'
end
# rubocop:enable Rails/OutputSafety
end
end
end
end
@@ -0,0 +1,4 @@
<div id="appliedParams" class="clearfix constraints-container">
<%= render 'start_over' %>
<%= link_back_to_catalog class: 'btn btn-outline-secondary' %>
</div>
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Blacklight
module SearchContext
class ServerAppliedParamsComponent < Blacklight::Component
delegate :current_search_session, :link_back_to_catalog, to: :helpers

def render?
current_search_session
end
end
end
end
5 changes: 3 additions & 2 deletions app/components/blacklight/search_context_component.rb
Expand Up @@ -4,13 +4,14 @@ module Blacklight
class SearchContextComponent < Blacklight::Component
with_collection_parameter :search_context

def initialize(search_context:, search_session:)
def initialize(search_context:, search_session:, current_document:)
@search_context = search_context
@search_session = search_session
@current_document_id = current_document.id
end

def render?
@search_context.present? && (@search_context[:prev] || @search_context[:next])
@search_context.present? && (@search_context[:prev] || @search_context[:next]) && (@search_session['document_id'] == @current_document_id)
end

##
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/concerns/blacklight/bookmarks.rb
Expand Up @@ -15,7 +15,7 @@ module Blacklight::Bookmarks

before_action :verify_user

blacklight_config.track_search_session = false
blacklight_config.track_search_session.storage = false
blacklight_config.http_method = Blacklight::Engine.config.blacklight.bookmarks_http_method
blacklight_config.add_results_collection_tool(:clear_bookmarks_widget)

Expand Down
52 changes: 46 additions & 6 deletions app/controllers/concerns/blacklight/search_context.rb
Expand Up @@ -28,6 +28,28 @@ def searches_from_history
session[:history].blank? ? ::Search.none : ::Search.where(id: session[:history]).order("updated_at desc")
end

# GET previous and next document json for the document specified by
# the counter param in current search
def page_links
counter_param = params.delete(:counter)
@page_link_data = {}
if counter_param
index = counter_param.to_i - 1
response, documents = search_service.previous_and_next_documents_for_search index, search_state.reset_search
if documents.detect(&:present?)
@page_link_data[:prev] = page_links_document_path(documents.first, index)
@page_link_data[:next] = page_links_document_path(documents.last, index + 2)
end
if response&.total && response.total.positive?
@page_link_data[:counterRaw] = counter_param
@page_link_data[:counterDelimited] = helpers.number_with_delimiter(counter_param.to_i)
@page_link_data[:totalRaw] = response.total
@page_link_data[:totalDelimited] = helpers.number_with_delimiter(response.total)
end
end
render json: @page_link_data
end

private

# sets up the session[:search] hash if it doesn't already exist
Expand Down Expand Up @@ -85,6 +107,8 @@ def agent_is_crawler?
end

def find_or_initialize_search_session_from_params params
return unless blacklight_config.track_search_session.storage == 'server'

params_copy = params.reject { |k, v| nonpersisted_search_session_params.include?(k.to_sym) || v.blank? }

return if params_copy.reject { |k, _v| [:action, :controller].include? k.to_sym }.blank?
Expand Down Expand Up @@ -127,15 +151,31 @@ def blacklisted_search_session_params
# calls setup_previous_document then setup_next_document.
# used in the show action for single view pagination.
def setup_next_and_previous_documents
if search_session['counter'] && current_search_session
index = search_session['counter'].to_i - 1
response, documents = search_service.previous_and_next_documents_for_search index, search_state.reset(current_search_session.query_params)
return { counter: params[:counter] } if setup_next_and_previous_on_client?
return nil unless setup_next_and_previous_on_server?

search_session['total'] = response.total
{ prev: documents.first, next: documents.last }
end
index = search_session['counter'].to_i - 1
response, documents = search_service.previous_and_next_documents_for_search index, search_state.reset(current_search_session.query_params)

search_session['total'] = response.total
{ prev: documents.first, next: documents.last }
rescue Blacklight::Exceptions::InvalidRequest => e
logger&.warn "Unable to setup next and previous documents: #{e}"
nil
end

def setup_next_and_previous_on_server?
search_session['counter'] && current_search_session && blacklight_config.track_search_session.storage == 'server'
end

def setup_next_and_previous_on_client?
params[:counter] && blacklight_config.track_search_session.storage == 'client'
end

def page_links_document_path(document, counter)
return nil unless document
return search_state.url_for_document(document, counter: counter) if blacklight_config.view_config(:show).route

solr_document_path(document, counter: counter)
end
end