geoblacklight_admin 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- 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/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 +22 -3
@@ -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
|
-
inject_into_file "app/controllers/catalog_controller.rb", after: '
|
310
|
-
"
|
316
|
+
def add_kithe_bulk_loading_service
|
317
|
+
inject_into_file "app/controllers/catalog_controller.rb", after: 'require "blacklight/catalog"' do
|
318
|
+
"\nrequire 'kithe/blacklight_tools/bulk_loading_search_service'"
|
319
|
+
end
|
320
|
+
|
321
|
+
inject_into_file "app/controllers/catalog_controller.rb", after: "include Blacklight::Catalog" do
|
322
|
+
"\nself.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
|