geoblacklight_admin 0.3.2 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/app/controllers/admin/document_downloads_controller.rb +1 -1
- data/app/controllers/admin/ids_controller.rb +3 -0
- data/app/controllers/admin/imports_controller.rb +2 -2
- data/app/helpers/geoblacklight_admin_helper.rb +30 -0
- data/app/jobs/bulk_action_collect_documents.rb +11 -0
- data/app/jobs/geoblacklight_admin/store_image_job.rb +12 -0
- data/app/models/asset.rb +13 -0
- data/app/models/bulk_action.rb +8 -5
- data/app/models/bulk_actions/change_publication_state.rb +21 -0
- data/app/models/concerns/geoblacklight_admin/publication_state_search_behavior.rb +26 -0
- data/app/models/document/date_validator.rb +46 -0
- data/app/models/document.rb +114 -2
- data/app/models/document_access.rb +3 -1
- data/app/models/document_download.rb +3 -1
- data/app/models/element.rb +1 -0
- data/app/services/geoblacklight_admin/image_service/dynamic_map_layer.rb +15 -0
- data/app/services/geoblacklight_admin/image_service/iiif.rb +17 -0
- data/app/services/geoblacklight_admin/image_service/image_map_layer.rb +17 -0
- data/app/services/geoblacklight_admin/image_service/tiled_map_layer.rb +15 -0
- data/app/services/geoblacklight_admin/image_service/wms.rb +28 -0
- data/app/services/geoblacklight_admin/image_service.rb +238 -0
- data/app/services/geoblacklight_admin/item_viewer.rb +31 -0
- data/app/uploaders/asset_uploader.rb +31 -0
- data/app/views/admin/document_assets/index.html.erb +13 -1
- data/app/views/admin/documents/_document.html.erb +1 -1
- data/app/views/admin/documents/_document_kithe.html.erb +47 -0
- data/app/views/admin/documents/_form_nav.html.erb +1 -1
- data/app/views/admin/documents/_form_nav_kithe.html.erb +30 -0
- data/app/views/admin/documents/_result_facets.html.erb +26 -2
- data/app/views/admin/documents/index.html.erb +4 -8
- data/app/views/admin/documents/versions.html.erb +1 -1
- data/app/views/admin/imports/show.html.erb +35 -9
- data/app/views/admin/shared/_navbar.html.erb +6 -6
- data/db/migrate/20231106215104_bulk_action_sti.rb +10 -0
- data/lib/generators/geoblacklight_admin/config_generator.rb +33 -3
- data/{app/controllers/admin → lib/generators/geoblacklight_admin/templates}/api_controller.rb +4 -1
- data/lib/generators/geoblacklight_admin/templates/config/initializers/shrine.rb +3 -2
- data/lib/generators/geoblacklight_admin/templates/config/settings.yml +4 -1
- data/lib/generators/geoblacklight_admin/templates/views/_index_split_default.html.erb +27 -0
- data/lib/geoblacklight_admin/version.rb +1 -1
- data/lib/tasks/geoblacklight_admin/images.rake +30 -0
- metadata +24 -5
@@ -0,0 +1,238 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "addressable/uri"
|
4
|
+
|
5
|
+
module GeoblacklightAdmin
|
6
|
+
class ImageService
|
7
|
+
attr_reader :document
|
8
|
+
attr_writer :metadata, :logger
|
9
|
+
|
10
|
+
def initialize(document)
|
11
|
+
@document = document
|
12
|
+
|
13
|
+
@metadata = {}
|
14
|
+
@metadata["solr_doc_id"] = document.id
|
15
|
+
@metadata["placeheld"] = false
|
16
|
+
|
17
|
+
@logger ||= ActiveSupport::TaggedLogging.new(
|
18
|
+
Logger.new(
|
19
|
+
Rails.root.join("log", "image_service_#{Rails.env}.log")
|
20
|
+
)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Stores the document's image in ActiveStorage
|
25
|
+
# @return [Boolean]
|
26
|
+
#
|
27
|
+
def store
|
28
|
+
# Gentle hands
|
29
|
+
sleep(1)
|
30
|
+
|
31
|
+
puts "Storing ImageService..."
|
32
|
+
puts "Document ID: #{@document.id}"
|
33
|
+
|
34
|
+
io_file = image_tempfile(@document.id)
|
35
|
+
|
36
|
+
if io_file.nil?
|
37
|
+
puts "IO is NIL"
|
38
|
+
else
|
39
|
+
puts "Attaching IO"
|
40
|
+
attach_io(io_file)
|
41
|
+
end
|
42
|
+
|
43
|
+
log_output
|
44
|
+
rescue => e
|
45
|
+
@metadata["exception"] = e.inspect
|
46
|
+
log_output
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def image_tempfile(document_id)
|
52
|
+
# puts "IMAGE TEMPFILE..."
|
53
|
+
puts "Document Viewer Protocol: #{@document.viewer_protocol}"
|
54
|
+
# puts "Image URL: #{image_url}"
|
55
|
+
# puts "IMAGE DATA: #{image_data}"
|
56
|
+
|
57
|
+
@metadata["viewer_protocol"] = @document.viewer_protocol
|
58
|
+
@metadata["image_url"] = image_url
|
59
|
+
@metadata["gblsi_thumbnail_uri"] = gblsi_thumbnail_uri
|
60
|
+
|
61
|
+
# puts "IMAGE DATA: #{image_data.inspect}"
|
62
|
+
|
63
|
+
return nil unless image_data && @metadata["placeheld"] == false
|
64
|
+
|
65
|
+
temp_file = Tempfile.new("#{document_id}.tmp")
|
66
|
+
temp_file.binmode
|
67
|
+
temp_file.write(image_data)
|
68
|
+
temp_file.rewind
|
69
|
+
|
70
|
+
# puts "TEMPFILE: #{temp_file.inspect}"
|
71
|
+
|
72
|
+
@metadata["image_tempfile"] = temp_file.inspect
|
73
|
+
temp_file
|
74
|
+
end
|
75
|
+
|
76
|
+
def attach_io(io)
|
77
|
+
# Remote content-type headers are untrustworthy
|
78
|
+
# Pull the mimetype and file extension via MimeMagic
|
79
|
+
content_type = Marcel::MimeType.for(File.open(io))
|
80
|
+
mime_type = Marcel::TYPES[content_type][0][0]
|
81
|
+
|
82
|
+
puts "Content Type: #{content_type.inspect}"
|
83
|
+
puts "MIME Type: #{mime_type.inspect}"
|
84
|
+
|
85
|
+
if content_type.start_with?("image")
|
86
|
+
|
87
|
+
puts "\n\nStoring an image!\n\n"
|
88
|
+
|
89
|
+
asset = Asset.new
|
90
|
+
asset.parent_id = @document.id
|
91
|
+
asset.file = io
|
92
|
+
asset.title = (asset.file&.original_filename || "Untitled")
|
93
|
+
asset.thumbnail = true
|
94
|
+
asset.save
|
95
|
+
else
|
96
|
+
# @TODO: If no thumb, what to do?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns geoserver auth credentials if the document is a restriced Local WMS layer.
|
101
|
+
def geoserver_credentials
|
102
|
+
return unless restricted_wms_layer?
|
103
|
+
|
104
|
+
Settings.PROXY_GEOSERVER_AUTH&.gsub("Basic ", "")
|
105
|
+
end
|
106
|
+
|
107
|
+
def restricted_wms_layer?
|
108
|
+
@document.local_restricted? && @document.viewer_protocol == "wms"
|
109
|
+
end
|
110
|
+
|
111
|
+
# Tests if geoserver credentials are set beyond the default.
|
112
|
+
def geoserver_credentials_valid?
|
113
|
+
Settings.PROXY_GEOSERVER_AUTH != "Basic base64encodedusername:password"
|
114
|
+
end
|
115
|
+
|
116
|
+
# Tests if local thumbnail method is configured
|
117
|
+
def gblsi_thumbnail_field?
|
118
|
+
Settings.GBLSI_THUMBNAIL_FIELD
|
119
|
+
end
|
120
|
+
|
121
|
+
def gblsi_thumbnail_uri
|
122
|
+
if gblsi_thumbnail_field? && @document.send(Settings.GBLSI_THUMBNAIL_FIELD)
|
123
|
+
@document.send(Settings.GBLSI_THUMBNAIL_FIELD)
|
124
|
+
else
|
125
|
+
false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Generates hash containing thumbnail mime_type and image.
|
130
|
+
def image_data
|
131
|
+
# puts "IMAGE DATA..."
|
132
|
+
return nil unless image_url
|
133
|
+
|
134
|
+
remote_image
|
135
|
+
end
|
136
|
+
|
137
|
+
# Gets thumbnail image from URL. On error, placehold image.
|
138
|
+
def remote_image
|
139
|
+
# puts "remote_image..."
|
140
|
+
auth = geoserver_credentials
|
141
|
+
|
142
|
+
uri = Addressable::URI.parse(image_url)
|
143
|
+
|
144
|
+
return nil unless uri.scheme.include?("http")
|
145
|
+
|
146
|
+
conn = Faraday.new(url: uri.normalize.to_s) do |b|
|
147
|
+
b.use Geoblacklight::FaradayMiddleware::FollowRedirects
|
148
|
+
b.adapter :net_http
|
149
|
+
end
|
150
|
+
|
151
|
+
conn.options.timeout = timeout
|
152
|
+
conn.authorization :Basic, auth if auth
|
153
|
+
conn.get.body
|
154
|
+
rescue Faraday::ConnectionFailed
|
155
|
+
@metadata["error"] = "Faraday::ConnectionFailed"
|
156
|
+
@metadata["placeheld"] = true
|
157
|
+
nil
|
158
|
+
rescue Faraday::TimeoutError
|
159
|
+
@metadata["error"] = "Faraday::TimeoutError"
|
160
|
+
@metadata["placeheld"] = true
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
|
164
|
+
# Returns the thumbnail url.
|
165
|
+
# If the layer is restriced Local WMS, and the geoserver credentials
|
166
|
+
# have not been set beyond the default, then a thumbnail url from
|
167
|
+
# dct references is used instead.
|
168
|
+
def image_url
|
169
|
+
# puts "IMAGE URL..."
|
170
|
+
# puts "gblsi_thumbnail_uri: #{gblsi_thumbnail_uri.inspect}"
|
171
|
+
# puts "restricted_scanned_map?: #{restricted_scanned_map?}"
|
172
|
+
# puts "service_url: #{service_url.inspect}"
|
173
|
+
# puts "image_reference: #{image_reference.inspect}"
|
174
|
+
|
175
|
+
@image_url ||= gblsi_thumbnail_uri || service_url || image_reference
|
176
|
+
end
|
177
|
+
|
178
|
+
# Checks if the document is Local restriced access and is a scanned map.
|
179
|
+
def restricted_scanned_map?
|
180
|
+
@document.local_restricted?
|
181
|
+
end
|
182
|
+
|
183
|
+
# Gets the url for a specific service endpoint if the item is
|
184
|
+
# public, has the same institution as the GBL instance, and the viewer
|
185
|
+
# protocol is not 'map' or nil. A module name is then dynamically generated
|
186
|
+
# from the viewer protocol, and if it's loaded, the image_url
|
187
|
+
# method is called.
|
188
|
+
def service_url
|
189
|
+
# puts "SERVICE URL..."
|
190
|
+
# Follow image_url instead
|
191
|
+
return nil if gblsi_thumbnail_uri
|
192
|
+
|
193
|
+
@service_url ||=
|
194
|
+
begin
|
195
|
+
return unless @document.available?
|
196
|
+
|
197
|
+
protocol = @document.viewer_protocol
|
198
|
+
|
199
|
+
if protocol == "map" || protocol.nil?
|
200
|
+
@metadata["error"] = "Unsupported viewer protocol"
|
201
|
+
@metadata["placeheld"] = true
|
202
|
+
return nil
|
203
|
+
end
|
204
|
+
|
205
|
+
puts "Image Service: #{protocol.to_s.camelcase}"
|
206
|
+
|
207
|
+
"GeoblacklightAdmin::ImageService::#{protocol.to_s.camelcase}".constantize.image_url(@document, image_size)
|
208
|
+
rescue NameError
|
209
|
+
@metadata["error"] = "service_url NameError"
|
210
|
+
@metadata["placeheld"] = true
|
211
|
+
return nil
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# Retreives a url to a static thumbnail from the document's dct_references field, if it exists.
|
216
|
+
def image_reference
|
217
|
+
@document.references["http://schema.org/thumbnailUrl"]
|
218
|
+
end
|
219
|
+
|
220
|
+
# Default image size.
|
221
|
+
def image_size
|
222
|
+
1500
|
223
|
+
end
|
224
|
+
|
225
|
+
# Faraday timeout value.
|
226
|
+
def timeout
|
227
|
+
30
|
228
|
+
end
|
229
|
+
|
230
|
+
# Capture metadata within image harvest log
|
231
|
+
def log_output
|
232
|
+
# @metadata["state"] = @document.sidecar.image_state.current_state
|
233
|
+
@metadata.each do |key, value|
|
234
|
+
@logger.tagged(@document.id, key.to_s) { @logger.info value }
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GeoblacklightAdmin
|
4
|
+
class ItemViewer
|
5
|
+
def initialize(references)
|
6
|
+
@references = references
|
7
|
+
@keys = references.keys.collect { |k| reference_uri_2_key(k) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def viewer_protocol
|
11
|
+
viewer_preference.find { |vp| @keys.include?(vp) } || :map
|
12
|
+
end
|
13
|
+
|
14
|
+
def viewer_endpoint
|
15
|
+
@references[viewer_protocol_2_endpoint]
|
16
|
+
end
|
17
|
+
|
18
|
+
def reference_uri_2_key(value)
|
19
|
+
Geoblacklight::Constants::URI.key(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def viewer_protocol_2_endpoint
|
23
|
+
Geoblacklight::Constants::URI[viewer_protocol]
|
24
|
+
end
|
25
|
+
|
26
|
+
def viewer_preference
|
27
|
+
[:oembed, :index_map, :tilejson, :xyz, :wmts, :tms, :wms, :iiif, :tiled_map_layer, :dynamic_map_layer,
|
28
|
+
:image_map_layer, :feature_layer]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class AssetUploader < Kithe::AssetUploader
|
2
|
+
# gives us md5, sha1, sha512
|
3
|
+
plugin :kithe_checksum_signatures
|
4
|
+
|
5
|
+
THUMB_WIDTHS = {
|
6
|
+
mini: 54,
|
7
|
+
large: 525,
|
8
|
+
standard: 208
|
9
|
+
}
|
10
|
+
|
11
|
+
# define thumb derivatives for TIFF, PDF, and other image input: :thumb_mini, :thumb_mini_2X, etc.
|
12
|
+
THUMB_WIDTHS.each_pair do |key, width|
|
13
|
+
# Single-width thumbnails
|
14
|
+
Attacher.define_derivative("thumb_#{key}", content_type: "image") do |original_file|
|
15
|
+
Kithe::VipsCliImageToJpeg.new(max_width: width, thumbnail_mode: true).call(original_file)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Double-width thumbnails
|
19
|
+
Attacher.define_derivative("thumb_#{key}_2X", content_type: "image") do |original_file|
|
20
|
+
Kithe::VipsCliImageToJpeg.new(max_width: width * 2, thumbnail_mode: true).call(original_file)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# and a full size jpg
|
25
|
+
Attacher.define_derivative("download_full", content_type: "image") do |original_file, attacher:|
|
26
|
+
# No need to do this if our original is a JPG
|
27
|
+
unless attacher.file.content_type == "image/jpeg"
|
28
|
+
Kithe::VipsCliImageToJpeg.new.call(original_file)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -30,16 +30,28 @@
|
|
30
30
|
<table class="table table-striped table-bordered sortable">
|
31
31
|
<thead class="thead-dark">
|
32
32
|
<tr>
|
33
|
+
<th>Thumbnail</th>
|
34
|
+
<th>Preview</th>
|
33
35
|
<th>Title</th>
|
34
36
|
<th>MimeType</th>
|
35
37
|
<th>Actions</th>
|
36
38
|
</tr>
|
37
39
|
</thead>
|
38
|
-
|
39
40
|
<tbody>
|
40
41
|
<% @document_assets.each do |document_asset| %>
|
41
42
|
<tr>
|
43
|
+
<td>
|
44
|
+
<% if document_asset.respond_to?(:thumbnail) %>
|
45
|
+
<%= document_asset.respond_to?(:thumbnail) %>
|
46
|
+
<% end %>
|
47
|
+
</td>
|
48
|
+
<td>
|
49
|
+
<% if document_asset.respond_to?(:thumbnail) %>
|
50
|
+
<%= image_tag(document_asset.file_url(:thumb_mini_2X), { height: 100 }) %>
|
51
|
+
<% end %>
|
52
|
+
</td>
|
42
53
|
<td><%= link_to(document_asset.title, document_asset.file.url) %></td>
|
54
|
+
|
43
55
|
<td>
|
44
56
|
<%= document_asset.file_data["metadata"]["mime_type"] %>
|
45
57
|
<span class="sr-only"><%= document_asset.inspect %></span>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<% bookmarked = current_user.document_is_bookmarked?(document) ? 'bookmarked' : '' %>
|
2
|
+
|
3
|
+
<% if document.respond_to?('friendlier_id') %>
|
4
|
+
<%= content_tag :li, id: document.friendlier_id, class: "#{bookmarked} mb-3" do %>
|
5
|
+
<div class="row">
|
6
|
+
<div class="doc-actions ml-3">
|
7
|
+
<%= check_box_tag nil, nil, false, data: { id: document.friendlier_id, action: 'click->results#checkChecked'}%>
|
8
|
+
<%= render 'admin/documents/document_bookmark', document: document %>
|
9
|
+
</div>
|
10
|
+
<div class="doc-hit col ml-2 mb-2">
|
11
|
+
<div class="row" style="font-size:1.1rem;">
|
12
|
+
<%= "#{@documents.meta['pages']['offset_value'] + index + 1}." if @documents %>
|
13
|
+
<%= link_to document.title, edit_admin_document_path(document.friendlier_id), { class: "js-truncate mb-2" } %>
|
14
|
+
</div>
|
15
|
+
<div class="row">
|
16
|
+
<div class="media">
|
17
|
+
<% if document&.members&.first&.file&.exists? %>
|
18
|
+
<%= link_to edit_admin_document_path(document.friendlier_id) do %>
|
19
|
+
<%= image_tag(document.members.first.file_url(:thumb_mini_2X), { height: 64, width:64 }) %>
|
20
|
+
<% end %>
|
21
|
+
<% else %>
|
22
|
+
<img class="" data-src="holder.js/64x64" alt="placeholder" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2264%22%20height%3D%2264%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_18bb5833508%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A10pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_18bb5833508%22%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2213.83984375%22%20y%3D%2236.65%22%3E64x64%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" data-holder-rendered="true" style="width: 64px; height: 64px;">
|
23
|
+
<% end %>
|
24
|
+
<div class="media-body ml-3">
|
25
|
+
<%- if document.send(Settings.FIELDS.RESOURCE_CLASS) %>
|
26
|
+
<%= geoblacklight_icon(document.send(Settings.FIELDS.RESOURCE_CLASS)&.first) %>
|
27
|
+
<% end %>
|
28
|
+
<%= publication_state_badge(document) %>
|
29
|
+
<% if document.send("schema_provider_s") %>
|
30
|
+
· <%= document.send("schema_provider_s") %>
|
31
|
+
<% end %>
|
32
|
+
<% if document.send("dct_temporal_sm") %>
|
33
|
+
· <%= document.send("dct_temporal_sm").join("-") %>
|
34
|
+
<% end %>
|
35
|
+
<% if document.send("dct_description_sm").present? %>
|
36
|
+
<p class="js-truncate"><%= document.send("dct_description_sm").join %></p>
|
37
|
+
<% end %>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
<% end %>
|
43
|
+
<% else %>
|
44
|
+
<li>
|
45
|
+
<p><strong>Missing from database: </strong><%= document.inspect %></p>
|
46
|
+
</li>
|
47
|
+
<% end %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="make-me-sticky mt-4 ml-4">
|
2
2
|
<nav class="nav flex-column ml-4 mt-6">
|
3
3
|
<% if @document.persisted? %>
|
4
|
-
<strong class="
|
4
|
+
<strong class="mb-4"><%= link_to "GBL♦Admin | View in GeoBlacklight", solr_document_url(@document), { class: 'btn btn-warning' } %></strong>
|
5
5
|
<% end %>
|
6
6
|
|
7
7
|
<%- form_elements = FormElement.all.order(position: :asc) %>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<div class="make-me-sticky mt-4 ml-4">
|
2
|
+
<nav class="nav flex-column ml-4 mt-6">
|
3
|
+
<% if @document.persisted? %>
|
4
|
+
<strong class="mb-4"><%= link_to "GBL♦Admin | View in GeoBlacklight", solr_document_url(@document), { class: 'btn btn-warning' } %></strong>
|
5
|
+
|
6
|
+
<% if @document&.members&.first&.file&.exists? %>
|
7
|
+
<%= link_to admin_document_document_assets_url(@document) do %>
|
8
|
+
<strong class="mt-2">Thumbnail</strong><br>
|
9
|
+
<%= image_tag(@document.members.first.file_url(:thumb_standard_2X), { class: "p-2", width: 150 }) %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%- form_elements = FormElement.all.order(position: :asc) %>
|
15
|
+
<%- form_elements.each do |form_element| %>
|
16
|
+
<% if form_element.kind_of? FormHeader %>
|
17
|
+
<strong class="mt-2"><a data-controller="scroll-to" class="mt-4" href="#<%= form_element.label.parameterize(separator: '-') %>"><%= form_element.label %></a></strong>
|
18
|
+
<% end %>
|
19
|
+
<% if form_element.kind_of? FormGroup %>
|
20
|
+
<a data-controller="scroll-to" class="ml-2" href="#<%= form_element.label.parameterize(separator: '-') %>"><%= form_element.label %></a>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<% if @document.persisted? %>
|
25
|
+
<%= link_to "Institutional Access Links", admin_document_document_accesses_url(@document), class: "ml-2" %>
|
26
|
+
<%= link_to "Multiple Download Links", admin_document_document_downloads_url(@document), class: "ml-2" %>
|
27
|
+
<%= link_to "Additional Assets", admin_document_document_assets_url(@document), class: "ml-2" %>
|
28
|
+
<% end %>
|
29
|
+
</nav>
|
30
|
+
</div>
|
@@ -1,4 +1,28 @@
|
|
1
|
-
|
1
|
+
<a class="h5" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
|
2
|
+
Imports
|
3
|
+
</a>
|
4
|
+
|
5
|
+
<% if params["f"]&.keys&.include?("b1g_geom_import_id_ssi") %>
|
6
|
+
<% import = Import.find_by_id(params["f"]["b1g_geom_import_id_ssi"]) %>
|
7
|
+
<ul class="list-unstyled mt-3">
|
8
|
+
<li><%= link_to("- #{import.name} ❌".html_safe) %></li>
|
9
|
+
</ul>
|
10
|
+
<% else %>
|
11
|
+
<div class="collapse" id="collapseExample">
|
12
|
+
<ul class="list-unstyled mt-3">
|
13
|
+
<% Import.last(20).sort_by(&:created_at).reverse.each do |import| %>
|
14
|
+
<li>
|
15
|
+
<%= link_to_admin_import(import) %> -
|
16
|
+
<small><%= time_ago_in_words(import.created_at) %> ago</small>
|
17
|
+
</li>
|
18
|
+
<% end %>
|
19
|
+
</ul>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<hr/>
|
24
|
+
|
25
|
+
<%= form_with url: '/admin/documents', method: :get, local: true do |form| %>
|
2
26
|
<div class="input-group mb-3" style="width:300px">
|
3
27
|
<%= form.text_field("daterange", { class: 'form-control', placeholder: 'Date range filter', size: 24, 'aria-label': "Date range filter", value: params['daterange'] }) %>
|
4
28
|
<%= params_as_hidden_fields(
|
@@ -16,7 +40,7 @@
|
|
16
40
|
<% if @documents.facets.present? %>
|
17
41
|
<% @documents.facets.each do |facet| %>
|
18
42
|
<% if facet['type'] == 'facet' %>
|
19
|
-
<%- next if ['b1g_code_s', 'dct_isPartOf_sm'].include?(facet['id']) %>
|
43
|
+
<%- next if ['b1g_geom_import_id_ssi', 'b1g_code_s', 'dct_isPartOf_sm'].include?(facet['id']) %>
|
20
44
|
<h3 class="h5"><%= facet['attributes']['label'] %></h3>
|
21
45
|
<ul class="list-unstyled">
|
22
46
|
<%- facet['attributes']['items'].each do |item| %>
|
@@ -11,18 +11,14 @@
|
|
11
11
|
</div>
|
12
12
|
|
13
13
|
<div id="resultset" class="col-8">
|
14
|
-
<p>
|
15
|
-
<%= render "result_toggle" %>
|
16
|
-
<%= render "result_selected_options" %>
|
17
|
-
<%= render "result_pagination" %>
|
18
|
-
</p>
|
19
|
-
|
20
|
-
<hr/>
|
21
14
|
|
15
|
+
<%= render "result_toggle" %>
|
16
|
+
<%= render "result_selected_options" %>
|
17
|
+
<%= render "result_pagination" %>
|
22
18
|
<%= render "result_selection_options" %>
|
23
19
|
|
24
20
|
<% if @documents.results.present? && @documents.results.kind_of?(Array) %>
|
25
|
-
<ol id='results' class='list-unstyled' data-controller='results'>
|
21
|
+
<ol id='results' class='list-unstyled mt-4' data-controller='results'>
|
26
22
|
<% @documents.results.each_with_index do |document, index| %>
|
27
23
|
<% doc = Document.find_by(friendlier_id: document['id']) %>
|
28
24
|
<% if doc.present? %>
|
@@ -33,7 +33,7 @@
|
|
33
33
|
<%- # Current Document %>
|
34
34
|
<%- if index == 0 %>
|
35
35
|
<%- current = @document.json_attributes %>
|
36
|
-
<%- previous = version
|
36
|
+
<%- previous = version&.previous&.reify&.json_attributes %>
|
37
37
|
<%- diff = Hashdiff.diff(previous,current) %>
|
38
38
|
<%- changeset = version.changeset.except(:json_attributes).collect{ |change| ["+", change[0], change[1][1]] }.flatten %>
|
39
39
|
<%- diff << changeset %>
|
@@ -50,7 +50,7 @@
|
|
50
50
|
<h3 class="h5">Imported Documents</h3>
|
51
51
|
</div>
|
52
52
|
<ul class="list-group list-group-flush">
|
53
|
-
<li class="list-group-item
|
53
|
+
<li class="list-group-item">
|
54
54
|
<% if @import.state_machine.current_state == 'mapped' %>
|
55
55
|
<%= form_tag run_admin_import_path(@import), method: :patch do -%>
|
56
56
|
<%= hidden_field_tag :run, true -%>
|
@@ -58,7 +58,34 @@
|
|
58
58
|
<%- end -%>
|
59
59
|
<% end %>
|
60
60
|
<% if @import.state_machine.current_state == 'imported' %>
|
61
|
-
|
61
|
+
<table class="table table-sm table-bordered import-documents">
|
62
|
+
<thead>
|
63
|
+
<tr>
|
64
|
+
<th>Publication State</th>
|
65
|
+
<th>Document Count</th>
|
66
|
+
</tr>
|
67
|
+
</thead>
|
68
|
+
<tbody>
|
69
|
+
<tr>
|
70
|
+
<td><%= link_to_gbl_import('Published', @import, 'published') %></td>
|
71
|
+
<td><%= @import.documents.where(publication_state: 'published').size %></td>
|
72
|
+
</tr>
|
73
|
+
<tr>
|
74
|
+
<td><%= link_to_gbl_import('Unpublished', @import, 'unpublished') %></td>
|
75
|
+
<td><%= @import.documents.where(publication_state: 'unpublished').size %></td>
|
76
|
+
</tr>
|
77
|
+
<tr>
|
78
|
+
<td><%= link_to_gbl_import('Draft', @import, 'draft') %></td>
|
79
|
+
<td><%= @import.documents.where(publication_state: 'draft').size %></td>
|
80
|
+
</tr>
|
81
|
+
</tbody>
|
82
|
+
<tfoot>
|
83
|
+
<tr>
|
84
|
+
<th><%= link_to_gbl_import('Total', @import) %></th>
|
85
|
+
<td><%= @import.documents.size %></td>
|
86
|
+
</tr>
|
87
|
+
</tfoot>
|
88
|
+
</table>
|
62
89
|
<% end %>
|
63
90
|
</li>
|
64
91
|
</ul>
|
@@ -104,19 +131,18 @@
|
|
104
131
|
|
105
132
|
<nav>
|
106
133
|
<div class="nav nav-tabs" id="import-state-tabs" role="tablist">
|
107
|
-
<a class="nav-item nav-link active" id="import-
|
108
|
-
<a class="nav-item nav-link" id="import-
|
109
|
-
aria-selected="false">Success</a>
|
134
|
+
<a class="nav-item nav-link active" id="import-success-tab" data-toggle="tab" href="#import-state-success" role="tab" aria-controls="import-state-success" aria-selected="true">Success</a>
|
135
|
+
<a class="nav-item nav-link" id="import-failed-tab" data-toggle="tab" href="#import-state-failed" role="tab" aria-controls="import-state-failed" aria-selected="false">Failed</a>
|
110
136
|
</div>
|
111
137
|
</nav>
|
112
138
|
|
113
139
|
<div class="tab-content" id="import-states">
|
114
|
-
<div class="tab-pane fade show active" id="import-state-
|
115
|
-
<%= render partial: '
|
140
|
+
<div class="tab-pane fade show active" id="import-state-success" role="tabpanel" aria-labelledby="import-state-success-tab">
|
141
|
+
<%= render partial: 'show_success_tab' %>
|
116
142
|
</div>
|
117
143
|
|
118
|
-
<div class="tab-pane fade" id="import-state-
|
119
|
-
<%= render partial: '
|
144
|
+
<div class="tab-pane fade" id="import-state-failed" role="tabpanel" aria-labelledby="import-state-failed-tab">
|
145
|
+
<%= render partial: 'show_failed_tab' %>
|
120
146
|
</div>
|
121
147
|
</div>
|
122
148
|
</div>
|
@@ -19,15 +19,15 @@
|
|
19
19
|
<% end %>
|
20
20
|
|
21
21
|
<div class="input-group-append">
|
22
|
-
<button class="btn btn-outline-secondary my-2 my-sm-0" type="submit">
|
23
|
-
|
24
|
-
|
22
|
+
<button class="btn btn-outline-secondary my-2 my-sm-0" type="submit">
|
23
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
|
24
|
+
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/>
|
25
|
+
</svg>
|
26
|
+
<span class="sr-only">Search</span>
|
25
27
|
</button>
|
26
|
-
<div class="dropdown-menu">
|
27
|
-
<%= link_to "Advanced", admin_search_path, { class: 'dropdown-item' } %>
|
28
|
-
</div>
|
29
28
|
</div>
|
30
29
|
</div>
|
30
|
+
<%= link_to "Advanced", admin_search_path, { class: 'btn my-2 my-sm-0' } %>
|
31
31
|
<% end %>
|
32
32
|
|
33
33
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class BulkActionSti < ActiveRecord::Migration[6.1]
|
4
|
+
def change
|
5
|
+
add_column :bulk_actions, :bulk_action_type, :string, default: "ChangePublicationState", null: false
|
6
|
+
add_column :bulk_actions, :action, :string, null: true
|
7
|
+
change_column :bulk_actions, :field_name, :string, null: true
|
8
|
+
change_column :bulk_actions, :field_value, :string, null: true
|
9
|
+
end
|
10
|
+
end
|
@@ -270,10 +270,18 @@ module GeoblacklightAdmin
|
|
270
270
|
end
|
271
271
|
end
|
272
272
|
|
273
|
+
def add_api_controller
|
274
|
+
copy_file "api_controller.rb", "app/controllers/admin/api_controller.rb"
|
275
|
+
end
|
276
|
+
|
273
277
|
def add_user_util_links
|
274
278
|
copy_file "_user_util_links.html.erb", "app/views/shared/_user_util_links.html.erb"
|
275
279
|
end
|
276
280
|
|
281
|
+
def copy_catalog_index_view
|
282
|
+
copy_file "views/_index_split_default.html.erb", "app/views/catalog/_index_split_default.html.erb"
|
283
|
+
end
|
284
|
+
|
277
285
|
def add_show_sidebar
|
278
286
|
copy_file "_show_sidebar.html.erb", "app/views/catalog/_show_sidebar.html.erb"
|
279
287
|
end
|
@@ -305,9 +313,31 @@ module GeoblacklightAdmin
|
|
305
313
|
end
|
306
314
|
end
|
307
315
|
|
308
|
-
def
|
309
|
-
|
310
|
-
"
|
316
|
+
def add_kithe_bulk_loading_service
|
317
|
+
prepend_to_file "app/controllers/catalog_controller.rb" do
|
318
|
+
"require 'kithe/blacklight_tools/bulk_loading_search_service'\n\n"
|
319
|
+
end
|
320
|
+
|
321
|
+
inject_into_file "app/controllers/catalog_controller.rb", after: "include Blacklight::Catalog" do
|
322
|
+
"\n self.search_service_class = Kithe::BlacklightTools::BulkLoadingSearchService"
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def add_kithe_model_to_solr_document
|
327
|
+
inject_into_file "app/models/solr_document.rb", after: "include Geoblacklight::SolrDocument" do
|
328
|
+
"\n\nattr_accessor :model"
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def add_search_builder_publication_state_concern
|
333
|
+
inject_into_file "app/models/search_builder.rb", after: "include Geoblacklight::SuppressedRecordsSearchBehavior" do
|
334
|
+
"\n include GeoblacklightAdmin::PublicationStateSearchBehavior"
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def add_import_id_facet
|
339
|
+
inject_into_file "app/controllers/catalog_controller.rb", before: "# Item Relationship Facets" do
|
340
|
+
"\nconfig.add_facet_field Settings.FIELDS.B1G_IMPORT_ID, label: 'Import ID', show: false\n"
|
311
341
|
end
|
312
342
|
end
|
313
343
|
end
|