blacklight-hierarchy 6.2.2 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 197182e820d76bcf3b9a8465f0067e628ca82227be36780b984ea30bbea06f74
4
- data.tar.gz: 7e66323965a18cd418d3f061666c4b91a0efbc572680d10991c446cfa17dfd35
3
+ metadata.gz: b780d7ff6b7ed70d165c74da681cfb5f4d5212c2e7526d82fe7777f1b441776b
4
+ data.tar.gz: 426ae299d6fb8c506e9620d5896326616a1d821dc5b51ab2a2f44421a4a85347
5
5
  SHA512:
6
- metadata.gz: 9c9aeb23ad9ada67f70b46cb0fb0d4722713be517c5b3a2b2d1dfd0671542774a86f5b2ade3cc0bfe403d0c6d4f50c62231f574c385116caca378be75fe2038e
7
- data.tar.gz: 5443b1921db952dc03ad698d2f2f60e20c586957103d64316be5f56affdc92d1e6439f05d0c71291d3f0231b15efe2e25f852a725002a4da9bf1805574ad8198
6
+ metadata.gz: 938ae89b5c5de9a0ee0e6fd8dd2ad2dbf1f7b2443aef8dce648b20fc38ae2b5cba76d1bbf7fbf89bfc8d382a2ac029ff797ef08f08810d9ba6330d205559f828
7
+ data.tar.gz: 230b2979506a765f719efee9193724b1bc13515e67839cefd2c55db064257a1a0380fcb13aaa8ef5e3a0d09c7fad537aaaaf94850344d375a0b6775425b566eb
@@ -18,7 +18,7 @@ jobs:
18
18
  runs-on: ubuntu-latest
19
19
  strategy:
20
20
  matrix:
21
- ruby: ['3.0', '3.1', '3.2']
21
+ ruby: ['3.0', '3.1', '3.2', '3.3']
22
22
  rails_version: ['7.0.8']
23
23
  blacklight_version: ['7.35.0']
24
24
  include:
@@ -36,6 +36,7 @@ jobs:
36
36
  uses: ruby/setup-ruby@v1
37
37
  with:
38
38
  ruby-version: ${{ matrix.ruby }}
39
+ bundler: latest
39
40
  - name: Install dependencies
40
41
  run: bundle install
41
42
  env:
data/README.md CHANGED
@@ -77,11 +77,27 @@ In the above configuration, 'queue_status_facet' is the full Solr field name, an
77
77
 
78
78
  The `[nil]` value is present in support of rotatable facet hierarchies, a totally undocumented feature.
79
79
 
80
+ You may optionally configure a custom facet item presenter, e.g.:
81
+
82
+ ```ruby
83
+ config.facet_display = {
84
+ :hierarchy => {
85
+ 'location_hierarchy' => [['f'], ':', MyApp::CustomFacetItemPresenter] # values are arrays: 1st element is array, 2nd is delimiter string, 3rd is a presenter
86
+ }
87
+ }
88
+ ```
89
+
80
90
  Facet fields should be added for each permutation of hierarchy key and term values, joined by **_**. Or, the output of:
81
91
 
82
92
  ```ruby
83
93
  config.facet_display[:hierarchy].each{ |k,v| puts "#{k}_#{v}" }
84
94
  ```
95
+ ### Sorting
96
+ Sorting for a hierarchical facet item list is configured just like a non-hierarchical Blacklight facet. By default, the list sorts by count. To specify alphabetical sorting, use `sort: 'alpha'` in `config.add_facet_field`, e.g.:
97
+
98
+ ```ruby
99
+ config.add_facet_field 'tag_facet', sort: 'alpha', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
100
+ ```
85
101
 
86
102
  ### Changing the icons
