arclight 0.0.1 → 1.6.2

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.
Files changed (204) hide show
  1. checksums.yaml +5 -5
  2. data/.all-contributorsrc +450 -0
  3. data/.codeclimate.yml +5 -0
  4. data/.eslintrc +22 -0
  5. data/.github/workflows/ruby.yml +51 -0
  6. data/.gitignore +7 -0
  7. data/.rspec +0 -1
  8. data/.rubocop.yml +521 -0
  9. data/.rubocop_todo.yml +122 -0
  10. data/.solr_wrapper +6 -0
  11. data/CONTRIBUTING.md +43 -0
  12. data/CONTRIBUTORS.md +79 -0
  13. data/Gemfile +41 -0
  14. data/LICENSE.txt +1 -0
  15. data/README.md +100 -12
  16. data/Rakefile +13 -3
  17. data/app/assets/images/arclight/logo.png +0 -0
  18. data/app/assets/images/blacklight/bookmark.svg +1 -0
  19. data/app/assets/images/blacklight/collection.svg +5 -0
  20. data/app/assets/images/blacklight/compact.svg +1 -0
  21. data/app/assets/images/blacklight/container.svg +5 -0
  22. data/app/assets/images/blacklight/ead.svg +1 -0
  23. data/app/assets/images/blacklight/file.svg +5 -0
  24. data/app/assets/images/blacklight/folder.svg +1 -0
  25. data/app/assets/images/blacklight/list.svg +1 -0
  26. data/app/assets/images/blacklight/minus.svg +1 -0
  27. data/app/assets/images/blacklight/online.svg +5 -0
  28. data/app/assets/images/blacklight/pdf.svg +1 -0
  29. data/app/assets/images/blacklight/plus.svg +1 -0
  30. data/app/assets/images/blacklight/repository.svg +1 -0
  31. data/app/assets/javascripts/arclight/arclight.js +4 -0
  32. data/app/assets/javascripts/arclight/oembed_controller.js +58 -0
  33. data/app/assets/javascripts/arclight/truncate_controller.js +27 -0
  34. data/app/assets/stylesheets/arclight/application.scss +14 -0
  35. data/app/assets/stylesheets/arclight/build.scss +4 -0
  36. data/app/assets/stylesheets/arclight/modules/collection_search.scss +3 -0
  37. data/app/assets/stylesheets/arclight/modules/hierarchy_and_online_contents.scss +155 -0
  38. data/app/assets/stylesheets/arclight/modules/highlights.scss +11 -0
  39. data/app/assets/stylesheets/arclight/modules/icons.scss +20 -0
  40. data/app/assets/stylesheets/arclight/modules/layout.scss +220 -0
  41. data/app/assets/stylesheets/arclight/modules/mastheads.scss +42 -0
  42. data/app/assets/stylesheets/arclight/modules/repositories.scss +25 -0
  43. data/app/assets/stylesheets/arclight/modules/repository_card.scss +9 -0
  44. data/app/assets/stylesheets/arclight/modules/search_form.scss +9 -0
  45. data/app/assets/stylesheets/arclight/modules/search_results.scss +250 -0
  46. data/app/assets/stylesheets/arclight/modules/show_collection.scss +38 -0
  47. data/app/assets/stylesheets/arclight/modules/truncator.scss +58 -0
  48. data/app/assets/stylesheets/arclight/responsive.scss +13 -0
  49. data/app/assets/stylesheets/arclight/variables.scss +25 -0
  50. data/app/components/arclight/access_component.html.erb +14 -0
  51. data/app/components/arclight/access_component.rb +25 -0
  52. data/app/components/arclight/bookmark_component.html.erb +25 -0
  53. data/app/components/arclight/bookmark_component.rb +9 -0
  54. data/app/components/arclight/breadcrumb_component.rb +50 -0
  55. data/app/components/arclight/breadcrumbs_hierarchy_component.html.erb +34 -0
  56. data/app/components/arclight/breadcrumbs_hierarchy_component.rb +25 -0
  57. data/app/components/arclight/collection_context_component.html.erb +12 -0
  58. data/app/components/arclight/collection_context_component.rb +27 -0
  59. data/app/components/arclight/collection_info_component.html.erb +28 -0
  60. data/app/components/arclight/collection_info_component.rb +26 -0
  61. data/app/components/arclight/collection_sidebar_component.html.erb +15 -0
  62. data/app/components/arclight/collection_sidebar_component.rb +39 -0
  63. data/app/components/arclight/constraints_component.html.erb +7 -0
  64. data/app/components/arclight/constraints_component.rb +17 -0
  65. data/app/components/arclight/document_collection_context_component.html.erb +29 -0
  66. data/app/components/arclight/document_collection_context_component.rb +28 -0
  67. data/app/components/arclight/document_collection_hierarchy_component.html.erb +50 -0
  68. data/app/components/arclight/document_collection_hierarchy_component.rb +62 -0
  69. data/app/components/arclight/document_component.html.erb +39 -0
  70. data/app/components/arclight/document_component.rb +49 -0
  71. data/app/components/arclight/document_components_hierarchy_component.html.erb +20 -0
  72. data/app/components/arclight/document_components_hierarchy_component.rb +34 -0
  73. data/app/components/arclight/document_download_component.html.erb +24 -0
  74. data/app/components/arclight/document_download_component.rb +71 -0
  75. data/app/components/arclight/embed_component.html.erb +10 -0
  76. data/app/components/arclight/embed_component.rb +43 -0
  77. data/app/components/arclight/expand_hierarchy_button_component.html.erb +5 -0
  78. data/app/components/arclight/expand_hierarchy_button_component.rb +16 -0
  79. data/app/components/arclight/group_component.html.erb +34 -0
  80. data/app/components/arclight/group_component.rb +23 -0
  81. data/app/components/arclight/header_component.html.erb +5 -0
  82. data/app/components/arclight/header_component.rb +10 -0
  83. data/app/components/arclight/index_metadata_field_component.html.erb +16 -0
  84. data/app/components/arclight/index_metadata_field_component.rb +20 -0
  85. data/app/components/arclight/masthead_component.html.erb +17 -0
  86. data/app/components/arclight/masthead_component.rb +10 -0
  87. data/app/components/arclight/metadata_section_component.html.erb +13 -0
  88. data/app/components/arclight/metadata_section_component.rb +22 -0
  89. data/app/components/arclight/oembed_viewer_component.html.erb +5 -0
  90. data/app/components/arclight/oembed_viewer_component.rb +16 -0
  91. data/app/components/arclight/online_content_filter_component.html.erb +15 -0
  92. data/app/components/arclight/online_content_filter_component.rb +17 -0
  93. data/app/components/arclight/online_status_indicator_component.rb +19 -0
  94. data/app/components/arclight/repository_breadcrumb_component.html.erb +10 -0
  95. data/app/components/arclight/repository_breadcrumb_component.rb +17 -0
  96. data/app/components/arclight/repository_location_component.html.erb +20 -0
  97. data/app/components/arclight/repository_location_component.rb +10 -0
  98. data/app/components/arclight/search_bar_component.html.erb +27 -0
  99. data/app/components/arclight/search_bar_component.rb +32 -0
  100. data/app/components/arclight/search_result_breadcrumbs_component.html.erb +6 -0
  101. data/app/components/arclight/search_result_breadcrumbs_component.rb +37 -0
  102. data/app/components/arclight/search_result_component.html.erb +20 -0
  103. data/app/components/arclight/search_result_component.rb +18 -0
  104. data/app/components/arclight/search_result_title_component.html.erb +15 -0
  105. data/app/components/arclight/search_result_title_component.rb +15 -0
  106. data/app/components/arclight/sidebar_component.html.erb +9 -0
  107. data/app/components/arclight/sidebar_component.rb +19 -0
  108. data/app/components/arclight/upper_metadata_layout_component.rb +10 -0
  109. data/app/components/blacklight/icons/bookmark_component.rb +12 -0
  110. data/app/components/blacklight/icons/collection_component.rb +14 -0
  111. data/app/components/blacklight/icons/compact_component.rb +12 -0
  112. data/app/components/blacklight/icons/container_component.rb +14 -0
  113. data/app/components/blacklight/icons/ead_component.rb +12 -0
  114. data/app/components/blacklight/icons/file_component.rb +14 -0
  115. data/app/components/blacklight/icons/folder_component.rb +12 -0
  116. data/app/components/blacklight/icons/online_component.rb +15 -0
  117. data/app/components/blacklight/icons/pdf_component.rb +12 -0
  118. data/app/components/blacklight/icons/repository_component.rb +12 -0
  119. data/app/controllers/arclight/repositories_controller.rb +40 -0
  120. data/app/helpers/arclight/ead_format_helpers.rb +309 -0
  121. data/app/helpers/arclight/field_config_helpers.rb +26 -0
  122. data/app/helpers/arclight_helper.rb +108 -0
  123. data/app/models/arclight/document_downloads.rb +122 -0
  124. data/app/models/arclight/parent.rb +24 -0
  125. data/app/models/arclight/parents.rb +39 -0
  126. data/app/models/arclight/requests/aeon_external_request.rb +42 -0
  127. data/app/models/arclight/requests/aeon_web_ead.rb +52 -0
  128. data/app/models/arclight/requests/google_form.rb +49 -0
  129. data/app/models/concerns/arclight/catalog.rb +44 -0
  130. data/app/models/concerns/arclight/search_behavior.rb +47 -0
  131. data/app/models/concerns/arclight/solr_document.rb +160 -0
  132. data/app/presenters/arclight/index_presenter.rb +10 -0
  133. data/app/presenters/arclight/show_presenter.rb +54 -0
  134. data/app/views/arclight/.keep +0 -0
  135. data/app/views/arclight/_requests.html.erb +7 -0
  136. data/app/views/arclight/repositories/_repository.html.erb +43 -0
  137. data/app/views/arclight/repositories/index.html.erb +9 -0
  138. data/app/views/arclight/repositories/show.html.erb +37 -0
  139. data/app/views/arclight/requests/_aeon_external_request_endpoint.html.erb +8 -0
  140. data/app/views/arclight/requests/_aeon_web_ead.html.erb +6 -0
  141. data/app/views/arclight/requests/_google_form.html.erb +10 -0
  142. data/app/views/catalog/_document_list.html.erb +8 -0
  143. data/app/views/catalog/_group.html.erb +4 -0
  144. data/app/views/catalog/_group_toggle.html.erb +10 -0
  145. data/app/views/catalog/_search_results_header.html.erb +3 -0
  146. data/app/views/catalog/hierarchy.html.erb +19 -0
  147. data/app/views/catalog/index.html.erb +17 -0
  148. data/app/views/shared/_breadcrumbs.html.erb +3 -0
  149. data/app/views/shared/_main_menu_links.html.erb +6 -0
  150. data/arclight.gemspec +29 -11
  151. data/bin/rails +13 -0
  152. data/config/breadcrumbs.rb +24 -0
  153. data/config/i18n-tasks.yml +134 -0
  154. data/config/importmap.rb +3 -0
  155. data/config/locales/arclight.en.yml +100 -0
  156. data/config/repositories.yml +0 -0
  157. data/config/routes.rb +6 -0
  158. data/docker-compose.yml +16 -0
  159. data/lib/arclight/digital_object.rb +27 -0
  160. data/lib/arclight/engine.rb +47 -0
  161. data/lib/arclight/exceptions.rb +19 -0
  162. data/lib/arclight/hash_absolute_xpath.rb +62 -0
  163. data/lib/arclight/level_label.rb +46 -0
  164. data/lib/arclight/missing_id_strategy.rb +21 -0
  165. data/lib/arclight/normalized_date.rb +49 -0
  166. data/lib/arclight/normalized_id.rb +30 -0
  167. data/lib/arclight/normalized_title.rb +33 -0
  168. data/lib/arclight/repository.rb +116 -0
  169. data/lib/arclight/routes/hierarchy.rb +19 -0
  170. data/lib/arclight/routes.rb +8 -0
  171. data/lib/arclight/traject/ead2_component_config.rb +335 -0
  172. data/lib/arclight/traject/ead2_config.rb +316 -0
  173. data/lib/arclight/traject/nokogiri_namespaceless_reader.rb +22 -0
  174. data/lib/arclight/version.rb +3 -1
  175. data/lib/arclight/year_range.rb +111 -0
  176. data/lib/arclight.rb +11 -1
  177. data/lib/generators/arclight/install_generator.rb +163 -0
  178. data/lib/generators/arclight/templates/arclight.scss +6 -0
  179. data/lib/generators/arclight/templates/catalog_controller.rb +423 -0
  180. data/lib/generators/arclight/templates/config/downloads.yml +25 -0
  181. data/lib/generators/arclight/templates/config/locales/arclight.en.yml +61 -0
  182. data/lib/generators/arclight/templates/config/repositories.yml +53 -0
  183. data/lib/generators/arclight/update_generator.rb +22 -0
  184. data/lib/tasks/index.rake +84 -0
  185. data/package.json +30 -0
  186. data/solr/conf/_rest_managed.json +3 -0
  187. data/solr/conf/admin-extra.html +31 -0
  188. data/solr/conf/elevate.xml +36 -0
  189. data/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  190. data/solr/conf/protwords.txt +21 -0
  191. data/solr/conf/schema.xml +400 -0
  192. data/solr/conf/solrconfig.xml +328 -0
  193. data/solr/conf/spellings.txt +2 -0
  194. data/solr/conf/stopwords.txt +58 -0
  195. data/solr/conf/stopwords_en.txt +58 -0
  196. data/solr/conf/synonyms.txt +31 -0
  197. data/solr/conf/xslt/example.xsl +132 -0
  198. data/solr/conf/xslt/example_atom.xsl +67 -0
  199. data/solr/conf/xslt/example_rss.xsl +66 -0
  200. data/solr/conf/xslt/luke.xsl +337 -0
  201. data/tasks/arclight.rake +79 -0
  202. data/template.rb +10 -0
  203. metadata +440 -20
  204. data/.travis.yml +0 -5
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render a simple metadata field (e.g. without labels) in a .row div
5
+ class IndexMetadataFieldComponent < Blacklight::MetadataFieldComponent
6
+ def initialize(field:, classes: ['col'], **kwargs)
7
+ super(field: field, **kwargs)
8
+
9
+ @classes = classes + ["al-document-#{@field.key.dasherize}"]
10
+ end
11
+
12
+ def render?
13
+ helpers.document_index_view_type != :compact || @field.field_config.compact
14
+ end
15
+
16
+ def truncate?
17
+ !!@field.field_config.truncate
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ <div class='al-masthead bg-light'>
2
+ <div class="container">
3
+ <div class="row align-items-center">
4
+ <div class="col-md-8" >
5
+ <div class="h1 my-4 text-center text-md-start"><%= heading %></div>
6
+ </div>
7
+
8
+ <div class="col-md-4">
9
+ <nav class="navbar navbar-expand d-flex justify-content-md-end justify-content-center" aria-label="browse">
10
+ <ul class="navbar-nav">
11
+ <%= render 'shared/main_menu_links' %>
12
+ </ul>
13
+ </nav>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ </div>
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render the masthead
5
+ class MastheadComponent < Blacklight::Component
6
+ def heading
7
+ t('arclight.masthead_heading_html')
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ <%= tag.div id: t("arclight.views.show.sections.#{@section}").parameterize do %>
2
+ <% if @heading %>
3
+ <h3 class='al-show-sub-heading'>
4
+ <%= t("arclight.views.show.sections.#{@section}", level: @presenter.document.level) %>
5
+ </h3>
6
+ <% end %>
7
+
8
+ <%= tag.dl class: @classes do %>
9
+ <% @presenter.field_presenters.each do |field_presenter| %>
10
+ <%= render (field_presenter.component || Blacklight::MetadataFieldComponent).new(field: field_presenter, show: true, **@metadata_attr) %>
11
+ <% end %>
12
+ <% end %>
13
+ <% end %>
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render a simple metadata field (e.g. without labels) in a .row div
5
+ class MetadataSectionComponent < ViewComponent::Base
6
+ with_collection_parameter :section
7
+
8
+ def initialize(section:, presenter:, metadata_attr: {}, classes: %w[row dl-invert], heading: false)
9
+ super()
10
+
11
+ @classes = classes
12
+ @section = section
13
+ @presenter = presenter.with_field_group(section)
14
+ @heading = heading
15
+ @metadata_attr = metadata_attr
16
+ end
17
+
18
+ def render?
19
+ @presenter.fields_to_render.any?
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ <%= tag.div(class: 'al-oembed-viewer', data: { controller: 'arclight-oembed', arclight_oembed_url_value: @resource.href }) do %>
2
+ <div class="al-digital-object">
3
+ <%= link_to(@resource.label, @resource.href) %>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render an oembed viewer for a document
5
+ class OembedViewerComponent < ViewComponent::Base
6
+ with_collection_parameter :resource
7
+
8
+ def initialize(resource:, document:, depth: 0)
9
+ super()
10
+
11
+ @resource = resource
12
+ @document = document
13
+ @depth = depth
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ <div class="card online-contents">
2
+ <div class="card-body d-flex align-items-center">
3
+ <div class="d-flex">
4
+ <span class="al-online-content-icon mr-2 me-2" aria-hidden="true"><%= helpers.blacklight_icon :online %></span>
5
+ <h2 class="d-none d-lg-inline">
6
+ <span class="visually-hidden">Filter</span>
7
+ <%= t('arclight.views.show.online_content.title') %>
8
+ </h2>
9
+ </div>
10
+ <div class="ms-3 ms-xl-5">
11
+ <div><%= t('arclight.views.show.online_content.description') %></div>
12
+ <%= link_to t('arclight.views.show.online_content.link_text'), helpers.search_action_path(f: { collection: [collection_name], access: ['online'] }) %>
13
+ </div>
14
+ </div>
15
+ </div>
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render the box that displays a link to filter only for online content
5
+ class OnlineContentFilterComponent < Blacklight::Component
6
+ def initialize(document:)
7
+ @document = document
8
+ super()
9
+ end
10
+
11
+ def render?
12
+ @document.collection? && @document.online_content?
13
+ end
14
+
15
+ delegate :collection_name, to: :@document
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render an online status indicator for a document
5
+ class OnlineStatusIndicatorComponent < Blacklight::Component
6
+ def initialize(document:, **)
7
+ @document = document
8
+ super()
9
+ end
10
+
11
+ def render?
12
+ @document.online_content?
13
+ end
14
+
15
+ def call
16
+ tag.span helpers.blacklight_icon(:online), class: 'al-online-content-icon'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ <li class='breadcrumb-item'>
2
+ <span class="ms-3" aria-hidden="true">
3
+ <%= blacklight_icon(:repository, classes: 'al-repository-content-icon') %>
4
+ </span>
5
+ <% if repository_path %>
6
+ <%= link_to(@document.repository, helpers.arclight_engine.repository_path(repository_path)) %>
7
+ <% else %>
8
+ <%= @document.repository %>
9
+ <% end %>
10
+ </li>
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Draws the repository breadcrumb item for a search result
5
+ class RepositoryBreadcrumbComponent < ViewComponent::Base
6
+ def initialize(document:)
7
+ super()
8
+ @document = document
9
+ end
10
+
11
+ delegate :blacklight_icon, to: :helpers
12
+
13
+ def repository_path
14
+ @document.repository_config&.slug
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ <%= render(@layout.new(field: @field)) do |component| %>
2
+ <% component.with_label do %>
3
+ <%= label %>
4
+ <% end %>
5
+ <% component.with_value do %>
6
+ <div class='al-in-person-repository-name'>
7
+ <% if repository.thumbnail_url %>
8
+ <%= image_tag repository.thumbnail_url, alt: '', class: 'img-fluid float-left' %>
9
+ <% end %>
10
+ <div>
11
+ <%= link_to(repository.name, helpers.arclight_engine.repository_path(repository.slug)) %>
12
+ </div>
13
+ </div>
14
+ <div class='al-in-person-repository-location'>
15
+ <address>
16
+ <%= repository.location %>
17
+ </address>
18
+ </div>
19
+ <% end %>
20
+ <% end %>
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render the repository location card as a metadata field
5
+ class RepositoryLocationComponent < Blacklight::MetadataFieldComponent
6
+ def repository
7
+ @field.values.first
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ <%= render(Blacklight::SearchBarComponent.new(
2
+ **@kwargs,
3
+ params: @params.merge(f: (@params[:f] || {}).except(:collection)),
4
+ q: @q,
5
+ search_field: @search_field)) do |c| %>
6
+
7
+ <% c.with_before_input_group do %>
8
+ <div class="input-group within-collection-dropdown">
9
+ <label class="input-group-text" for="within_collection">
10
+ <%= t('arclight.within_collection_dropdown.label_html') %>
11
+ </label>
12
+ <%= select_tag ('f[collection][]' if collection_name.present?), within_collection_options, id: 'within_collection', class: 'form-select search-field rounded-end' %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <% c.with_prepend do %>
17
+ <%= prepend %>
18
+ <% end %>
19
+
20
+ <% c.with_append do %>
21
+ <%= append %>
22
+ <% end if append? %>
23
+
24
+ <% c.with_search_button do %>
25
+ <%= search_button %>
26
+ <% end if respond_to?(:search_button?) && search_button? # only BL8 has this option %>
27
+ <% end %>
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Override Blacklight's SearchBarComponent to add a dropdown for choosing
5
+ # the context of the search (within "this collection" or "all collections").
6
+ # If a collection has not been chosen, it displays a dropdown with only "all collections"
7
+ # as the only selectable option.
8
+ class SearchBarComponent < Blacklight::SearchBarComponent
9
+ def initialize(**kwargs)
10
+ super
11
+
12
+ @kwargs = kwargs
13
+ end
14
+
15
+ def within_collection_options
16
+ value = collection_name || 'none-selected'
17
+ options_for_select(
18
+ [
19
+ [t('arclight.within_collection_dropdown.all_collections'), ''],
20
+ [t('arclight.within_collection_dropdown.this_collection'), value]
21
+ ],
22
+ selected: collection_name,
23
+ disabled: 'none-selected'
24
+ )
25
+ end
26
+
27
+ def collection_name
28
+ @collection_name ||= Array(@params.dig(:f, :collection)).reject(&:empty?).first ||
29
+ helpers.current_context_document&.collection_name
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,6 @@
1
+ <dt class="visually-hidden">Collection Context</dt>
2
+ <dd>
3
+ <div class='breadcrumb-links'>
4
+ <%= rendered_breadcrumbs %>
5
+ </div>
6
+ </dd>
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render the breadcrumbs for a search result document
5
+ class SearchResultBreadcrumbsComponent < Blacklight::MetadataFieldComponent
6
+ delegate :document, to: :@field
7
+
8
+ def initialize(field:, **kwargs)
9
+ @field = field
10
+ super
11
+ end
12
+
13
+ def breadcrumbs
14
+ offset = grouped? ? 2 : 0
15
+
16
+ Arclight::BreadcrumbComponent.new(document: document, count: breadcrumb_count, offset: offset)
17
+ end
18
+
19
+ def rendered_breadcrumbs
20
+ @rendered_breadcrumbs ||= capture { render breadcrumbs }
21
+ end
22
+
23
+ def render?
24
+ rendered_breadcrumbs.present?
25
+ end
26
+
27
+ def breadcrumb_count
28
+ @field.field_config.compact&.dig(:count) if compact?
29
+ end
30
+
31
+ delegate :grouped?, to: :helpers
32
+
33
+ def compact?
34
+ helpers.document_index_view_type == :compact
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ <%= content_tag @component,
2
+ id: @id,
3
+ data: {
4
+ 'document-id': @document.id.to_s.parameterize,
5
+ 'document-counter': @counter,
6
+ },
7
+ itemscope: true,
8
+ itemtype: @document.itemtype,
9
+ class: classes.flatten.join(' ') do %>
10
+ <div class="px-2 document-type-icon">
11
+ <%= icon %>
12
+ </div>
13
+ <div class="container">
14
+ <%= render Arclight::SearchResultTitleComponent.new(document: document, compact: compact?) %>
15
+
16
+ <div class="row">
17
+ <%= metadata %>
18
+ </div>
19
+ </div>
20
+ <% end %>
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render a document for a search result; this works with
5
+ # both the compact and list views for grouped or ungrouped
6
+ # results.
7
+ class SearchResultComponent < Blacklight::DocumentComponent
8
+ attr_reader :document
9
+
10
+ def compact?
11
+ presenter.view_config.key.to_s == 'compact'
12
+ end
13
+
14
+ def icon
15
+ helpers.blacklight_icon helpers.document_or_parent_icon(@document)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ <header class="documentHeader row" data-document-id="<%= @document.id %>">
2
+ <h3 class="index_title document-title-heading col">
3
+ <%= helpers.link_to_document @document, counter: @counter %>
4
+ <% @document.extent.each do |extent| %>
5
+ <%= tag.span extent, class: 'al-document-extent badge' unless compact? %>
6
+ <% end %>
7
+ <%= tag.span class: 'al-document-container text-muted' do %>
8
+ <%= @document.containers.join(', ') %>
9
+ <% end if @document.containers.present? %>
10
+ </h3>
11
+
12
+ <% actions.each do |action| %>
13
+ <%= action %>
14
+ <% end %>
15
+ </header>
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Render a document title for a search result
5
+ class SearchResultTitleComponent < Blacklight::DocumentTitleComponent
6
+ def initialize(compact:, **args)
7
+ @compact = compact
8
+ super(**args)
9
+ end
10
+
11
+ def compact?
12
+ @compact
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ <div class="offcanvas-lg offcanvas-start p-3 p-lg-1" tabindex="-1" id="sidebar">
2
+ <%= collection_context %>
3
+ <%= render 'show_tools', document: document %>
4
+ <%= collection_sidebar %>
5
+ <div id="collection-context" class="sidebar-section">
6
+ <h2><%= t('arclight.views.show.has_content') %></h2>
7
+ <%= turbo_frame_tag "al-hierarchy-#{document.root}", loading: 'lazy', src: hierarchy_solr_document_path(id: document.root, nest_path: @document.nest_path, hierarchy: true) %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # A sidebar with collection context widget and tools
5
+ class SidebarComponent < Blacklight::Document::SidebarComponent
6
+ delegate :blacklight_config, :document_presenter, :should_render_field?,
7
+ :turbo_frame_tag, to: :helpers
8
+
9
+ def collection_context
10
+ render Arclight::CollectionContextComponent.new(presenter: document_presenter(document), download_component: Arclight::DocumentDownloadComponent)
11
+ end
12
+
13
+ def collection_sidebar
14
+ render Arclight::CollectionSidebarComponent.new(document: document,
15
+ collection_presenter: document_presenter(document.collection),
16
+ partials: blacklight_config.show.metadata_partials)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Override upstream to add an offset bootstrap column class
5
+ class UpperMetadataLayoutComponent < Blacklight::MetadataFieldLayoutComponent
6
+ def initialize(field:, label_class: 'col-md-3 offset-md-1', value_class: 'col-md-8')
7
+ super
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The bookmark icon
6
+ class BookmarkComponent < Blacklight::Icons::IconComponent
7
+ self.svg = <<~SVG
8
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 384 512"><path d="M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z"/></svg>
9
+ SVG
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The collection icon
6
+ class CollectionComponent < Blacklight::Icons::IconComponent
7
+ # Used unmodified from https://fontawesome.com
8
+ # CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
9
+ self.svg = <<~SVG
10
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><path d="M32 448c0 17.7 14.3 32 32 32h384c17.7 0 32-14.3 32-32V160H32v288zm160-212c0-6.6 5.4-12 12-12h104c6.6 0 12 5.4 12 12v8c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-8zM480 32H32C14.3 32 0 46.3 0 64v48c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16V64c0-17.7-14.3-32-32-32z"/></svg>
11
+ SVG
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The compact icon
6
+ class CompactComponent < Blacklight::Icons::IconComponent
7
+ self.svg = <<~SVG
8
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><path d="M3,15H21V13H3Zm0,4H21V17H3Zm0-8H21V9H3ZM3,5V7H21V5Z"/></svg>
9
+ SVG
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The container icon
6
+ class ContainerComponent < Blacklight::Icons::IconComponent
7
+ # Used unmodified from https://fontawesome.com
8
+ # CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
9
+ self.svg = <<~SVG
10
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 512 512"><path d="M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"/></svg>
11
+ SVG
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The ead icon
6
+ class EadComponent < Blacklight::Icons::IconComponent
7
+ self.svg = <<~SVG
8
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 384 512"><path d="M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z"/></svg>
9
+ SVG
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The file icon
6
+ class FileComponent < Blacklight::Icons::IconComponent
7
+ # Used unmodified from https://fontawesome.com
8
+ # CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
9
+ self.svg = <<~SVG
10
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 384 512"><path d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"/></svg>
11
+ SVG
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The folder icon
6
+ class FolderComponent < Blacklight::Icons::IconComponent
7
+ self.svg = <<~SVG
8
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 512 512"><path d="M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"/></svg>
9
+ SVG
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The online icon
6
+ class OnlineComponent < Blacklight::Icons::IconComponent
7
+ # Used unmodified from https://fontawesome.com
8
+ # CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
9
+ self.svg = <<~SVG
10
+
11
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 640 512"><path d="M608 0H160a32 32 0 0 0-32 32v96h160V64h192v320h128a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32zM232 103a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm352 208a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm-168 57H32a32 32 0 0 0-32 32v288a32 32 0 0 0 32 32h384a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32zM96 224a32 32 0 1 1-32 32 32 32 0 0 1 32-32zm288 224H64v-32l64-64 32 32 128-128 96 96z"/></svg>
12
+ SVG
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The pdf icon
6
+ class PdfComponent < Blacklight::Icons::IconComponent
7
+ self.svg = <<~SVG
8
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 384 512"><path d="M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z"/></svg>
9
+ SVG
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ module Icons
5
+ # The repository icon
6
+ class RepositoryComponent < Blacklight::Icons::IconComponent
7
+ self.svg = <<~SVG
8
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z"/></svg>
9
+ SVG
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # Controller for our /repositories index page
5
+ class RepositoriesController < ApplicationController
6
+ def index
7
+ @repositories = Arclight::Repository.all
8
+ load_collection_counts
9
+ end
10
+
11
+ def show
12
+ @repository = Arclight::Repository.find_by!(slug: params[:id])
13
+ search_service = Blacklight.repository_class.new(blacklight_config)
14
+ @response = search_service.search(
15
+ q: "level_ssim:Collection repository_ssim:\"#{@repository.name}\"",
16
+ rows: 100
17
+ )
18
+ @collections = @response.documents
19
+ end
20
+
21
+ private
22
+
23
+ def load_collection_counts
24
+ counts = fetch_collection_counts
25
+ @repositories.each do |repository|
26
+ repository.collection_count = counts[repository.name] || 0
27
+ end
28
+ end
29
+
30
+ def fetch_collection_counts
31
+ search_service = Blacklight.repository_class.new(blacklight_config)
32
+ results = search_service.search(
33
+ q: 'level_ssim:Collection',
34
+ 'facet.field': 'repository_ssim',
35
+ rows: 0
36
+ )
37
+ Hash[*results.facet_fields['repository_ssim']]
38
+ end
39
+ end
40
+ end