-
Notifications
You must be signed in to change notification settings - Fork 0
Add pagination support to 'all' tab #280
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,54 +1,58 @@ | ||
| class Analyzer | ||
| attr_accessor :pagination | ||
|
|
||
| RESULTS_PER_PAGE = 20 | ||
|
|
||
| # Primo API theoretical maximum recommended offset is 2000 records (per Ex Libris documentation) | ||
| # but in practice, the API often can't deliver results beyond ~960 records for large result sets, | ||
| # likely due to performance constraints. | ||
| PRIMO_MAX_OFFSET = 960 | ||
|
|
||
| def initialize(enhanced_query, response, source) | ||
| # Initializes pagination analysis for search results. | ||
| # | ||
| # @param enhanced_query [Hash] Query parameters including :page (current page number) | ||
| # @param hits [Integer] Number of hits from primary source (TIMDEX for :all, source-specific otherwise) | ||
| # @param source [Symbol] Source tab (:primo, :timdex, or :all) | ||
| # @param secondary_hits [Integer, nil] Optional hit count from secondary source (Primo hits for :all) | ||
| def initialize(enhanced_query, hits, source, secondary_hits = nil) | ||
| @source = source | ||
| @enhanced_query = enhanced_query | ||
| @pagination = {} | ||
| @pagination[:hits] = hits(response) | ||
| @pagination[:start] = ((enhanced_query[:page] - 1) * RESULTS_PER_PAGE) + 1 | ||
| @pagination[:end] = [enhanced_query[:page] * RESULTS_PER_PAGE, @pagination[:hits]].min | ||
| @pagination[:prev] = enhanced_query[:page] - 1 if enhanced_query[:page] > 1 | ||
| @pagination[:next] = next_page(enhanced_query[:page], @pagination[:hits]) if next_page( | ||
| enhanced_query[:page], @pagination[:hits] | ||
| ) | ||
| @pagination[:per_page] = RESULTS_PER_PAGE | ||
| set_pagination(hits, secondary_hits) | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def hits(response) | ||
| return 0 if response.nil? | ||
|
|
||
| if @source == :primo | ||
| primo_hits(response) | ||
| elsif @source == :timdex | ||
| timdex_hits(response) | ||
| # Sets the pagination hash with hit counts and per_page values. | ||
| # | ||
| # @param hits [Integer] Hit count from primary source | ||
| # @param secondary_hits [Integer, nil] Optional hit count from secondary source | ||
| def set_pagination(hits, secondary_hits = nil) | ||
| if @source == :all | ||
| @pagination[:hits] = (secondary_hits || 0) + (hits || 0) | ||
| @pagination[:per_page] = ENV.fetch('RESULTS_PER_PAGE', '20').to_i | ||
| calculate_pagination_values | ||
| else | ||
| 0 | ||
| @pagination[:hits] = hits || 0 | ||
| @pagination[:per_page] = ENV.fetch('RESULTS_PER_PAGE', '20').to_i | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No change requested at this time, but we should consider a future refactor to set this once at Rails startup rather than the constant Env.fetch logic. I doubt it would change anything performance-wise, but it would be a lot cleaner code to stop repeating this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean like setting it as a global constant? That would be a big improvement, especially if we ever want to change the default number of results.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking more Rails custom config or something similar: So maybe we'd end up with I'm not sure we've done that in any of our apps, but doing that or setting a global constant in an initializer might be worth exploring in the future.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, interesting. I haven't used custom config before, but it looks useful! |
||
| calculate_pagination_values | ||
| end | ||
| end | ||
|
|
||
| def primo_hits(response) | ||
| return 0 unless response.is_a?(Hash) | ||
|
|
||
| response.dig('info', 'total') || 0 | ||
| end | ||
|
|
||
| def timdex_hits(response) | ||
| return 0 unless response.is_a?(Hash) && response.key?(:data) && response[:data].key?('search') | ||
| return 0 unless response[:data]['search'].is_a?(Hash) && response[:data]['search'].key?('hits') | ||
|
|
||
| response[:data]['search']['hits'] | ||
| # Calculates and sets pagination navigation values (start, end, prev, next). | ||
| # Uses the already-set @pagination[:hits] and @pagination[:per_page] values. | ||
| def calculate_pagination_values | ||
| page = @enhanced_query[:page] || 1 | ||
| @pagination[:start] = ((page - 1) * @pagination[:per_page]) + 1 | ||
| @pagination[:end] = [page * @pagination[:per_page], @pagination[:hits]].min | ||
| @pagination[:prev] = page - 1 if page > 1 | ||
| @pagination[:next] = next_page(page, @pagination[:hits]) if next_page(page, @pagination[:hits]) | ||
| end | ||
|
|
||
| # Calculates the next page number if more results are available. | ||
| # | ||
| # @param page [Integer] Current page number | ||
| # @param hits [Integer] Total number of results available | ||
| # @return [Integer, nil] Next page number or nil if no more pages | ||
| def next_page(page, hits) | ||
| page + 1 if page * RESULTS_PER_PAGE < hits | ||
| page + 1 if page * @pagination[:per_page] < hits | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the smaller methods here. It's much easier to read with well named methods.