87
103
  We store our closed/open icons as the SASS variables `$b-h-closed-icon` and `$b-h-closed-icon` in `hierarchy.scss`. By default we use SVGs provided by the [Font Awesome](https://github.com/FortAwesome/Font-Awesome) library. To change the icon, reassign these SASS variables with new SVG code.
@@ -8,30 +8,40 @@ $text-muted: #777 !default;
8
8
  .facet-hierarchy {
9
9
  list-style-type: none;
10
10
  padding-left: 0;
11
+ flex: 1 1 100%;
12
+ width: 100%;
11
13
 
12
14
  ul {
13
- border-bottom: 0;
14
15
  list-style-type: none;
15
- padding-bottom: 0;
16
- padding-left: 1.3em;
16
+ padding-left: 0.75rem;
17
+ flex: 1 1 100%;
18
+ width: 100%;
17
19
  }
18
20
 
19
- .facet_select {
20
- display: inline-block;
21
- margin-bottom: 6px;
22
- max-width: calc(100% - 5em);
21
+ .facet-label {
22
+ flex: 1;
23
+ }
24
+
25
+ .facet-select {
26
+ flex: 1;
27
+ word-break: break-word;
23
28
  }
24
29
 
25
30
  .facet-count {
26
31
  float: right;
32
+ flex: 0 0 auto;
33
+ padding-left: 0.5rem;
27
34
  }
28
35
 
29
36
  .toggle-handle {
30
37
  border: 0;
31
38
  margin: 0;
32
- min-width: 1em;
39
+ width: 1.5rem;
40
+ height: 1.5rem;
33
41
  padding: 0;
34
42
  vertical-align: top;
43
+ display: flex;
44
+ align-items: flex-start;
35
45
 
36
46
  .closed,
37
47
  .opened {
@@ -46,9 +56,9 @@ $text-muted: #777 !default;
46
56
  .twiddle>.toggle-handle .toggle-icon {
47
57
  background-position: center;
48
58
  background-repeat: no-repeat;
49
- margin-top: 3px;
50
- min-height: 20px;
51
- min-width: 20px;
59
+ margin-top: 0.25rem;
60
+ min-height: 1.1rem;
61
+ min-width: 1.1rem;
52
62
  }
53
63
 
54
64
  .twiddle>.toggle-handle .closed {
@@ -69,12 +79,14 @@ $text-muted: #777 !default;
69
79
  display: inline-block;
70
80
  }
71
81
 
72
- .h-leaf {
73
- padding-left: 1.3em;
82
+ .h-node, .h-leaf {
83
+ display: flex;
84
+ flex-wrap: wrap;
85
+ padding: 3px 0;
74
86
  }
75
87
 
76
- .h-node {
77
- cursor: pointer;
88
+ .h-leaf {
89
+ padding-left: 1.5rem;
78
90
  }
79
91
 
80
92
  .remove {
@@ -11,7 +11,7 @@
11
11
 
12
12
  <% unless subset.empty? %>
13
13
  <ul id="<%= ul_id %>" class="collapse" data-b-h-collapsible-target="list" role="group">
14
- <% subset.keys.sort.each do |subkey| %>
14
+ <% subset.keys.each do |subkey| %>
15
15
  <%= render self.class.new(field_name: field_name, tree: subset[subkey], key: subkey) %>
16
16
  <% end %>
17
17
  </ul>
@@ -4,7 +4,7 @@
4
4
  <% end %>
5
5
  <% component.with_body do %>
6
6
  <ul class="facet-hierarchy" role="tree">
7
- <% tree.keys.sort.collect do |key| %>
7
+ <% tree.keys.collect do |key| %>
8
8
  <%= render Blacklight::Hierarchy::FacetFieldComponent.new(field_name: @facet_field.facet_field.field, tree: tree[key], key: key) %>
9
9
  <% end %>
10
10
  </ul>
@@ -3,7 +3,7 @@
3
3
  module Blacklight
4
4
  module Hierarchy
5
5
  class FacetFieldListComponent < Blacklight::FacetFieldListComponent
6
- DELIMETER = '_'
6
+ DELIMITER = '_'
7
7
 
8
8
  # @param [Blacklight::Configuration::FacetField] as defined in controller with config.add_facet_field (and with :partial => 'blacklight/hierarchy/facet_hierarchy')
9
9
  # @return [String] html for the facet tree
@@ -42,7 +42,7 @@ module Blacklight
42
42
  # might contain values like ['LB', 'LB/2395', 'LB/2395/.C65', 'LB/2395/.C65/1991'].
43
43
  # note: the suffixes (e.g. 'ssim' for 'exploded_tag' in the above example) can't have underscores, otherwise things break.
44
44
  def prefix
45
- @prefix ||= field_name.gsub("#{DELIMETER}#{field_name.split(/#{DELIMETER}/).last}", '')
45
+ @prefix ||= field_name.gsub("#{DELIMITER}#{field_name.split(/#{DELIMITER}/).last}", '')
46
46
  end
47
47
 
48
48
  delegate :blacklight_config, to: :helpers
@@ -1 +1,4 @@
1
- <%= link_to_unless suppress_link, item.value, path_for_facet, id: id, class: 'facet_select' %> <%= render_facet_count %>
1
+ <span class="facet-label">
2
+ <%= link_to label_value, path_for_facet, id: id, class: 'facet-select', rel: 'nofollow' %>
3
+ </span>
4
+ <%= render_facet_count %>
@@ -12,15 +12,35 @@ module Blacklight
12
12
 
13
13
  attr_reader :field_name, :item, :id, :suppress_link
14
14
 
15
+ def label_value
16
+ return item.value if facet_item_presenter_class == Blacklight::FacetItemPresenter
17
+ facet_item_presenter_class.new(item.qvalue, facet_config, helpers, field_name).label
18
+ end
19
+
15
20
  def path_for_facet
16
- facet_config = helpers.facet_configuration_for_field(field_name)
17
- Blacklight::FacetItemPresenter.new(item.qvalue, facet_config, helpers, field_name).href
21
+ facet_item_presenter_class.new(item.qvalue, facet_config, helpers, field_name).href
18
22
  end
19
23
 
20
24
  def render_facet_count
21
25
  classes = "facet-count"
22
26
  content_tag("span", t('blacklight.search.facets.count', number: number_with_delimiter(item.hits)), class: classes)
23
27
  end
28
+
29
+ def facet_config
30
+ helpers.facet_configuration_for_field(field_name)
31
+ end
32
+
33
+ def hierarchy_config
34
+ helpers.blacklight_config.facet_display[:hierarchy]
35
+ end
36
+
37
+ def field_name_prefix
38
+ @field_name_prefix ||= field_name.gsub("_#{field_name.split(/_/).last}", '')
39
+ end
40
+
41
+ def facet_item_presenter_class
42
+ hierarchy_config.dig(field_name_prefix)[2] || Blacklight::FacetItemPresenter
43
+ end
24
44
  end
25
45
  end
26
46
  end
@@ -1,5 +1,8 @@
1
- <span class="selected"><%= render Blacklight::Hierarchy::QfacetValueComponent.new(field_name: field_name, item: item, suppress_link: true) %></span>
1
+ <span class="facet-label">
2
+ <%= content_tag :span, label_value, id: id, class: 'selected' %>
3
+ </span>
2
4
  <%= link_to(remove_href, class: 'remove') do %>
3
5
  <span class="remove-icon" aria-hidden="true">✖</span>
4
6
  <span class="sr-only"><%= t('blacklight.search.facets.selected.remove') %></span>
5
7
  <% end %>
8
+ <%= render_facet_count %>
@@ -3,7 +3,7 @@
3
3
  module Blacklight
4
4
  module Hierarchy
5
5
  # Standard display of a SELECTED facet value, no link, special span with class, and 'remove' button.
6
- class SelectedQfacetValueComponent < ::ViewComponent::Base
6
+ class SelectedQfacetValueComponent < QfacetValueComponent
7
7
  def initialize(field_name:, item:)
8
8
  @field_name = field_name
9
9
  @item = item
@@ -1,5 +1,5 @@
1
1
  module Blacklight
2
2
  module Hierarchy
3
- VERSION = '6.2.2'.freeze
3
+ VERSION = '6.3.0'.freeze
4
4
  end
5
5
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blacklight-hierarchy",
3
- "version": "6.2.2",
3
+ "version": "6.3.0",
4
4
  "description": "[![Build Status](https://github.com/sul-dlss/blacklight-hierarchy/workflows/CI/badge.svg)](https://github.com/sul-dlss/blacklight-hierarchy/actions?query=branch%3Amain)",
5
5
  "main": "app/assets/javascripts/blacklight/hierarchy/hierarchy.js",
6
6
  "files": [
@@ -17,7 +17,7 @@
17
17
  "url": "https://github.com/sul-dlss/blacklight-hierarchy/issues"
18
18
  },
19
19
  "homepage": "https://github.com/sul-dlss/blacklight-hierarchy#readme",
20
- "devDependencies": { },
20
+ "devDependencies": {},
21
21
  "dependencies": {
22
22
  "blacklight-frontend": ">=7.1 || 8.0",
23
23
  "jquery": ">=3.0"
@@ -1,131 +1,254 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
- shared_examples 'catalog' do
4
- context 'facet tree without repeated nodes' do
5
- before do
6
- solr_facet_resp = { 'responseHeader' => { 'status' => 0, 'QTime' => 4, 'params' => { 'wt' => 'ruby', 'rows' => '0' } },
7
- 'response' => { 'numFound' => 30, 'start' => 0, 'maxScore' => 1.0, 'docs' => [] },
8
- 'facet_counts' => {
9
- 'facet_queries' => {},
10
- 'facet_fields' => {
11
- 'tag_facet' => [
12
- 'a:b:c', 30,
13
- 'a:b:d', 25,
14
- 'a:c:d', 5,
15
- 'p:r:q', 25,
16
- 'x:y', 5,
17
- 'n', 1],
18
- 'my_top_facet' => [
19
- 'f/g/h', 30,
20
- 'j/k', 5,
21
- 'z', 1]
22
- },
23
- 'facet_dates' => {},
24
- 'facet_ranges' => {}
25
- }
26
- }
27
- rsolr_client = double('rsolr_client')
28
- expect(rsolr_client).to receive(:send_and_receive).and_return solr_facet_resp
29
- expect(RSolr).to receive(:connect).and_return rsolr_client
30
- end
5
+ RSpec.describe 'Basic feature specs', type: :feature do
6
+ let(:solr_facet_resp) do
7
+ { 'responseHeader' => { 'status' => 0, 'QTime' => 4, 'params' => { 'wt' => 'ruby', 'rows' => '0' } },
8
+ 'response' => { 'numFound' => 30, 'start' => 0, 'maxScore' => 1.0, 'docs' => [] },
9
+ 'facet_counts' => {
10
+ 'facet_queries' => {},
11
+ 'facet_fields' => {
12
+ 'tag_facet' => [
13
+ 'a:b:c', 30,
14
+ 'a:b:d', 25,
15
+ 'a:c:d', 5,
16
+ 'p:r:q', 25,
17
+ 'x:y', 5,
18
+ 'n', 1
19
+ ],
20
+ 'my_top_facet' => [
21
+ 'f/g/h', 30,
22
+ 'j/k', 5,
23
+ 'z', 1
24
+ ]
25
+ },
26
+ 'facet_dates' => {},
27
+ 'facet_ranges' => {}
28
+ } }
29
+ end
31
30
 
32
- it 'should display the hierarchy' do
33
- visit '/'
34
- expect(page).to have_selector('li.h-node[data-controller="b-h-collapsible"]', text: 'a')
35
- expect(page).to have_selector('li.h-node > ul > li.h-node[data-controller="b-h-collapsible"]', text: 'b')
36
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'c 30')
37
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'd 25')
38
- expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'c')
39
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'd 5')
40
- expect(page).to have_selector('li.h-node', text: 'p')
41
- expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'r')
42
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'q 25')
43
- expect(page).to have_selector('li.h-node', text: 'x')
44
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'y 5')
45
- expect(page).to have_selector('.facet-hierarchy > li.h-leaf', text: 'n 1')
46
- end
31
+ before do
32
+ rsolr_client = instance_double(RSolr::Client, send_and_receive: solr_facet_resp)
33
+ allow(RSolr).to receive(:connect).and_return rsolr_client
34
+ end
47
35
 
48
- it 'should properly link the hierarchy' do
49
- visit '/'
50
- expect(page.all(:css, 'li.h-leaf a').map { |a| a[:href].to_s }).to include(root_path('f' => { 'tag_facet' => ['n'] }))
51
- expect(page.all(:css, 'li.h-leaf a').map { |a| a[:href].to_s }).to include(root_path('f' => { 'tag_facet' => ['a:b:c'] }))
52
- expect(page.all(:css, 'li.h-leaf a').map { |a| a[:href].to_s }).to include(root_path('f' => { 'tag_facet' => ['x:y'] }))
36
+ shared_examples 'catalog' do
37
+ context 'facet tree without repeated nodes' do
38
+ it 'displays the hierarchy' do
39
+ visit '/'
40
+ expect(page).to have_selector('li.h-node[data-controller="b-h-collapsible"]', text: 'a')
41
+ expect(page).to have_selector('li.h-node > ul > li.h-node[data-controller="b-h-collapsible"]', text: 'b')
42
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'c 30')
43
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'd 25')
44
+ expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'c')
45
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'd 5')
46
+ expect(page).to have_selector('li.h-node', text: 'p')
47
+ expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'r')
48
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'q 25')
49
+ expect(page).to have_selector('li.h-node', text: 'x')
50
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'y 5')
51
+ expect(page).to have_selector('.facet-hierarchy > li.h-leaf', text: 'n 1')
52
+ end
53
+
54
+ it 'properly links the hierarchy' do
55
+ visit '/'
56
+ expect(page.all(:css, 'li.h-leaf a').map { |a| a[:href].to_s }).to include(root_path('f' => { 'tag_facet' => ['n'] }))
57
+ expect(page.all(:css, 'li.h-leaf a').map { |a| a[:href].to_s }).to include(root_path('f' => { 'tag_facet' => ['a:b:c'] }))
58
+ expect(page.all(:css, 'li.h-leaf a').map { |a| a[:href].to_s }).to include(root_path('f' => { 'tag_facet' => ['x:y'] }))
59
+ end
60
+
61
+ it 'works with a different value delimiter' do
62
+ visit '/'
63
+ expect(page).to have_selector('li.h-node', text: 'f')
64
+ expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'g')
65
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'h 30')
66
+ expect(page).to have_selector('li.h-node', text: 'j')
67
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'k 5')
68
+ expect(page).to have_selector('.facet-hierarchy > li.h-leaf', text: 'z 1')
69
+ end
53
70
  end
