geoblacklight 4.1.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +3 -11
  3. data/.gitignore +9 -0
  4. data/Gemfile +14 -0
  5. data/Procfile.dev +3 -0
  6. data/README.md +5 -30
  7. data/app/assets/images/blacklight/geoblacklight-icons.json +1857 -966
  8. data/app/assets/javascripts/geoblacklight/modules/util.js +8 -3
  9. data/app/assets/javascripts/geoblacklight/templates/index_map_info.hbs +22 -1
  10. data/app/assets/javascripts/geoblacklight/viewers/cog.js +5 -0
  11. data/app/assets/javascripts/geoblacklight/viewers/pmtiles.js +5 -0
  12. data/app/controllers/download_controller.rb +1 -21
  13. data/app/frontend/clover/clover_initializer.js +29 -0
  14. data/app/frontend/entrypoints/application.js +28 -0
  15. data/app/frontend/entrypoints/clover.js +5 -0
  16. data/app/frontend/entrypoints/ol.js +5 -0
  17. data/app/frontend/openlayers/basemaps.js +47 -0
  18. data/app/frontend/openlayers/ol_initializer.js +105 -0
  19. data/app/frontend/stylesheets/openlayers.css +1 -0
  20. data/app/helpers/geoblacklight/application_helper.rb +8 -0
  21. data/app/helpers/geoblacklight_helper.rb +54 -0
  22. data/app/views/catalog/_citation.html.erb +1 -1
  23. data/app/views/catalog/_show_default_viewer_container.html.erb +1 -2
  24. data/app/views/catalog/_web_services_default.html.erb +6 -1
  25. data/app/views/catalog/_web_services_wfs.html.erb +6 -1
  26. data/app/views/catalog/_web_services_wms.html.erb +6 -1
  27. data/app/views/catalog/web_services.html.erb +16 -0
  28. data/bin/vite +29 -0
  29. data/config/locales/geoblacklight.en.yml +12 -2
  30. data/config/vite.json +14 -0
  31. data/geoblacklight.gemspec +7 -5
  32. data/lib/generators/geoblacklight/install_generator.rb +19 -4
  33. data/lib/generators/geoblacklight/templates/base.html.erb +52 -0
  34. data/lib/generators/geoblacklight/templates/catalog_controller.rb +0 -2
  35. data/lib/generators/geoblacklight/templates/settings.yml +4 -0
  36. data/lib/generators/geoblacklight/templates/vite.json +16 -0
  37. data/lib/geoblacklight/constants.rb +3 -1
  38. data/lib/geoblacklight/engine.rb +24 -0
  39. data/lib/geoblacklight/faraday_middleware/follow_redirects.rb +1 -1
  40. data/lib/geoblacklight/item_viewer.rb +13 -1
  41. data/lib/geoblacklight/metadata_transformer/base.rb +1 -1
  42. data/lib/geoblacklight/version.rb +1 -1
  43. data/package.json +8 -12
  44. data/spec/features/download_layer_spec.rb +1 -2
  45. data/spec/features/full_screen_controll_spec.rb +8 -1
  46. data/spec/features/home_page_spec.rb +3 -0
  47. data/spec/features/search_results_map_spec.rb +1 -0
  48. data/spec/features/web_services_modal_spec.rb +30 -0
  49. data/spec/fixtures/index_maps/index-map-point.geojson +949 -0
  50. data/spec/fixtures/index_maps/index-map-polygon-no-downloadurl.geojson +970 -0
  51. data/spec/fixtures/index_maps/index-map-polygon.geojson +970 -0
  52. data/spec/fixtures/index_maps/index-map-stanford.geojson +390 -0
  53. data/spec/fixtures/index_maps/index-map-v1-complex.geojson +12249 -0
  54. data/spec/fixtures/solr_documents/README.md +1 -0
  55. data/spec/fixtures/solr_documents/b1g_iiif_manifest.json +64 -0
  56. data/spec/fixtures/solr_documents/index-map-polygon-no-downloadurl.json +1 -1
  57. data/spec/fixtures/solr_documents/index-map-polygon.json +1 -1
  58. data/spec/fixtures/solr_documents/index-map-stanford.json +1 -1
  59. data/spec/fixtures/solr_documents/index-map-v1-complex.json +56 -0
  60. data/spec/fixtures/solr_documents/index_map_point.json +1 -1
  61. data/spec/fixtures/solr_documents/public_cog_princeton.json +57 -0
  62. data/spec/fixtures/solr_documents/public_pmtiles_princeton.json +41 -0
  63. data/spec/helpers/geoblacklight_helper_spec.rb +42 -0
  64. data/spec/spec_helper.rb +1 -1
  65. data/spec/test_app_templates/Gemfile.extra +0 -1
  66. data/spec/test_app_templates/lib/generators/test_app_generator.rb +7 -17
  67. data/vite.config.ts +8 -0
  68. metadata +74 -27
  69. data/spec/test_app_templates/solr_documents +0 -1
  70. /data/spec/{test_app_templates → fixtures}/metadata/fgdc.html +0 -0
  71. /data/spec/{test_app_templates → fixtures}/metadata/fgdc.xml +0 -0
  72. /data/spec/{test_app_templates → fixtures}/metadata/iso.html +0 -0
  73. /data/spec/{test_app_templates → fixtures}/metadata/iso.xml +0 -0
