blacklight-hierarchy 4.3.0 → 5.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 +4 -4
- data/.github/workflows/ruby.yml +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/blacklight/hierarchy/blacklight_hierarchy_controller.js +12 -0
- data/app/assets/javascripts/blacklight/hierarchy/hierarchy.js +9 -12
- data/app/components/blacklight/hierarchy/facet_field_component.html.erb +4 -3
- data/app/components/blacklight/hierarchy/facet_field_component.rb +5 -0
- data/app/components/blacklight/hierarchy/facet_field_list_component.html.erb +2 -2
- data/app/components/blacklight/hierarchy/facet_field_list_component.rb +4 -25
- data/app/components/blacklight/hierarchy/selected_qfacet_value_component.html.erb +3 -2
- data/app/helpers/blacklight/hierarchy_helper.rb +14 -188
- data/app/models/blacklight/hierarchy/facet_tree.rb +42 -0
- data/blacklight-hierarchy.gemspec +1 -1
- data/lib/blacklight/hierarchy/version.rb +1 -1
- data/lib/generators/blacklight_hierarchy/templates/blacklight_hierarchy.js +9 -1
- data/package.json +2 -2
- data/spec/features/basic_spec.rb +2 -2
- data/spec/helpers/hierarchy_helper_spec.rb +1 -10
- metadata +7 -6
- data/.travis.yml +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d1b8143cbf272d885f0ba8c3b16b5f7e2f410f4cfea16424f86dc6f9b77fa19
|
|
4
|
+
data.tar.gz: 05f3ad702fac07799e4898c7449b0672838108d265dea23c1023dac37992d681
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0b875f0426e21c3982ef5832e55210832267e1926cc789dc7ab2a7bb87570901c217b6b48b2d1387677108dd30b1039242035294aa8c2e7ea42f4b03f7011709
|
|
7
|
+
data.tar.gz: cacf30cfc7cd49124829a6a464221162a6e8849ff7f363c3b29bbb8f193ee00a8eeff97d177bf6ab7a264a3c346e6d86caeaf552915de4a76c533507f13e4112
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -9,16 +9,16 @@ name: CI
|
|
|
9
9
|
|
|
10
10
|
on:
|
|
11
11
|
push:
|
|
12
|
-
branches: [
|
|
12
|
+
branches: [ main ]
|
|
13
13
|
pull_request:
|
|
14
|
-
branches: [
|
|
14
|
+
branches: [ main ]
|
|
15
15
|
|
|
16
16
|
jobs:
|
|
17
17
|
test:
|
|
18
18
|
runs-on: ubuntu-latest
|
|
19
19
|
strategy:
|
|
20
20
|
matrix:
|
|
21
|
-
ruby: [2.
|
|
21
|
+
ruby: [2.7, 3.0]
|
|
22
22
|
steps:
|
|
23
23
|
- uses: actions/checkout@v2
|
|
24
24
|
- name: Set up Ruby
|
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
runs-on: ubuntu-latest
|
|
36
36
|
strategy:
|
|
37
37
|
matrix:
|
|
38
|
-
ruby: [2.
|
|
38
|
+
ruby: [2.7, 2.6]
|
|
39
39
|
steps:
|
|
40
40
|
- uses: actions/checkout@v2
|
|
41
41
|
- name: Set up Ruby
|
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Blacklight::Hierarchy
|
|
2
|
-
[](https://github.com/sul-dlss/blacklight-hierarchy/actions?query=branch%3Amain) [](https://coveralls.io/r/sul-dlss/blacklight-hierarchy) [](http://badge.fury.io/rb/blacklight-hierarchy)
|
|
3
3
|
|
|
4
4
|
This plugin provides hierarchical facets for [Blacklight](https://github.com/projectblacklight/blacklight).
|
|
5
5
|
|
|
@@ -8,27 +8,24 @@ Blacklight.onLoad(function(){
|
|
|
8
8
|
Blacklight.hierarchical_facet_expand_contract
|
|
9
9
|
);
|
|
10
10
|
}
|
|
11
|
-
Blacklight.do_hierarchical_facet_expand_contract_behavior.selector = '
|
|
11
|
+
Blacklight.do_hierarchical_facet_expand_contract_behavior.selector = '[data-controller="b-h-collapsible"]';
|
|
12
|
+
Blacklight.do_hierarchical_facet_expand_contract_behavior.handle = '[data-action="click->b-h-collapsible#toggle"]';
|
|
13
|
+
Blacklight.do_hierarchical_facet_expand_contract_behavior.list = '[data-b-h-collapsible-target="list"]';
|
|
12
14
|
|
|
13
15
|
Blacklight.hierarchical_facet_expand_contract = function() {
|
|
14
16
|
var li = $(this);
|
|
17
|
+
li.addClass('twiddle');
|
|
15
18
|
|
|
16
|
-
$(
|
|
17
|
-
|
|
18
|
-
if($('span.selected', this).length == 0){
|
|
19
|
-
$(this).hide();
|
|
20
|
-
} else {
|
|
19
|
+
$(Blacklight.do_hierarchical_facet_expand_contract_behavior.list, this).each(function() {
|
|
20
|
+
if($('span.selected', this).length != 0){
|
|
21
21
|
li.addClass('twiddle-open');
|
|
22
|
-
li.children('.
|
|
22
|
+
li.children('.collapse').addClass('in');
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
// attach the toggle behavior to the li tag
|
|
27
|
-
li.children(
|
|
28
|
-
|
|
29
|
-
$(this).attr('aria-expanded', $(this).attr('aria-expanded') === 'true' ? 'false' : 'true');
|
|
30
|
-
$(this).parent('li').toggleClass('twiddle-open');
|
|
31
|
-
$(this).parent('li').children('ul').slideToggle();
|
|
27
|
+
li.children(Blacklight.do_hierarchical_facet_expand_contract_behavior.handle).click(function(e){
|
|
28
|
+
li.toggleClass('twiddle-open');
|
|
32
29
|
});
|
|
33
30
|
};
|
|
34
31
|
})(jQuery);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
<li class="<%= li_class %>" role="treeitem">
|
|
2
|
-
|
|
1
|
+
<li class="<%= li_class %>" data-controller="<%= controller_name %>" role="treeitem">
|
|
2
|
+
<% ul_id = "b-h-#{SecureRandom.alphanumeric(10)}" %>
|
|
3
|
+
<%= helpers.facet_toggle_button(field_name, id, ul_id) if subset.any? %>
|
|
3
4
|
<% if item.nil? %>
|
|
4
5
|
<%= key %>
|
|
5
6
|
<% elsif qfacet_selected? %>
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
<% end %>
|
|
10
11
|
|
|
11
12
|
<% unless subset.empty? %>
|
|
12
|
-
<ul role
|
|
13
|
+
<ul id="<%= ul_id %>" class="collapse" data-b-h-collapsible-target="list" role="group">
|
|
13
14
|
<% subset.keys.sort.each do |subkey| %>
|
|
14
15
|
<%= render self.class.new(field_name: field_name, tree: subset[subkey], key: subkey) %>
|
|
15
16
|
<% end %>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<%= render(@layout.new(facet_field: @facet_field)) do |component| %>
|
|
2
|
-
<% component.
|
|
2
|
+
<% component.label do %>
|
|
3
3
|
<%= @facet_field.label %>
|
|
4
4
|
<% end %>
|
|
5
|
-
<% component.
|
|
5
|
+
<% component.body do %>
|
|
6
6
|
<ul class="facet-hierarchy" role="tree">
|
|
7
7
|
<% tree.keys.sort.collect do |key| %>
|
|
8
8
|
<%= render Blacklight::Hierarchy::FacetFieldComponent.new(field_name: @facet_field.facet_field.field, tree: tree[key], key: key) %>
|
|
@@ -8,8 +8,11 @@ module Blacklight
|
|
|
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
|
|
10
10
|
def tree
|
|
11
|
+
|
|
11
12
|
@tree ||= begin
|
|
12
|
-
facet_tree_for_prefix =
|
|
13
|
+
facet_tree_for_prefix = FacetTree.build(prefix: prefix,
|
|
14
|
+
facet_display: blacklight_config.facet_display,
|
|
15
|
+
facet_field: @facet_field)
|
|
13
16
|
facet_tree_for_prefix ? facet_tree_for_prefix[field_name] : nil
|
|
14
17
|
end
|
|
15
18
|
end
|
|
@@ -42,31 +45,7 @@ module Blacklight
|
|
|
42
45
|
@prefix ||= field_name.gsub("#{DELIMETER}#{field_name.split(/#{DELIMETER}/).last}", '')
|
|
43
46
|
end
|
|
44
47
|
|
|
45
|
-
|
|
46
48
|
delegate :blacklight_config, to: :helpers
|
|
47
|
-
|
|
48
|
-
def facet_tree
|
|
49
|
-
@facet_tree ||= {}
|
|
50
|
-
return @facet_tree[prefix] unless @facet_tree[prefix].nil?
|
|
51
|
-
return @facet_tree[prefix] unless blacklight_config.facet_display[:hierarchy] && blacklight_config.facet_display[:hierarchy][prefix]
|
|
52
|
-
@facet_tree[prefix] = {}
|
|
53
|
-
facet_config = blacklight_config.facet_display[:hierarchy][prefix]
|
|
54
|
-
split_regex = Regexp.new("\s*#{Regexp.escape(facet_config.length >= 2 ? facet_config[1] : ':')}\s*")
|
|
55
|
-
facet_config.first.each do |key|
|
|
56
|
-
# TODO: remove baked in notion of underscores being part of the blacklight facet field names
|
|
57
|
-
facet_field = [prefix, key].compact.join('_')
|
|
58
|
-
@facet_tree[prefix][facet_field] ||= {}
|
|
59
|
-
data = @facet_field.display_facet
|
|
60
|
-
next if data.nil?
|
|
61
|
-
data.items.each do |facet_item|
|
|
62
|
-
path = facet_item.value.split(split_regex)
|
|
63
|
-
loc = @facet_tree[prefix][facet_field]
|
|
64
|
-
loc = loc[path.shift] ||= {} while path.length > 0
|
|
65
|
-
loc[:_] = HierarchicalFacetItem.new(facet_item.value, facet_item.value.split(split_regex).last, facet_item.hits)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
@facet_tree[prefix]
|
|
69
|
-
end
|
|
70
49
|
end
|
|
71
50
|
end
|
|
72
51
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<span class="selected"><%= render Blacklight::Hierarchy::QfacetValueComponent.new(field_name: field_name, item: item, suppress_link: true) %></span>
|
|
2
|
-
<%= link_to
|
|
3
|
-
<span class="
|
|
2
|
+
<%= link_to(remove_href, class: 'remove') do %>
|
|
3
|
+
<span class="remove-icon" aria-hidden="true">✖</span>
|
|
4
|
+
<span class="sr-only"><%= t('blacklight.search.facets.selected.remove') %></span>
|
|
4
5
|
<% end %>
|
|
@@ -1,139 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Blacklight::HierarchyHelper
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# Putting bare HTML strings in a helper sucks. But in this case, with a
|
|
7
|
-
# lot of recursive tree-walking going on, it's an order of magnitude faster
|
|
8
|
-
# than either render(:partial) or content_tag
|
|
9
|
-
def render_facet_hierarchy_item(field_name, data, key)
|
|
10
|
-
item = data[:_]
|
|
11
|
-
subset = data.reject { |k, _v| !k.is_a?(String) }
|
|
12
|
-
|
|
13
|
-
Deprecation.silence(Blacklight::HierarchyHelper) do
|
|
14
|
-
li_class = subset.empty? ? 'h-leaf' : 'h-node'
|
|
15
|
-
id = SecureRandom.uuid
|
|
16
|
-
ul = ''
|
|
17
|
-
li = ''
|
|
18
|
-
li << facet_toggle_button(field_name, id) if subset.any?
|
|
19
|
-
li << if item.nil?
|
|
20
|
-
key
|
|
21
|
-
elsif qfacet_selected?(field_name, item)
|
|
22
|
-
render_selected_qfacet_value(field_name, item)
|
|
23
|
-
else
|
|
24
|
-
render_qfacet_value(field_name, item, id: id)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
unless subset.empty?
|
|
28
|
-
subul = subset.keys.sort.collect do |subkey|
|
|
29
|
-
render_facet_hierarchy_item(field_name, subset[subkey], subkey)
|
|
30
|
-
end.join('')
|
|
31
|
-
ul = "<ul role=\"group\">#{subul}</ul>".html_safe
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
%(<li class="#{li_class}" role="treeitem">#{li.html_safe}#{ul.html_safe}</li>).html_safe
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
deprecation_deprecate :render_facet_hierarchy_item
|
|
38
|
-
|
|
39
|
-
def qfacet_selected?(field_name, item)
|
|
40
|
-
config = facet_configuration_for_field(field_name)
|
|
41
|
-
search_state.has_facet?(config, value: facet_value_for_facet_item(item.qvalue))
|
|
42
|
-
end
|
|
43
|
-
private :qfacet_selected?
|
|
44
|
-
|
|
45
|
-
# @param [Blacklight::Configuration::FacetField] as defined in controller with config.add_facet_field (and with :partial => 'blacklight/hierarchy/facet_hierarchy')
|
|
46
|
-
# @return [String] html for the facet tree
|
|
47
|
-
def render_hierarchy(bl_facet_field, delim = '_')
|
|
48
|
-
field_name = bl_facet_field.field
|
|
49
|
-
prefix = field_name.gsub("#{delim}#{field_name.split(/#{delim}/).last}", '')
|
|
50
|
-
facet_tree_for_prefix = facet_tree(prefix)
|
|
51
|
-
tree = facet_tree_for_prefix ? facet_tree_for_prefix[field_name] : nil
|
|
52
|
-
|
|
53
|
-
return '' unless tree
|
|
54
|
-
tree.keys.sort.collect do |key|
|
|
55
|
-
render_facet_hierarchy_item(field_name, tree[key], key)
|
|
56
|
-
end.join("\n").html_safe
|
|
57
|
-
end
|
|
58
|
-
deprecation_deprecate :render_hierarchy
|
|
59
|
-
|
|
60
|
-
def render_qfacet_value(facet_solr_field, item, options = {})
|
|
61
|
-
Deprecation.silence(Blacklight::FacetsHelperBehavior) do
|
|
62
|
-
id = options.delete(:id)
|
|
63
|
-
facet_config = facet_configuration_for_field(facet_solr_field)
|
|
64
|
-
path_for_facet = facet_item_presenter(facet_config, item.qvalue, facet_solr_field).href
|
|
65
|
-
(link_to_unless(options[:suppress_link], item.value, path_for_facet, id: id, class: 'facet_select') + ' ' + render_facet_count(item.hits)).html_safe
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
deprecation_deprecate :render_qfacet_value
|
|
69
|
-
|
|
70
|
-
# Standard display of a SELECTED facet value, no link, special span with class, and 'remove' button.
|
|
71
|
-
def render_selected_qfacet_value(facet_solr_field, item)
|
|
72
|
-
remove_href = search_action_path(search_state.remove_facet_params(facet_solr_field, item.qvalue))
|
|
73
|
-
content_tag(:span, render_qfacet_value(facet_solr_field, item, suppress_link: true), class: 'selected') + ' ' +
|
|
74
|
-
link_to(content_tag(:span, '', class: 'glyphicon glyphicon-remove') +
|
|
75
|
-
content_tag(:span, '[remove]', class: 'sr-only'),
|
|
76
|
-
remove_href,
|
|
77
|
-
class: 'remove'
|
|
78
|
-
)
|
|
79
|
-
end
|
|
80
|
-
deprecation_deprecate :render_selected_qfacet_value
|
|
81
|
-
|
|
82
|
-
# @param [String] hkey - a key to access the rest of the hierarchy tree, as defined in controller config.facet_display[:hierarchy] declaration.
|
|
83
|
-
# e.g. if you had this in controller:
|
|
84
|
-
# config.facet_display = {
|
|
85
|
-
# :hierarchy => {
|
|
86
|
-
# 'wf' => [['wps','wsp','swp'], ':'],
|
|
87
|
-
# 'callnum_top' => [['facet'], '/'],
|
|
88
|
-
# 'exploded_tag' => [['ssim'], ':']
|
|
89
|
-
# }
|
|
90
|
-
# }
|
|
91
|
-
# then possible hkey values would be 'wf', 'callnum_top', and 'exploded_tag'.
|
|
92
|
-
#
|
|
93
|
-
# the key in the :hierarchy hash is the "prefix" for the solr field with the hierarchy info. the value
|
|
94
|
-
# in the hash is a list, where the first element is a list of suffixes, and the second element is the delimiter
|
|
95
|
-
# used to break up the sections of hierarchical data in the solr field being read. when joined, the prefix and
|
|
96
|
-
# suffix should form the field name. so, for example, 'wf_wps', 'wf_wsp', 'wf_swp', 'callnum_top_facet', and
|
|
97
|
-
# 'exploded_tag_ssim' would be the solr fields with blacklight-hierarchy related configuration according to the
|
|
98
|
-
# hash above. ':' would be the delimiter used in all of those fields except for 'callnum_top_facet', which would
|
|
99
|
-
# use '/'. exploded_tag_ssim might contain values like ['Book', 'Book : Multi-Volume Work'], and callnum_top_facet
|
|
100
|
-
# might contain values like ['LB', 'LB/2395', 'LB/2395/.C65', 'LB/2395/.C65/1991'].
|
|
101
|
-
# note: the suffixes (e.g. 'ssim' for 'exploded_tag' in the above example) can't have underscores, otherwise things break.
|
|
102
|
-
def facet_tree(hkey)
|
|
103
|
-
@facet_tree ||= {}
|
|
104
|
-
return @facet_tree[hkey] unless @facet_tree[hkey].nil?
|
|
105
|
-
return @facet_tree[hkey] unless blacklight_config.facet_display[:hierarchy] && blacklight_config.facet_display[:hierarchy][hkey]
|
|
106
|
-
@facet_tree[hkey] = {}
|
|
107
|
-
facet_config = blacklight_config.facet_display[:hierarchy][hkey]
|
|
108
|
-
split_regex = Regexp.new("\s*#{Regexp.escape(facet_config.length >= 2 ? facet_config[1] : ':')}\s*")
|
|
109
|
-
facet_config.first.each do |key|
|
|
110
|
-
# TODO: remove baked in notion of underscores being part of the blacklight facet field names
|
|
111
|
-
facet_field = [hkey, key].compact.join('_')
|
|
112
|
-
@facet_tree[hkey][facet_field] ||= {}
|
|
113
|
-
data = @response.aggregations[facet_field]
|
|
114
|
-
next if data.nil?
|
|
115
|
-
data.items.each do |facet_item|
|
|
116
|
-
path = facet_item.value.split(split_regex)
|
|
117
|
-
loc = @facet_tree[hkey][facet_field]
|
|
118
|
-
loc = loc[path.shift] ||= {} while path.length > 0
|
|
119
|
-
loc[:_] = HierarchicalFacetItem.new(facet_item.value, facet_item.value.split(split_regex).last, facet_item.hits)
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
@facet_tree[hkey]
|
|
123
|
-
end
|
|
124
|
-
deprecation_deprecate :facet_tree
|
|
125
|
-
|
|
126
|
-
def facet_toggle_button(field_name, described_by)
|
|
4
|
+
def facet_toggle_button(field_name, described_by, controls)
|
|
127
5
|
aria_label = I18n.t(
|
|
128
6
|
"blacklight.hierarchy.#{field_name}_toggle_aria_label",
|
|
129
7
|
default: :'blacklight.hierarchy.toggle_aria_label'
|
|
130
8
|
)
|
|
131
9
|
|
|
132
10
|
# For Rails 5.2 support all options must be symbols. See https://github.com/rails/rails/issues/39813
|
|
133
|
-
tag.button(:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
11
|
+
tag.button(aria: {
|
|
12
|
+
expanded: 'false',
|
|
13
|
+
label: aria_label,
|
|
14
|
+
describedby: described_by,
|
|
15
|
+
controls: controls
|
|
16
|
+
},
|
|
17
|
+
data: {
|
|
18
|
+
action: 'click->b-h-collapsible#toggle',
|
|
19
|
+
toggle: 'collapse',
|
|
20
|
+
target: "##{controls}"
|
|
21
|
+
},
|
|
22
|
+
class: 'toggle-handle') do
|
|
137
23
|
tag.span(Blacklight::Hierarchy::Engine.config.closed_icon, :'aria-hidden' => 'true', class: 'closed') +
|
|
138
24
|
tag.span(Blacklight::Hierarchy::Engine.config.opened_icon, :'aria-hidden' => 'true', class: 'opened')
|
|
139
25
|
end
|
|
@@ -143,68 +29,8 @@ module Blacklight::HierarchyHelper
|
|
|
143
29
|
# below are methods pertaining to the "rotate" notion where you may want to look at the same tree data organized another way
|
|
144
30
|
# --------------------------------------------------------------------------------------------------------------------------------
|
|
145
31
|
|
|
146
|
-
# FIXME: remove baked in underscore separator in field name
|
|
147
|
-
def is_hierarchical?(field_name)
|
|
148
|
-
(prefix, order) = field_name.split(/_/, 2)
|
|
149
|
-
(list = blacklight_config.facet_display[:hierarchy][prefix]) && list.include?(order)
|
|
150
|
-
end
|
|
151
|
-
deprecation_deprecate :is_hierarchical?
|
|
152
|
-
|
|
153
|
-
def facet_order(prefix)
|
|
154
|
-
param_name = "#{prefix}_facet_order".to_sym
|
|
155
|
-
params[param_name] || blacklight_config.facet_display[:hierarchy][prefix].first
|
|
156
|
-
end
|
|
157
|
-
deprecation_deprecate :facet_order
|
|
158
|
-
|
|
159
32
|
def facet_after(prefix, order)
|
|
160
33
|
orders = blacklight_config.facet_display[:hierarchy][prefix]
|
|
161
34
|
orders[orders.index(order) + 1] || orders.first
|
|
162
35
|
end
|
|
163
|
-
|
|
164
|
-
# FIXME: remove baked in underscore separator in field name
|
|
165
|
-
def hide_facet?(field_name)
|
|
166
|
-
return false unless is_hierarchical?(field_name)
|
|
167
|
-
prefix = field_name.split(/_/).first
|
|
168
|
-
field_name != "#{prefix}_#{facet_order(prefix)}"
|
|
169
|
-
end
|
|
170
|
-
deprecation_deprecate :hide_facet?
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
# FIXME: remove baked in colon separator
|
|
174
|
-
def rotate_facet_value(val, from, to)
|
|
175
|
-
components = Hash[from.split(//).zip(val.split(/:/))]
|
|
176
|
-
new_values = components.values_at(*to.split(//))
|
|
177
|
-
new_values.pop while new_values.last.nil?
|
|
178
|
-
return nil if new_values.include?(nil)
|
|
179
|
-
new_values.compact.join(':')
|
|
180
|
-
end
|
|
181
|
-
deprecation_deprecate :rotate_facet_value
|
|
182
|
-
|
|
183
|
-
# FIXME: remove baked in underscore separator in field name
|
|
184
|
-
def rotate_facet_params(prefix, from, to, p = params.dup)
|
|
185
|
-
return p if from == to
|
|
186
|
-
from_field = "#{prefix}_#{from}"
|
|
187
|
-
to_field = "#{prefix}_#{to}"
|
|
188
|
-
p[:f] = (p[:f] || {}).dup # the command above is not deep in rails3, !@#$!@#$
|
|
189
|
-
p[:f][from_field] = (p[:f][from_field] || []).dup
|
|
190
|
-
p[:f][to_field] = (p[:f][to_field] || []).dup
|
|
191
|
-
p[:f][from_field].reject! { |v| p[:f][to_field] << rotate_facet_value(v, from, to); true }
|
|
192
|
-
p[:f].delete(from_field)
|
|
193
|
-
p[:f][to_field].compact!
|
|
194
|
-
p[:f].delete(to_field) if p[:f][to_field].empty?
|
|
195
|
-
p
|
|
196
|
-
end
|
|
197
|
-
deprecation_deprecate :rotate_facet_params
|
|
198
|
-
|
|
199
|
-
# FIXME: remove baked in underscore separator in field name
|
|
200
|
-
def render_facet_rotate(field_name)
|
|
201
|
-
return unless is_hierarchical?(field_name)
|
|
202
|
-
(prefix, order) = field_name.split(/_/, 2)
|
|
203
|
-
return if blacklight_config.facet_display[:hierarchy][prefix].length < 2
|
|
204
|
-
new_order = facet_after(prefix, order)
|
|
205
|
-
new_params = rotate_facet_params(prefix, order, new_order)
|
|
206
|
-
new_params["#{prefix}_facet_order"] = new_order
|
|
207
|
-
link_to image_tag('icons/rotate.png', title: new_order.upcase).html_safe, new_params, class: 'no-underline'
|
|
208
|
-
end
|
|
209
|
-
deprecation_deprecate :render_facet_rotate
|
|
210
36
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Blacklight
|
|
4
|
+
module Hierarchy
|
|
5
|
+
class FacetTree
|
|
6
|
+
def self.build(prefix:, facet_display:, facet_field:)
|
|
7
|
+
new(prefix: prefix, facet_display: facet_display, facet_field: facet_field).build
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(prefix:, facet_display:, facet_field:)
|
|
11
|
+
@prefix = prefix
|
|
12
|
+
@facet_config = facet_display.dig(:hierarchy, prefix)
|
|
13
|
+
@facet_field = facet_field
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :prefix, :facet_config, :data
|
|
17
|
+
|
|
18
|
+
def build
|
|
19
|
+
return unless facet_config
|
|
20
|
+
{}.tap do |tree|
|
|
21
|
+
facet_config.first.each do |key|
|
|
22
|
+
# TODO: remove baked in notion of underscores being part of the blacklight facet field names
|
|
23
|
+
facet_field = [prefix, key].compact.join('_')
|
|
24
|
+
tree[facet_field] ||= {}
|
|
25
|
+
data = @facet_field.display_facet
|
|
26
|
+
next if data.nil?
|
|
27
|
+
data.items.each do |facet_item|
|
|
28
|
+
path = facet_item.value.split(split_regex)
|
|
29
|
+
loc = tree[facet_field]
|
|
30
|
+
loc = loc[path.shift] ||= {} while path.length > 0
|
|
31
|
+
loc[:_] = HierarchicalFacetItem.new(facet_item.value, facet_item.value.split(split_regex).last, facet_item.hits)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def split_regex
|
|
38
|
+
@split_regex ||= Regexp.new("\s*#{Regexp.escape(facet_config.length >= 2 ? facet_config[1] : ':')}\s*")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
|
18
18
|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
19
19
|
s.require_paths = ['lib']
|
|
20
20
|
|
|
21
|
-
s.add_dependency 'blacklight', '~> 7.
|
|
21
|
+
s.add_dependency 'blacklight', '~> 7.18'
|
|
22
22
|
s.add_dependency 'rails', '>= 5.1', '< 7'
|
|
23
23
|
s.add_dependency 'deprecation'
|
|
24
24
|
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
//= require blacklight/hierarchy/hierarchy
|
|
1
|
+
//= require blacklight/hierarchy/hierarchy
|
|
2
|
+
|
|
3
|
+
// If you use Stimulus in your application you can remove the line above and require
|
|
4
|
+
// blacklight_hierarchy_controller instead:
|
|
5
|
+
//
|
|
6
|
+
// import BlacklightHierarchyController from 'blacklight-hierarchy/app/assets/javascripts/blacklight/hierarchy/blacklight_hierarchy_controller'
|
|
7
|
+
// import { Application } from 'stimulus'
|
|
8
|
+
// const application = Application.start()
|
|
9
|
+
// application.register("b-h-collapsible", BlacklightHierarchyController)
|
data/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blacklight-hierarchy",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "[](https://github.com/sul-dlss/blacklight-hierarchy/actions?query=branch%3Amain)",
|
|
5
5
|
"main": "app/assets/javascripts/blacklight/hierarchy/hierarchy.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"app/assets/javascripts/blacklight/hierarchy/*.js",
|
data/spec/features/basic_spec.rb
CHANGED
|
@@ -31,8 +31,8 @@ shared_examples 'catalog' do
|
|
|
31
31
|
|
|
32
32
|
it 'should display the hierarchy' do
|
|
33
33
|
visit '/'
|
|
34
|
-
expect(page).to have_selector('li.h-node', text: 'a')
|
|
35
|
-
expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'b')
|
|
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
36
|
expect(page).to have_selector('li.h-node li.h-leaf', text: 'c 30')
|
|
37
37
|
expect(page).to have_selector('li.h-node li.h-leaf', text: 'd 25')
|
|
38
38
|
expect(page).to have_selector('li.h-node > ul > li.h-node', text: 'c')
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
RSpec.describe Blacklight::HierarchyHelper do
|
|
4
|
-
describe '#render_hierarchy' do
|
|
5
|
-
it 'should remove the _suffix from the field name' do
|
|
6
|
-
expect(Deprecation).to receive(:warn)
|
|
7
|
-
field = OpenStruct.new(field: 'the_field_name_facet')
|
|
8
|
-
expect(helper).to receive(:facet_tree).with('the_field_name').and_return({})
|
|
9
|
-
helper.render_hierarchy(field)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
4
|
describe '#facet_toggle_button' do
|
|
14
|
-
subject { helper.facet_toggle_button(field_name, described_by) }
|
|
5
|
+
subject { helper.facet_toggle_button(field_name, described_by, 'randomtext123') }
|
|
15
6
|
let(:field_name) { 'exploded_tag_ssim' }
|
|
16
7
|
let(:described_by) { 'unique-string' }
|
|
17
8
|
|
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:
|
|
4
|
+
version: 5.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:
|
|
11
|
+
date: 2021-08-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: blacklight
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '7.
|
|
19
|
+
version: '7.18'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '7.
|
|
26
|
+
version: '7.18'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rails
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -155,11 +155,11 @@ files:
|
|
|
155
155
|
- ".rspec"
|
|
156
156
|
- ".rubocop.yml"
|
|
157
157
|
- ".rubocop_todo.yml"
|
|
158
|
-
- ".travis.yml"
|
|
159
158
|
- Gemfile
|
|
160
159
|
- LICENSE
|
|
161
160
|
- README.md
|
|
162
161
|
- Rakefile
|
|
162
|
+
- app/assets/javascripts/blacklight/hierarchy/blacklight_hierarchy_controller.js
|
|
163
163
|
- app/assets/javascripts/blacklight/hierarchy/hierarchy.js
|
|
164
164
|
- app/assets/stylesheets/blacklight/hierarchy/hierarchy.scss
|
|
165
165
|
- app/components/blacklight/hierarchy/facet_field_component.html.erb
|
|
@@ -171,6 +171,7 @@ files:
|
|
|
171
171
|
- app/components/blacklight/hierarchy/selected_qfacet_value_component.html.erb
|
|
172
172
|
- app/components/blacklight/hierarchy/selected_qfacet_value_component.rb
|
|
173
173
|
- app/helpers/blacklight/hierarchy_helper.rb
|
|
174
|
+
- app/models/blacklight/hierarchy/facet_tree.rb
|
|
174
175
|
- app/models/hierarchical_facet_item.rb
|
|
175
176
|
- app/views/blacklight/hierarchy/_facet_hierarchy.html.erb
|
|
176
177
|
- blacklight-hierarchy.gemspec
|
|
@@ -208,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
208
209
|
- !ruby/object:Gem::Version
|
|
209
210
|
version: '0'
|
|
210
211
|
requirements: []
|
|
211
|
-
rubygems_version: 3.1.
|
|
212
|
+
rubygems_version: 3.1.2
|
|
212
213
|
signing_key:
|
|
213
214
|
specification_version: 4
|
|
214
215
|
summary: Hierarchical Facets for Blacklight
|