54
71
 
55
- it 'should work with a different value delimiter' do
56
- visit '/'
57
- expect(page).to have_selector('li.h-node', text: 'f')
58
- expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'g')
59
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'h 30')
60
- expect(page).to have_selector('li.h-node', text: 'j')
61
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'k 5')
62
- expect(page).to have_selector('.facet-hierarchy > li.h-leaf', text: 'z 1')
72
+ context 'facet tree with repeated nodes' do
73
+ let(:solr_facet_resp) do
74
+ { 'responseHeader' => { 'status' => 0, 'QTime' => 4, 'params' => { 'wt' => 'ruby', 'rows' => '0' } },
75
+ 'response' => { 'numFound' => 30, 'start' => 0, 'maxScore' => 1.0, 'docs' => [] },
76
+ 'facet_counts' => {
77
+ 'facet_queries' => {},
78
+ 'facet_fields' => {
79
+ 'tag_facet' => [
80
+ 'm:w:w:t', 15,
81
+ 'm:w:v:z', 10
82
+ ]
83
+ },
84
+ 'facet_dates' => {},
85
+ 'facet_ranges' => {}
86
+ } }
87
+ end
88
+ it 'displays all child nodes when a node value is repeated at its child level' do
89
+ visit '/'
90
+ expect(page).to have_selector('li.h-node', text: 'm')
91
+ expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'w')
92
+ expect(page).to have_selector('li.h-node > ul > li.h-node > ul > li.h-node', text: 'w')
93
+ expect(page).to have_selector('li.h-node > ul > li.h-node > ul > li.h-node', text: 'v')
94
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 't 15')
95
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'z 10')
96
+ end
63
97
  end