@@ -95,10 +95,6 @@ module Geoblacklight
95
95
  FileUtils.mkdir_p("tmp/cache/downloads") unless File.directory?("tmp/cache/downloads")
96
96
  end
97
97
 
98
- def disable_turbolinks
99
- gsub_file("app/assets/javascripts/application.js", %r{//= require turbolinks}, "")
100
- end
101
-
102
98
  def update_application_name
103
99
  gsub_file("config/locales/blacklight.en.yml", "Blacklight", "GeoBlacklight")
104
100
  end
@@ -108,9 +104,28 @@ module Geoblacklight
108
104
  FileUtils.mkdir_p("app/assets/images") unless File.directory?("app/assets/images")
109
105
  end
110
106
 
107
+ # Vite - Required for successful installation
108
+ def install_vite_rails
109
+ append_to_file "Gemfile" do
110
+ "gem \"vite_rails\", \"~> 3.0\""
111
+ end
112
+ end
113
+
114
+ # Vite - GBL Base Layout with Vite Helper Tags
115
+ def geoblacklight_base_layout
116
+ copy_file "base.html.erb", "app/views/layouts/blacklight/base.html.erb"
117
+ end
118
+
119
+ # Vite - Copy config file
120
+ def copy_config_vite_json
121
+ copy_file "vite.json", "config/vite.json"
122
+ end
123
+
124
+ # Run bundle with vite install
111
125
  def bundle_install
112
126
  Bundler.with_clean_env do
113
127
  run "bundle install"
128
+ run "bundle exec vite install"
114
129
  end
115
130
  end
116
131
  end
@@ -0,0 +1,52 @@
1
+ <!DOCTYPE html>
2
+ <%= content_tag :html, class: 'no-js', **html_tag_attributes do %>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
+ <meta name="geoblacklight-version" content="<%= Geoblacklight::VERSION %>">
8
+
9
+ <!-- Internet Explorer use the highest version available -->
10
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
11
+
12
+ <title><%= render_page_title %></title>
13
+ <script>
14
+ document.querySelector('html').classList.remove('no-js');
15
+ </script>
16
+ <%= opensearch_description_tag application_name, opensearch_catalog_url(format: 'xml') %>
17
+ <%= favicon_link_tag %>
18
+ <%= stylesheet_link_tag "application", media: "all", "data-turbo-track": "reload" %>
19
+ <%= javascript_include_tag "application", "data-turbo-track": "reload" %>
20
+
21
+ <%= vite_client_tag %>
22
+ <% if openlayers_container? %>
23
+ <%= vite_javascript_tag 'ol' %>
24
+ <% elsif iiif_manifest_container? %>
25
+ <%= vite_javascript_tag 'clover' %>
26
+ <% end %>
27
+
28
+ <%= csrf_meta_tags %>
29
+ <%= content_for(:head) %>
30
+ </head>
31
+ <body class="<%= render_body_class %>">
32
+ <nav id="skip-link" role="navigation" aria-label="<%= t('blacklight.skip_links.label') %>">
33
+ <%= link_to t('blacklight.skip_links.search_field'), '#search_field', class: 'element-invisible element-focusable rounded-bottom py-2 px-3', data: { turbolinks: 'false' } %>
34
+ <%= link_to t('blacklight.skip_links.main_content'), '#main-container', class: 'element-invisible element-focusable rounded-bottom py-2 px-3', data: { turbolinks: 'false' } %>
35
+ <%= content_for(:skip_links) %>
36
+ </nav>
37
+ <%= render partial: 'shared/header_navbar' %>
38
+
39
+ <main id="main-container" class="<%= container_classes %>" role="main" aria-label="<%= t('blacklight.main.aria.main_container') %>">
40
+ <%= content_for(:container_header) %>
41
+
42
+ <%= render partial: 'shared/flash_msg', layout: 'shared/flash_messages' %>
43
+
44
+ <div class="row">
45
+ <%= content_for?(:content) ? yield(:content) : yield %>
46
+ </div>
47
+ </main>
48
+
49
+ <%= render partial: 'shared/footer' %>
50
+ <%= render partial: 'shared/modal' %>
51
+ </body>
52
+ <% end %>
@@ -1,5 +1,3 @@
1
- require "blacklight/catalog"
2
-
3
1
  class CatalogController < ApplicationController
4
2
  include Blacklight::Catalog
5
3
 
@@ -119,6 +119,8 @@ WEBSERVICES_SHOWN:
119
119
  - 'tiled_map_layer'
120
120
  - 'dynamic_map_layer'
121
121
  - 'image_map_layer'
122
+ - 'cog'
123
+ - 'pmtiles'
122
124
 
123
125
  # Display Notes to display / Non-prefixed default bootstrap class is alert-secondary
124
126
  DISPLAY_NOTES_SHOWN:
@@ -281,6 +283,8 @@ HELP_TEXT:
281
283
  - 'wms'
282
284
  - 'tms'
283
285
  - 'oembed'
286
+ - 'pmtiles'
287
+ - 'cog'
284
288
 
285
289
  # Enable catalog#show sidebar static map for items with the following viewer protocols
286
290
  SIDEBAR_STATIC_MAP:
@@ -0,0 +1,16 @@
1
+ {
2
+ "all": {
3
+ "sourceCodeDir": "app/frontend",
4
+ "watchAdditionalPaths": []
5
+ },
6
+ "development": {
7
+ "autoBuild": true,
8
+ "publicOutputDir": "vite-dev",
9
+ "port": 3036
10
+ },
11
+ "test": {
12
+ "autoBuild": true,
13
+ "publicOutputDir": "vite-test",
14
+ "port": 3037
15
+ }
16
+ }
@@ -28,7 +28,9 @@ module Geoblacklight
28
28
  image_map_layer: "urn:x-esri:serviceType:ArcGIS#ImageMapLayer",
29
29
  data_dictionary: "http://lccn.loc.gov/sh85035852",
30
30
  index_map: "https://openindexmaps.org",
31
- oembed: "https://oembed.com"
31
+ oembed: "https://oembed.com",
32
+ cog: "https://github.com/cogeotiff/cog-spec",
33
+ pmtiles: "https://github.com/protomaps/PMTiles"
32
34
  }.freeze
33
35
  end
34
36
  end
@@ -8,9 +8,33 @@ require "geoblacklight/version"
8
8
  require "nokogiri"
9
9
  require "mime/types"
10
10
  require "handlebars_assets"
11
+ require "vite_ruby"
11
12
 
12
13
  module Geoblacklight
13
14
  class Engine < ::Rails::Engine
15
+ delegate :vite_ruby, to: :class
16
+
17
+ def self.vite_ruby
18
+ @vite_ruby ||= ViteRuby.new(root: root)
19
+ end
20
+
21
+ # Expose compiled assets via Rack::Static when running in the host app.
22
+ config.app_middleware.use(Rack::Static,
23
+ urls: ["/#{vite_ruby.config.public_output_dir}"],
24
+ root: root.join(vite_ruby.config.public_dir))
25
+
26
+ initializer "vite_rails_engine.proxy" do |app|
27
+ if vite_ruby.run_proxy?
28
+ app.middleware.insert_before 0, ViteRuby::DevServerProxy, ssl_verify_none: true, vite_ruby: vite_ruby
29
+ end
30
+ end
31
+
32
+ initializer "vite_rails_engine.logger" do
33
+ config.after_initialize do
34
+ vite_ruby.logger = Rails.logger
35
+ end
36
+ end
37
+
14
38
  # GeoblacklightHelper is needed by all helpers, so we inject it
15
39
  # into action view base here.
16
40
  initializer "geoblacklight.helpers" do
@@ -18,7 +18,7 @@ module Geoblacklight
18
18
  attr_reader :response
19
19
 
20
20
  def initialize(response)
21
- super "too many redirects; last one to: #{response["location"]}"
21
+ super("too many redirects; last one to: #{response["location"]}")
22
22
  @response = response
23
23
  end
24
24
  end
@@ -24,6 +24,10 @@ module Geoblacklight
24
24
  @references.iiif
25
25
  end
26
26
 
27
+ def iiif_manifest
28
+ @references.iiif_manifest
29
+ end
30
+
27
31
  def tiled_map_layer
28
32
  @references.tiled_map_layer
29
33
  end
@@ -64,8 +68,16 @@ module Geoblacklight
64
68
  @references.wmts
65
69
  end
66
70
 
71
+ def cog
72
+ @references.cog
73
+ end
74
+
75
+ def pmtiles
76
+ @references.pmtiles
77
+ end
78
+
67
79
  def viewer_preference
68
- [oembed, index_map, tilejson, xyz, wmts, tms, wms, iiif, tiled_map_layer, dynamic_map_layer,
80
+ [cog, pmtiles, oembed, index_map, tilejson, xyz, wmts, tms, wms, iiif_manifest, iiif, tiled_map_layer, dynamic_map_layer,
69
81
  image_map_layer, feature_layer].compact.map(&:to_hash).first
70
82
  end
71
83
  end
@@ -32,7 +32,7 @@ module Geoblacklight
32
32
  def cleaned_metadata
33
33
  transformed_doc = Nokogiri::XML(@metadata.to_html)
34
34
  if transformed_doc.xpath("//body").children.empty?
35
- fail TransformError, \
35
+ fail TransformError,
36
36
  "Failed to extract the <body> child elements from the transformed metadata"
37
37
  end
38
38
  transformed_doc.xpath("//body").children
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Geoblacklight
4
- VERSION = "4.1.1"
4
+ VERSION = "4.2.0"
5
5
  end
data/package.json CHANGED
@@ -1,20 +1,16 @@
1
1
  {
2
2
  "name": "geoblacklight",
3
- "version": "2.1.2",
3
+ "version": "4.0.0",
4
4
  "private": true,
5
5
  "license": "Apache-2.0",
6
- "private": true,
7
- "scripts": {
8
- "test": "jest -c jest.config.js"
6
+ "dependencies": {
7
+ "@samvera/clover-iiif": "^2.3.2",
8
+ "ol": "8.1.0",
9
+ "ol-pmtiles": "^0.3.0",
10
+ "react": "^18.2.0"
9
11
  },
10
12
  "devDependencies": {
11
- "@babel/cli": "^7.12.16",
12
- "@babel/core": "^7.12.16",
13
- "@babel/plugin-transform-runtime": "^7.12.15",
14
- "@babel/preset-env": "^7.12.16",
15
- "@testing-library/dom": "^7.29.4",
16
- "@testing-library/jest-dom": "^5.11.9",
17
- "jest": "^26.6.3",
18
- "jest-fixtures": "^0.6.0"
13
+ "vite": "^5.0.0",
14
+ "vite-plugin-ruby": "^5.0.0"
19
15
  }
20
16
  }
@@ -27,8 +27,7 @@ feature "Download layer" do
27
27
  visit solr_document_path("mit-f6rqs4ucovjk2")
28
28
  find("#downloads-button").click
29
29
  find('#downloads-collapse a[data-download-type="shapefile"]', text: "Export Shapefile").click
30
- expect(page).to have_css "div.alert.alert-danger", text: "Sorry, the requested file could not be downloaded. Try downloading it directly from:"
31
- expect(page).to have_css "a", text: "http://www.example.com/failed"
30
+ expect(page).to have_css "div.alert.alert-danger", text: "Sorry, the requested file could not be downloaded."
32
31
  end
33
32
 
34
33
  scenario "clicking kmz download button should trigger download", js: true do
@@ -4,7 +4,7 @@ require "spec_helper"
4
4
 
5
5
  feature "Leaflet fullscreen control", js: true do
6
6
  scenario "IIIF layer should have full screen control" do
7
- visit solr_document_path("princeton-sx61dn82p")
7
+ visit solr_document_path("princeton-02870w62c")
8
8
  expect(page).to have_css(".leaflet-control-fullscreen-button")
9
9
  end
10
10
 
@@ -13,3 +13,10 @@ feature "Leaflet fullscreen control", js: true do
13
13
  expect(page).to have_css(".leaflet-control-fullscreen-button")
14
14
  end
15
15
  end
16
+
17
+ feature "Clover IIIF fullscreen control", js: true do
18
+ scenario "IIIF layer should have full screen control" do
19
+ visit solr_document_path("princeton-sx61dn82p")
20
+ expect(page).to have_css("#fullPage")
21
+ end
22
+ end
@@ -44,4 +44,7 @@ feature "Home page", js: true do # use js: true for tests which require js, but
44
44
  results = page.all(:css, "article.document")
45
45
  expect(results.count).to equal(4)
46
46
  end
47
+ scenario "pages should have meta tag with geoblacklight version" do
48
+ expect(page.body).to include("geoblacklight-version")
49
+ end
47
50
  end
@@ -36,6 +36,7 @@ feature "search results map", js: true do
36
36
  expect(top.to_f).to be_within(1).of(45)
37
37
  end
38
38
  scenario "view is scoped to NYC" do
39
+ skip "spec inconsistently failing"
39
40
  visit root_path
40
41
  click_link "New York, New York"
41
42
  expect(page).to have_css "#map"
@@ -57,4 +57,34 @@ feature "web services tools" do
57
57
  end
58
58
  end
59
59
  end
60
+ feature "when a PMTiles reference is provided", js: true do
61
+ scenario "shows up in tools" do
62
+ visit solr_document_path "princeton-t722hd30j"
63
+ expect(page).to have_css "div.web-services-sidebar a", text: "Web services"
64
+ click_link "Web services"
65
+ within ".modal-body" do
66
+ expect(page).to have_css "label", text: "PMTiles Layer"
67
+ expect(page).to have_css 'input[value="https://geodata.lib.princeton.edu/fe/d2/80/fed28076eaa04506b7956f10f61a2f77/display_vector.pmtiles"]'
68
+ end
69
+ end
70
+ end
71
+ feature "when a COG reference is provided", js: true do
72
+ scenario "shows up in tools" do
73
+ visit solr_document_path "princeton-dc7h14b252v"
74
+ expect(page).to have_css "div.web-services-sidebar a", text: "Web services"
75
+ click_link "Web services"
76
+ within ".modal-body" do
77
+ expect(page).to have_css "label", text: "COG Layer"
78
+ expect(page).to have_css 'input[value="https://geodata.lib.princeton.edu/13/f5/58/13f5582c32a54be98fc2982077d0456e/display_raster.tif"]'
79
+ end
80
+ end
81
+ end
82
+ feature "copy to clipboard is provided", js: true do
83
+ scenario "shows up in tools" do
84
+ visit solr_document_path "princeton-dc7h14b252v"
85
+ expect(page).to have_css "div.web-services-sidebar a", text: "Web services"
86
+ click_link "Web services"
87
+ expect(page).to have_text "Copy"
88
+ end
89
+ end
60
90
  end