diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 9933617c..6bcec29c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -6,18 +6,24 @@ class ApplicationController < ActionController::Base
# We set this in a session cookie to persist user preference across searches.
# Clicking on a different tab will update the cookie.
def set_active_tab
- @active_tab = if Feature.enabled?(:geodata)
- # Determine which tab to load - default to primo unless gdt is enabled
- 'geodata'
- elsif params[:tab].present?
- # If params[:tab] is set, use it and set session
+ # GeoData doesn't use the tab system.
+ return if Feature.enabled?(:geodata)
+
+ @active_tab = if params[:tab].present? && valid_tab?(params[:tab])
+ # If params[:tab] is set and valid, use it and set session
cookies[:last_tab] = params[:tab]
- elsif cookies[:last_tab].present?
- # Otherwise, check for last used tab in session
+ elsif cookies[:last_tab].present? && valid_tab?(cookies[:last_tab])
+ # Otherwise, check for last used tab in session if valid
cookies[:last_tab]
else
# Default behavior when no tab is specified in params or session
- cookies[:last_tab] = 'primo'
+ cookies[:last_tab] = 'all'
end
end
+
+ private
+
+ def valid_tab?(tab)
+ %w[primo timdex all].include?(tab)
+ end
end
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index d5ef583c..3157eab0 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -17,15 +17,21 @@ def results
@enhanced_query = Enhancer.new(params).enhanced_query
+ # Load GeoData results if applicable
+ if Feature.enabled?(:geodata)
+ load_geodata_results
+ render 'results_geo'
+ return
+ end
+
# Route to appropriate search based on active tab
case @active_tab
when 'primo'
load_primo_results
when 'timdex'
load_timdex_results
- when 'geodata'
- load_gdt_results
- render 'results_geo'
+ when 'all'
+ load_all_results
end
end
@@ -50,7 +56,7 @@ def sleep_if_too_fast
sleep(1 - duration)
end
- def load_gdt_results
+ def load_geodata_results
query = QueryBuilder.new(@enhanced_query).query
response = query_timdex(query)
@@ -66,49 +72,96 @@ def load_gdt_results
end
def load_primo_results
+ data = fetch_primo_data
+ @results = data[:results]
+ @pagination = data[:pagination]
+ @errors = data[:errors]
+ @show_primo_continuation = data[:show_continuation]
+ end
+
+ def load_timdex_results
+ data = fetch_timdex_data
+ @results = data[:results]
+ @pagination = data[:pagination]
+ @errors = data[:errors]
+ end
+
+ def load_all_results
+ # Parallel fetching from both APIs
+ primo_thread = Thread.new { fetch_primo_data }
+ timdex_thread = Thread.new { fetch_timdex_data }
+
+ # Wait for both threads to complete
+ primo_data = primo_thread.value
+ timdex_data = timdex_thread.value
+
+ # Collect any errors from either API
+ all_errors = []
+ all_errors.concat(primo_data[:errors]) if primo_data[:errors]
+ all_errors.concat(timdex_data[:errors]) if timdex_data[:errors]
+ @errors = all_errors.any? ? all_errors : nil
+
+ # Zipper merge results from both APIs
+ primo_results = primo_data[:results] || []
+ timdex_results = timdex_data[:results] || []
+ @results = primo_results.zip(timdex_results).flatten.compact
+
+ # For now, just use primo pagination as a placeholder
+ @pagination = primo_data[:pagination] || {}
+
+ # Handle primo continuation for high page numbers
+ @show_primo_continuation = primo_data[:show_continuation] || false
+ end
+
+ def fetch_primo_data
current_page = @enhanced_query[:page] || 1
per_page = @enhanced_query[:per_page] || 20
offset = (current_page - 1) * per_page
# Check if we're beyond Primo API limits before making the request.
if offset >= Analyzer::PRIMO_MAX_OFFSET
- @show_primo_continuation = true
- return
+ return { results: [], pagination: {}, errors: nil, show_continuation: true }
end
primo_response = query_primo
- @results = NormalizePrimoResults.new(primo_response, @enhanced_query[:q]).normalize
+ results = NormalizePrimoResults.new(primo_response, @enhanced_query[:q]).normalize
+ pagination = Analyzer.new(@enhanced_query, primo_response, :primo).pagination
# Handle empty results from Primo API. Sometimes Primo will return no results at a given offset,
# despite claiming in the initial query that more are available. This happens randomly and
# seemingly for no reason (well below the recommended offset of 2,000). While the bug also
# exists in Primo UI, sending users there seems like the best we can do.
- if @results.empty?
+ show_continuation = false
+ errors = nil
+
+ if results.empty?
docs = primo_response['docs'] if primo_response.is_a?(Hash)
if docs.nil? || docs.empty?
# Only show continuation for pagination scenarios (page > 1), not for searches with no results
- @show_primo_continuation = true if current_page > 1
+ show_continuation = true if current_page > 1
else
- @errors = [{ 'message' => 'No more results available at this page number.' }]
+ errors = [{ 'message' => 'No more results available at this page number.' }]
end
end
- # Use Analyzer for consistent pagination across all search types
- @pagination = Analyzer.new(@enhanced_query, primo_response, :primo).pagination
+ { results: results, pagination: pagination, errors: errors, show_continuation: show_continuation }
rescue StandardError => e
- @errors = handle_primo_errors(e)
+ { results: [], pagination: {}, errors: handle_primo_errors(e), show_continuation: false }
end
- def load_timdex_results
+ def fetch_timdex_data
query = QueryBuilder.new(@enhanced_query).query
response = query_timdex(query)
-
- @errors = extract_errors(response)
- return unless @errors.nil?
-
- @pagination = Analyzer.new(@enhanced_query, response, :timdex).pagination
- raw_results = extract_results(response)
- @results = NormalizeTimdexResults.new(raw_results, @enhanced_query[:q]).normalize
+ errors = extract_errors(response)
+
+ if errors.nil?
+ pagination = Analyzer.new(@enhanced_query, response, :timdex).pagination
+ raw_results = extract_results(response)
+ results = NormalizeTimdexResults.new(raw_results, @enhanced_query[:q]).normalize
+ { results: results, pagination: pagination, errors: nil }
+ else
+ { results: [], pagination: {}, errors: errors }
+ end
end
def active_filters
@@ -121,9 +174,9 @@ def query_timdex(query)
# Builder hands off to wrapper which returns raw results here.
Rails.cache.fetch("#{cache_key}/#{@active_tab}", expires_in: 12.hours) do
- raw = if @active_tab == 'geodata'
+ raw = if Feature.enabled?(:geodata)
execute_geospatial_query(query)
- elsif @active_tab == 'timdex'
+ elsif @active_tab == 'timdex' || @active_tab == 'all'
TimdexBase::Client.query(TimdexSearch::BaseQuery, variables: query)
end
diff --git a/app/helpers/filter_helper.rb b/app/helpers/filter_helper.rb
index ae93d8d7..6fd60696 100644
--- a/app/helpers/filter_helper.rb
+++ b/app/helpers/filter_helper.rb
@@ -33,7 +33,7 @@ def nice_labels
}
end
- def gdt_sources(value, category)
+ def geodata_sources(value, category)
return value if category != :sourceFilter
return 'Non-MIT institutions' if value == 'opengeometadata gis resources'
diff --git a/app/javascript/search_form.js b/app/javascript/search_form.js
index daddf67f..fa603040 100644
--- a/app/javascript/search_form.js
+++ b/app/javascript/search_form.js
@@ -57,7 +57,7 @@ function updateKeywordPlaceholder() {
}
}
-// Add event listeners for all panels in the DOM. For GDT, this is currently both geospatial panels and the advanced
+// Add event listeners for all panels in the DOM. For GeoData, this is currently both geospatial panels and the advanced
// panel. In all other TIMDEX UI apps, it's just the advanced panel.
if (Array.from(allPanels).includes(geoboxPanel && geodistancePanel)) {
document.getElementById('geobox-summary').addEventListener('click', () => {
diff --git a/app/models/feature.rb b/app/models/feature.rb
index 171d4ee9..b36fd77e 100644
--- a/app/models/feature.rb
+++ b/app/models/feature.rb
@@ -11,13 +11,13 @@
#
# @example Setting Flags in Environment
# # In local ENV or Heroku config:
-# FEATURE_GEODATA=true # Enables the GDT feature
+# FEATURE_GEODATA=true # Enables the GeoData feature
# FEATURE_BOOLEAN_PICKER=true # Enables the boolean picker feature
#
# # Any non-true value or not setting ENV does not enable the feature
-# FEATURE_GEODATA=false # Does not enable the GDT feature
-# FEATURE_GEODATA=1 # Does not enable the GDT feature
-# FEATURE_GEODATA=on # Does not enable the GDT feature
+# FEATURE_GEODATA=false # Does not enable the GeoData feature
+# FEATURE_GEODATA=1 # Does not enable the GeoData feature
+# FEATURE_GEODATA=on # Does not enable the GeoData feature
#
# @example Usage in Different Contexts
# # In models/controllers:
diff --git a/app/views/record/_record_geo.html.erb b/app/views/record/_record_geo.html.erb
index aa247a62..165042f5 100644
--- a/app/views/record/_record_geo.html.erb
+++ b/app/views/record/_record_geo.html.erb
@@ -41,7 +41,7 @@
<% end %>
-
+
<% if @record['publishers'].present? %>