64
- end # facet tree without repeated nodes
98
+ end
65
99
 
66
- context 'facet tree with repeated nodes' do
67
- before do
68
- facet_resp = { 'responseHeader' => { 'status' => 0, 'QTime' => 4, 'params' => { 'wt' => 'ruby', 'rows' => '0' } },
69
- 'response' => { 'numFound' => 30, 'start' => 0, 'maxScore' => 1.0, 'docs' => [] },
70
- 'facet_counts' => {
71
- 'facet_queries' => {},
72
- 'facet_fields' => {
73
- 'tag_facet' => [
74
- 'm:w:w:t', 15,
75
- 'm:w:v:z', 10]
76
- },
77
- 'facet_dates' => {},
78
- 'facet_ranges' => {}
79
- }
80
- }
81
- my_rsolr_client = double('rsolr_client')
82
- expect(my_rsolr_client).to receive(:send_and_receive).and_return facet_resp
83
- expect(RSolr).to receive(:connect).and_return my_rsolr_client
100
+ describe 'config_1' do
101
+ it_behaves_like 'catalog' do
102
+ before do
103
+ CatalogController.blacklight_config = Blacklight::Configuration.new
104
+ CatalogController.configure_blacklight do |config|
105
+ config.add_facet_field 'tag_facet', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
106
+ config.add_facet_field 'my_top_facet', label: 'Slash Delim', component: Blacklight::Hierarchy::FacetFieldListComponent
107
+ config.facet_display = {
108
+ hierarchy: {
109
+ 'tag' => [['facet'], ':'], # stupidly, the facet field is expected to have an underscore followed by SOMETHING; in this case it is "facet"
110
+ 'my_top' => [['facet'], '/']
111
+ }
112
+ }
113
+ end
114
+ end
84
115
  end
