blacklight 7.19.2 → 7.21.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.babelrc +11 -0
- data/.env +1 -1
- data/.github/workflows/ruby.yml +21 -3
- data/.rubocop.yml +4 -0
- data/Gemfile +1 -1
- data/README.md +2 -2
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +50 -27
- data/app/assets/stylesheets/blacklight/_constraints.scss +7 -4
- data/app/assets/stylesheets/blacklight/_controls.scss +8 -0
- data/app/assets/stylesheets/blacklight/_facets.scss +2 -2
- data/app/assets/stylesheets/blacklight/_pagination.scss +1 -1
- data/app/assets/stylesheets/blacklight/_twitter_typeahead.scss +1 -0
- data/app/components/blacklight/constraints_component.rb +1 -1
- data/app/components/blacklight/document_component.rb +4 -4
- data/app/components/blacklight/facet_item_component.rb +2 -2
- data/app/components/blacklight/metadata_field_layout_component.rb +1 -1
- data/app/components/blacklight/response/pagination_component.html.erb +1 -1
- data/app/components/blacklight/system/modal_component.html.erb +2 -2
- data/app/controllers/concerns/blacklight/bookmarks.rb +0 -3
- data/app/controllers/concerns/blacklight/catalog.rb +5 -2
- data/app/controllers/concerns/blacklight/controller.rb +9 -5
- data/app/controllers/concerns/blacklight/search_context.rb +1 -1
- data/app/helpers/blacklight/catalog_helper_behavior.rb +1 -3
- data/app/javascript/blacklight/core.js +14 -3
- data/app/javascript/blacklight/modal.js +1 -1
- data/app/javascript/blacklight/search_context.js +5 -2
- data/app/models/concerns/blacklight/document/email.rb +18 -6
- data/app/models/concerns/blacklight/document/sms.rb +16 -4
- data/app/models/record_mailer.rb +9 -1
- data/app/presenters/blacklight/facet_item_presenter.rb +2 -0
- data/app/views/catalog/_home_text.html.erb +2 -2
- data/app/views/catalog/_paginate_compact.html.erb +1 -0
- data/app/views/record_mailer/sms_record.text.erb +1 -1
- data/app/views/shared/_header_navbar.html.erb +2 -2
- data/blacklight.gemspec +4 -2
- data/config/locales/blacklight.de.yml +4 -2
- data/config/locales/blacklight.en.yml +6 -2
- data/config/locales/blacklight.es.yml +3 -1
- data/config/locales/blacklight.fr.yml +3 -1
- data/config/locales/blacklight.it.yml +3 -1
- data/lib/blacklight/configuration.rb +9 -0
- data/lib/blacklight/engine.rb +2 -0
- data/lib/blacklight/search_state/filter_field.rb +35 -11
- data/lib/blacklight/solr/response/facets.rb +2 -1
- data/lib/blacklight/solr/response/group_response.rb +3 -2
- data/lib/blacklight/solr/response/pagination_methods.rb +1 -1
- data/lib/blacklight/solr/search_builder_behavior.rb +2 -0
- data/lib/blacklight.rb +5 -1
- data/lib/generators/blacklight/assets_generator.rb +4 -2
- data/lib/generators/blacklight/install_generator.rb +4 -1
- data/lib/generators/blacklight/user_generator.rb +1 -1
- data/package.json +5 -3
- data/spec/components/blacklight/facet_item_component_spec.rb +6 -2
- data/spec/controllers/catalog_controller_spec.rb +14 -2
- data/spec/features/axe_spec.rb +33 -0
- data/spec/features/facet_missing_spec.rb +67 -0
- data/spec/features/facets_spec.rb +1 -1
- data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +2 -2
- data/spec/lib/blacklight/search_state/filter_field_spec.rb +13 -0
- data/spec/models/blacklight/configuration_spec.rb +92 -0
- data/spec/models/blacklight/document/email_spec.rb +32 -0
- data/spec/models/blacklight/document/sms_spec.rb +33 -0
- data/spec/models/blacklight/solr/response/facets_spec.rb +1 -1
- data/spec/models/blacklight/solr/response/group_response_spec.rb +3 -2
- data/spec/models/record_mailer_spec.rb +30 -2
- data/spec/spec_helper.rb +18 -12
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -3
- metadata +44 -11
@@ -2,13 +2,25 @@
|
|
2
2
|
# This module provides the body of an email export based on the document's semantic values
|
3
3
|
module Blacklight::Document::Email
|
4
4
|
# Return a text string that will be the body of the email
|
5
|
-
def to_email_text
|
6
|
-
semantics = to_semantic_values
|
5
|
+
def to_email_text(config = nil)
|
7
6
|
body = []
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
|
8
|
+
if config
|
9
|
+
body = config.email_fields.map do |name, field|
|
10
|
+
values = [self[name]].flatten
|
11
|
+
"#{field.label} #{values.join(' ')}" if self[name].present?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Use to_semantic_values for backwards compatibility
|
16
|
+
if body.empty?
|
17
|
+
semantics = to_semantic_values
|
18
|
+
body << I18n.t('blacklight.email.text.title', value: semantics[:title].join(" ")) if semantics[:title].present?
|
19
|
+
body << I18n.t('blacklight.email.text.author', value: semantics[:author].join(" ")) if semantics[:author].present?
|
20
|
+
body << I18n.t('blacklight.email.text.format', value: semantics[:format].join(" ")) if semantics[:format].present?
|
21
|
+
body << I18n.t('blacklight.email.text.language', value: semantics[:language].join(" ")) if semantics[:language].present?
|
22
|
+
end
|
23
|
+
|
12
24
|
return body.join("\n") unless body.empty?
|
13
25
|
end
|
14
26
|
end
|
@@ -2,11 +2,23 @@
|
|
2
2
|
# This module provides the body of an email export based on the document's semantic values
|
3
3
|
module Blacklight::Document::Sms
|
4
4
|
# Return a text string that will be the body of the email
|
5
|
-
def to_sms_text
|
6
|
-
semantics = to_semantic_values
|
5
|
+
def to_sms_text(config = nil)
|
7
6
|
body = []
|
8
|
-
|
9
|
-
|
7
|
+
|
8
|
+
if config
|
9
|
+
body = config.sms_fields.map do |name, field|
|
10
|
+
values = [self[name]].flatten
|
11
|
+
"#{field.label} #{values.first}" if self[name].present?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Use to_semantic_values for backwards compatibility
|
16
|
+
if body.empty?
|
17
|
+
semantics = to_semantic_values
|
18
|
+
body << I18n.t('blacklight.sms.text.title', value: semantics[:title].first) if semantics[:title].present?
|
19
|
+
body << I18n.t('blacklight.sms.text.author', value: semantics[:author].first) if semantics[:author].present?
|
20
|
+
end
|
21
|
+
|
10
22
|
return body.join unless body.empty?
|
11
23
|
end
|
12
24
|
end
|
data/app/models/record_mailer.rb
CHANGED
@@ -3,7 +3,12 @@
|
|
3
3
|
class RecordMailer < ActionMailer::Base
|
4
4
|
def email_record(documents, details, url_gen_params)
|
5
5
|
title = begin
|
6
|
-
|
6
|
+
title_field = details[:config].email.title_field
|
7
|
+
if title_field
|
8
|
+
[documents.first[title_field]].flatten.first
|
9
|
+
else
|
10
|
+
documents.first.to_semantic_values[:title]
|
11
|
+
end
|
7
12
|
rescue
|
8
13
|
I18n.t('blacklight.email.text.default_title')
|
9
14
|
end
|
@@ -14,6 +19,7 @@ class RecordMailer < ActionMailer::Base
|
|
14
19
|
|
15
20
|
@documents = documents
|
16
21
|
@message = details[:message]
|
22
|
+
@config = details[:config]
|
17
23
|
@url_gen_params = url_gen_params
|
18
24
|
|
19
25
|
mail(to: details[:to], subject: subject)
|
@@ -21,7 +27,9 @@ class RecordMailer < ActionMailer::Base
|
|
21
27
|
|
22
28
|
def sms_record(documents, details, url_gen_params)
|
23
29
|
@documents = documents
|
30
|
+
@config = details[:config]
|
24
31
|
@url_gen_params = url_gen_params
|
32
|
+
|
25
33
|
mail(to: details[:to], subject: "")
|
26
34
|
end
|
27
35
|
end
|
@@ -56,6 +56,8 @@ module Blacklight
|
|
56
56
|
view_context.public_send(facet_config.helper_method, label_value)
|
57
57
|
elsif facet_config.query && facet_config.query[label_value]
|
58
58
|
facet_config.query[label_value][:label]
|
59
|
+
elsif value == Blacklight::SearchState::FilterField::MISSING
|
60
|
+
I18n.t("blacklight.search.facets.missing")
|
59
61
|
elsif facet_config.date
|
60
62
|
localization_options = facet_config.date == true ? {} : facet_config.date
|
61
63
|
I18n.l(Time.zone.parse(label_value), **localization_options)
|
@@ -1,11 +1,11 @@
|
|
1
|
-
<div class="jumbotron text-center">
|
1
|
+
<div class="jumbotron text-center p-5 mb-4 bg-light rounded-3">
|
2
2
|
<h1 class="jumbotron-heading"><%= t('blacklight.welcome') %></h1>
|
3
3
|
|
4
4
|
<p class="lead">Blacklight is a multi-institutional open-source collaboration building a better discovery platform framework.</p>
|
5
5
|
|
6
6
|
<p>
|
7
7
|
<%= link_to 'Read the Documentation', 'https://github.com/projectblacklight/blacklight/wiki', class: 'btn btn-primary' %>
|
8
|
-
<%= link_to 'See Examples', 'http://projectblacklight.org', class: 'btn btn-
|
8
|
+
<%= link_to 'See Examples', 'http://projectblacklight.org', class: 'btn btn-light' %>
|
9
9
|
</p>
|
10
10
|
</div>
|
11
11
|
|
@@ -11,8 +11,8 @@
|
|
11
11
|
</div>
|
12
12
|
</nav>
|
13
13
|
|
14
|
-
|
14
|
+
<%= content_tag :div, class: 'navbar-search navbar navbar-light bg-light', role: 'navigation', aria: { label: t('blacklight.search.header') } do %>
|
15
15
|
<div class="<%= container_classes %>">
|
16
16
|
<%= render_search_bar %>
|
17
17
|
</div>
|
18
|
-
|
18
|
+
<% end %>
|
data/blacklight.gemspec
CHANGED
@@ -32,14 +32,16 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.add_dependency "deprecation"
|
33
33
|
s.add_dependency "i18n", '>= 1.7.0' # added named parameters
|
34
34
|
s.add_dependency "ostruct", '>= 0.3.2'
|
35
|
-
s.add_dependency "view_component", '
|
35
|
+
s.add_dependency "view_component", '~> 2.42'
|
36
36
|
|
37
37
|
s.add_development_dependency "rsolr", ">= 1.0.6", "< 3" # Library for interacting with rSolr.
|
38
38
|
s.add_development_dependency "rspec-rails", "~> 4.0.0.beta2"
|
39
39
|
s.add_development_dependency "rspec-its"
|
40
40
|
s.add_development_dependency "rspec-collection_matchers", ">= 1.0"
|
41
|
+
s.add_development_dependency 'axe-core-rspec'
|
41
42
|
s.add_development_dependency "capybara", '~> 3'
|
42
|
-
s.add_development_dependency '
|
43
|
+
s.add_development_dependency 'webdrivers'
|
44
|
+
s.add_development_dependency 'selenium-webdriver'
|
43
45
|
s.add_development_dependency 'engine_cart', '~> 2.1'
|
44
46
|
s.add_development_dependency "equivalent-xml"
|
45
47
|
s.add_development_dependency "simplecov"
|
@@ -169,7 +169,7 @@ de:
|
|
169
169
|
pagination:
|
170
170
|
title: 'Ergebnisse Navigation'
|
171
171
|
pagination_info:
|
172
|
-
no_items_found: '
|
172
|
+
no_items_found: 'Keine %{entry_name} gefunden'
|
173
173
|
single_item_found: '<strong>1</strong> %{entry_name} gefunden'
|
174
174
|
pages:
|
175
175
|
one: '<strong>%{start_num}</strong> - <strong>%{end_num}</strong> von <strong>%{total_num}</strong>'
|
@@ -230,7 +230,9 @@ de:
|
|
230
230
|
list: "Liste"
|
231
231
|
|
232
232
|
entry_name:
|
233
|
-
default:
|
233
|
+
default:
|
234
|
+
one: Eintrag
|
235
|
+
other: Einträge
|
234
236
|
grouped:
|
235
237
|
default: 'gruppiertes Ergebnis'
|
236
238
|
|
@@ -230,9 +230,13 @@ en:
|
|
230
230
|
list: "List"
|
231
231
|
|
232
232
|
entry_name:
|
233
|
-
default:
|
233
|
+
default:
|
234
|
+
one: 'entry'
|
235
|
+
other: 'entries'
|
234
236
|
grouped:
|
235
|
-
default:
|
237
|
+
default:
|
238
|
+
one: 'grouped result'
|
239
|
+
other: 'grouped results'
|
236
240
|
|
237
241
|
did_you_mean: 'Did you mean to type: %{options}?'
|
238
242
|
|
@@ -101,6 +101,9 @@ module Blacklight
|
|
101
101
|
show: { top_level_config: :show },
|
102
102
|
citation: { parent_config: :show }
|
103
103
|
),
|
104
|
+
# SMS and Email configurations.
|
105
|
+
sms: ViewConfig.new,
|
106
|
+
email: ViewConfig.new,
|
104
107
|
# Configurations for specific types of index views
|
105
108
|
view: NestedOpenStructWithHashAccess.new(ViewConfig,
|
106
109
|
list: {},
|
@@ -167,6 +170,12 @@ module Blacklight
|
|
167
170
|
# solr fields to use for sorting results
|
168
171
|
define_field_access :sort_field
|
169
172
|
|
173
|
+
# solr fields to use in text message
|
174
|
+
define_field_access :sms_field
|
175
|
+
|
176
|
+
# solr fields to use in email message
|
177
|
+
define_field_access :email_field
|
178
|
+
|
170
179
|
def initialize(hash = {})
|
171
180
|
super(self.class.default_values.deep_dup.merge(hash))
|
172
181
|
yield(self) if block_given?
|
data/lib/blacklight/engine.rb
CHANGED
@@ -4,6 +4,8 @@ module Blacklight
|
|
4
4
|
class SearchState
|
5
5
|
# Modeling access to filter query parameters
|
6
6
|
class FilterField
|
7
|
+
MISSING = { missing: true }.freeze
|
8
|
+
|
7
9
|
# @param [Blacklight::Configuration::FacetField] config
|
8
10
|
attr_reader :config
|
9
11
|
|
@@ -25,7 +27,9 @@ module Blacklight
|
|
25
27
|
def add(item)
|
26
28
|
new_state = search_state.reset_search
|
27
29
|
|
28
|
-
if item.
|
30
|
+
if item.try(:missing)
|
31
|
+
# if this is a 'missing' facet value, the :fq is only for backwards compatibility
|
32
|
+
elsif item.respond_to?(:fq)
|
29
33
|
Array(item.fq).each do |f, v|
|
30
34
|
new_state = new_state.filter(f).add(v)
|
31
35
|
end
|
@@ -35,21 +39,28 @@ module Blacklight
|
|
35
39
|
return new_state.filter(item.field).add(item)
|
36
40
|
end
|
37
41
|
|
42
|
+
url_key = key
|
38
43
|
params = new_state.params
|
39
44
|
param = :f
|
40
45
|
value = as_url_parameter(item)
|
46
|
+
|
47
|
+
if value == Blacklight::SearchState::FilterField::MISSING
|
48
|
+
url_key = "-#{key}"
|
49
|
+
value = Blacklight::Engine.config.facet_missing_param
|
50
|
+
end
|
51
|
+
|
41
52
|
param = :f_inclusive if value.is_a?(Array)
|
42
53
|
|
43
54
|
# value could be a string
|
44
55
|
params[param] = (params[param] || {}).dup
|
45
56
|
|
46
57
|
if value.is_a? Array
|
47
|
-
params[param][
|
58
|
+
params[param][url_key] = value
|
48
59
|
elsif config.single
|
49
|
-
params[param][
|
60
|
+
params[param][url_key] = [value]
|
50
61
|
else
|
51
|
-
params[param][
|
52
|
-
params[param][
|
62
|
+
params[param][url_key] = Array(params[param][url_key] || []).dup
|
63
|
+
params[param][url_key].push(value)
|
53
64
|
end
|
54
65
|
|
55
66
|
new_state.reset(params)
|
@@ -63,19 +74,26 @@ module Blacklight
|
|
63
74
|
return new_state.filter(item.field).remove(item)
|
64
75
|
end
|
65
76
|
|
77
|
+
url_key = config.key
|
66
78
|
params = new_state.params
|
67
79
|
|
68
80
|
param = :f
|
69
81
|
value = as_url_parameter(item)
|
82
|
+
|
83
|
+
if value == Blacklight::SearchState::FilterField::MISSING
|
84
|
+
url_key = "-#{key}"
|
85
|
+
value = Blacklight::Engine.config.facet_missing_param
|
86
|
+
end
|
87
|
+
|
70
88
|
param = :f_inclusive if value.is_a?(Array)
|
71
89
|
|
72
90
|
# need to dup the facet values too,
|
73
91
|
# if the values aren't dup'd, then the values
|
74
92
|
# from the session will get remove in the show view...
|
75
93
|
params[param] = (params[param] || {}).dup
|
76
|
-
params[param][
|
94
|
+
params[param][url_key] = (params[param][url_key] || []).dup
|
77
95
|
|
78
|
-
collection = params[param][
|
96
|
+
collection = params[param][url_key]
|
79
97
|
# collection should be an array, because we link to ?f[key][]=value,
|
80
98
|
# however, Facebook (and maybe some other PHP tools) tranform that parameters
|
81
99
|
# into ?f[key][0]=value, which Rails interprets as a Hash.
|
@@ -83,8 +101,9 @@ module Blacklight
|
|
83
101
|
Deprecation.warn(self, 'Normalizing parameters in FilterField#remove is deprecated')
|
84
102
|
collection = collection.values
|
85
103
|
end
|
86
|
-
|
87
|
-
params[param]
|
104
|
+
|
105
|
+
params[param][url_key] = collection - Array(value)
|
106
|
+
params[param].delete(url_key) if params[param][url_key].empty?
|
88
107
|
params.delete(param) if params[param].empty?
|
89
108
|
|
90
109
|
new_state.reset(params)
|
@@ -95,8 +114,9 @@ module Blacklight
|
|
95
114
|
params = search_state.params
|
96
115
|
f = Array(params.dig(:f, key))
|
97
116
|
f_inclusive = [params.dig(:f_inclusive, key)] if params.dig(:f_inclusive, key).present?
|
117
|
+
f_missing = [Blacklight::SearchState::FilterField::MISSING] if params.dig(:f, "-#{key}")&.any? { |v| v == Blacklight::Engine.config.facet_missing_param }
|
98
118
|
|
99
|
-
f + (f_inclusive || [])
|
119
|
+
f + (f_inclusive || []) + (f_missing || [])
|
100
120
|
end
|
101
121
|
delegate :any?, to: :values
|
102
122
|
|
@@ -112,6 +132,8 @@ module Blacklight
|
|
112
132
|
|
113
133
|
if value.is_a?(Array)
|
114
134
|
(params.dig(:f_inclusive, key) || []).to_set == value.to_set
|
135
|
+
elsif value == Blacklight::SearchState::FilterField::MISSING
|
136
|
+
(params.dig(:f, "-#{key}") || []).include?(Blacklight::Engine.config.facet_missing_param)
|
115
137
|
else
|
116
138
|
(params.dig(:f, key) || []).include?(value)
|
117
139
|
end
|
@@ -121,7 +143,9 @@ module Blacklight
|
|
121
143
|
|
122
144
|
# TODO: this code is duplicated in Blacklight::FacetsHelperBehavior
|
123
145
|
def as_url_parameter(item)
|
124
|
-
if item.respond_to?
|
146
|
+
if item.respond_to?(:missing) && item.missing
|
147
|
+
Blacklight::SearchState::FilterField::MISSING
|
148
|
+
elsif item.respond_to? :value
|
125
149
|
item.value
|
126
150
|
else
|
127
151
|
item
|
@@ -171,7 +171,8 @@ module Blacklight::Solr::Response::Facets
|
|
171
171
|
# legacy solr facet.missing serialization
|
172
172
|
if value.nil?
|
173
173
|
i.label = I18n.t(:"blacklight.search.fields.facet.missing.#{facet_field_name}", default: [:"blacklight.search.facets.missing"])
|
174
|
-
i.fq = "-#{facet_field_name}:[* TO *]"
|
174
|
+
i.fq = "-#{facet_field_name}:[* TO *]" # this explicit fq is deprecated; the missing attribute below is a better thing to check for this case
|
175
|
+
i.value = Blacklight::SearchState::FilterField::MISSING
|
175
176
|
i.missing = true
|
176
177
|
end
|
177
178
|
|
@@ -45,8 +45,9 @@ class Blacklight::Solr::Response::GroupResponse
|
|
45
45
|
def entry_name(options)
|
46
46
|
I18n.t(
|
47
47
|
"blacklight.entry_name.grouped.#{key}",
|
48
|
-
default: :'blacklight.entry_name.grouped.default'
|
49
|
-
|
48
|
+
default: :'blacklight.entry_name.grouped.default',
|
49
|
+
count: options[:count]
|
50
|
+
)
|
50
51
|
end
|
51
52
|
|
52
53
|
def method_missing meth, *args, &block
|
@@ -24,6 +24,6 @@ module Blacklight::Solr::Response::PaginationMethods
|
|
24
24
|
##
|
25
25
|
# Meant to have the same signature as Kaminari::PaginatableArray#entry_name
|
26
26
|
def entry_name(options)
|
27
|
-
I18n.t('blacklight.entry_name.default'
|
27
|
+
I18n.t('blacklight.entry_name.default', count: options[:count])
|
28
28
|
end
|
29
29
|
end
|
@@ -370,6 +370,8 @@ module Blacklight::Solr
|
|
370
370
|
elsif value.is_a?(Range)
|
371
371
|
prefix = "{!#{local_params.join(' ')}}" unless local_params.empty?
|
372
372
|
"#{prefix}#{solr_field}:[#{value.first} TO #{value.last}]"
|
373
|
+
elsif value == Blacklight::SearchState::FilterField::MISSING
|
374
|
+
"-#{solr_field}:[* TO *]"
|
373
375
|
else
|
374
376
|
"{!term f=#{solr_field}#{(' ' + local_params.join(' ')) unless local_params.empty?}}#{convert_to_term_value(value)}"
|
375
377
|
end
|
data/lib/blacklight.rb
CHANGED
@@ -96,7 +96,11 @@ module Blacklight
|
|
96
96
|
end
|
97
97
|
|
98
98
|
begin
|
99
|
-
@blacklight_yml =
|
99
|
+
@blacklight_yml = if RUBY_VERSION > '2.6'
|
100
|
+
YAML.safe_load(blacklight_erb, aliases: true)
|
101
|
+
else
|
102
|
+
YAML.safe_load(blacklight_erb, [], [], true)
|
103
|
+
end
|
100
104
|
rescue => e
|
101
105
|
raise("#{blacklight_config_file} was found, but could not be parsed.\n#{e.inspect}")
|
102
106
|
end
|
@@ -3,9 +3,11 @@ module Blacklight
|
|
3
3
|
class Assets < Rails::Generators::Base
|
4
4
|
source_root File.expand_path('../templates', __FILE__)
|
5
5
|
|
6
|
+
class_option :'bootstrap-version', type: :string, default: ENV.fetch('BOOTSTRAP_VERSION', '~> 4.0'), desc: "Set the generated app's bootstrap version"
|
7
|
+
|
6
8
|
# This could be skipped if you want to use webpacker
|
7
9
|
def add_javascript_dependencies
|
8
|
-
gem 'bootstrap', '
|
10
|
+
gem 'bootstrap', options[:'bootstrap-version']
|
9
11
|
gem 'twitter-typeahead-rails', '0.11.1.pre.corejavascript'
|
10
12
|
end
|
11
13
|
|
@@ -15,7 +17,7 @@ module Blacklight
|
|
15
17
|
|
16
18
|
create_file 'app/assets/javascripts/application.js' do
|
17
19
|
<<~CONTENT
|
18
|
-
//= require
|
20
|
+
//= require jquery3
|
19
21
|
//= require rails-ujs
|
20
22
|
//= require turbolinks
|
21
23
|
CONTENT
|
@@ -10,6 +10,7 @@ module Blacklight
|
|
10
10
|
|
11
11
|
class_option :devise, type: :boolean, default: false, aliases: "-d", desc: "Use Devise as authentication logic."
|
12
12
|
class_option :marc, type: :boolean, default: false, aliases: "-m", desc: "Generate MARC-based demo."
|
13
|
+
class_option :'bootstrap-version', type: :string, default: nil, desc: "Set the generated app's bootstrap version"
|
13
14
|
class_option :'skip-assets', type: :boolean, default: !defined?(Sprockets), desc: "Skip generating javascript and css assets into the application"
|
14
15
|
class_option :'skip-solr', type: :boolean, default: false, desc: "Skip generating solr configurations."
|
15
16
|
|
@@ -33,7 +34,9 @@ module Blacklight
|
|
33
34
|
# Call external generator in AssetsGenerator, so we can
|
34
35
|
# leave that callable seperately too.
|
35
36
|
def copy_public_assets
|
36
|
-
|
37
|
+
generated_options = "--bootstrap-version #{options[:'bootstrap-version']}" if options[:'bootstrap-version']
|
38
|
+
|
39
|
+
generate "blacklight:assets", generated_options unless options[:'skip-assets']
|
37
40
|
end
|
38
41
|
|
39
42
|
def bundle_install
|
data/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "blacklight-frontend",
|
3
|
-
"version": "7.
|
4
|
-
"description": "[![Build Status](https://travis-ci.com/projectblacklight/blacklight.png?branch=
|
3
|
+
"version": "7.21.1",
|
4
|
+
"description": "[![Build Status](https://travis-ci.com/projectblacklight/blacklight.png?branch=main)](https://travis-ci.com/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Coverage Status](https://coveralls.io/repos/github/projectblacklight/blacklight/badge.svg?branch=main)](https://coveralls.io/github/projectblacklight/blacklight?branch=main)",
|
5
5
|
"main": "app/assets/javascripts/blacklight",
|
6
6
|
"scripts": {
|
7
7
|
"js-compile-bundle": "shx cat app/javascript/blacklight/core.js app/javascript/blacklight/autocomplete.js app/javascript/blacklight/bookmark_toggle.js app/javascript/blacklight/button_focus.js app/javascript/blacklight/checkbox_submit.js app/javascript/blacklight/facet_load.js app/javascript/blacklight/modal.js app/javascript/blacklight/search_context.js | shx sed \"s/^(import|export).*//\" | babel --filename app/javascript/blacklight/blacklight.js > app/assets/javascripts/blacklight/blacklight.js"
|
@@ -23,11 +23,13 @@
|
|
23
23
|
"devDependencies": {
|
24
24
|
"@babel/cli": "^7.2.3",
|
25
25
|
"@babel/core": "^7.2.3",
|
26
|
+
"@babel/preset-env": "^7.16.0",
|
26
27
|
"shx": "^0.3.2"
|
27
28
|
},
|
29
|
+
"browserslist": "> 0.25%, not dead",
|
28
30
|
"dependencies": {
|
29
31
|
"bloodhound-js": "^1.2.3",
|
30
|
-
"bootstrap": "
|
32
|
+
"bootstrap": ">=4.3.1 <6.0.0",
|
31
33
|
"jquery": "^3.5.1",
|
32
34
|
"typeahead.js": "^0.11.1"
|
33
35
|
}
|
@@ -20,7 +20,9 @@ RSpec.describe Blacklight::FacetItemComponent, type: :component do
|
|
20
20
|
|
21
21
|
it 'links to the facet and shows the number of hits' do
|
22
22
|
expect(rendered).to have_selector 'li'
|
23
|
-
expect(rendered).to have_link 'x', href: '/catalog?f=x'
|
23
|
+
expect(rendered).to have_link 'x', href: '/catalog?f=x' do |link|
|
24
|
+
link['rel'] == 'nofollow'
|
25
|
+
end
|
24
26
|
expect(rendered).to have_selector '.facet-count', text: '10'
|
25
27
|
end
|
26
28
|
|
@@ -39,7 +41,9 @@ RSpec.describe Blacklight::FacetItemComponent, type: :component do
|
|
39
41
|
it 'links to the facet and shows the number of hits' do
|
40
42
|
expect(rendered).to have_selector 'li'
|
41
43
|
expect(rendered).to have_selector '.selected', text: 'x'
|
42
|
-
expect(rendered).to have_link '[remove]', href: '/catalog'
|
44
|
+
expect(rendered).to have_link '[remove]', href: '/catalog' do |link|
|
45
|
+
link['rel'] == 'nofollow'
|
46
|
+
end
|
43
47
|
expect(rendered).to have_selector '.selected.facet-count', text: '10'
|
44
48
|
end
|
45
49
|
end
|
@@ -501,6 +501,12 @@ RSpec.describe CatalogController, api: true do
|
|
501
501
|
end
|
502
502
|
|
503
503
|
describe "email", api: false do
|
504
|
+
let(:config) { Blacklight::Configuration.new }
|
505
|
+
|
506
|
+
before do
|
507
|
+
allow(controller).to receive(:blacklight_config).and_return(config)
|
508
|
+
end
|
509
|
+
|
504
510
|
it "gives error if no TO parameter" do
|
505
511
|
post :email, params: { id: doc_id }
|
506
512
|
expect(request.flash[:error]).to eq "You must enter a recipient in order to send this message"
|
@@ -518,7 +524,7 @@ RSpec.describe CatalogController, api: true do
|
|
518
524
|
|
519
525
|
it "redirects back to the record upon success" do
|
520
526
|
allow(RecordMailer).to receive(:email_record)
|
521
|
-
.with(anything, { to: 'test_email@projectblacklight.org', message: 'xyz' }, hash_including(host: 'test.host'))
|
527
|
+
.with(anything, { to: 'test_email@projectblacklight.org', message: 'xyz', config: config }, hash_including(host: 'test.host'))
|
522
528
|
.and_return double(deliver: nil)
|
523
529
|
post :email, params: { id: doc_id, to: 'test_email@projectblacklight.org', message: 'xyz' }
|
524
530
|
expect(request.flash[:error]).to be_nil
|
@@ -533,6 +539,12 @@ RSpec.describe CatalogController, api: true do
|
|
533
539
|
end
|
534
540
|
|
535
541
|
describe "sms", api: false do
|
542
|
+
let(:config) { Blacklight::Configuration.new }
|
543
|
+
|
544
|
+
before do
|
545
|
+
allow(controller).to receive(:blacklight_config).and_return(config)
|
546
|
+
end
|
547
|
+
|
536
548
|
it "gives error if no phone number is given" do
|
537
549
|
post :sms, params: { id: doc_id, carrier: 'att' }
|
538
550
|
expect(request.flash[:error]).to eq "You must enter a recipient's phone number in order to send this message"
|
@@ -562,7 +574,7 @@ RSpec.describe CatalogController, api: true do
|
|
562
574
|
it "sends to the appropriate carrier email address" do
|
563
575
|
expect(RecordMailer)
|
564
576
|
.to receive(:sms_record)
|
565
|
-
.with(anything, { to: '5555555555@txt.att.net' }, hash_including(host: 'test.host'))
|
577
|
+
.with(anything, { to: '5555555555@txt.att.net', config: config }, hash_including(host: 'test.host'))
|
566
578
|
.and_return double(deliver: nil)
|
567
579
|
post :sms, params: { id: doc_id, to: '5555555555', carrier: 'txt.att.net' }
|
568
580
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe 'Accessibility testing', api: false, js: true do
|
4
|
+
it 'validates the home page' do
|
5
|
+
visit root_path
|
6
|
+
expect(page).to be_accessible
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'validates the catalog page' do
|
10
|
+
visit root_path
|
11
|
+
fill_in "q", with: 'history'
|
12
|
+
click_button 'search'
|
13
|
+
|
14
|
+
expect(page).to be_accessible
|
15
|
+
|
16
|
+
within '.card.blacklight-language_ssim' do
|
17
|
+
click_button 'Language'
|
18
|
+
click_link "Tibetan"
|
19
|
+
end
|
20
|
+
|
21
|
+
expect(page).to be_accessible
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'validates the single results page' do
|
25
|
+
visit solr_document_path('2007020969')
|
26
|
+
expect(page).to be_accessible
|
27
|
+
end
|
28
|
+
|
29
|
+
def be_accessible(skipping: [])
|
30
|
+
# typeahead does funny things with the search bar
|
31
|
+
be_axe_clean.excluding('.tt-hint').skipping(skipping + [('color-contrast' if Bootstrap::VERSION < '5')].compact)
|
32
|
+
end
|
33
|
+
end
|