arclight 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc +12 -0
  3. data/.gitignore +5 -0
  4. data/.rubocop.yml +66 -0
  5. data/.solr_wrapper +5 -0
  6. data/.travis.yml +30 -2
  7. data/CONTRIBUTING.md +43 -0
  8. data/Gemfile +36 -0
  9. data/LICENSE.txt +1 -0
  10. data/README.md +85 -12
  11. data/Rakefile +14 -3
  12. data/app/assets/images/blacklight/compact.svg +25 -0
  13. data/app/assets/images/blacklight/logo.png +0 -0
  14. data/app/assets/javascripts/arclight/arclight.js +9 -0
  15. data/app/assets/javascripts/arclight/collection_context.js +18 -0
  16. data/app/assets/javascripts/arclight/collection_navigation.js +114 -0
  17. data/app/assets/javascripts/arclight/collection_scrollspy.js +6 -0
  18. data/app/assets/javascripts/arclight/component_ancestors.js +56 -0
  19. data/app/assets/javascripts/arclight/oembed_viewer.js +39 -0
  20. data/app/assets/javascripts/arclight/truncator.js.erb +23 -0
  21. data/app/assets/stylesheets/arclight/application.scss +13 -0
  22. data/app/assets/stylesheets/arclight/bootstrap_overrides.scss +3 -0
  23. data/app/assets/stylesheets/arclight/modules/collection_search.scss +3 -0
  24. data/app/assets/stylesheets/arclight/modules/hierarchy_and_online_contents.scss +174 -0
  25. data/app/assets/stylesheets/arclight/modules/highlights.scss +10 -0
  26. data/app/assets/stylesheets/arclight/modules/layout.scss +33 -0
  27. data/app/assets/stylesheets/arclight/modules/mastheads.scss +60 -0
  28. data/app/assets/stylesheets/arclight/modules/repositories.scss +29 -0
  29. data/app/assets/stylesheets/arclight/modules/repository_card.scss +54 -0
  30. data/app/assets/stylesheets/arclight/modules/search_results.scss +75 -0
  31. data/app/assets/stylesheets/arclight/modules/show_collection.scss +78 -0
  32. data/app/assets/stylesheets/arclight/modules/sidebar.scss +16 -0
  33. data/app/assets/stylesheets/arclight/variables.scss +2 -0
  34. data/app/controllers/arclight/repositories_controller.rb +40 -0
  35. data/app/controllers/concerns/arclight/field_config_helpers.rb +86 -0
  36. data/app/factories/blacklight_field_configuration_factory.rb +29 -0
  37. data/app/helpers/arclight_helper.rb +173 -0
  38. data/app/models/arclight/parent.rb +24 -0
  39. data/app/models/arclight/parents.rb +34 -0
  40. data/app/models/arclight/requests/google_form.rb +44 -0
  41. data/app/models/concerns/arclight/catalog.rb +22 -0
  42. data/app/models/concerns/arclight/search_behavior.rb +46 -0
  43. data/app/models/concerns/arclight/solr_document.rb +131 -0
  44. data/app/presenters/arclight/index_presenter.rb +10 -0
  45. data/app/presenters/arclight/show_presenter.rb +27 -0
  46. data/app/views/arclight/.keep +0 -0
  47. data/app/views/arclight/repositories/_in_person_repository.html.erb +19 -0
  48. data/app/views/arclight/repositories/_repository.html.erb +62 -0
  49. data/app/views/arclight/repositories/index.html.erb +4 -0
  50. data/app/views/arclight/repositories/show.html.erb +38 -0
  51. data/app/views/arclight/requests/_google_form.html.erb +11 -0
  52. data/app/views/arclight/viewers/_oembed.html.erb +7 -0
  53. data/app/views/catalog/_arclight_document_index_header.html.erb +13 -0
  54. data/app/views/catalog/_arclight_document_index_header_hierarchy_default.html.erb +0 -0
  55. data/app/views/catalog/_arclight_document_index_header_online_contents_default.html.erb +0 -0
  56. data/app/views/catalog/_arclight_document_show_header.html.erb +15 -0
  57. data/app/views/catalog/_arclight_document_show_header_collection.html.erb +12 -0
  58. data/app/views/catalog/_arclight_index_compact_default.html.erb +15 -0
  59. data/app/views/catalog/_arclight_online_content_indicator.html.erb +5 -0
  60. data/app/views/catalog/_arclight_rangelimit.html.erb +24 -0
  61. data/app/views/catalog/_arclight_viewer_default.html.erb +1 -0
  62. data/app/views/catalog/_collection_contents.html.erb +12 -0
  63. data/app/views/catalog/_collection_count.html.erb +7 -0
  64. data/app/views/catalog/_collection_downloads.html.erb +17 -0
  65. data/app/views/catalog/_collection_online_contents.html.erb +17 -0
  66. data/app/views/catalog/_collection_overview.html.erb +7 -0
  67. data/app/views/catalog/_component_overview.html.erb +46 -0
  68. data/app/views/catalog/_context_card.html.erb +27 -0
  69. data/app/views/catalog/_context_sidebar.html.erb +8 -0
  70. data/app/views/catalog/_custom_metadata.html.erb +16 -0
  71. data/app/views/catalog/_home.html.erb +1 -0
  72. data/app/views/catalog/_index_breadcrumb_default.html.erb +3 -0
  73. data/app/views/catalog/_index_default.html.erb +17 -0
  74. data/app/views/catalog/_index_header.html.erb +7 -0
  75. data/app/views/catalog/_index_header_hierarchy_default.html.erb +42 -0
  76. data/app/views/catalog/_index_header_online_contents_default.html.erb +1 -0
  77. data/app/views/catalog/_index_hierarchy_default.html.erb +28 -0
  78. data/app/views/catalog/_index_online_contents_default.html.erb +6 -0
  79. data/app/views/catalog/_results_histogram.html.erb +10 -0
  80. data/app/views/catalog/_search_results.html.erb +31 -0
  81. data/app/views/catalog/_search_results_repository.html.erb +6 -0
  82. data/app/views/catalog/_search_within_form.html.erb +16 -0
  83. data/app/views/catalog/_show_breadcrumbs_default.html.erb +7 -0
  84. data/app/views/catalog/_show_collection.html.erb +40 -0
  85. data/app/views/catalog/_show_component_sidebar.html.erb +12 -0
  86. data/app/views/catalog/_show_default.html.erb +32 -0
  87. data/app/views/catalog/_show_header.html.erb +5 -0
  88. data/app/views/catalog/_show_sidebar.html.erb +30 -0
  89. data/app/views/catalog/index.html.erb +8 -0
  90. data/app/views/layouts/catalog_result.html.erb +7 -0
  91. data/app/views/shared/_breadcrumbs.html.erb +15 -0
  92. data/app/views/shared/_context_sidebar.html.erb +8 -0
  93. data/app/views/shared/_header_navbar.html.erb +54 -0
  94. data/app/views/shared/_main_menu_links.html.erb +6 -0
  95. data/arclight.gemspec +17 -4
  96. data/bin/rails +13 -0
  97. data/config/locales/arclight.en.yml +65 -0
  98. data/config/routes.rb +6 -0
  99. data/lib/arclight.rb +5 -0
  100. data/lib/arclight/custom_component.rb +98 -0
  101. data/lib/arclight/custom_document.rb +93 -0
  102. data/lib/arclight/digital_object.rb +26 -0
  103. data/lib/arclight/engine.rb +55 -0
  104. data/lib/arclight/exceptions.rb +18 -0
  105. data/lib/arclight/indexer.rb +9 -0
  106. data/lib/arclight/normalized_date.rb +45 -0
  107. data/lib/arclight/normalized_id.rb +25 -0
  108. data/lib/arclight/normalized_title.rb +30 -0
  109. data/lib/arclight/repository.rb +91 -0
  110. data/lib/arclight/shared_indexing_behavior.rb +97 -0
  111. data/lib/arclight/shared_terminology_behavior.rb +65 -0
  112. data/lib/arclight/solr_ead_indexer_ext.rb +159 -0
  113. data/lib/arclight/version.rb +3 -1
  114. data/lib/arclight/viewer.rb +45 -0
  115. data/lib/arclight/viewers/oembed.rb +56 -0
  116. data/lib/arclight/year_range.rb +102 -0
  117. data/lib/generators/arclight/install_generator.rb +63 -0
  118. data/lib/generators/arclight/templates/arclight.js +2 -0
  119. data/lib/generators/arclight/templates/arclight.scss +3 -0
  120. data/lib/generators/arclight/templates/catalog_controller.rb +347 -0
  121. data/lib/generators/arclight/templates/config/downloads.yml +13 -0
  122. data/lib/generators/arclight/templates/config/repositories.yml +42 -0
  123. data/lib/generators/arclight/update_generator.rb +22 -0
  124. data/lib/tasks/index.rake +87 -0
  125. data/package.json +24 -0
  126. data/solr/conf/_rest_managed.json +3 -0
  127. data/solr/conf/admin-extra.html +31 -0
  128. data/solr/conf/elevate.xml +36 -0
  129. data/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  130. data/solr/conf/protwords.txt +21 -0
  131. data/solr/conf/schema.xml +631 -0
  132. data/solr/conf/scripts.conf +24 -0
  133. data/solr/conf/solrconfig.xml +393 -0
  134. data/solr/conf/spellings.txt +2 -0
  135. data/solr/conf/stopwords.txt +58 -0
  136. data/solr/conf/stopwords_en.txt +58 -0
  137. data/solr/conf/synonyms.txt +31 -0
  138. data/solr/conf/xslt/example.xsl +132 -0
  139. data/solr/conf/xslt/example_atom.xsl +67 -0
  140. data/solr/conf/xslt/example_rss.xsl +66 -0
  141. data/solr/conf/xslt/luke.xsl +337 -0
  142. data/tasks/arclight.rake +68 -0
  143. data/template.rb +15 -0
  144. data/vendor/assets/javascripts/responsiveTruncator.js +69 -0
  145. data/vendor/assets/javascripts/stickyfill.js +480 -0
  146. metadata +301 -6
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # A factory to return blacklight field configurations given a field key
5
+ # that represents a field group (e.g. summary_fields, access_fields, etc)
6
+ class BlacklightFieldConfigurationFactory
7
+ def self.for(config:, field:, field_group:)
8
+ new(config: config, field: field, field_group: field_group).field_config
9
+ end
10
+
11
+ def initialize(config:, field:, field_group:)
12
+ @config = config
13
+ @field = field
14
+ @field_group = field_group
15
+ end
16
+
17
+ def field_config
18
+ return null_field unless config.respond_to?(:"#{field_group}s")
19
+ config.send(:"#{field_group}s").fetch(field) { null_field }
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :config, :field, :field_group
25
+
26
+ def null_field
27
+ Blacklight::Configuration::NullField.new(field)
28
+ end
29
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Generic Helpers used in Arclight
5
+ module ArclightHelper
6
+ ##
7
+ # @param [SolrDocument]
8
+ def parents_to_links(document)
9
+ safe_join(Arclight::Parents.from_solr_document(document).as_parents.map do |parent|
10
+ link_to parent.label, solr_document_path(parent.global_id)
11
+ end, t('arclight.breadcrumb_separator'))
12
+ end
13
+
14
+ def repository_collections_path(repository)
15
+ search_action_url(
16
+ f: {
17
+ repository_sim: [repository.name],
18
+ level_sim: ['Collection']
19
+ }
20
+ )
21
+ end
22
+
23
+ ##
24
+ # Classes used for customized show page in arclight
25
+ def custom_show_content_classes
26
+ 'col-md-12 show-document'
27
+ end
28
+
29
+ def normalize_id(id)
30
+ Arclight::NormalizedId.new(id).to_s
31
+ end
32
+
33
+ def collection_active?
34
+ try(:search_state) && search_state.params_for_search.try(:[], 'f').try(:[], 'level_sim') == ['Collection']
35
+ end
36
+
37
+ def collection_active_class
38
+ 'active' if collection_active?
39
+ end
40
+
41
+ def collection_count
42
+ facets_from_request.find { |f| f.name == 'collection_sim' }.try(:items).try(:count)
43
+ end
44
+
45
+ ##
46
+ # Looks for `document.unitid` in the downloads configuration
47
+ # @param [SolrDocument] `document`
48
+ # @param [Hash] `config` metadata for downloadable files
49
+ # @return [Hash] with `:href` and `:size` keys
50
+ def collection_downloads(document, config = load_download_config)
51
+ config = config[document.unitid] if config.present?
52
+ return {} if config.blank?
53
+ parse_collection_downloads(config)
54
+ end
55
+
56
+ def on_repositories_show?
57
+ controller_name == 'repositories' && action_name == 'show'
58
+ end
59
+
60
+ def on_repositories_index?
61
+ controller_name == 'repositories' && action_name == 'index'
62
+ end
63
+
64
+ # the Repositories menu item is only active on the Repositories index page
65
+ def repositories_active_class
66
+ 'active' if on_repositories_index?
67
+ end
68
+
69
+ def fields_have_content?(document, field_accessor)
70
+ generic_document_fields(field_accessor).any? do |_, field|
71
+ generic_should_render_field?(field_accessor, document, field)
72
+ end
73
+ end
74
+
75
+ # If we have a facet on the repository, then return the Repository object for it
76
+ #
77
+ # @return [Repository]
78
+ def repository_faceted_on
79
+ return unless try(:search_state)
80
+ repos = facets_from_request.find { |f| f.name == 'repository_sim' }.try(:items)
81
+ faceted = repos && repos.length == 1 && repos.first.value
82
+ Arclight::Repository.find_by(name: repos.first.value) if faceted
83
+ end
84
+
85
+ def hierarchy_component_context?
86
+ params[:hierarchy_context] == 'component'
87
+ end
88
+
89
+ # @return [Hash] loaded from config/downloads.yml, or `{}` if missing file
90
+ def load_download_config(filename = Rails.root.join('config', 'downloads.yml'))
91
+ YAML.safe_load(File.read(filename))
92
+ rescue Errno::ENOENT
93
+ {}
94
+ end
95
+
96
+ # @return [Hash] the downloads for the given configuration using Hash symbols
97
+ # @example `{ pdf: { href: 'http://...', size: '123 KB' } }`
98
+ def parse_collection_downloads(config, results = {})
99
+ %w[pdf ead].each do |type|
100
+ next if config[type].blank?
101
+ results[type.to_sym] = {
102
+ href: config[type]['href'],
103
+ size: display_size(config[type]['size'])
104
+ }
105
+ end
106
+ results
107
+ end
108
+
109
+ # Show a human readable size, or if it's already a string, show that
110
+ # @return [String] human readable siz
111
+ def display_size(size)
112
+ size = number_to_human_size(size.to_i + 1) if size.is_a?(Numeric) || size =~ /^[0-9]+$/ # assumes bytes
113
+ size.to_s
114
+ end
115
+
116
+ ##
117
+ # Defines custom helpers used for creating unique metadata blocks to render
118
+ Arclight::Engine.config.catalog_controller_field_accessors.each do |config_field|
119
+ ##
120
+ # Mimics what document_show_fields from Blacklight does
121
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/configuration_helper_behavior.rb#L35-L38
122
+ define_method(:"document_#{config_field}s") do |_document = nil|
123
+ blacklight_config.send(:"#{config_field}s")
124
+ end
125
+
126
+ ##
127
+ # Mimics what render_document_show_field_label from Blacklight does
128
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/blacklight_helper_behavior.rb#L136-L156
129
+ define_method(:"render_document_#{config_field}_label") do |*args|
130
+ options = args.extract_options!
131
+ document = args.first
132
+
133
+ field = options[:field]
134
+
135
+ t(:'blacklight.search.show.label', label: send(:"document_#{config_field}_label", document, field))
136
+ end
137
+
138
+ ##
139
+ # Mimics what document_show_field_label from Blacklight does
140
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/configuration_helper_behavior.rb#L67-L74
141
+ define_method(:"document_#{config_field}_label") do |document, field|
142
+ field_config = send(:"document_#{config_field}s", document)[field]
143
+ field_config ||= Blacklight::Configuration::NullField.new(key: field)
144
+
145
+ field_config.display_label('show')
146
+ end
147
+
148
+ ##
149
+ # Mimics what should_render_show_field? from Blacklight does
150
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/blacklight_helper_behavior.rb#L84-L92
151
+ define_method(:"should_render_#{config_field}?") do |document, field_config|
152
+ should_render_field?(field_config, document) && document_has_value?(document, field_config)
153
+ end
154
+ end
155
+
156
+ ##
157
+ # Calls the method for a configured field
158
+ def generic_document_fields(config_field)
159
+ send(:"document_#{config_field}s")
160
+ end
161
+
162
+ ##
163
+ # Calls the method for a configured field
164
+ def generic_should_render_field?(config_field, document, field)
165
+ send(:"should_render_#{config_field}?", document, field)
166
+ end
167
+
168
+ ##
169
+ # Calls the method for a configured field
170
+ def generic_render_document_field_label(config_field, document, field: field_name)
171
+ send(:"render_document_#{config_field}_label", document, field: field)
172
+ end
173
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Logic containing information about Solr_Ead "Parent"
6
+ # https://github.com/awead/solr_ead/blob/8cf7ffaa66e0e4c9c0b12f5646d6c2e20984cd99/lib/solr_ead/behaviors.rb#L54-L57
7
+ class Parent
8
+ attr_reader :id, :label, :eadid
9
+ def initialize(id:, label:, eadid:)
10
+ @id = id
11
+ @label = label
12
+ @eadid = eadid
13
+ end
14
+
15
+ ##
16
+ # Concatenates the eadid and the id, to return an "id" in the context of
17
+ # Blacklight and Solr
18
+ # @return [String]
19
+ def global_id
20
+ return id if eadid == id
21
+ "#{eadid}#{id}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Object for parsing and formalizing Solr_Ead "Parents"
6
+ # https://github.com/awead/solr_ead/blob/8cf7ffaa66e0e4c9c0b12f5646d6c2e20984cd99/lib/solr_ead/behaviors.rb#L54-L57
7
+ class Parents
8
+ attr_reader :ids, :labels
9
+ def initialize(ids:, labels:, eadid:)
10
+ @ids = ids
11
+ @labels = labels
12
+ @eadid = eadid
13
+ end
14
+
15
+ def eadid
16
+ Arclight::NormalizedId.new(@eadid).to_s
17
+ end
18
+
19
+ ##
20
+ # @return [Array[Arclight::Parent]]
21
+ def as_parents
22
+ Hash[ids.zip(labels)].map { |k, v| Arclight::Parent.new(id: k, label: v, eadid: eadid) }
23
+ end
24
+
25
+ ##
26
+ # @param [SolrDocument] document
27
+ def self.from_solr_document(document)
28
+ ids = document.parent_ids
29
+ labels = document.parent_labels
30
+ eadid = document.eadid
31
+ new(ids: ids, labels: labels, eadid: eadid)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ module Requests
5
+ ##
6
+ # This object relies on the ability to respond to attributes passed in as
7
+ # query parameters from the form mapping configuratino
8
+ class GoogleForm
9
+ attr_reader :document, :presenter, :document_url
10
+ delegate :collection_name, :collection_creator, :eadid, :containers, to: :document
11
+
12
+ ##
13
+ # @param [Blacklight::SolrDocument] document
14
+ # @param [Arclight::ShowPresenter] presenter
15
+ # @param [String] document_url
16
+ def initialize(document, presenter, document_url)
17
+ @document = document
18
+ @presenter = presenter
19
+ @document_url = document_url
20
+ end
21
+
22
+ ##
23
+ # Url of form to fill
24
+ def url
25
+ document.repository_config.google_request_url
26
+ end
27
+
28
+ ##
29
+ # Converts mappings as a query url param into a Hash used for sending
30
+ # messages and providing pre-filled form fields
31
+ # "collection_name=entry.123" => { "collection_name" => "entry.123" }
32
+ # @return [Hash]
33
+ def form_mapping
34
+ Rack::Utils.parse_nested_query(
35
+ document.repository_config.google_request_mappings
36
+ )
37
+ end
38
+
39
+ def title
40
+ presenter.heading
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Arclight specific methods for the Catalog
6
+ module Catalog
7
+ ##
8
+ # Overriding the Blacklight method so that the hierarchy view does not start
9
+ # a new search session
10
+ def start_new_search_session?
11
+ !%w[hierarchy online_contents].include?(params[:view]) && super
12
+ end
13
+
14
+ ##
15
+ # Overriding the Blacklight method so that hierarchy does not get stored as
16
+ # the preferred view
17
+ def store_preferred_view
18
+ return if %w[hierarchy online_contents].include?(params[:view])
19
+ super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Customized Search Behavior for Arclight
6
+ module SearchBehavior
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ self.default_processor_chain += %i[
11
+ add_hierarchy_max_rows
12
+ add_hierarchy_sort
13
+ add_highlighting
14
+ ]
15
+ end
16
+
17
+ ##
18
+ # For the hierarchy view, set a higher (unlimited) maximum document return
19
+ def add_hierarchy_max_rows(solr_params)
20
+ if blacklight_params[:view] == 'hierarchy'
21
+ solr_params[:rows] = 999_999_999
22
+ end
23
+ solr_params
24
+ end
25
+
26
+ ##
27
+ # For the hierarchy view, set the sort order to preserve the order of components
28
+ def add_hierarchy_sort(solr_params)
29
+ solr_params[:sort] = 'sort_ii asc' if blacklight_params[:view] == 'hierarchy'
30
+ solr_params
31
+ end
32
+
33
+ ##
34
+ # Disable highlighting for hiearchy, and enable it for all other searches
35
+ def add_highlighting(solr_params)
36
+ if blacklight_params[:view] == 'hierarchy'
37
+ solr_params['hl'] = false
38
+ else
39
+ solr_params['hl'] = true
40
+ solr_params['hl.fl'] = 'text'
41
+ solr_params['hl.snippets'] = 3
42
+ end
43
+ solr_params
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Extends Blacklight::Solr::Document to provide Arclight specific behavior
6
+ module SolrDocument
7
+ extend Blacklight::Solr::Document
8
+
9
+ def repository_config
10
+ return unless repository
11
+ @repository_config ||= Arclight::Repository.find_by(name: repository)
12
+ end
13
+
14
+ def parent_ids
15
+ fetch('parent_ssm', [])
16
+ end
17
+
18
+ def parent_labels
19
+ fetch('parent_unittitles_ssm', [])
20
+ end
21
+
22
+ def eadid
23
+ fetch('ead_ssi', nil)
24
+ end
25
+
26
+ def unitid
27
+ first('unitid_ssm')
28
+ end
29
+
30
+ def repository
31
+ first('repository_ssm')
32
+ end
33
+
34
+ def repository_and_unitid
35
+ [repository, unitid].compact.join(': ')
36
+ end
37
+
38
+ def collection_name
39
+ first('collection_ssm')
40
+ end
41
+
42
+ def extent
43
+ first('extent_ssm')
44
+ end
45
+
46
+ def abstract_or_scope
47
+ first('abstract_ssm') || first('scopecontent_ssm')
48
+ end
49
+
50
+ def creator
51
+ first('creator_ssm')
52
+ end
53
+
54
+ def collection_creator
55
+ first('collection_creator_ssm')
56
+ end
57
+
58
+ def online_content?
59
+ first('has_online_content_ssim') == 'true'
60
+ end
61
+
62
+ def number_of_children
63
+ first('child_component_count_isim') || 0
64
+ end
65
+
66
+ def children?
67
+ number_of_children.positive?
68
+ end
69
+
70
+ def reference
71
+ first('ref_ssm')
72
+ end
73
+
74
+ def component_level
75
+ first('component_level_isim')
76
+ end
77
+
78
+ def level
79
+ first('level_ssm')
80
+ end
81
+
82
+ def digital_object_viewer
83
+ @digital_object_viewer ||= Arclight::Viewer.render(self)
84
+ end
85
+
86
+ def terms
87
+ first('userestrict_ssm')
88
+ end
89
+
90
+ # Restrictions for component sidebar
91
+ def parent_restrictions
92
+ first('parent_access_restrict_ssm')
93
+ end
94
+
95
+ # Terms for component sidebar
96
+ def parent_terms
97
+ first('parent_access_terms_ssm')
98
+ end
99
+
100
+ def digital_objects
101
+ digital_objects_field = fetch('digital_objects_ssm', [])
102
+ return [] if digital_objects_field.blank?
103
+
104
+ digital_objects_field.map do |object|
105
+ Arclight::DigitalObject.from_json(object)
106
+ end
107
+ end
108
+
109
+ def containers
110
+ # note that .titlecase strips punctuation, like hyphens, we want to keep
111
+ fetch('containers_ssim', []).map(&:capitalize)
112
+ end
113
+
114
+ def normalized_title
115
+ first('normalized_title_ssm')
116
+ end
117
+
118
+ def normalized_date
119
+ first('normalized_date_ssm')
120
+ end
121
+
122
+ # @return [Array<String>] with embedded highlights using <em>...</em>
123
+ def highlights
124
+ highlight_response = response[:highlighting]
125
+ return if highlight_response.blank? ||
126
+ highlight_response[id].blank? ||
127
+ highlight_response[id][:text].blank?
128
+ highlight_response[id][:text]
129
+ end
130
+ end
131
+ end