85
- it 'should display all child nodes when a node value is repeated at its child level' do
86
- visit '/'
87
- expect(page).to have_selector('li.h-node', text: 'm')
88
- expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'w')
89
- expect(page).to have_selector('li.h-node > ul > li.h-node > ul > li.h-node', text: 'w')
90
- expect(page).to have_selector('li.h-node > ul > li.h-node > ul > li.h-node', text: 'v')
91
- expect(page).to have_selector('li.h-node li.h-leaf', text: 't 15')
92
- expect(page).to have_selector('li.h-node li.h-leaf', text: 'z 10')
116
+ end
117
+
118
+ describe 'config_2' do
119
+ it_behaves_like 'catalog' do
120
+ before do
121
+ CatalogController.blacklight_config = Blacklight::Configuration.new
122
+ CatalogController.configure_blacklight do |config|
123
+ config.add_facet_field 'tag_facet', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
124
+ config.add_facet_field 'my_top_facet', label: 'Slash Delim', component: Blacklight::Hierarchy::FacetFieldListComponent
125
+ config.facet_display = {
126
+ hierarchy: {
127
+ 'tag' => [['facet']], # rely on default delim
128
+ 'my_top' => [['facet'], '/']
129
+ }
130
+ }
131
+ end
132
+ end
93
133
  end
