Skip to content

Commit 2f80ef2

Browse files
Adds feature to allow ENV to reorder & filter aggs
** Why are these changes being introduced: While the API provides a large number of possible options for users to filter and aggregate their search results, not every instance of the application will want to use every category (GeoData and the basic Search application will likely use different sets, for example). One good option for enabling these differences is to leverage environment variables. ** Relevant ticket(s): * https://mitlibraries.atlassian.net/browse/gdt-128 ** How does this address that need: This adds a new environment variable to the application, ACTIVE_FILTERS. This is meant to be a list of the filter categories which should be displayed in the application. The variable is optional - without it, the application should include every available category, in the order they appear in the query model. The env variable is loaded and processed in the search controller, which is then used to order and filter the categories returned from the API before sending the result to the user in the UI. The tests added in this commit demonstrate the impact of this change. ** Document any side effects to this change: Because the env var is optional, I'm not adding it to app.json. I'm leaning toward adding it to the Heroku pipeline, to preserve the current behavior (only content type and source being shown).
1 parent e7b8cdf commit 2f80ef2

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ change as part of the work.
5151

5252
- `ABOUT_APP`: If populated, an 'about' partial containing the contents of this variable will render on
5353
`basic_search#index`.
54+
- `ACTIVE_FILTERS`: If populated, this list of strings defines which filters are shown to the user, and the order in which they appear. Values are case sensitive, and must match those used in the TIMDEX GraphQL query. Extraneous values will be ignored. If not populated, all filters will be shown.
5455
- `GDT`: Enables features related to geospatial data discovery. Setting this variable with any value will trigger GDT
5556
mode (e.g., `GDT=false` will still enable GDT features). Note that this is currently intended _only_ for the GDT app and
5657
may have unexpected consequences if applied to other TIMDEX UI apps.

app/controllers/search_controller.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def results
2525

2626
private
2727

28+
def active_filters
29+
ENV.fetch('ACTIVE_FILTERS', '').split(',').map(&:strip)
30+
end
31+
2832
def extract_errors(response)
2933
response&.errors&.details&.to_h&.dig('data')
3034
end
@@ -33,17 +37,27 @@ def extract_filters(response)
3337
aggs = response&.data&.search&.to_h&.dig('aggregations')
3438
return if aggs.blank?
3539

40+
aggs = reorder_filters(aggs, active_filters) unless active_filters.blank?
41+
3642
# We use aggregations to determine which terms can be filtered. However, agg names do not include 'filter', whereas
3743
# our filter fields do (e.g., 'source' vs 'sourceFilter'). Because of this mismatch, we need to modify the
3844
# aggregation key names before collecting them as filters, so that when a filter is applied, it searches the
3945
# correct field name.
40-
aggs.select { |_, agg_values| agg_values.present? }.transform_keys { |key| (key.dup << 'Filter').to_sym }
46+
aggs
47+
.select { |_, agg_values| agg_values.present? }
48+
.transform_keys { |key| (key.dup << 'Filter').to_sym }
4149
end
4250

4351
def extract_results(response)
4452
response&.data&.search&.to_h&.dig('records')
4553
end
4654

55+
def reorder_filters(aggs, active_filters)
56+
aggs
57+
.select { |key, _| active_filters.include?(key) }
58+
.sort_by { |key, _| active_filters.index(key) }.to_h
59+
end
60+
4761
def validate_q!
4862
return if params[:advanced]&.strip.present?
4963
return if params[:q]&.strip.present?

test/controllers/search_controller_test.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,42 @@ def source_filter_count(controller)
417417
assert(source_filter_count(@controller) == 2)
418418
end
419419
end
420+
421+
test 'applications can customize the displayed filters via ENV' do
422+
VCR.use_cassette('data basic controller',
423+
allow_playback_repeats: true,
424+
match_requests_on: %i[method uri body]) do
425+
# Our standard test ENV does not define ACTIVE_FILTERS, but this confirms
426+
# the behavior when it is not defined.
427+
ClimateControl.modify ACTIVE_FILTERS: '' do
428+
get '/results?q=data'
429+
assert_response :success
430+
assert_select '#filters .category .filter-label', { minimum: 1 }
431+
end
432+
433+
# Ask for a single filter, get that filter.
434+
ClimateControl.modify ACTIVE_FILTERS: 'subjects' do
435+
get '/results?q=data'
436+
assert_response :success
437+
assert_select '#filters .category .filter-label', { count: 1 }
438+
assert_select '#filters .category:first-of-type .filter-label', 'Subject'
439+
end
440+
441+
# The order of the terms matter, so now Format should be first.
442+
ClimateControl.modify ACTIVE_FILTERS: 'format, contentType, source' do
443+
get '/results?q=data'
444+
assert_response :success
445+
assert_select '#filters .category .filter-label', { count: 3 }
446+
assert_select '#filters .category:first-of-type .filter-label', 'Format'
447+
end
448+
449+
# Including extra values does not affect anything - "nonsense" is extraneous.
450+
ClimateControl.modify ACTIVE_FILTERS: 'contentType, nonsense, source' do
451+
get '/results?q=data'
452+
assert_response :success
453+
assert_select '#filters .category .filter-label', { count: 2 }
454+
assert_select '#filters .category:first-of-type .filter-label', 'Content type'
455+
end
456+
end
457+
end
420458
end

0 commit comments

Comments
 (0)