94
134
  end
95
- end
96
135
 
97
- describe 'config_1' do
98
- it_behaves_like 'catalog' do
136
+ describe 'configure labels via a custom FacetItemPresenter' do
99
137
  before do
138
+ class MyCustomFacetItemPresenter < Blacklight::FacetItemPresenter
139
+ def label
140
+ # Derive a custom label from the original value
141
+ value.upcase
142
+ end
143
+ end
144
+
100
145
  CatalogController.blacklight_config = Blacklight::Configuration.new
101
146
  CatalogController.configure_blacklight do |config|
102
- config.add_facet_field 'tag_facet', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
103
- config.add_facet_field 'my_top_facet', label: 'Slash Delim', component: Blacklight::Hierarchy::FacetFieldListComponent
147
+ config.add_facet_field 'tag_facet', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
104
148
  config.facet_display = {
105
149
  hierarchy: {
106
- # 'rotate' => [['tag' ], ':'], # this would work if config.add_facet_field was called rotate_tag_facet, instead of tag_facet, I think.
107
- 'tag' => [['facet'], ':'], # stupidly, the facet field is expected to have an underscore followed by SOMETHING; in this case it is "facet"
108
- 'my_top' => [['facet'], '/']
150
+ 'tag' => [['facet'], ':', MyCustomFacetItemPresenter] # configure a custom presenter
109
151
  }
110
152
  }
111
153
  end
112
154
  end
155
+
156
+ it 'uses custom labels for the facet items' do
157
+ visit '/'
158
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'A:B:C 30')
159
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'A:B:D 25')
160
+ expect(page).to have_selector('li.h-node li.h-leaf', text: 'A:C:D 5')
161
+ end
113
162
  end
114
- end
115
163
 
116
- describe 'config_2' do
117
- it_behaves_like 'catalog' do
118
- before do
119
- CatalogController.blacklight_config = Blacklight::Configuration.new
120
- CatalogController.configure_blacklight do |config|
121
- config.add_facet_field 'tag_facet', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
122
- config.add_facet_field 'my_top_facet', label: 'Slash Delim', component: Blacklight::Hierarchy::FacetFieldListComponent
123
- config.facet_display = {
124
- hierarchy: {
125
- 'tag' => [['facet']], # rely on default delim
126
- 'my_top' => [['facet'], '/']
164
+ describe 'Item sort determined by existing add_facet_field config' do
165
+ context 'with alpha sort' do
166
+ before do
167
+ CatalogController.blacklight_config = Blacklight::Configuration.new
168
+ CatalogController.configure_blacklight do |config|
169
+ config.add_facet_field 'tag_facet', sort: 'alpha', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
170
+ config.facet_display = {
171
+ hierarchy: {
172
+ 'tag' => [['facet'], ':']
173
+ }
127
174
  }
128
- }
175
+ end
176
+ end
177
+
178
+ # Note that sort: 'alpha' in the add_facet_field config will sort the facets in the response;
179
+ # This is the order in which they will render in the facet tree.
180
+ let(:solr_facet_resp) do
181
+ { 'responseHeader' => { 'status' => 0, 'QTime' => 4, 'params' => { 'wt' => 'ruby', 'rows' => '0' } },
182
+ 'response' => { 'numFound' => 30, 'start' => 0, 'maxScore' => 1.0, 'docs' => [] },
183
+ 'facet_counts' => {
184
+ 'facet_queries' => {},
185
+ 'facet_fields' => {
186
+ 'tag_facet' => [
187
+ 'a', 100,
188
+ 'a:b', 80,
189
+ 'a:b:c', 70,
190
+ 'a:b:d', 9,
191
+ 'a:b:e', 1,
192
+ 'a:f', 20,
193
+ 'g', 200,
194
+ 'g:h', 50,
195
+ 'g:i', 150
196
+ ]
197
+ },
198
+ 'facet_dates' => {},
199
+ 'facet_ranges' => {}
200
+ } }
201
+ end
202
+
203
+ it 'sorts the facet items alphabetically' do
204
+ visit '/'
205
+ facet_text = first('.facet-hierarchy').text.squish
206
+ expect(facet_text).to eq('a 100 b 80 c 70 d 9 e 1 f 20 g 200 h 50 i 150')
207
+ end
208
+ end
209
+
210
+ context 'with count sort' do
211
+ before do
212
+ CatalogController.blacklight_config = Blacklight::Configuration.new
213
+ CatalogController.configure_blacklight do |config|
214
+ config.add_facet_field 'tag_facet', sort: 'count', label: 'Tag', component: Blacklight::Hierarchy::FacetFieldListComponent
215
+ config.facet_display = {
216
+ hierarchy: {
217
+ 'tag' => [['facet'], ':']
218
+ }
219
+ }
220
+ end
221
+ end
222
+
223
+ # Note that sort: 'count' in the add_facet_field config (default) will sort the facets in the response;
224
+ # This is the order in which they will render in the facet tree.
225
+ let(:solr_facet_resp) do
226
+ { 'responseHeader' => { 'status' => 0, 'QTime' => 4, 'params' => { 'wt' => 'ruby', 'rows' => '0' } },
227
+ 'response' => { 'numFound' => 30, 'start' => 0, 'maxScore' => 1.0, 'docs' => [] },
228
+ 'facet_counts' => {
229
+ 'facet_queries' => {},
230
+ 'facet_fields' => {
231
+ 'tag_facet' => [
232
+ 'g', 200,
233
+ 'g:i', 150,
234
+ 'g:h', 50,
235
+ 'a', 100,
236
+ 'a:b', 80,
237
+ 'a:b:c', 70,
238
+ 'a:b:d', 9,
239
+ 'a:b:e', 1,
240
+ 'a:f', 20
241
+ ]
242
+ },
243
+ 'facet_dates' => {},
244
+ 'facet_ranges' => {}
245
+ } }
246
+ end
247
+
248
+ it 'sorts the facet items by count' do
249
+ visit '/'
250
+ facet_text = first('.facet-hierarchy').text.squish
251
+ expect(facet_text).to eq('g 200 i 150 h 50 a 100 b 80 c 70 d 9 e 1 f 20')
129
252
  end
130
253
  end
131
254
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacklight-hierarchy
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.2.2
4
+ version: 6.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael B. Klein
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-25 00:00:00.000000000 Z
11
+ date: 2024-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: blacklight
@@ -200,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
200
  - !ruby/object:Gem::Version
201
201
  version: '0'
202
202
  requirements: []
203
- rubygems_version: 3.5.4
203
+ rubygems_version: 3.5.10
204
204
  signing_key:
205
205
  specification_version: 4
206
206
  summary: Hierarchical Facets for Blacklight